This issue has gone back-and-forth a few times. Originally, the intent was to allow usage of theme() in templates as opposed to using Twig 'include' directives. However, usage of theme() in a template is an anti-pattern since markup should be pre-generated or a subset of the parent template.
Usage of theme() in templates in core was found to be only 3 instances, in tables and for filter-tips. These instances seemed trivial enough such that the instances could be refactored.
Currently, removal of theme() in the table template is being handled in #1778968: Convert theme_table to Twig, so resulting patches here will likely result in just attending to filter-tips. We may retitle the issue to reflect such.
Original issue summary, wishing to have theme() available in templates
Originally, we had decided to use {% include %} statements for including one template file from within another, but this posed two problems:
1) the path to the include file must be literal. This defeats the purpose of overrides and the theme registry.
2) We were unsure whether to preprocess before including the referenced file.
Instead, we have decided to leave the {% include %} statements as originally intended for twig. when we need to include something literal, without preprocessing, we can. If we need to preprocess variables for that template, we will have to do it ourselves.
We also decided to add the use of theme() from within twig templates. Here, we can call theme functions (that will run preprocess automatically, and respect overrides) directly from within a template.
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | drupal-allow-theme-in-twig--1842160-12.patch | 731 bytes | steveoliver |
| #9 | drupal-allow-theme-in-twig--1842160-9.patch | 551 bytes | steveoliver |
Comments
Comment #1
jenlamptonI think this is actually a dupe of #1777532: Extend Twig_Loader_Filesystem instance to get .twig templates paths with hierarchy for theme dependencies
Comment #2
fabianx commentedNo, this is different.
Comment #3
fabianx commentedPlease apply to front-end.
Comment #4
japerryApplied to frontend branch
11555f703d690a5b0f3975a7eb7e31fc23da5a4a
Comment #5
c4rl commentedSome questions and concerns here. I believe from conversations in IRC earlier this week, we decided that everything sent to a Twig template would be renderable and that Twig template variables should know how to render themselves. Therefore, variable addressability in Twig, by definition, means that it should be renderable, and it is up to the render array to define this structure in an extensible and flexible way.
So, instead of calling
theme('node', $node)from Twig, we'd simply be able to do{{ node }}and it would understand. It was via this principle where I started doing some tinkering around here https://gist.github.com/4061841 as a conceptual demo.Can someone provide some insight here as to why theme function calls should be available via Twig as opposed to having Twig template variables understand their inherent printing method?
Comment #6
fabianx commentedThis is needed to include another template of your own choice, while calling suggestions, etc. without being dependent that preprocess set things up correctly in a render array.
It completes that {% include is not calling suggestions, pre-process, etc, but rather hard-codes the template to be used.
Comment #7
jenlampton@C4rl It would be nice if we could make
theme('table')unnecessary from within twig templates, and instead be able to print {{ table }}, but as it is now {{ table }} doesn't exist as a variable for that template, only $header and $rows. Plus, tables are not yet renderable objects. We need to add theme so that our template files can be cleaner and continue working, right now. Plus, it will allow front-end devs to render one template easily within another, even if the module devs didn't prepare renderable objects for the appropriate template file beforehand.We can, of course, revisit this later after we have all the renderable objects we need. For now this is a great solution. Thanks @FabianX!
I've opened #1848116: Revise usage of {% include %} as a follow-up.
Comment #9
steveoliver commentedMoving this to the core queue from Twig sandbox. Attached patch allows use of
theme()within Twig templates.Comment #10
steveoliver commentedComment #11
fabianx commentedThanks, steveoliver.
According to the prototype of theme we don't need the arguments by reference, such we can and probably should use:
new \Twig_Function_Function('theme')
Comment #12
steveoliver commentedas per #11
Comment #13
c4rl commentedAs expressed in November, I still think this is a bad idea. theme() functions are just (poor) abstractions of nested renderables. A grep for this usage yields the following 3 calls:
These are minimal, and I think can be removed. Does it seem logical that we can change this issue to simply eliminate the use of theme() in Twig templates and refactor the above instances? What do you guys think?
Comment #14
steveoliver commentedThis rides the line of where our theme "system" calls something done, vs. done-done*. ;)
I agree, c4rl, we should be done-done by now (within a template).
I see the theme layer(s) as this
1. Theme data (PHP data objects) - theme()
2. Theme object (Twig renderables) - [pre]process()
3. Theme output (HTML markup) - templates
I agree, let's not call theme() in templates.
We really do need these lines drawn. I think c4rl you've got just the right vision on this. I'm in 'just effin' make it work' mode. :)
Comment #15
steveoliver commented*Thanks, sdboyer :)
Comment #16
steveoliver commentedMoving this back to the sandbox, where we've been calling theme() within templates, but should stop. :)
Comment #17
steveoliver commented...working on this, incorporating #1778624: rework theme_filter_tips to use the new Attributes, and call theme('item_list) while we're at it
Comment #18
c4rl commentedI updated the issue summary here.
Comment #19
steveoliver commentedSince we are allowing
theme()in templates for the time being, I've fixed various fatal errors related to+=/array_mergeissues by registering thetheme()function as a\Twig_Function_Functionrather than aTwigReferenceFunctionin git commit 249490c.Comment #20
c4rl commentedBetter title. Let's postpone this for now given that we have some disagreement?
Comment #21
fabianx commentedHere is further information:
#1905694: Introduce theme_to_render helper function
Comment #22
c4rl commentedI've updated #1905694: Introduce theme_to_render helper function to reflect that instead of using theme() calls at all, we should use render arrays:
becomes
Marking this one as fixed.
Comment #23.0
(not verified) commentedUpdated issue summary to indicate our new direction with this issue.