Problem/Motivation
Entity link templates are still route names instead of paths, and the names of the corresponding routes do not always start with entity..
Proposed resolution
- Convert link template values from route names to paths.
- Make sure the names of the routes belonging to link templates are prefixed with
entity..
Remaining tasks
None.
User interface changes
None.
API changes
Route renames.
Data model changes
None.
Original report
If currency is installed and you enable devel module you get the above exception.
Additional uncaught exception thrown while handling exception.
Original
InvalidArgumentException: Link templates accepts paths, which have to start with a leading slash. in Drupal\Core\Entity\EntityType->setLinkTemplate() (line 582 of /var/www/MY-PROJECT/core/lib/Drupal/Core/Entity/EntityType.php).
Drupal\Core\Entity\EntityType->setLinkTemplate('devel-load', 'currency.currency.edit/devel')
devel_entity_type_alter(Array, NULL, NULL)
Drupal\Core\Extension\ModuleHandler->alter('entity_type', Array)
Drupal\Core\Entity\EntityManager->findDefinitions()
Drupal\Core\Plugin\DefaultPluginManager->getDefinitions()
Drupal\Core\Plugin\DefaultPluginManager->getDefinition('user_role', )
Drupal\Core\Entity\EntityManager->getDefinition('user_role', )
Drupal\Core\Entity\EntityManager->hasHandler('user_role', 'storage')
Drupal\user\Theme\AdminNegotiator->applies(Object)
Drupal\Core\Theme\ThemeNegotiator->determineActiveTheme(Object)
Drupal\Core\Theme\ThemeManager->initTheme(NULL)
Drupal\Core\Theme\ThemeManager->getActiveTheme()
Drupal\Core\Render\ElementInfoManager->getInfo('page')
Drupal\Core\Render\Renderer->doRender(Array, 1)
Drupal\Core\Render\Renderer->render(Array, 1)
Drupal\Core\Render\BareHtmlPageRenderer->renderBarePage(Array, 'Error', 'maintenance_page', Array)
Drupal\Core\DependencyInjection\Container\prod\Drupal_Core_Render_BareHtmlPageRenderer_Proxy->renderBarePage(Array, 'Error', 'maintenance_page')
Drupal\Core\EventSubscriber\DefaultExceptionSubscriber->onHtml(Object)
Drupal\Core\EventSubscriber\DefaultExceptionSubscriber->onException(Object, 'kernel.exception', Object)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.exception', Object)
Symfony\Component\HttpKernel\HttpKernel->handleException(Object, Object, 1)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1)
Drupal\Core\DependencyInjection\Container\prod\Symfony_Component_HttpKernel_HttpKernel_Proxy->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1)
Drupal\Core\DependencyInjection\Container\prod\Drupal_Core_StackMiddleware_Session_Proxy->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1)
Drupal\Core\DependencyInjection\Container\prod\Drupal_Core_StackMiddleware_KernelPreHandle_Proxy->handle(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1)
Stack\StackedHttpKernel->handle(Object, 1, 1)
Drupal\Core\DrupalKernel->handle(Object)
Additional
InvalidArgumentException: Link templates accepts paths, which have to start with a leading slash. in Drupal\Core\Entity\EntityType->setLinkTemplate() (line 582 of /var/www/MY-PROJECT/core/lib/Drupal/Core/Entity/EntityType.php).
Drupal\Core\Entity\EntityType->setLinkTemplate('devel-load', 'currency.currency.edit/devel')
devel_entity_type_alter(Array, NULL, NULL)
Drupal\Core\Extension\ModuleHandler->alter('entity_type', Array)
Drupal\Core\Entity\EntityManager->findDefinitions()
Drupal\Core\Plugin\DefaultPluginManager->getDefinitions()
Drupal\Core\Plugin\DefaultPluginManager->getDefinition('currency', )
Drupal\Core\Entity\EntityManager->getDefinition('currency')
Drupal\Core\Entity\EntityManager->getHandler('currency', 'storage')
Drupal\Core\Entity\EntityManager->getStorage('currency')
Drupal\currency\Element\CurrencyAmount::create(Object, Array, 'currency_amount', Array)
Drupal\Core\Plugin\Factory\ContainerFactory->createInstance('currency_amount', Array)
Drupal\Component\Plugin\PluginManagerBase->createInstance('currency_amount', Array)
Drupal\Core\Render\ElementInfoManager->createInstance('currency_amount')
Drupal\Core\Render\ElementInfoManager->buildInfo('np8_base_theme')
Drupal\Core\Render\ElementInfoManager->getInfo('page')
Drupal\Core\Render\Renderer->doRender(Array, 1)
Drupal\Core\Render\Renderer->render(Array, 1)
Drupal\Core\Render\BareHtmlPageRenderer->renderBarePage(Array, 'Error', 'maintenance_page', Array)
Drupal\Core\DependencyInjection\Container\prod\Drupal_Core_Render_BareHtmlPageRenderer_Proxy->renderBarePage(Array, 'Error', 'maintenance_page')
_drupal_log_error(Array, 1)
_drupal_exception_handler(Object)
This is due to the fact that in the entity annotations the leading "/" is missing.
/**
* Defines a currency locale entity.
*
* @ConfigEntityType(
* handlers = {
* "access" = "Drupal\currency\Entity\CurrencyLocale\CurrencyLocaleAccessControlHandler",
* "form" = {
* "default" = "Drupal\currency\Entity\CurrencyLocale\CurrencyLocaleForm",
* "delete" = "Drupal\currency\Entity\CurrencyLocale\CurrencyLocaleDeleteForm"
* },
* "list_builder" = "Drupal\currency\Entity\CurrencyLocale\CurrencyLocaleListBuilder",
* "storage" = "Drupal\Core\Config\Entity\ConfigEntityStorage",
* },
* entity_keys = {
* "id" = "locale",
* "label" = "locale",
* "uuid" = "uuid",
* "status" = "status"
* },
* id = "currency_locale",
* label = @Translation("Currency currency locale"),
* links = {
* "canonical" = "currency.currency_locale.edit",
* "create-form" = "currency.currency_locale.add",
* "edit-form" = "currency.currency_locale.edit",
* "delete-form" = "currency.currency_locale.delete"
* }
* )
*/
class CurrencyLocale extends ConfigEntityBase implements CurrencyLocaleInterface {
use StringTranslationTrait;
...
The links pattern need a "/" in front.
I will send a patch after getting an issue number.
Comments
Comment #1
marcusx commentedThis fixes the problem in my case.
Comment #2
berdirIt's still wrong.
The value needs to be the link pattern, the path that's in those routes, not the route name.
Comment #3
edurenye commentedAdded the routes with the leading slashes in both files.
Comment #4
berdircanonical and edit-form used to have the same route, so they should also have the same path now.
Import is a custom form, so the add path should be used for create-form.
And we have another problem there. The link name needs to match the route name (edit-form => edit_form). Not sure if add is even a thing, Node for example doesn't have that.
Something that does exist is the canonical link template, however. It would be useful to add that, it should point to the list route (which then needs to be renamed to entity.currency.collection, including everything that points to it.
Comment #5
edurenye commentedIt has some tests that doesn't pass, but I don't know if I should change the tests or is still something wrong with the routes.
Comment #6
LKS90 commentedThe changes to Currency.php and CurrencyLocale.php are not correct yet. They used to be route names, you changed them to a path. The idea would be to replace the old route with the new equivalent. Example:
OLD:
"canonical" = "currency.currency.edit",NOW:
"canonical" = "/admin/config/regional/currency/{currency}",SHOULD BE:
"canonical" = "entity.currency.edit_form"You define route names in the routing.yml file and use those instead of full paths (unlike you currently do in Currency and CurrencyLocale). Your changes to routing.yml are not really correct either, you are changing where route names point:
The routes
entity.currency.canonicalandentity.currency.edit_formnow point to the same path, that doesn't make sense.Edit: Nearly forgot: change the status to Needs review when you want it reviewed/the patch tested.
Comment #7
berdirThat actually makes sense, because there's no way to view a currency, just edit it. So the workaround to still have a canonical link template defined is to use the same path. Not sure how well that works though.
canonical might not be needed at all. @Xano told me that he's on holiday until the 10th. Maybe we should wait for feedback from him.
Comment #8
edurenye commentedNow just fails one test, but I think it has nothing to do with routes.
Comment #10
LKS90 commentedThe problem is in
currency.links.task.yml. The base_route should becurrency.amount_formatting, same as above in entity.currency_locale.collection.The route you changed it to (
entity.amount_formatting) doesn't exist in the routing file, so the tab isn't rendered and the test fails.Edit: The correct currency.links.task.yml:
Comment #11
edurenye commentedSolved, now pass all the tests, I've changed this route by mistake, sorry.
Comment #12
LKS90 commentedYep, looks good now.
Comment #15
xanoThank you for picking this up!
As far as I know, route names only have to prefixed with
entity.if they map to link paths. The currency collection route is not a canonical URL and does not map to any of a currency entity's link paths.Comment #16
berdircollection is a standard route/link template and renaming it makes sense, but the patch only does 90% of the work and doesn't actually add the link template.
collection is for example used by the default delete forms for the cancel/redirect destination.
Comment #17
edurenye commentedAll the routes are changed now.
Comment #18
xanoI wasn't talking about
collectionat all, but about theentityroute name prefix. As far as I know that's only supposed to be used for routes that map to entity link templates. The last two patches, however, add the prefix to routes that have nothing to do with entity link templates or specific entities. Maybe I missed a recent core change, so if so, could you please share a link?Comment #19
berdirNo, that patch was the wrong direction I think :)
I know you were. But collection *is* a link template, see NodeType for example. So renaming that is correct, but it only makes sense if we *also* add it as a link template.
So, back to #11 and just add the link template for collection.
So the actual change that we are supposed to do here is now actually lost.
These need to be paths. Which it was until comment #5.
Comment #20
edurenye commentedSo if I understand is like this, just editing to entity the link templates from the entities.
I think now it's ok, I didn't understand before.
Comment #21
edurenye commentedAnd also change those templates for the paths.
Comment #22
edurenye commentedComment #25
xanoSo the root cause is really that the entity link templates are still route names instead of paths, and that the names of the corresponding routes do not always start with
entity..Comment #26
xano@edurenye: If you diff between branches to create patches, then you must rebase your feature branch after you've pulled the master branch. If you don't, all new changes will become part of the patch, which is what happened in #21.
Comment #27
edurenye commentedSorry, I always try to do that, but sometimes I forget.
I don't provide a interdiff as I did not change anything, just rebase.
Comment #28
xanoOverall this looks good. Thanks a lot for working on this!
This route has no corresponding entity link template.
This route has no corresponding entity link template.
This route has no corresponding entity link template.
This route has no corresponding entity link template.
This is an exact duplicate of the
entity.currency.edit_formform route. We need to alias one to the other (is that even possible?), or drop one of the routes.This is an exact duplicate of the
entity.currency_locale.edit_formform route. We need to alias one to the other (is that even possible?), or drop one of the routes. I checked several of core's config entity types and they don't providecanonicallink templates.To reiterate what @berdir and I said in previous comments: if we introduce routes that are prefixed with
entity., these must be exposed as link templates.Comment #29
berdir@Xano: AFAIK, the reason for those duplicate routes is that you have duplicate link templates ( canonical and edit-form) that point to the same path. so I think we need duplicate routes so that urlInfo('edit-form/canonical') can resolve that to the correct route
Or remove canonical from the link templates.. core doesn't have those for config entitities anywhere AFAIK.
Comment #30
edurenye commentedDone.
Comment #31
berdirThat's looking much better now. As a follow-up, we could try to use the default entity delete forms and save a bit of custom code...
Comment #32
xanoThere was something about the default deletion forms that I thoroughly hated, but that may have only been for content entities.
Thanks for working on this!