0

I am in the process of migrating a large Joomla component from v3.x (with lots of legacy code from 1.5+!) to Joomla 5 at present.

One item I have stumbled upon is how best to bootstrap the component's site router for use within the administrator component code. That is, I have the following line within a utility function that is invoked both from within the administrator and site component code:

Route::link("site", "index.php?option=com_helloworld&view=hellowview&id=123");

At present, I get a No router available for this application. error message.

As far as I can surmise, I have correctly migrated my old router.php file to src/Service/Router.php within the site code and updated it to implement RouterInterface. However, the class is not loaded when in the Adminstrator area and I am not certain what the correct way to get this loaded would be.

3
  • The Joomla back-end does not use SEF URLs and does not use a router.
    – pe7er
    Feb 28 at 12:49
  • Well, I still need to be able to generate SEF URLs for front-end content within views in the back-end. The above worked find in J3.x
    – John Rix
    Feb 28 at 12:51
  • I wrote the answer below, but investigating the issue a bit more I don't think what I've said is correct. I think the className is still the \..\Site\Service\Router that it looks for. So it either can't find your file, or the fully qualified class name in your file is incorrect. Could you post the namespace and class name that you use within your Router.php file? Feb 29 at 19:45

1 Answer 1

2

Corrected Response ----------------

I tried this on a Joomla 4 component which I have and it worked ok, so I reckon you should be able to get it working.

That exception gets created in the RouterFactory in libraries/src/Component/Router/RouterFactory.php. It's because it's trying to create the class name from:

$className = trim($this->namespace, '\\') . '\\' . ucfirst($application->getName()) . '\\Service\\Router';

On the admin site the $application->getName() will return 'administrator', so it will build the namespace prefix using \Administrator, and will look for the Service Router class in administrator/components/<your component>/src/Service/Router.php and thus not find it.

You could copy your Router.php to there, and change your namespace statement in that PHP file to be in the \Administrator side. Then it would find your class.

The alternative is to create the Router class yourself, rather than use the Joomla RouterFactory to create it. In your extension you can provide your own function

public function createRouter(CMSApplicationInterface $application, AbstractMenu $menu): RouterInterface
{
    return new Router($application, $menu, $this->categoryFactory, $this->getDatabase());
}

where Router points to your site Router class. Then you would use the same Router class for both when you're on the front-end and the back-end.

You can see a bit more explanation at https://docs.joomla.org/J3.x:Developing_an_MVC_Component/Upgrading_to_Joomla4#Router where the equivalent class is called TraditionalRouter, and there's a link to a zip file for that component.

If you're getting the menuitems inside your router code then to make it work on the back end you'll need to do

use Joomla\CMS\Factory;
$app = Factory::getApplication();
$sitemenu = $app->getMenu('site');
$sitemenu->load();

but you're probably aware of that if you have it working before.

Note also that there are some changes as to how you need to code your custom router when you upgrade to Joomla 4. That tutorial step lists those as well.

1
  • Thankyou! Both alternatives of copying the file to the administrator area or adding my own createRouter method to my extension class got things over the line. I have opted for the latter to keep things clean. (Note, the last two parameters in your sample there are not necessary, at least not according to the RouterServiceInterface definition.) Regarding the article you mentioned, I have already been using that a good bit up to now and found it quite helpful, so thank you again on that count also. I recognised your name here accordingly!
    – John Rix
    Mar 1 at 0:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.