Cara mendapatkan Itemid dengan URL dan meneruskannya ke JRoute

14

Saya memiliki item menu untuk tampilan tertentu dalam komponen khusus. Terlampir pada item menu ini saya telah Template Stylememilih yang lain , bukan template standar. Mengakses tampilan melalui menu berfungsi dengan baik, karena melampirkan ke URL Itemid.

Sekarang saya ingin menautkan, menggunakan JRoute, tampilan dengan yang lain, namun JRoute tidak menghasilkan URL yang diinginkan.

echo JRoute::_('index.php?option=com_example&view=reporting');

/index.php?option=com_example&view=reporting

JRoute tidak akan menambahkan Itemid ke URL, menyebabkan gaya templat yang dipilih untuk item menu tidak berfungsi.

Apakah ada cara untuk "menghitung" Itemid (selain dari melakukan kueri dalam tabel jos_menupada kolom link) dan melampirkannya ke JRoute?

Valentin Despa
sumber
jika Anda tahu itemid daripada yang dilakukan, pelaporan & Itemid = 123. Saya tidak menyarankan prosedur ini karena komponen khusus Anda harus melakukan ini secara otomatis jika sudah diterbitkan.
Dan

Jawaban:

20

Berikut adalah teknik yang saya gunakan (tidak dapat mengingat di mana saya menemukannya).

$app = JFactory::getApplication(); 
$menu = $app->getMenu();
$menuItem = $menu->getItems( 'link', 'index.php?option=com_example&view=reporting', true );
echo JRoute::_('index.php?Itemid='.$menuItem->id);

Ini merupakan keajaiban bagi saya.

Jordan Ramstad
sumber
4

output dari JRoute akan tergantung pada apa yang Anda makan.

JRoute::_("index.php?option=com_content&view=article&id=10"); 

mungkin mengembalikan sesuatu selain

JRoute::_("index.php?option=com_content&view=article&id=10&catid=5"); 

Bahkan jika Anda memiliki item menu kategori daftar blog untuk catid = 5, yang terakhir mungkin memberi Anda menu-url (Saya belum menguji url ini dengan tepat). Coba dengan parameter get yang berbeda untuk mendapatkan hasil yang berbeda (terkadang sangat salah, seperti kata @Fedik)

jonasfh
sumber
3

Kuncinya di sini adalah mengatur file komponen router.php Anda (yang harus ditemukan di folder root komponen Anda di ujung depan) dengan logika yang akan mencari dan memilih item menu yang sesuai. Saya ingin melihat ini terjadi secara otomatis, tetapi sejauh yang saya tahu ini bukan masalahnya.

Mungkin akan lebih baik untuk mengerjakan blok kode ini ke beberapa jenis fungsi pembantu yang dapat digunakan untuk secara otomatis menemukan item menu yang paling cocok untuk konten.

Berikut adalah kode yang telah saya gunakan di beberapa komponen khusus saya untuk mendapatkan item menu yang paling pas:

// I use this first empty array to avoid having unset properties in my query
$base_array = array('Itemid'=>'', 'option'=>'', 'view'=>'', 'layout'=>'', 'id'=>'');

$app =& JFactory::getApplication();
$menu       = $app->getMenu();
$active = $menu->getActive();

// hack to protect the actual current item as well as the search module or other places that use JRoute::_('index.php');
if (count($query)==2 && isset($query['option']) && isset($query['Itemid']) && $query['option'] && $query['Itemid']) {
    return $segments;
}

// start with no match found
$match = false;
$match_level = 0;

$query += $base_array;

// we want to find a menu item for this if possible. If the active menu item is the current menu item then we should see if there is a better match.
if (empty($query['Itemid']) || ($query['Itemid'] == $active->id && empty($query['task']))) {
    // load all menu items
    $items = $menu->getMenu();

    // use the current item over others if it ties for the best match
    if ($active->query['option'] == $query['option']) {
        $match_level = 1;
        $match = $active;
        if ($active->query['view'] == $query['view']) {
            $match_level = 2;
            if ($active->query['layout'] == $query['layout'] || ($query['layout']=='default' && !$active->query['layout'])) {
                $match_level = 3;
                if ($active->query['id'] == $query['id']) {
                    $match_level = 4;
                }
            }
        }
    }

    // loop through each menu item in order
    foreach ($items as $item) {
        $item->query += $base_array;
        // base check is that it is for this component
        // then cycle through each possibility finding it's match level
        if ($item->query['option'] == $query['option']) {
            $item_match = 1;
            if ($item->query['view'] == $query['view']) {
                $item_match = 2;
                if (!$query['layout'] && $item->query['layout']) {
                    $query['layout'] = 'default';
                }
                if ($item->query['layout'] == $query['layout'] || ($query['layout']=='default' && !$item->query['layout'])) {
                    $item_match = 3;
                    if ($item->query['id'] == $query['id']) {
                        $item_match = 4;
                    }
                }
            }
        }

        // if this item is a better match than our current match, set it as the best match
        if ($item_match > $match_level) {
            $match = $item;
            $match_level = $item_match;
        }

    }

    // if there is a match update Itemid to match that menu item
    if ($match) {
        $query['Itemid'] = $match->id;
        $menuItem = $menu->getItem($match->id);
    } else {
        $menuItem = $menu->getActive();
    }
}

Semua ini agak berantakan (dan saya ingin perbaikan jika ada yang memilikinya!), Tapi itu menyelesaikan pekerjaan. Jika item menu saat ini adalah yang paling cocok, itu akan selalu tetap dengan itu.

Kalau tidak, ia akan menemukan kecocokan terbaik berdasarkan Nama komponen -> nama tampilan -> nama tata letak -> nilai id. Semakin jauh ke kanan cocok, semakin baik saya menganggap pertandingan!

David Fritsch
sumber
2

Afaik JRoute akan mengambil yang aktif Itemid(dan juga yang aktif option) jika tidak ada yang disediakan. Jika itu tidak berhasil, itu berarti panggilan ke kode Anda datang tanpa Itemid untuk memulai. Jika demikian, hal termudah adalah menambahkan Itemid ke panggilan awal.

Jika Anda perlu mencari item menu, saya tidak akan melakukan query langsung tetapi menggunakan JMenu sebagai gantinya.

Bakual
sumber
Saya perhatikan bahwa dalam beberapa kasus JRouter dapat mengembalikan beberapa URL gila, jika coba berikan Itemid sendiri, contoh untuk JRoute::_('index.php?option=com_example&view=reporting&Itemid=10')JRouter dapat kembali /current-path?view=reporting&Itemid=10... apakah ada beberapa hal khusus?
Fedik