Currently JRoute generates URLs for my component which look like this https://mysite.com/component/mycomponent/xxx
, where I'm handling xxx in my component's router. Instead I'd like JRoute to generate a URL for the same location with https://mysite.com/myseflocation/xxx
.
I've found four ways of achieving what I want, but I don't find any of them particularly satisfactory. All of my ideas require a menu item with alias myseflocation
to which a view from my component is assigned. Its the creation and assignment of this menu item which is fundamentally where my problem lies.
My first idea was to include the Itemid=xx
query string parameter in URLs passed into JRoute. The problem with this approach is that I'd be hard coding the menu Itemids all over the place which is a terrible idea as its tightly coupling the fixed code to the dynamic database.
The next idea I had, was to give my component a menuitem
parameter, then the admin could create a menu item, assign one of the component's views to it, then assign that new menu item back to the component parameter. Whenever using JRoute, you could just get the menu item id from the component parameter.
The problem with this is that it requires the site admin to have knowledge of how my component works; they have to create a menu item and then assign that item back within the component. The problem with this is that if the menu item is ever removed, then the component parameter becomes broken unless the admin reassigns it.
The next two ideas are just really extensions on the last one, but requiring a little less intervention on behalf of the admin.
It may be possible to generate a hidden menu item on installation of the component, then use JFactory::getApplication()->getMenu()
to fetch the menu's item id when needed, using the name of the menu. However, this would also suffer from the problem of an admin deleting the menu item and would also require quite a bit of additional code to save the menu item correctly and check for duplicates.
My final idea it to add code to my component router's build
method, to get all menu items to which my component is assigned, like this:
$menu = JFactory::getApplication()->getMenu()
->getItems('component','com_sorn')
Then just get the first menu item from the resulting array and set it as the Itemid
within the $query array.
The upside of this last method is that it can fall back to the /component/mycomponent/
path if no menu item is set. However, if the admin wanted two menu items to work with my component, only the first would generate correct URLs.
I guess the fundamental problem here is that I don't think Joomla allows components to claim first-level routes (first slug in URL), only menu items can do this. This means you're left with an item id you cannot know at component installation time and which could change in the future.