Split off of #2444003: Optimize Drupal\Core\Template\Attribute, this dealing with the Extension class. In addition to the tests, one method was found to be acting differently than documented - will try modifying it to behave as documented.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Aki Tendo created an issue. See original summary.

Status: Needs review » Needs work

The last submitted patch, extension.diff, failed testing.

Aki Tendo’s picture

Status: Needs work » Needs review
FileSize
2.92 KB
1.41 KB

Sending failing assert to its own ticket.

jhedstrom’s picture

How would $this->urlGenerator ever not be an instance of UrlGeneratorInterface given that this code:

  public function setGenerators(UrlGeneratorInterface $url_generator) {
    return $this->setUrlGenerator($url_generator);
  }

will throw an exception if an object that isn't an instance of that interface is passed in? Is the issue that this method might not be called, and then the generator is null?

Aki Tendo’s picture

It will be null if the setter is never called at all - that's the danger of having the dependency container instantiate the object then attach dependencies to it with a setter. And this isn't that hard to do - all you need to do is incorrectly override the core services.yml configuration for the drupal twig extension using any module's services.yml file.

I do understand sometimes the dependency injector cannot avoid creating the object then assigning dependencies - particularly in the case of circular references - but when this occurs an assertion is pretty much required to ensure the object is in a legal state when the call occurs.

Aki Tendo’s picture

Subsequent to the Twig upgrade this patch remains appliable. Re-running global tests on it.

Aki Tendo queued 3: 2558079-3.diff for re-testing.

star-szr’s picture

Looks fairly reasonable, assert newbie questions:

+++ b/core/lib/Drupal/Core/Template/TwigExtension.php
@@ -198,6 +198,8 @@ public function getName() {
+    assert('$this->urlGenerator instanceof \\Drupal\\Core\\Routing\\UrlGeneratorInterface',
+      'Invalid Object State encountered. Check recently changed or added services.yml files such as in a recently installed module.');

@@ -219,6 +221,9 @@ public function getPath($name, $parameters = array(), $options = array()) {
+    assert('$this->urlGenerator instanceof \\Drupal\\Core\\Routing\\UrlGeneratorInterface',
+      'Invalid Object State encountered. Check recently changed or added services.yml files such as in a recently installed module.');

Do these give any other information when they happen? If I ran into this I'm not sure I'd know where to look or what to do. Does it show the context the assertion is called from or any other information?

Aki Tendo’s picture

Per IRC, improved messages and typo corrections. For those following here only in response to Cottser's question above, a failed assertion message provides the asserted code, file and line number in addition to the error string given as the second argument.

Aki Tendo’s picture

Issue summary: View changes

Running the patch against 8.0.0. It has been decided that runtime assertions may be included in incremental updates.

Aki Tendo queued 9: 2558079-9.diff for re-testing.

Aki Tendo’s picture

Version: 8.0.x-dev » 8.2.x-dev

Let's see if this still works (I'll be surprised if it does).

Aki Tendo’s picture

Requeing on new system.

Wim Leers’s picture

  1. +++ b/core/lib/Drupal/Core/Template/TwigExtension.php
    @@ -220,6 +220,7 @@ public function getName() {
    +    assert('$this->urlGenerator instanceof \Drupal\Core\Routing\UrlGeneratorInterface', 'The URL Generator hasn\'t been set up. Any configuration YAML file with a service directive dealing with the twig configuration can cause this, most likely found in a recently installed or changed module.');
    
    @@ -241,6 +242,8 @@ public function getPath($name, $parameters = array(), $options = array()) {
    +    assert('$this->urlGenerator instanceof \Drupal\Core\Routing\UrlGeneratorInterface', 'The URL Generator hasn\'t been set up. Any configuration YAML file with a service directive dealing with the twig configuration can cause this, most likely found in a recently installed or changed module.');
    

    s/Generator/generator/
    s/twig/Twig/

  2. +++ b/core/lib/Drupal/Core/Template/TwigExtension.php
    @@ -265,6 +268,9 @@ public function getUrl($name, $parameters = array(), $options = array()) {
    +    assert('is_string($url) || $url instanceof \Drupal\Core\Url', 'Argument #2 must be a string or object of type \Drupal\Core\Url');
    +    assert('is_array($attributes) || $attributes instanceof \Drupal\Core\Template\Attribute', 'Argument #3, if set, must be an array or object of type \Drupal\Core\Template\Attribute');
    

    Ugh, again this "argument #n" stuff, why not just specify the name?

  3. +++ b/core/lib/Drupal/Core/Template/TwigExtension.php
    @@ -373,8 +381,10 @@ public function attachLibrary($library) {
    -  public function escapePlaceholder($env, $string) {
    -    return '<em class="placeholder">' . $this->escapeFilter($env, $string) . '</em>';
    +  public function escapePlaceholder(\Twig_Environment $env, $string) {
    +    $return = $this->escapeFilter($env, $string);
    +
    +    return $return ? '<em class="placeholder">' . $return . '</em>' : NULL;
    

    This changes the behavior… but actually makes it match the docs :)

Wim Leers’s picture

Status: Needs review » Needs work

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Aki Tendo’s picture

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

borisson_’s picture

Issue tags: +Needs reroll

Patch no longer applies and #14 needs to be fixed.

jofitz’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
2.88 KB
3.02 KB

Rerolled and addressed changes suggested in #14.

borisson_’s picture

Status: Needs review » Needs work

I can only find one more thing that should be fixed.
That is that we should update the assertions so that they don't use strings anymore, see the php change doc.

jofitz’s picture

Status: Needs work » Needs review
FileSize
3.2 KB
2.93 KB

Assertions no longer use strings.

Status: Needs review » Needs work

The last submitted patch, 24: 2558079-24.patch, failed testing. View results

borisson_’s picture

Status: Needs work » Reviewed & tested by the community

This looks solid.

Aki Tendo’s picture

Yay! I've gotten a new job and I've been out learning Java for a client, but I'm very excited and happy to see this patch reach this point. Thanks to everyone who picked up the torch on this.

Wim Leers’s picture

@Aki Tendo: does that mean we won't bee seeing you around in the Drupal issue queue anymore? :(

Aki Tendo’s picture

No, I intend to stay around and stay sharp. I'm trying to steer my new employer into trying the Drupal waters but it's slow going.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 24: 2558079-24.patch, failed testing. View results

jofitz’s picture

Status: Needs work » Reviewed & tested by the community

Re-ran tests successfully. Appears to have been a testbot issue. Returning to RTBC.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

  • lauriii committed d2e0ae4 on 8.7.x
    Issue #2558079 by Aki Tendo, Jo Fitzgerald, Wim Leers, borisson_:...
lauriii’s picture

Status: Reviewed & tested by the community » Fixed
FileSize
1.9 KB

Made some code style adjustments on commit, attached interdiff here.

Committed d2e0ae4 and pushed to 8.7.x. Thanks! 🙌

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

alexismmd’s picture

After updted from 8.6.15 to 8.7.0 this patch cause this error:

AssertionError: $attributes, if set, must be an array or object of type \Drupal\Core\Template\Attribute in assert() (line 285 of core/lib/Drupal/Core/Template/TwigExtension.php).
assert(, '$attributes, if set, must be an array or object of type \Drupal\Core\Template\Attribute') (Line: 285)
Drupal\Core\Template\TwigExtension->getLink('Galería', Object, NULL) (Line: 154)
__TwigTemplate_ce69e45d4a658a4b4fdf883f647bc795d80aded976d9382b3096af92650d2f65->getmenu_links(Array, Object, 1) (Line: 161)
__TwigTemplate_ce69e45d4a658a4b4fdf883f647bc795d80aded976d9382b3096af92650d2f65->getmenu_links(Array, Object, 0) (Line: 60)
__TwigTemplate_ce69e45d4a658a4b4fdf883f647bc795d80aded976d9382b3096af92650d2f65->doDisplay(Array, Array) (Line: 443)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 414)
Twig\Template->display(Array) (Line: 422)
Twig\Template->render(Array) (Line: 64)
twig_render_template('themes/custom/intu_theme/templates/menu/menu--main.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('menu__main', Array) (Line: 437)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 501)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 105)
__TwigTemplate_7e9fbbd547258e18fc1884393a58e87b40d63ca51d598e4390db33988a658eda->block_content(Array, Array) (Line: 216)
Twig\Template->displayBlock('content', Array, Array) (Line: 94)
__TwigTemplate_7e9fbbd547258e18fc1884393a58e87b40d63ca51d598e4390db33988a658eda->doDisplay(Array, Array) (Line: 443)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 414)
Twig\Template->display(Array) (Line: 422)
Twig\Template->render(Array) (Line: 64)
twig_render_template('themes/contrib/bootstrap_barrio/templates/block/block--system-menu-block.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('block', Array) (Line: 437)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 450)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 501)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 99)
__TwigTemplate_e6d48c3c0763c6eb53da1d2a025b9c7ed3a3edb2055d6d436046df976ed15f43->block_head(Array, Array) (Line: 216)
Twig\Template->displayBlock('head', Array, Array) (Line: 67)
__TwigTemplate_fc7cb81f09885c0620c15e29ab1d7303923f977be2817cc659e50bbe570dd382->doDisplay(Array, Array) (Line: 443)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 414)
Twig\Template->display(Array, Array) (Line: 62)
__TwigTemplate_e6d48c3c0763c6eb53da1d2a025b9c7ed3a3edb2055d6d436046df976ed15f43->doDisplay(Array, Array) (Line: 443)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 414)
Twig\Template->display(Array) (Line: 422)
Twig\Template->render(Array) (Line: 64)
twig_render_template('themes/custom/intu_theme/templates/page.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('page', Array) (Line: 437)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 501)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 113)
__TwigTemplate_5e89771120344869bd8b2d426bb493ce465eef29a2b44583f8837624a214d01c->doDisplay(Array, Array) (Line: 443)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 414)
Twig\Template->display(Array) (Line: 422)
Twig\Template->render(Array) (Line: 64)
twig_render_template('themes/custom/intu_theme/templates/html.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('html', Array) (Line: 437)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array) (Line: 147)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 582)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 148)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object) (Line: 156)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 67)
Drupal\simple_oauth\HttpMiddleware\BasicAuthSwap->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 693)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

Any solution? Thanks!

ivavictoria’s picture

@alexismmd: I ran into the same problem when I upgraded to 8.7.0. I've fixed it for my site, so here is what I did, in case it's helpful:

Upon close inspection, I found that the error was caused by a complex custom menu template I had written. In that template, there was a macro using the link() function, and I was sometimes passing it an empty value instead of an actual attributes array/object. (I wanted to give some links ARIA attributes, but not all of them. So, sometimes the attributes variable was set, and sometimes it wasn't.)

In my template, I was able to resolve the problem by adding an if-statement to make sure the attributes exist:

Before:

{{ link(title, url, attributes) }}

After:

{% if attributes is empty %}
  {{ link(title, url) }}
{% else %}
  {{ link(title, url, attributes) }}
{% endif %}

The solution that works best for you will depend on your specific template. According to your error message, maybe look at this template: themes/custom/intu_theme/templates/menu/menu--main.html.twig
Look at where you're using the link() function, and if you're passing in an attributes parameter, make sure it actually contains something.

alexismmd’s picture

@Aurif3x thanks works perfectly!. Beside my custom templates, I have also fixed "menus attribute" module, from where I overwrote that templates.

https://www.drupal.org/project/menus_attribute/issues/3053598

jkwilson’s picture

Thanks @Aurif3x (#37) for the lead. This was exactly the issue.

Specific code I needed to change from Bootstrap theme's menu.html.twig:

{#  Previously: #}
{#  {{ link(link_title, item.url, link_attributes.addClass(item.in_active_trail ? 'active-trail')) }} #}

{#  Updated to: #}
{% if link_attributes is empty %}
    {{ link(link_title, item.url) }}
{% else %}
    {{ link(link_title, item.url, link_attributes.addClass(item.in_active_trail ? 'active-trail')) }}
{% endif %}
rfletcher73’s picture

I tried to add a user_account_menu in the header and footer of my site. Now i am getting this assertion error and i can't get my frontpage to load anymore.

I removed it from the footer and it was still a no-go. Frontpage was still crashing.

I just disabled it in the header and now the front page loads. Why is the user account menu a problem to have it in both the header and footer?

le72’s picture

I have same situation as rfletcher73

Sseto’s picture

+2 on #37!!