Replace $hook/$info parameters with render context in preprocess/theme_suggestions hook

Created on 31 December 2020, over 3 years ago
Updated 23 June 2023, about 1 year ago

Problem/Motivation

Both preprocess functions and theme_suggestions functions have a $hook parameter. For preprocess functions, $hook is “The name of the theme hook.”, i.e. the specific theme hook suggestion being rendered. For theme_suggestions functions, $hook is “The base hook name.” It's mildly awkward that these parameters are named the same but have different values.

Preprocess functions also have a $info parameter after $hook (it was added with #1972514: Impossible to set attributes for all entities but never documented.) This $info contains the info from hook_theme for the current theme $hook. It seems we have the need to add more context to preprocess functions and right now the only way to do that is add more parameters.

Lastly, one day Add a "context" array variable to all theme hooks and "#context" array property to all elements to provide optional contextual data Needs work will go into core and will:

  1. set a special $variables['context'] for preprocess/theme_suggestions
  2. remove the special $variables['context'] before variables go to templates
  3. add a $context param to THEME_ENGINE_render_template($template_file, $variables, $context)

The reason we stuff $context into $variables is because there is no backwards-compatible way to add context into those functions. It's super awkward that core will have to delete $variables['context'] and that themers who see this "variable" in preprocess/theme_suggestions functions and see it disappear from templates.

Proposed resolution

Since $context contains theme_hook and theme_base_hook and theme_hook_info, we can deprecate and replace the $hook and $info parameters of preprocess/theme_suggestions functions with $context and we will no longer need to stuff context into $variables['context'].

Even though the function signatures are changing significantly, it will actually be easy for modules/themes to be compatible with both 9.x and 10.x. For example:

// Use the 10.x signature (without a type hint on the 2nd param)
function hook_preprocess_HOOK(array &$variables, $context) {
  // Recreate the Drupal 9.x $hook and $info params.
  $isDrupal9 = is_string($context);
  $hook = $isDrupal9 ? $context : $context['theme_hook'];
  $info = $isDrupal9 ? $variables['context']['theme_hook_info'] : $context['theme_hook_info'];
}

// Use the 10.x signature (without a type hint on the 3rd param)
function hook_theme_suggestions_HOOK_alter(array &$suggestions, array $variables, $context) {
  // Recreate the Drupal 9.x $hook param.
  $hook = is_string($context) ? $context : $context['theme_base_hook'];
}

Remaining tasks

  1. Decide if this is a good idea.
  2. Wait for Add a "context" array variable to all theme hooks and "#context" array property to all elements to provide optional contextual data Needs work to land.
  3. Mark $hook and $info as deprecated for 9.x. With just docs?
  4. Replace the $hook/$info params (and $variables['context']) with a $context param for 10.x.

API changes

The following functions have a new $context parameter that replaces any $hook or $info parameters that they may have had:

  • 9.x: hook_preprocess(array &$variables, $hook, array $info)
    10.x: hook_preprocess(array &$variables, array $context)
  • 9.x: hook_preprocess_HOOK(array &$variables, $hook, array $info)
    10.x: hook_preprocess_HOOK(array &$variables, array $context)
  • 9.x: hook_theme_suggestions_HOOK(array $variables)
    10.x: hook_theme_suggestions_HOOK(array $variables, array $context)
  • 9.x: hook_theme_suggestions_alter(array &$suggestions, array $variables, $hook)
    10.x: hook_theme_suggestions_alter(array &$suggestions, array $variables, array $context)
  • 9.x: hook_theme_suggestions_HOOK_alter(array &$suggestions, array $variables, $hook)
    10.x: hook_theme_suggestions_HOOK_alter(array &$suggestions, array $variables, array $context)

Data model changes

None.

Release notes snippet

TBD.

Feature request
Status

Active

Version

11.0 🔥

Component
Render 

Last updated 2 days ago

Created by

🇹🇼Taiwan JohnAlbin Taipei, Taiwan

Live updates comments and jobs are added and updated live.
  • Needs frontend framework manager review

    Used to alert the fron-tend framework manager core committer(s) that a front-end focused issue significantly impacts (or has the potential to impact) multiple subsystems or represents a significant change or addition in architecture or public APIs, and their signoff is needed (see the governance policy for more information). If an issue significantly impacts only one subsystem, use Needs subsystem maintainer review instead, and make sure the issue component is set to the correct subsystem.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024