If the module uses a symfony controller then the best way of route generation is described in symfony docs. However, module, especially if using legacy controllers, don’t always have access to the symfony container or router. The Link
component offers some helpers to help generate urls related to Symfony controllers and routes.
<?php
use Link;
// Generate url with Symfony route
$symfonyUrl = Link::getUrlSmarty(array('entity' => 'sf', 'route' => 'admin_product_catalog'));
// Generate url with Symfony route and arguments
$symfonyUrl = Link::getUrlSmarty(array(
'entity' => 'sf',
'route' => 'admin_product_unit_action',
'sf-params' => array(
'action' => 'delete',
'id' => 42,
)
));
<?php
use Context;
$link = Context::getContext()->link;
// Generate url with Symfony route (first argument is the legacy controller, even though it should be ignored)
$symfonyUrl = $link->getAdminLink('AdminProducts', true, array('route' => 'admin_product_catalog'));
// Generate url with Symfony route and arguments
$symfonyUrl = $link->getAdminLink('AdminProducts', true, array(
'route' => 'admin_product_unit_action',
'action' => 'delete',
'id' => 42,
));
Not every developer use the getAdminLink
method the same way, therefore the _legacy_link
is able to recognize different
uses of this method, for example via an action
parameter (e.g: ?controller=AdminEmails&action=export
).
But sometimes urls simply insert the action name as a parameter (e.g: ?controller=AdminPaymentPreferences&update
). As
long as the actions have been migrated and correctly set up they will be successfully converted.
Given this configuration:
admin_payment_preferences:
path: /preferences
methods: [GET]
defaults:
_controller: PrestaShopBundle:Admin\Improve\Payment\PaymentPreferences:index
_legacy_controller: AdminPaymentPreferences
_legacy_link: AdminPaymentPreferences
admin_payment_preferences_process:
path: /preferences/update
methods: [POST]
defaults:
_controller: PrestaShopBundle:Admin\Improve\Payment\PaymentPreferences:processForm
_legacy_controller: AdminPaymentPreferences
_legacy_link: AdminPaymentPreferences:update
<?php
$link = New Link();
//These calls will return /preferences
$link->getAdminLink('AdminPaymentPreferences');
$link->getAdminLink('AdminPaymentPreferences', true, ['action' => 'list']);
$link->getAdminLink('AdminPaymentPreferences', true, [], ['action' => 'index']);
//These calls will return /preferences/update
$link->getAdminLink('AdminPaymentPreferences', true, [], ['action' => 'update']);
$link->getAdminLink('AdminPaymentPreferences', true, [], ['update' => true]); =>
$link->getAdminLink('AdminPaymentPreferences', true, [], ['update' => '']); =>
//This call will return ?controller=AdminPaymentPreferences&action=export
//because the export action has not been migrated yet
$link->getAdminLink('AdminPaymentPreferences', true, [], ['action' => 'export']);
Be careful, Link is sometimes misused
Some examples have been found where urls are generated by a mix of getAdminLink
and concatenating parameters:
<?php
$link = new Link();
$link->getAdminLink('AdminPaymentPreferences') . '?action=update';
This won’t work because the parameters will be appended to the index url. You should be extra careful about these misused code and replace it according to the minimum PrestaShop version you are targeting:
Router
service directly with the appropriate route name and parameters.getAdminLink
method with the parameters fully injected in the function.Remember that _legacy_link
is only available since 1.7.5 version of PrestaShop, for older versions you need to update the Link
class to manage routing conversion.
<?php
// classes/Link.php, in getAdminLink()
$routes = array(
'AdminModulesSf' => 'admin_module_manage',
'AdminStockManagement' => 'admin_stock_overview',
//...
'LegacyController' => 'migrated_route',
);
This will only work for one route/one controller the association by action does not work before 1.7.5.
In order to generate a symfony route in javascript, you can use the Router
component.
You can use it like this:
import Router from '@components/router';
this.router = new Router();
const route = this.router.generate('my_route', {parameters});
It however uses a computed file that you might need to recompute if you modified some route settings.
You can recompute it using this:
php bin/console fos:js-routing:dump --format=json
And put it in admin-dev/themes/new-theme/js/fos_js_routes.json
exposed: true
in route configuration), else javascript router will not be able to discover and generate the route.