Як отримати Itemid за URL-адресою та передати його JRoute


14

У мене є пункт меню для певного перегляду в користувацькому компоненті. До цього пункту меню у мене є ще один Template Styleобраний, а не стандартний шаблон. Доступ до подання через меню працює добре, оскільки додається до URL-адреси Itemid.

Тепер я хочу зв’язати, використовуючи JRoute, подання з іншим, однак JRoute не генерує потрібну URL-адресу.

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

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

JRoute не додасть Itemid до URL-адреси, внаслідок чого вибраний стиль шаблону для пункту меню не працює.

Чи є спосіб "обчислити" Itemid (крім того, щоб робити запит у таблиці jos_menuна стовпчику link) та приєднати його до JRoute?


якщо ви знаєте itemid, ніж робити, звітування & Itemid = 123. Я не раджу цю процедуру, оскільки ваш користувацький компонент повинен робити це автоматично, якщо він уже опублікований.
День

Відповіді:


20

Ось метод, який я використав (не можу згадати, де я його знайшов).

$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);

Це творило чудеса для мене.


4

вихід від JRoute буде залежати від того, чим ви його годуєте.

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

може повернути щось інше, ніж

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

Насправді, якщо у вас є список блогу пункту меню для catid = 5, останній може дати вам URL-адресу меню (я не перевіряв цю точну URL-адресу). Спробуйте з різними параметрами get отримати різні результати (іноді дуже неправильно, як, наприклад, @Fedik сказав)


3

Тут важливо налаштувати ваш файл router.php компонентів (який слід знайти у кореневій папці вашого компонента на передньому кінці) з логікою, яка шукатиме та вибирає відповідний пункт меню. Я хотів би, щоб це відбувалося автоматично, але наскільки я знаю, це не так.

Напевно, найкраще буде опрацювати цей блок коду в якомусь типі допоміжної функції, який можна використовувати для автоматичного пошуку найкращого пункту меню для вмісту.

Ось код, який я використав у кількох моїх користувацьких компонентах, щоб отримати найкращий варіант меню:

// 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();
    }
}

Все це є свого роду безлад (і я б хотів покращити, якщо хтось їх має!), Але це робить роботу. Якщо поточний пункт меню найкраще відповідає, він завжди буде дотримуватися цього.

В іншому випадку він повинен знайти найкращу відповідність на основі назви компонента -> ім'я перегляду -> назва макета -> значення id. Чим далі справа відповідає, тим краще я вважаю відповідність!


2

Afaik JRoute візьме активного Itemid(а також активного option), якщо такого не передбачено. Якщо це не працює, це означає, що дзвінок до вашого коду починається без Itemid. Якщо так, найпростіше було б додати Itemid до початкового виклику.

Якщо вам потрібно шукати пункт меню, я б не робив прямий запит, а використовував натомість JMenu.


Я помітив, що в деяких випадках JRouter може повернути якусь божевільну URL-адресу, якщо спробувати надати власний Itemid, приклад для JRoute::_('index.php?option=com_example&view=reporting&Itemid=10')JRouter може повернутися /current-path?view=reporting&Itemid=10... чи є якісь конкретні речі?
Федік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.