array( * 'variables' => array( * '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. * * hook_theme() implementations can also specify that a theme hook * implementation is a theme function, but that is uncommon and not recommended. * Note that while Twig templates will auto-escape variables, theme functions * must explicitly escape any variables by using theme_render_and_autoescape(). * Failure to do so is likely to result in security vulnerabilities. Theme * functions are deprecated in Drupal 8.0.x and will be removed before * Drupal 9.0.x. Use Twig templates instead. * * @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. * * In the uncommon case that a theme hook uses a theme function instead of a * template file, a module would provide a default implementation function * called theme_HOOK, where HOOK is the name of the theme hook (for example, * theme_search_result() would be the name of the function for search result * theming). In this case, a theme can override the default implementation by * defining a function called THEME_HOOK() in its THEME.theme file, where THEME * is the machine name of the theme (for example, 'bartik' is the machine name * of the core Bartik theme, and it would define a function called * bartik_search_result() in the bartik.theme file, if the search_result hook * implementation was a function instead of a template). Normally, copying the * default function is again a good starting point for overriding its behavior. * Again, note that theme functions (unlike templates) must explicitly escape * variables using theme_render_and_autoescape() or risk security * vulnerabilities. Theme functions are deprecated in Drupal 8.0.x and will be * removed before Drupal 9.0.x. Use Twig templates instead. * * @section sec_preprocess_templates Preprocessing for Template Files * If the theme implementation is a template file, 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: * - template_preprocess(&$variables, $hook): Creates a default set of variables * for all theme hooks with template implementations. Provided by Drupal Core. * - template_preprocess_HOOK(&$variables): Should be implemented by the module * that registers the theme hook, to set up default variables. * - 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_preprocess_functions Preprocessing for Theme Functions * If the theming implementation is a function, only the theme-hook-specific * preprocess functions (the ones ending in _HOOK) are called from the list * above. This is because theme hooks with function implementations need to be * fast, and calling the non-theme-hook-specific preprocess functions for them * would incur a noticeable performance penalty. * * @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'][] = 'mytheme/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 Modernizr's touch test for button styling. * $variables['#attached']['library'][] = 'core/modernizr'; * } * @endcode * * @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_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_render(), and * return that result, rather than writing the markup directly. See the * documentation of drupal_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,