Problem/Motivation

The theme registry has several problems, which make it impossible to move it into a proper service and keep finding functions.

1. - Especially all modules and includes need to be loaded.

The reason is that theme engines search for the theme functions instead of the registry searching for the theme functions for this particular "entity" processed.

2. - You can only define a theme suggestion in the registry by registering a template or hacking the registry. It should be possible to use a theme suggestion, but fall back to the "base hook" for the rendering.

3. - You cannot define a hook that is only used for suggestions and has neither a template nor a theme function. A theme_link is very necessary, but completely useless and performance problem if not using a suggestion or inline template.

These changes are all not BC breaking however.

Especially 1) might be necessary as it seems that update functions use theme() and so theme() cannot use the ModuleHandler to invoke things ...

Proposed resolution

- Change the order of registry execution to find theme functions and theme__suggestion functions as part of the "entity" processed not as part of the theme engine.

- Make it possible to define a stub in the registry, by introducing a public "base hook" key that is the only one that needs to be set (or again use function => FALSE, or inherit => TRUE or something).

- Make it possible to define 'function' => FALSE explicitly and have the theme registry react on this.

Remaining tasks

* Fix the theme registry.
* Write tests.

User interface changes

* None.

API changes

Just additions, no BC breaking:

* Changes theme registry processing order to make sure what is processed is loaded.
* Allow to set function => FALSE and introduce another key for (inherit or base hook) to specify only a suggestion.

* #2004872: [meta] Theme system architecture changes

Original report by Fabianx

The process we use to build the theme registry is updated in the following ways:

  • A theme's callbacks, default arguments, and template file name are defined in hook_theme. This remains unchanged from D7.
  • Let modules and themes define suggestions for base hooks, by adding hook_theme_suggestions. This will allow preprocess functions to run for the suggestion without having to define a template or specific preprocess function.
  • Let modules and themes define a render function for specific template suggestions by adding hook_theme_render_TEMPLATE_SUGGESTION to replace theme_THEMEID__suggestion and [module]_THEMEID; the highest priority implementation wins.
  • Priority will be determined by a single theme_stack. A theme in this stack may have an associated theme engine. This simplifies things by replacing the distinction between base themes and themes.
  • Processing in the registry will be executed in the following order: Modules first, Theme Stack second.

Processing in the registry will execute the following steps, for each module and theme:

  1. Invoke hook_theme().
  2. Invoke hook_theme_suggestions() where suggestions may be registered and base_hook may be set, if it exists, otherwise ignore it. The precedence on suggestions is structured such that suggestions added later overrule earlier ones.
  3. Foreach of those $theme_ids returned in hook_theme (not the suggestions) execute the following:
    • Call theme_retrieve_render_functions([hook], $theme_id) on each themes produced from
      • Looks for hook_theme_render_THEME_ID() and hook_theme_render_THEME_ID__*
      • Registers suggestions if needed and sets base_hook to $theme_id and 'function' => found function.
  4. For the whole module or theme call:
    • Call theme_retrieve_templates($engine, [hook], $path, $hooks)
      • Foreach found template matching of of $hooks, the engine sets 'template' => 'path' and 'function' => 'engine_render_function'.

The above process changes are beneficial in the following ways:

  • Functions will now be found during registry build, they just need to be in the "include" or file defining hook_theme(). If hook_theme() can be called, so can the theme or render functions. This is the biggest and most important change to the status quo, which currently uses the engine to search for the theme functions (WHAT?).
  • Theme engines will set render_function directly. No more need to special case the template case.
  • There will be one single theme stack, listed in reverse order. No more need to special case base_themes.
  • Later implementations overwrite earlier implementations completely.
  • The theme registry will now be much simpler to build because a function will be defined for each hook, base hooks may now be nested, and the first hook to implement 'function' wins - regardless whether it is a theme function or a template rendered via engine function.

Comments

Fabianx’s picture

Issue summary: View changes

added original report

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

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.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.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should 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.

joelpittet’s picture

@Fabianx, is this still valid proposal/plan for 8.x? I'm sure this could use an issue summary clean-up/refactor considering the age of the issue.

joelpittet’s picture

Assigned: Unassigned » Fabianx
Status: Active » Postponed (maintainer needs more info)
Fabianx’s picture

Status: Postponed (maintainer needs more info) » Closed (outdated)

I think it is outdated.

joelpittet’s picture

Assigned: Fabianx » Unassigned

@Fabianx, they are likely to resurface by others or you I'd bet if they still are relevant. Thanks for closing.