简体   繁体   中英

Force Joomla JRoute to use the menu item

I'm building a component for Joomla! 2.5 and inside I'm using JRoute::_('index.php?option=com_myapp&view=cpanel') to build all my links. This works, BUT it produces links which look like that:

/component/myapp/cpanel.html

In the menu however I have defined that index.php?option=com_myapp&view=cpanel has an alias of "myapp" so the link should rather be

/myapp/cpanel.html

The component is accessible via this path. If I do that, also all links generated inside will have the /myapp prefix. But for use in a template (special login link) and if the user stumbles upon /component/myapp .... I still want all links to go to /myapp prefix.

How can I force JRoute to use this menu item entry by itself?

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

Beware: This is NOT language-safe. It takes the first menu entry found in the db. If you setup different menu aliases for different languages you have to check for the right language in the SQL query, too.

Because I struggled a lot with this issue, here's a quick function I did that will try to find the link based on a menu item. It's mainly based on other answers.

This has only been tested on Joomla 3.5. JRequest is deprecated, so $app->input is used instead. This might be done better, but at least it works for the use I have of it. Hopes it can help other people too !

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;
}

The parameter requires a not rewrited link such as : index.php?option=com_content&view=article&id=10 . Check your database if you need to be sure about how to build up this link.

You ideally need to set a router as part of your component. The menu manager will override the component/myapp bit, but what comes after that will be determined by what is in the router.php file.

http://docs.joomla.org/Supporting_SEF_URLs_in_your_component

If, however, you simply need to create a link to a specific menu item, then you can always just add an Itemid to your parameter

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

will point to any menu item with the id 12, so if that is your menu item ID for your com_myapp component, it will create the menu version of the link to that page.

edit:

You could technically assign the same component to two menu items, so I don't believe that handling the beginning of the URL is default behaviour when you link to a component outside of a menu item without giving the link an itemid. Joomla say (on creating a link for JRoute)...

"Notice that it is possible to leave out the parameters option and Itemid. option defaults to the name of the component currently being executed, and Itemid defaults to the current menu item's ID."

ie, call it from your homepage (or any page outside of one set to use your component) without an itemid or option and it is likely to think you are in com_content and with the homepage menu item.

If you want to link to the component outside of a menu item but without hard-coding an itemid, then one way would be to add a Menuitem field type to the config options of the module or template where you are linking from, and then add the itemid it generates to your link.

You could also use JFactory::getApplication()->getMenu() to find which menu item is linking to your component. Not had chance to test this - but using that could also mean that you can set an itemid parameter in your router.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM