【问题标题】:Force Joomla JRoute to use the menu item强制 Joomla JRoute 使用菜单项
【发布时间】:2014-08-31 21:15:55
【问题描述】:

我正在为 Joomla 构建一个组件! 2.5 和内部我使用JRoute::_('index.php?option=com_myapp&view=cpanel') 来构建我的所有链接。这可行,但它会产生如下所示的链接:

/component/myapp/cpanel.html

然而,在菜单中,我已经定义 index.php?option=com_myapp&view=cpanel 的别名是“myapp”,所以链接应该是

/myapp/cpanel.html

组件可通过此路径访问。如果我这样做,内部生成的所有链接也将具有 /myapp 前缀。但是用于模板(特殊登录链接)并且如果用户偶然发现/component/myapp.... 我仍然希望所有链接都转到/myapp 前缀。

如何强制 JRoute 自己使用这个菜单项?

【问题讨论】:

    标签: php joomla routes joomla2.5 url-routing


    【解决方案1】:

    理想情况下,您需要将路由器设置为组件的一部分。菜单管理器将覆盖 component/myapp 位,但之后的内容将由 router.php 文件中的内容决定。

    http://docs.joomla.org/Supporting_SEF_URLs_in_your_component

    但是,如果您只需要创建指向特定菜单项的链接,那么您可以随时将 Itemid 添加到您的参数中

    JRoute::_('index.php?Itemid=12')
    

    将指向任何 ID 为 12 的菜单项,因此如果这是您的 com_myapp 组件的菜单项 ID,它将创建指向该页面的链接的菜单版本。

    编辑:

    从技术上讲,您可以将相同的组件分配给两个菜单项,因此当您链接到菜单项之外的组件而不为链接提供 itemid 时,我不认为处理 URL 的开头是默认行为。 Joomla 说(关于为 JRoute 创建链接)...

    "请注意,可以省略参数选项和 项目编号。选项默认为当前正在使用的组件的名称 已执行,Itemid 默认为当前菜单项的 ID。"

    即,从您的主页(或一组之外的任何页面以使用您的组件)调用它,不带 itemid 或选项,它可能会认为您在 com_content 中并带有主页菜单项。

    如果您想链接到菜单项之外的组件但不硬编码 itemid,那么一种方法是将 Menuitem 字段类型添加到您要链接的模块或模板的配置选项中,然后将它生成的 itemid 添加到您的链接中。

    您还可以使用 JFactory::getApplication()->getMenu() 来查找链接到您的组件的菜单项。没有机会对此进行测试 - 但使用它也可能意味着您可以在路由器中设置 itemid 参数。

    【讨论】:

    • 感谢您的回答。我的组件中有一个 router.php,这部分工作正常。问题是:当我用这个组件设置另一个 Joomla 时,菜单项会有不同的 id。通常(如果我正确理解核心 router.php)Joomla 应该注意将正确菜单项上的 sef 路由分配给我的组件。
    • Joomla 使用反向查找来查找潜在的匹配菜单项,如果您不使用类别,它基本上对您没有多大帮助。所以你需要为此编写一些自定义处理。您可能需要克隆 sef 插件并添加自己的处理方式。
    • 感谢两位的意见。似乎确实没有办法自动检测相应的菜单项。现在我只使用我的答案中的代码。
    【解决方案2】:
    //look if there is a menu item set for myapp. if yes, we use that one to redirect
    $db  = JFactory::getDBO();
    $defaultRedirect = 'index.php?option=com_myapp&view=cpanel';
    $db->setQuery('SELECT `id` FROM #__menu WHERE `link` LIKE '. $db->Quote($defaultRedirect) .' LIMIT 1' );
    $itemId = ($db->getErrorNum())? 0 : intval($db->loadResult());
    if($itemId){
        $rpath = JRequest::getString('return', base64_encode(JRoute::_('index.php?Itemid='.$itemId)));
    }else{
        $rpath = JRequest::getString('return', base64_encode(JRoute::_('index.php?option=com_myapp&view=cpanel')));
    }
    

    注意:这不是语言安全的。它采用在 db 中找到的第一个菜单项。如果您为不同的语言设置不同的菜单别名,您也必须在 SQL 查询中检查正确的语言。

    【讨论】:

    • 您应该在查询中添加“ AND published = 1 ”,否则您的查询将导致未发布/截断项目的错误。
    【解决方案3】:

    因为我在这个问题上遇到了很多困难,所以我做了一个快速功能,它会尝试根据菜单项找到链接。主要是根据其他答案。

    这仅在 Joomla 3.5 上进行了测试。 JRequest 已被弃用,因此使用 $app->input 代替。这可能会做得更好,但至少它适用于我对它的使用。希望它也可以帮助其他人!

    public static function getRouteMenu($default_url) {
        $db = JFactory::getDbo();
        $app = JFactory::getApplication();
        $jinput = $app->input;
    
        $db->setQuery('SELECT `id` FROM #__menu WHERE `link` LIKE '. $db->Quote($default_url) .' AND `published` = 1 LIMIT 1' );
        $itemId = $db->loadResult();
        if($itemId) {
            $route = $jinput->getString('return', JRoute::_('index.php?Itemid='.$itemId));
            $route = str_replace('index.php/', '', $route);
        } else {
            $route = $jinput->getString('return', JRoute::_($default_url));
        }
    
        return $route;
    }
    

    该参数需要一个未重写的链接,例如:index.php?option=com_content&view=article&id=10。如果您需要确定如何建立此链接,请检查您的数据库。

    【讨论】:

      猜你喜欢
      • 2011-10-13
      • 2011-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多