Problem/Motivation
Fairly often there is a need for some sort of contextual data when rendering an element, which parts of, ultimately needs to make its way down the theme system pipeline.
This is especially true when certain render elements or theme hooks, that are not normally aware of the context in which they'll be rendered, needs additional information to provide rendering variations (i.e. per type or identifier).
While it is possible to add any variable you want in preprocess functions, it is often too late in the process and the original data that usually contains the needed information has long since been lost.
This is, in part, due to arbitrary properties (not registered in the theme hook) from being automatically transferred from a renderable element's properties.
Example from the search module in core, where a 'context' variable was manually added to allow for this flexibility (#2495419: Move the 'search-results' class from the render array and into a Classy template):
$build['search_results'] = [
'#theme' => ['item_list__search_results__' . $plugin->getPluginId(), 'item_list__search_results'],
//...
'#context' => ['plugin' => $plugin->getPluginId()],
];
Another example of use is for Views suggestions (which this issue is blocking): #2923634: [PP-1] Use hook_theme_suggestions in views.
Proposed resolution
Add a context
variable as an empty array for all theme hooks, if one doesn't already exist.
Add a #context
property as an empty array to all elements, if one doesn't already exist.
Remaining tasks
Create test(s)Create patch
User interface changes
None
API changes
- The addition of a default
#context
property added to all elements - The addition of a default
context
property added to all theme hooks (for preprocessing purposes only) - The automatic mapping of a renderable element's
#context
property to thecontext
variable - Removal of the
context
variable immediately prior to rendering (for security concerns).
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#133 | interdiff-2511548-131_133.txt | 1.27 KB | Anchal_gupta |
#133 | 2511548-133.patch | 55.32 KB | Anchal_gupta |
#131 | 2511548-render-context-no-testing-10.2.x.patch | 26.47 KB | edmoreta |
#129 | 2511548-render-context-no-testing-10.1.1.patch | 26.97 KB | manikandank03 |
#124 | core-render-context-2511548-124-no-testing-9.4.0.patch | 35.99 KB | B-Prod |
Issue fork drupal-2511548
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #1
star-szrSmall clarification on the inline template #type thing for the IS.
Comment #2
joelpittetThis issue may be able to sidestep @fabianx's concern with my other approach! :)
Assigning to fabianx to see if maybe this gels better.
Comment #3
star-szrRight. This sidesteps the idea of having arbitrary #-prefixed keys by sticking them all in #context :)
Comment #4
Fabianx CreditAttribution: Fabianx as a volunteer commented+1 to that, I myself have used that in D7 using hook_theme_registry_alter().
There might be even an open core issue by me to introduce a #theme_context ...
My main usage was #theme => 'user_picture' ...
Comment #5
Fabianx CreditAttribution: Fabianx as a volunteer commentedI propose to use #theme_context instead of just #context, because context is a very overloaded word.
Comment #6
star-szrYeah, theme_context works. I'm not too bothered about the name, that bit of namespacing sounds nice though.
Also, just adding to _template_preprocess_default_variables() of course doesn't work, I should have realized. Too late in the process. Need to add it earlier, possibly via the registry itself.
Comment #7
star-szrComment #12
xjm#2761525: Accessing the original entity in field templates is hard provided another usecase for this.
Comment #13
xjmBeta evaluations aren't a thing anymore since the beta ended like two years ago. :)
Comment #15
willeaton CreditAttribution: willeaton commentedNot sure if this solution would solve my issue, but Im trying to pass some context to my theme from a render array in a module and its impossible. All I want to do is conditionally add a body class depending on if a template file was used or not, without using JS it doesn't seem possible.
Comment #16
lauriii@willeaton even though this feature is missing, it should be possible to achieve what you are trying to do. Are you using Drupal Slack? Feel free to ping me on Slack and we can try to figure out how you could add the class.
Comment #17
lauriiiThanks @willeaton for providing more context for your specific requirements! While there's ways to work around this, for example, by passing necessary contextual metadata to the static cache, fixing this with the proposed solutions is a lot cleaner.
Here's initial patch which adds the theme context for html and page level. I guess next step would be to figure out how to spread this information for every template. I figured it wouldn't be as simple as passing information while rendering the tree since we now have '#lazy_builders' which makes the rendering happen in multiple trees.
Comment #18
willeaton CreditAttribution: willeaton commented@lauriii, this is a great solution that works perfectly. When rendering a theme array e.g.
... I am able to access all the information from "theme_context" in my myTheme_preprocess_html() and thus apply body classes based on things I've rendered, or values that have come back from an API call. For example:
I will test this further and keep you posted on my findings. As discussed in slack, it may be necessary to send this information down the tree too, i.e. we render something which in turn renders something else further down, we may want to have context of who called us in the sub-element.
Comment #20
lauriiiThis will hopefully fix some of the failing tests
Comment #21
markhalliwellConsidering that issue never really contained any patches, this comment in the IS doesn't really make any sense. "Lite version" of what exactly? I'll just close that issue as a dup of this one and remove this from the IS.
Yes, it is an "overloaded word", but that's the whole point. It's arbitrary and could be used for anything by anything. It's really not specific to themes. We're just, currently, using it for that purpose due to a limitation of the conversion between a render array element to theme hook variables. This could and probably will expand to more use cases over time.
The "context" (in this context, pardon the pun) is a reference to the element itself, not specifically the theme system. It should be provided when additional information/data needs to be passed, regardless of who may use it.
Namspacing this variable/property with "theme_" makes little sense when it is intentionally arbitrary in nature.
As you can see from the IS, we're already using
#context
in core and in contrib, we've been using#context
for years):https://drupal-bootstrap.org/api/bootstrap/src%21Bootstrap.php/function/...
https://drupal-bootstrap.org/api/bootstrap/src%21Plugin%21Alter%21Elemen...
https://drupal-bootstrap.org/api/bootstrap/src%21Plugin%21Alter%21ThemeR...
Comment #22
markhalliwellAfter discussing this with @lauriii in slack, it seems there is confusion as to what this issue actually is.
The above patch/comments suggest a "global" context for the current render stack. That is not what the original intention of this issue was about (nor do I believe that is very maintainable/manageable).
Context is specific to the render array/theme hook/element itself during the creation of said render array.
It does not "bubble up" to other render arrays/theme hooks/elements, nor should it (e.g.
$build['#context']['entity'] = $entity;
wouldn't make sense all the way at the top, especially if there are 100s of entities on the page, each overwriting that "entity" context).The issue raised in #15 is actually an entirely different concept and is, yes, quite difficult to achieve (especially when render caching is involved).
The easiest way to accomplish this will be, in fact, using JavaScript. Doing it via Drupal's theming system, properly, would likely require creating custom cache contexts and config (settings). Although, one may be able to get away with utilizing (abusing, really)
drupalSettings
to do what you want (bubbling up a flag).---
Anyway, that all being said, I will attempt to get this issue back on track with a new patch (hopefully) later today.
Comment #23
markhalliwellAnother use case is #2923634: [PP-1] Use hook_theme_suggestions in views
Comment #24
willeaton CreditAttribution: willeaton commentedHi Mark
It might be, but in my site we have so much JavaScript that in this rerole we are trying to do away with client side as much as possible, plus it's not efficient, why should the browser on every page load have to detect that an element exists (which could change classes) and add a class to the body tag, when it can be donde once and cached?
In my situation it's a massive limitation that causes me to have to use global variables to communicate between a module and a theme, and the proposed solution is very valid if used carefully, naming standards etc.
Suppose i have an element that might be loaded on a page based on conditions, if it gets rendered i need a class on the body tag to affect other elements on the page because CSS is cascading so can't affect other elements directly. In my opinion we should empower the developers out there (like me) that look at the Drupal rendering system and don't have the first clue of how it works, and by providing this context array it gives freedom to resolve situations that aren't even imagined when creating Drupal, as is it's beauty.
Drupal 8 was supposedly all about context, but the lack of communication between module and theme for the cool idea of decoupled and API first drupal is also limiting when you're building a website.
Can't it at least be considered, even if it has to be moved to its own case?
Comment #25
markhalliwellThis is an over-generalized statement and only true if the JS wasn't properly architected. I understand the logic/desire to have the raw HTML generated with the proper classes prior to it reaching the browser. I'm was simply saying that it's far easier to implement this via JS than custom config/settings/cache contexts is all.
Because, apparently, that is the design of the site in question. Personally, I think the decision to "add classes to the body" is an architectural mistake. If only due to the complexities of Drupal's theming system.
It is actually very rare that you need a conditional top-level class added to a page that is affected by something nested deep within the page. Does this single template really affect the entire page?
Can you not simply add said class to the element's
#wrapper_attributes
? Or, if it's in a view, to the view itself?It is. You just haven't really looked at existing APIs that much yet is all.
Core already has mechanisms in place to accomplish what you're asking to do. Albeit, it is or rather can be somewhat difficult to achieve natively in Drupal, especially if you don't understand how the render system or cache context works.
The only example I can really point to is the Background Image module I recently created. This module needs to add classes to the body when a background image is "dark" or uses the "full viewport" settings.
The only way to, properly, add these classes is to extract these variables from the current background_image entity config (settings):
https://cgit.drupalcode.org/background_image/tree/background_image.modul...
In D7, that would be enough because we didn't have render cache.
However, in D8 and to ensure that the page doesn't cache the first setting value it comes across, cache contexts need to be added to the page.
This requires custom cache contexts to be created to handle the variations of a background_entity that may be on the page:
https://cgit.drupalcode.org/background_image/tree/src/Cache/Context
The concept of a "runtime bubbling global context" sounds great in theory.
However, in practice, it would be a nightmare to implement and maintain... if only due to render caching, lazy loading, placeholders, etc.
The template, if it was already cached, wouldn't be able to add context via said "runtime bubbling global context". So it'd be empty and the page could potentially render without said context.
I'm not saying we wouldn't investigate making all this easier for developers, but it is an entirely separate issue/feature. One that will likely take a while to implement and be quite tricky so that it "just works".
---
I didn't get to creating a patch yesterday, I'll try later this weekend.
Comment #26
markhalliwellAlrighty. Here's a patch that gets this issue back on track. There's no interdiff since previous patches were around a different concept.
I've also included a tests only patch that should fail. The full patch should pass just fine.
Comment #29
markhalliwellThis fixes a couple tests that expected a specific default array which has now changed.
Comment #30
lauriiiNice! The changes look good for me. Slightly concerned if this will be breaking some tests in contributed projects but these should be easy enough to fix. This type of changes are allowed according to our BC policy, and it does urge people to take this type of scenarios into account.
Let's start drafting a change record for this. We should also add some documentation to the theme.api.php so that it's easier to find this feature.
Comment #31
markhalliwellOk, I've done the initial pass of the CR here: https://www.drupal.org/node/2971707
I'll get started on making some documentation changes in the patch.
Comment #32
markhalliwellComment #33
markhalliwellAfter discussing this with @lauriii in slack, we realized that there's a potential security implication (leaking sensitive information) if we don't remove context from the variables prior to actually rendering it.
There's also a limitation with module and theme alters that prevent us from passing an additional context parameter for callbacks like theme hook suggestions. So we'll have to keep this context in
$variables
(for now) until we can have properly typed objects (e.g.Variables
) where we can set the context on that object before passing it via alters.Comment #34
markhalliwellComment #35
markhalliwellOk, here's a patch that helps lock down context a bit more.
Unfortunately, due to a lack of proper documentation, we cannot simply "append context" to things like preprocess functions because they've been receiving the same three variables for years:
$variables, $hook, $info
. To prevent BC breaks (in case someone actually determined what has been sent to the functions for the past 5+ years without looking at the API documentation) we'll have to nest this inside of$variables
(which is also necessary due to the alter method parameter limit).So, I went ahead and updated some of that documentation too (when was
contextual_links_view()
ever used in core?).I also moved the theme hook context property into its own top-level property (outside of variables), mainly due to the fact that any data in context aren't actual variables to be printed (which is confusing since it's inside $variables of the functions... I know, see paragraph above).
Suffice it to say, most of this will get cleaned up when we have a better theme system in place (e.g. #2869859: [PP-1] Refactor theme hooks/registry into plugin managers) and proper strong typed objects for some of this stuff.
Comment #37
markhalliwellMight help if I actually set the proper context property names from the documentation...
Comment #38
markhalliwellThis got buried in recent issue updates, but it could use a proper review.
Comment #39
Anonymous (not verified) CreditAttribution: Anonymous commentedThis is a blocker for a major task #2923634: [PP-1] Use hook_theme_suggestions in views (which is actually critical regression bug for theming). So priority up. Are there any reasons against RTBC?
Comment #40
dawehnerMaybe it is just me, but for me these comments don't really add any information. Maybe we could explain at least, why we need it again after the altering: "Altering might have added additional values".
Reading the code though I am wondering why the first normalization isn't moved into the previous foreach loop
Do we have a follow up issue for that? I am wondering whether it would be possible to start in this issue already. It would allow us to not have to worry about BC for example, but also help with documentation etc. I am wondering whether there should be a immutable and mutable version during construction time.
I am wondering: Is this needed as part of this particular issue?
Comment #41
markhalliwell#40.1: Perhaps the comments should just be removed. The method itself describes what it does:
#40.2: It doesn't have a specific issue created, yet, but it's semi-related to #2972143: Create \Drupal\Component\Utility\ArrayObject.
#40.3: Yes. This is just matching the code to what is documented in the APIs (variables aren't referenced in suggestions build/alter) and should not be alterable (even if
&$variables
is used). It's related to the tests that exist to ensure context isn't alterable in preprocess... but maybe there should be another test to ensure it's not alterable from suggestions hooks.Comment #42
markhalliwellComment #44
markhalliwellBump. Would appreciate some theme system maintainer reviews here. This is blocking #2923634: [PP-1] Use hook_theme_suggestions in views.
Comment #45
5n00py CreditAttribution: 5n00py as a volunteer commentedHi everyone. Found this draft change record.
I want to know if this context can solve my task.
I have basic setup:
Node type -> entity_reference field called field_image -> media entity -> field_image_file
I want to have image field with image linked to node, like classic image field formatted can do(but with media).
Additionally I wand to save all media markup with contextual links, etc. so it can't be done from node's/media/field preprocess.
To solve my task I need to pass (somehow) additional data from node to media entity and it's image formatter.
Maybe this is possible using #context ? If yes, than i can create new entity reference formatter.
Comment #46
markhalliwellBump... again
Comment #47
markhalliwellComment #48
markhalliwellComment #49
markhalliwellRe-roll and expanded comments to address #40.1.
Setting back to RTBC.
Comment #50
markhalliwellSomehow BC support for
$variables['theme_hook_original']
was lost along the way.Comment #51
markhalliwellAdded links to some of the @todos to link to #2972143: Create \Drupal\Component\Utility\ArrayObject temporarily until more solidified issues can be made.
Comment #52
markhalliwell@joelpittet found one minor reference to the old
$variables['theme_hook_original']
.Comment #53
lauriiiAs part of #2809683: Make it required to specify variables passed to templates and #3016948: Type check theme variables, I'm proposing stricter rules for defining and validating variables passed to templates. I feel like this is going to the opposite direction since this would allow passing new variables in a render array although only under the context variable.
I'm wondering what are the downsides of requiring developers to define the variables they want to pass to the template? This is already possible with
hook_theme_registry_alter
. Maybe instead of allowing developers to pass variables to templates without defining them, we should make it easier to define new variables?Comment #54
markhalliwellIt's not. This data is not a variable, it does not reach the template; on purpose.
Per #33, you and I had already discussed that context should not reach the template level due to sechole concerns; which I wholeheartedly agree with.
The entire point of
#context
is to allow additional, contextual and intentionally arbitrary, data into the theming pipeline.The purpose of this is to allow easier communication between the back-end and the front-end; only up to the preprocessing layer (keeping it, technically in the back-end, PHP side, of things).
It is up to the developer how to use context; using it to create/populate/override existing variables as they see fit.
This idea isn't anything new and has been implemented in base themes like Drupal Bootstrap since its inception.
Further, this is a step is to declutter the
$variables
array from providing unnecessary meta information that is simply contextual in nature; information that really doesn't belong in$variables
:While these issues are, indeed necessary in the long run, this is just as important and just one of the baby steps to get there.
Comment #55
lauriiiThanks for the input @markcarver! I was confused by the issue summary and didn't recognize this issue as the same we had discussed earlier. We should update the issue summary to match what we are proposing here. I'm still +1 to what we have discussed and what @markcarver described in #54.
I don't think we have a process in place how deprecations for theme variables should happen. Let's file a change record for this and ask for feedback from release managers.
Should we give some warning for anyone who has
'context'
variable defined inhook_theme
? How about if someone has created preprocess function that adds'context'
variable?I think we should create a separate change record warning people specifically about this. It would be great if we could do something more than that though.
Comment #56
lauriiiComment #57
markhalliwell#55.1: I don't think we do. It's also very difficult to "trigger" anything since it's only consumed down the theming pipeline. Perhaps this could be/should be officially deprecated once we have an actual
Variables
(#2972143: Create \Drupal\Component\Utility\ArrayObject) object that we could intercept a magic get method request for this specific key? If so, maybe then we could create a CR for this?#55.2: I added a note to the existing CR that mentions this property is removed for security reasons. Ultimately, it shouldn't belong in
$variables
at all, but we really don't have a way to mark this as@internal
either.This is one of the reasons we're trying to move away from arbitrary arrays like this, ironically by introducing a new one, but only because this is just one of the baby steps for a feature that we've really needed for a very, very long time.
We're a long ways off from having dedicated objects for all this stuff though (probably even well into 9.x).
I don't believe this is a very common variable that makes its way to an actual template. In the Drupal Bootstrap base theme, we create this variable, but it's never used on the template level; only to pass contextual data down from modules.
I'd almost be half tempted to maybe mention in the CR that both the
#context
element property and the variablescontext
property should both be considered@internal
and are subject to change.If we need to reflect this in the documentation of this patch, I'd be happy to change that as well.
Comment #58
lauriiiThanks for updating the CR and the issue summary. I still think it would be useful to have specific mention in a change record that we have moved
theme_hook_original
under the'context'
variable.It seems like this change would comply with the Drupal Core frontend BC policy. Given the potential risks and the fact that the policy is quite permissive, it would be useful to get a review from a release manager before committing this.
Comment #59
markhalliwellThis seems to indicate that variables in preprocess functions are not guaranteed at all, by default.
It's a little unclear if this includes preprocess hook signatures (e.g. array of variables vs. a strong-typed
Variables
object).Regardless, this sounds like good news.
I've gone ahead and updated the CR to make the change a little clearer and prominent.
Comment #60
catchSpecific data structures are subject to change and counted as @internal.
I don't think we've done any significant introduction of new patterns for data structures in 8.x though, so it's slightly different to introduce something that generally affects all preprocess hooks. This is still doable in a minor release though. Will have to think a bit more if there's anything extra to worry about.
Changing from array to ArrayAccess/ArrayObject is also theoretically doable, except in this case it's a function parameter that can be type hinted to
array
so I don't really see a clean way to do it (i.e. it might be necessary to introduce a parallel hook or something). Return values are a bit more flexible and we did some of that in 7.x.Comment #61
markhalliwellYes. I'm thinking we should just introduce a new method via #2869859: [PP-1] Refactor theme hooks/registry into plugin managers; which would ultimately deprecate preprocess hooks anyway. We'd still pass the variables as an array to the preprocess hooks for BC reasons though.
We could do the same for the context object.
Comment #62
catchRemoving the release manager review tag for now.
Comment #63
lauriiiThanks for the review @catch! I have no more concerns on this, and the latest patch and the change record look good for me. Moving to the RTBC queue.
Note for committing, please only publish this change record.
Comment #64
larowlanI have a couple of comments/questions as follows
- what if an existing contrib module/custom code defines a theme hook that requires a variable named context - should we be using something a bit more obscure like _context for the key instead?
- should we be using a class constant for the 'context' key instead of a magic string?
Comment #65
markhalliwell#64.1: No, see #58 and #59.
#64.2: I'm not entirely sure what you mean by "magic string"... but unlikely since this will eventually be moved to a dedicated object.
Comment #66
lauriiiI think #64.2 is referring to providing the variable key with a constant, and changing
'context'
into something more random to avoid collisions. I'm not sure if there would be much value in having the constant by itself, but since this would essentially solve #64.1 as well, it might make sense.Comment #67
markhalliwellThis entire issue is based on years of contrib using this parameter in $variables for this exact purpose.
If there is anyone using this, it's likely because they're already using it by a base theme that already provides this exact functionality.
That isn't this hypothetical "collision" though. Which, I might remind everyone, is still permissible by the Drupal Core frontend BC policy.
This issue is/has always been intended to be an upstream-port of a very useful contrib feature that needs to make its way into core.
So #64.2 is
$variables[SomeObject::CONTEXT]
? No, I don't think sticking this behind some random class constant is the wisest decision at this point.Especially given that this is still just the first baby step in this process. Things are bound to change and I'd rather not introduce a constant that will likely be deprecated and replaced with another down the line when things solidify more.
This issue/patch has tests that check for this parameter; I think that's quite sufficient at this point.
Comment #68
AnybodyI agree with #67 and confirm RTBC. Great and important work, thank you very much!
Comment #69
marcoscanoPatch in #52 doesn't apply to 8.6.x.
For folks needing to apply it with current stable version, here is a rerolled patch for 8.6.7 only.
Comment #70
marcoscanoHiding patch in #69 from IS, so it doesn't generate unnecessary confusion.
Comment #72
markhalliwellBump...
Comment #74
lauriiiDiscussed with @larowlan on Slack and we agreed that it wouldn't make sense to provide a constant for this variable, even though it could bring some benefits. It would be a new pattern for the theme system, and given the direction we're trying to take in the theme system, it could end up being the only place where constants are being used for theme variable key names.
I retitled the change record to be even clearer about
#context
not being available in templates.Comment #75
larowlanwe could just write this as
and could even replace the foreach with array_map
as » has
Again we can use
+=
here to simplify the codeWe need an issue for this - as well as a way of signalling to someone that they're using the deprecated path, which I can't see happening without #2972143: Create \Drupal\Component\Utility\ArrayObject so probably just an issue at this stage
do we need to trigger a deprecation error here for folks who invoke this without the third argument, so we can enforce the context argument in D9?
$context is optional, we can't rely on it here. This therefore points to us needing to trigger an error and construct a psuedo context value from the old $variables if $context is not passed
edit: removed an item I found later in the patch but forgot to remove when I posted
Comment #76
larowlanComment #77
markhalliwelledit: @larowlan, just an FYI, I was able to apply #52 to 8.8.x using both
patch -p1
andgit apply --index
(some slight offset, but still succeeded). I think maybe you were trying to apply #69, which is for 8.6.x?Comment #78
markhalliwell$type
key from the array which array_map doesn't let us do.I also went ahead and updated the documentation and example code for
hook_preprocess()
to match the change record (and vice versa).Comment #79
markhalliwellOops, been a while since I've worked on this. Forgot
$variables['theme_hook_suggestions']
already existed.Comment #81
markhalliwellThat last patch will fail because TwigWhiteListTest manually invokes twig_render_template().
Here's a new patch that fixes that and simplifies twig_render_template() a little bit more.
Comment #83
markhalliwellSigh, the last patch will still fail because it doesn't actually check if the parameter was passed, just if it's empty.
This will allow an empty context array, which technically doesn't affect the output of the template... but also won't print any debugging information since that requires contextual information about the theme hook invoked. This can be purposefully omitted if invoked manually and not ran through the theme system (like TwigWhiteListTest is doing).
Comment #85
markhalliwellPing...
Comment #86
Martijn de WitUsing this patch (#83) in combination with #2923634: [PP-1] Use hook_theme_suggestions in views for a while on several sites.
It really helps a front-end developer to do his job :)
Comment #87
johnwebdev CreditAttribution: johnwebdev commented++
Can't wait to be able to use this.
Why can't we just do this only after the alterations?
Comment #88
markhalliwellBecause alter hooks will need normalized elements to actually alter.
---
@larowlan, can this go back to RTBC?
Comment #89
markhalliwellBump
Comment #90
markhalliwellBump.... again..............
Comment #91
lauriiiI did some research just to make sure that this wouldn't cause regressions for contrib modules or themes. Luckily I found only one instance where context variable is being printed in a template. We should open an issue to fix that in the module.
I also realized that we are using
#context
for passing variables to inline templates. This patch makes the behavior inconsistent, since in that instance#context
is specifically used for passing variables to templates, and here we want to specifically avoid passing that variable to templates.Comment #92
markhalliwellNo,
#context
in the case of inline templates is prerendered to#markup
: InlineTemplate::preRenderInlineTemplate(); it never reaches a preprocess hook/template because it's... inline.We could rename it to
#variables
and deprecate#context
for inline templates... but at this point, I think just adding a note to the CR will suffice:edit: added note to CR
Comment #93
markhalliwellAgain, to remind everyone, this change is permissible per Drupal Core frontend BC policy.
It's not like there isn't a workaround to this change either. The benefits of adding this certainly outweigh the relatively minor cost of anyone having to do a simple variable rename for any contrib/custom code actually affected.
Regardless, I went ahead an opened an issue: #3082665: Use container with theme hook suggestions and attributes instead of custom template and variables
As a side note, ^ is a byproduct of poor design.
Comment #94
alphawebgroup@markcarver
Hi
Could you explain then, how we can add a special suggestion for the element what depends on parent element?
Basically if we pass $variables (not a clone) by reference, then we have a chance add parents' suggestions, etc.
and, now, after applying the patch we don't have that possibility because of:
Comment #97
Trea CreditAttribution: Trea at Flink [NL] commentedHi,
Any chance this patch could be made available for core version 8.9?
Comment #98
viappidu CreditAttribution: viappidu as a volunteer commentedWorking on 8.9.0.
Though I don't do testing so not sure if my modifications where right.
Interdiff only shows the .rej modifications on
core/modules/system/tests/modules/theme_test/theme_test.module
and
core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
Comment #99
milovan CreditAttribution: milovan commentedNot tested, do not apply on production :)
Edit: the patch is for 8.9.x, my bad in setting up test.
Comment #100
lawxen CreditAttribution: lawxen commented#99 can't be applied on Drupal9.0.1, needs reroll
Comment #101
ridhimaabrol24 CreditAttribution: ridhimaabrol24 at Srijan | A Material+ Company for Drupal India Association commentedRerolling patch for 9.1.x
Comment #103
KapilV CreditAttribution: KapilV as a volunteer and at OpenSense Labs commentedAdded patch for 9.1.x
Comment #105
JeroenTThis patch should fix some of the test failures. There is still 1 left. I haven't had the time to check the issue completely:
Drupal\Tests\help_topics\Functional\HelpTopicSearchTest::testHelpSearch
is failing because context is no longer added to the templateitem-list--search-result.html.twig
andcontext.plugin
is added as a class to the search result list.Drupal\Tests\help_topics\Functional\HelpTopicSearchTest::assertSearchResultsCount
usescontext.plugin ~ '-results'
to check the nr of results. Since that class is no longer present, this will always fail.Comment #110
JohnAlbinSince patch #83 on Drupal 8.8.x was the last patch to pass all tests, I took that patch and then rebased it onto 9.2.x and confirmed that the differences between my merge conflict resolutions were trivially similar to the patch in #105. So I took the patch in #105 and applied it to the Merge Request branch and then applied my rebased #83 on top of it. You can see any interdiff by examining the commits on the MR.
Lastly, I think I fixed the broken tests. Let's see what the testbot says.
I should note that we really have broken the
context.plugin ~ '-results'
class added by Classy and its children. However, no core theme is using any class ending in_search-results
. The previously broken test was looking for thehelp_search-results
class, but I changed that to the class that still exists,search-results
.If I'm reading Drupal Core frontend BC policy correctly, we'll need to fix that.
Comment #111
JohnAlbinSo, if I'm understanding this new context correctly, if I wanted to change a CSS class based on a context, I'd need to do it in a preprocess function. And since class names need to live in a .twig file (best practice), I'd need to have the preprocess function take the context and create a new variable to use in a twig file. Right?
Given that's the preferred way to use context, I went ahead and fixed the search plugin context by creating a new variable based on context.plugin.
I also noticed that the item-list.html.twig templates have a
context.list_style
variable which is broken. I'll fix that in the morning since it's late at night here.Comment #112
JohnAlbinI reverted the changes to the stable9 theme. I believe we're not supposed to change the Twig markup in that theme. Also, I noticed that removing the
$variables['context']
in the MR meant we were breaking anyitem-list.html.twig
not in core. I've added the 2 context variables used in those templates to an allow list for the remainder of 9.x.Comment #113
JohnAlbinAfter thinking about the next steps after this MR, I created #3190462: Replace $hook/$info parameters with render context in preprocess/theme_suggestions hook to discuss whether we should deprecate the
$hook
and$info
parameters in favor of making this new$context
the last parameter for preprocess/theme_suggestions. It seems logical to me; please join in that discussion to pipe in.In the meantime, I'm going to add
$theme_info
to$context
in this MR.Comment #115
slv_ CreditAttribution: slv_ at Lullabot for Georgia Public Broadcasting commentedUploading patch file of the latest merge request against latest stable (9.2).
Comment #116
JohnAlbin9.3.0-alpha1 was released. Tthat means feature requests have to be applied to 9.4.x.
Comment #117
JohnAlbinComment #118
phoang CreditAttribution: phoang as a volunteer commentedPatch #115 failed to applies on 9.3.x.
Re-roll to #105
Comment #119
Martijn de Wit@phoang since 9.3 is already released, JohnAlbin set the ticket to 9.4.x-dev.
The issue status is reflecting the merge request that's now at 9.4.x-dev. Not a previous stable version.
When this is needed specially for 9.3 it could be back ported... but seeing the ticket history, change and impact; it probably isn't.
Comment #120
JohnAlbinI pushed a commit that fixes the merge conflict with 9.4.x's theme.api.php file.
Someone else (besides phoang) asked how to apply this changeset to 9.3.x. The only place where this fails to apply to 9.3.x is the theme.api.php file. But to make this easier for others to use on 9.3.x, I've created a patch file by taking the 9.4.x diff and removing the theme.api.php and test files changes. You can't use this patch file to test and review this issue though. Please use the MR for testing and reviewing.
Comment #122
alphawebgroupit's not mergeable to 9.5.x anymore, sorry
Comment #123
alphawebgroupComment #124
B-Prod CreditAttribution: B-Prod at Aïon Solutions commentedThis is a patch against current stable version 9.4.0
Comment #126
g-brodieiAdding bug smash tag for targeting!
Comment #127
maskedjellybeanThanks for the work on this everybody. This would be super useful. It's one of those things you just assume you can do. Then when you really need to do it and learn you can't, it's quite frustrating.
Comment #129
manikandank03 CreditAttribution: manikandank03 as a volunteer commentedRe-rolled patch #124 to support Drupal 10 latest version(10.1.1) and below themes twig changes removed because those themes not support for Drupal 10,
bartik, classy, seven, stable.
Comment #130
AnybodyCould someone perhaps give an update on the plan here?
Since @markhalliwell's Bio says:
there seems to be not much movement here any more and I think for Drupal 11 it would be worth a review and discussion, if this still makes sense as improvement to Core.
If yes, we should take it over the finish line. If not, we should point out, why this plan is deprecated.
Does anyone know?
Comment #131
edmoreta CreditAttribution: edmoreta commentedPatch for 10.2.x based on #129
Comment #132
manikandank03 CreditAttribution: manikandank03 as a volunteer commentedPatch #131 works fine in Drupal 10.2.2 with PHP 8.2.
Comment #133
Anchal_gupta CreditAttribution: Anchal_gupta at Srijan | A Material+ Company for Drupal India Association commentedFixed phpstan
Please review
Comment #134
nicolas-lsn CreditAttribution: nicolas-lsn at Aïon Solutions commentedPlease note that such changes could cause issue with third-party modules, for example ui_patterns.
This last module define a #context object, which is overridden if we apply the patch. This leads to a fatal error.
So maybe it could be better to override or extends the #context element if it is empty or array, otherwise the variable should be kept as this.
An issue has been filled for the UI Patterns module: https://www.drupal.org/project/ui_patterns/issues/3422997