Updated: Comment #23
Problem/Motivation
When a theme suggestion is called directly, like theme('comment__node__article', …)
, the Twig debug output does not show the base template - in this case comment.html.twig, or the derived template comment--node.html.twig.
Proposed resolution
Add code to twig.engine to handle this scenario and display all possible template suggestions in the correct order
Remaining tasks
Write tests.
User interface changes
Twig debug output will display the base template and derived template suggestions when theme suggestions are called directly. Suggestions added via preprocess (theme_hook_suggestions) will display in the correct order.
API changes
None
Related Issues
#2118743: Twig debug output does not display all suggestions when an array of theme hooks is passed to #theme
#1751194: Introduce hook_theme_suggestions[_HOOK]() and hook_theme_suggestions[_HOOK]_alter()
Comment | File | Size | Author |
---|---|---|---|
#39 | interdiff.txt | 1.36 KB | star-szr |
#39 | 2029225-39.patch | 5.05 KB | star-szr |
Comments
Comment #1
star-szrPatch, then I will set to CNW and tag for tests.
Comment #2
star-szrWe have some Twig debug tests already in \Drupal\system\Tests\Theme\TwigDebugMarkupTest, so we can add tests there for this case.
Comment #3
star-szrI also think adding tests for this should be a good novice automated testing task :)
Comment #4
cilefen CreditAttribution: cilefen commentedThis is an attempt to add the test, using theme('comment__node__article', ...). I passed in a comment object and it looks as though theme() finds the comment template but the debug output is not there so the test fails.
Comment #5
star-szrThanks @cilefen, looks good at a glance. Setting the issue to 'needs review' so that this gets tested.
If you can also upload a test-only patch that would be great - see the screenshot near the bottom of https://drupal.org/contributor-tasks/write-tests. Uploading a test-only patch shows very clearly on the issue that the test is doing its job and failing appropriately.
Comment #6
cilefen CreditAttribution: cilefen commentedI will do that as soon as possible but I think 2029225-4.patch will not pass testing as-is.
Comment #7
cilefen CreditAttribution: cilefen commentedThe strange thing is -- the tests alone are passing for me. Let's see what the test bot says.
Comment #8
cilefen CreditAttribution: cilefen commented2029225-7-tests.patch and 2029225-7-complete.patch are probably both going to pass--and that's bad. I am not sure 2029225.patch is doing what was intended.
Is the purpose of this issue to show the possible template files and the selected file indicated with an asterisk in the debug area? It is happening with theme('node', ...) but not with theme('comment__node', ...).
Comment #9
star-szrThis is very good and is a perfect example of why we write tests :) the fix in #1 was not correct for the case of a theme hook with no additional suggestions. Node inserts additional template suggestions in its preprocess function (template_preprocess_node()) by adding to the 'theme_hook_suggestions' key in the $variables array. Sidenote: see #1751194: Introduce hook_theme_suggestions[_HOOK]() and hook_theme_suggestions[_HOOK]_alter() for a new plan to handle that functionality.
Here is an updated "fix" patch, I think you should be able to get a failing/passing test for this with some minor tweaks. It might be helpful to use debug() to check the $output when running tests if you aren't already.
Comment #11
star-szrNeeded a quick reroll after #1843650: Remove the process layer (hook_process and hook_process_HOOK), the \Drupal\forum\Tests\ForumTest failure was random.
Comment #12
cilefen CreditAttribution: cilefen commentedComment #14
star-szr#12: 2029225-complete-12.patch queued for re-testing.
Comment #15
Fabianx CreditAttribution: Fabianx commentedCan we always set this and move the logic to twig_render_template instead?
Comment #16
star-szr@Fabianx - Sure, we could do that. But I'm also realizing:
This should probably use the standard suggestion format of comment__node__article - two underscores as delimiters.
And then the debug output should show:
And all of these possibilities should be shown, even if comment--node.html.twig or comment--node--article.html.twig templates are implemented. This is not the case with the current patch.
Currently if you call comment__node__article and have a comment--node--article.html.twig template you don't get any information about suggestions because theme_hook_called == theme_hook_derived, or in other words an implementation was found for the hook passed into theme().
To accomplish this, I think our next steps will be to update theme() and/or twig_render_template() and expand test coverage. There is some code in theme() used to determine the derivative suggestions, but for the debug output we can't stop once an implementation is found.
Comment #17
cilefen CreditAttribution: cilefen commentedI see - I will rewrite the test.
Comment #18
cilefen CreditAttribution: cilefen commentedComment #19
Fabianx CreditAttribution: Fabianx commented.
Comment #21
cilefen CreditAttribution: cilefen commentedI missed a hyphen.
Comment #23
star-szrThanks @cilefen, that's really helpful. Go TDD :)
This patch doesn't add any code to theme() - the added code only fires when twig_debug is on. This also fixes the incorrect order of suggestions in the debug output - they should start with the most specific suggestions. That change could be moved to a separate issue but at this point I think it's a small enough change.
The fix code being added could really use some refactoring but I wanted to get it up here. It works for the test case provided in #21 as well as the case of node__foo__bar and displays the suggestions in the correct order of how the templates are matched, most specific to least specific.
I'd like to see more test coverage for the order that the suggestions are displayed in, particularly for the more complex node case below. Having consistent debug markup is going to be very important for good TX.
Comment #24
cilefen CreditAttribution: cilefen commentedThis one checks the order of template file suggestions and adds theme('node__foo__bar', ..).
Comment #25
markhalliwellI was debating on whether or not to create a new issue or not. I think we should just expand the scope to include this change too. I won't change the status of the issue and will leave the decision up to @Cottser.
After reading http://www.webomelette.com/how-to-theme-fields-drupal-7 via Planet Drupal, I realized one of the most frustrating things a themer has is figuring out where these templates are located if they want to override them. Not sure _how_ we want to do this, but maybe we could append the currently "selected" template (noted by "X") with the full (base) path to the template:
Comment #26
star-szrWe already display the full path to the template file being used, check your debug markup :)
Example can be seen in the Twig settings/debug change notice: https://drupal.org/node/1922666
Comment #27
markhalliwellOmg, duh. It was a random thought. Never mind me.
Comment #28
star-szrHere's a reroll with some improved inline comments. Looking at this again I'm okay with the fix but will leave it up to someone else to review :)
Thanks again @cilefen for working on the tests, you rock!
Comment #29
joelpittetI've had a look at this patch and it seems to work as designed. The test's expected reqults could be built before the assert to make them easier to read but that's about it.
Comment #31
star-szrThanks @joelpittet! We could maybe simplify the test and not use the comment example :)
Comment #32
cilefen CreditAttribution: cilefen commentedHere it is without the comment template test.
I noticed in getInfo, the test name is set in lower case like this:
'name' => 'Twig debug markup'
But other tests in the Twig category use caps, so it would be this:
'name' => 'Twig Debug Markup'
Is that something we should change, and if so, change now?
Comment #33
cilefen CreditAttribution: cilefen commentedWhoa, interdiff fail, use this one instead.
Comment #34
cilefen CreditAttribution: cilefen commentedWhoa, interdiff double-fail. Thanks for your patience!
Comment #35
cilefen CreditAttribution: cilefen commentedComment #36
star-szr@dawehner pointed out on IRC that the debug output also doesn't match up when an array of suggestions is passed into theme().
Created a separate issue for that: #2118743: Twig debug output does not display all suggestions when an array of theme hooks is passed to #theme
Comment #36.0
star-szrUpdate to reflect more recent status
Comment #36.1
star-szrAdd related issue for an array of suggestions
Comment #37
joelpittetAssigning for review.
Comment #38
star-szrSmall reroll for #2173655: Refactor theme() to _theme(); make it a private API to discourage module developers from circumventing the renderable build system.
Comment #39
star-szrUpdating the added test case to not use theme() or _theme(). Going to cancel the last one.
Comment #41
joelpittetThese assertTrue can be easier written with assertRaw, which does exactly the same thing.
I'm mentioning this because the output string is quite hard to read.
That and the CALL: should be replaced with something else like "Rendered theme:"
I don't know if you'd rather take care of those here or in a follow-up issue?
Comment #42
star-szrThanks @joelpittet!
We can't use assertRaw here because we aren't doing a drupalGet(). I agree the lines are a bit long/hard to read but not sure how to improve upon them, we really want to check the order that things are output. See #23/#24.
I'd rather the "CALL" stuff be changed in #2029225: Twig debug output does not show the base or derived hooks when a theme suggestion is called directly.
Comment #43
joelpittetOk well this does all the things it needs to do:)
Comment #44
webchickCommitted and pushed to 8.x. Thanks!