如何通过URL获取Itemid并将其传递给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?


如果您比item知道itemid,则reporting&Itemid = 123。我不建议执行此过程,因为如果您的自定义组件已经发布,则应自动执行此操作。
2014年

Answers:


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...是否有一些特定的东西?
Fedik
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.