[ * 'variables' => [ * 'result' => NULL, * 'plugin_id' => NULL, * ], * 'file' => 'search.pages.inc', * ], * ]; * @endcode * Given this definition, the template file with the default implementation is * search-result.html.twig, which can be found in the * core/modules/search/templates directory, and the variables for rendering are * the search result and the plugin ID. In addition, there is a function * template_preprocess_search_result(), located in file search.pages.inc, which * preprocesses the information from the input variables so that it can be * rendered by the Twig template; the processed variables that the Twig template * receives are documented in the header of the default Twig template file. * * Theme hooks can declare a variable deprecated using the reserved * 'deprecations' variable. For example: * @code * search_result' => [ * 'variables' => [ * 'result' => NULL, * 'new_result' => NULL, * 'plugin_id' => NULL, * 'deprecations' => [ * 'result' => "'result' is deprecated in drupal:X.0.0 and is removed from drupal:Y.0.0. Use 'new_result' instead. See https://www.example.com." * ] * ], * ], * @endcode * Template engines should trigger a deprecation error if a deprecated * variable is used in a template. * * @section sec_overriding_theme_hooks Overriding Theme Hooks * Themes may register new theme hooks within a hook_theme() implementation, but * it is more common for themes to override default implementations provided by * modules than to register entirely new theme hooks. Themes can override a * default implementation by creating a template file with the same name as the * default implementation; for example, to override the display of search * results, a theme would add a file called search-result.html.twig to its * templates directory. A good starting point for doing this is normally to * copy the default implementation template, and then modifying it as desired. * * @section sec_preprocess_templates Preprocessing for Template Files * Several functions are called before the template file is invoked to modify * the variables that are passed to the template. These make up the * "preprocessing" phase, and are executed (if they exist), in the following * order (note that in the following list, HOOK indicates the hook being called * or a less specific hook. For example, if '#theme' => 'node__article' is * called, hook is node__article and node. MODULE indicates a module name, * THEME indicates a theme name, and ENGINE indicates a theme engine name). * Modules, themes, and theme engines can provide these functions to modify how * the data is preprocessed, before it is passed to the theme template: * - ThemeManager::addDefaultTemplateVariables(&$variables): Creates a default * set of variables for all theme hooks. Provided by Drupal Core. * - initial preprocess: A callback set on the theme hook definition, * to set up default variables. Supports services with the service:method * syntax, see \Drupal\Core\Utility\CallableResolver and hook_theme(). * - MODULE_preprocess(&$variables, $hook): hook_preprocess() is invoked on all * implementing modules. * - MODULE_preprocess_HOOK(&$variables): hook_preprocess_HOOK() is invoked on * all implementing modules, so that modules that didn't define the theme hook * can alter the variables. * - ENGINE_engine_preprocess(&$variables, $hook): Allows the theme engine to * set necessary variables for all theme hooks with template implementations. * - ENGINE_engine_preprocess_HOOK(&$variables): Allows the theme engine to set * necessary variables for the particular theme hook. * - THEME_preprocess(&$variables, $hook): Allows the theme to set necessary * variables for all theme hooks with template implementations. * - THEME_preprocess_HOOK(&$variables): Allows the theme to set necessary * variables specific to the particular theme hook. * * @section sec_suggestions Theme hook suggestions * In some cases, instead of calling the base theme hook implementation (either * the default provided by the module that defined the hook, or the override * provided by the theme), the theme system will instead look for "suggestions" * of other hook names to look for. Suggestions can be specified in several * ways: * - In a render array, the '#theme' property (which gives the name of the hook * to use) can be an array of theme hook names instead of a single hook name. * In this case, the render system will look first for the highest-priority * hook name, and if no implementation is found, look for the second, and so * on. Note that the highest-priority suggestion is at the end of the array. * - In a render array, the '#theme' property can be set to the name of a hook * with a '__SUGGESTION' suffix. For example, in search results theming, the * hook 'item_list__search_results' is given. In this case, the render system * will look for theme templates called item-list--search-results.html.twig, * which would only be used for rendering item lists containing search * results, and if this template is not found, it will fall back to using the * base item-list.html.twig template. This type of suggestion can also be * combined with providing an array of theme hook names as described above. * - A module can implement hook_theme_suggestions_HOOK(). This allows the * module that defines the theme template to dynamically return an array * containing specific theme hook names (presumably with '__' suffixes as * defined above) to use as suggestions. For example, the Search module * does this in search_theme_suggestions_search_result() to suggest * search_result__PLUGIN as the theme hook for search result items, where * PLUGIN is the machine name of the particular search plugin type that was * used for the search (such as node_search or user_search). * * For further information on overriding theme hooks see * https://www.drupal.org/node/2186401 * * @section sec_alternate_suggestions Altering theme hook suggestions * Modules can also alter the theme suggestions provided using the mechanisms * of the previous section. There are two hooks for this: the * theme-hook-specific hook_theme_suggestions_HOOK_alter() and the generic * hook_theme_suggestions_alter(). These hooks get the current list of * suggestions as input, and can change this array (adding suggestions and * removing them). * * @section assets Assets * We can distinguish between three types of assets: * - Unconditional page-level assets (loaded on all pages where the theme is in * use): these are defined in the theme's *.info.yml file. * - Conditional page-level assets (loaded on all pages where the theme is in * use and a certain condition is met): these are attached in * hook_page_attachments_alter(), e.g.: * @code * function THEME_page_attachments_alter(array &$page) { * if ($some_condition) { * $page['#attached']['library'][] = 'my_theme/something'; * } * } * @endcode * - Template-specific assets (loaded on all pages where a specific template is * in use): these can be added by in preprocessing functions, using @code * $variables['#attached'] @endcode, e.g.: * @code * function THEME_preprocess_menu_local_action(array &$variables) { * // We require touch events detection for button styling. * $variables['#attached']['library'][] = 'core/drupal.touchevents-test'; * } * @endcode * * @section front_matter Front Matter * Twig has been extended in Drupal to provide an easy way to parse front * matter from template files. See \Drupal\Component\FrontMatter\FrontMatter * for more information: * @code * $metadata = \Drupal::service('twig')->getTemplateMetadata('/path/to/template.html.twig'); * @endcode * Note: all front matter is stripped from templates prior to rendering. * * @section theme_updates Theme Update functions * Themes support post updates in order to install module dependencies that have * been added to the THEME.info.yml after the theme has been installed. * Additionally, if a theme has changed its configuration schema, post updates * can fix theme settings configuration. See * @link hook_post_update_NAME hook_post_update_NAME @endlink for more * information about post updates. * * @see hooks * @see callbacks * @see theme_render * * @} */ /** * @defgroup theme_render Render API overview * @{ * Overview of the Theme system and Render API. * * The main purpose of Drupal's Theme system is to give themes complete control * over the appearance of the site, which includes the markup returned from HTTP * requests and the CSS files used to style that markup. In order to ensure that * a theme can completely customize the markup, module developers should avoid * directly writing HTML markup for pages, blocks, and other user-visible output * in their modules, and instead return structured "render arrays" (see * @ref arrays below). Doing this also increases usability, by ensuring that the * markup used for similar functionality on different areas of the site is the * same, which gives users fewer user interface patterns to learn. * * For further information on the Theme and Render APIs, see: * - https://www.drupal.org/docs/8/theming * - https://www.drupal.org/developing/api/8/render * - @link themeable Theme system overview @endlink. * * @section arrays Render arrays * The core structure of the Render API is the render array, which is a * hierarchical associative array containing data to be rendered and properties * describing how the data should be rendered. A render array that is returned * by a function to specify markup to be sent to the web browser or other * services will eventually be rendered by a call to * \Drupal\Core\Render\RendererInterface::render(), which will recurse through * the render array hierarchy if appropriate, making calls into the theme system * to do the actual rendering. If a function or method actually needs to return * rendered output rather than a render array, the best practice would be to * create a render array, render it by calling * \Drupal\Core\Render\RendererInterface::render(), and return that result, * rather than writing the markup directly. See the documentation of * \Drupal\Core\Render\RendererInterface::render() for more details of the * rendering process. * * Each level in the hierarchy of a render array (including the outermost array) * has one or more array elements. Array elements whose names start with '#' are * known as "properties", and the array elements with other names are "children" * (constituting the next level of the hierarchy); the names of children are * flexible, while property names are specific to the Render API and the * particular type of data being rendered. A special case of render arrays is a * form array, which specifies the form elements for an HTML form; see the * @link form_api Form generation topic @endlink for more information on forms. * * Render arrays (at any level of the hierarchy) will usually have one of the * following properties defined: * - #type: Specifies that the array contains data and options for a particular * type of "render element" (for example, 'form', for an HTML form; * 'textfield', 'submit', for HTML form element types; 'table', for a table * with rows, columns, and headers). See @ref elements below for more on * render element types. * - #theme: Specifies that the array contains data to be themed by a particular * theme hook. Modules define theme hooks by implementing hook_theme(), which * specifies the input "variables" used to provide data and options; if a * hook_theme() implementation specifies variable 'foo', then in a render * array, you would provide this data using property '#foo'. Modules * implementing hook_theme() also need to provide a default implementation for * each of their theme hooks, normally in a Twig file. For more information * and to discover available theme hooks, see the documentation of * hook_theme() and the * @link themeable Default theme implementations topic. @endlink * - #markup: Specifies that the array provides HTML markup directly. Unless * the markup is very simple, such as an explanation in a paragraph tag, it * is normally preferable to use #theme or #type instead, so that the theme * can customize the markup. Note that the value is passed through * \Drupal\Component\Utility\Xss::filterAdmin(), which strips known XSS * vectors while allowing a permissive list of HTML tags that are not XSS * vectors. (For example,