Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 292339

Modernize theme initialization

$
0
0

code at http://cgit.drupalcode.org/sandbox-sun-1255586/?h=theme-init-2228093-dawehner2

Problem

Theme system is a mess.

If you interact with the theme functionality, you currently use one of the following ways:

  1. You use global $theme, ..., to get information about the current theme.
  2. You use _theme()/drupal_render() to generate some output.

This direct access only works, because the current theme happens to be manually initialized in various spots of the code-base. (@see LegacyRequestSubscriber)

Proposed resolution

Provide a service ('theme') which you can use to either render some output or get the current theme.
This is the canonical place for interaction.

In case you don't have the current theme initialized yet, the theme service asks the negotiator to get one and initializes (direct or indirect) that theme.

In order to do that, it needs a domain object of the current theme, which for example contains the theme info, stylesheets and libraries, as well as a list of the same domain object representing the parent themes (if any).

<?php
// @todo Find a better name.
interface ThemeServiceInterface {
 
/**
   * @return string
   */
 
public function render($hook, $variables);
 
/**
   * @return \Drupal\Core\Theme\ActiveTheme
   */
 
public function getActiveTheme();
 
/**
   * Execute the alter hook on the current theme.
   */
 
public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL);
}
?>

The theme service has the following dependencies:

theme:
  class: Drupal\Core\Theme\Theme
  arguments: ['@theme_handler', '@theme.negotiator', '@theme.initialization', '@state']

State is used instead of cache to not rebuild the theme domain object all the time. (as in HEAD)

High-level service overview

  1. ThemeHandler only cares about managing theme extension objects, in the exact same way as ModuleHandler.

    The Extension objects are no longer manipulated with theme info/data.

  2. ThemeNegotiator determines the theme to use for a particular request.

  3. ThemeInitialization consults ThemeHandler to retrieve the list of enabled themes, in order to instantiate the ActiveTheme domain object initialize the required theme engines.

    This is essentially drupal_theme_initialize() + _drupal_theme_initialize().

    ThemeHandler::rebuildThemeData() + system_rebuild_theme_data() is moved into this service.

  4. The ActiveTheme domain object is only built once for each theme and stored in state.

    This domain object consists of global $theme_info and global $base_theme_info.

  5. The Theme service returns the initialized ActiveTheme domain object of the current/active theme for consumers.

    This replaces access to all global $theme* variables.

Notes

  1. Theme::alter() removes support for themes to participate in all alter hooks from ModuleHandler::alter().

    Instead, Theme::alter() will be specifically invoked manually for the few hooks in which themes are supposed to participate. That list is very limited; e.g.:

    hook_form_alter()
    hook_page_alter()
    hook_theme_suggestions_alter()
    hook_theme_registry_alter()

  2. This plan should allow us to get rid of $request->attributes->set('_theme_active') in ThemeNegotiator, but we admit that we don't know how many things depend on that currently.


Viewing all articles
Browse latest Browse all 292339

Trending Articles