Commit 3f5bb7d9 authored by catch's avatar catch

Issue #2346369 by Wim Leers: Support special '#attached' variable for...

Issue #2346369 by Wim Leers: Support special '#attached' variable for attaching assets in preprocess functions.
parent 93c6556d
...@@ -372,6 +372,15 @@ function _theme($hook, $variables = array()) { ...@@ -372,6 +372,15 @@ function _theme($hook, $variables = array()) {
$preprocessor_function($variables, $hook, $info); $preprocessor_function($variables, $hook, $info);
} }
} }
// Allow theme preprocess functions to set $variables['#attached'] and use
// it like the #attached property on render arrays. In Drupal 8, this is the
// (only) officially supported method of attaching assets from preprocess
// functions. Assets attached here should be associated with the template
// that we're preprocessing variables for.
if (isset($variables['#attached'])) {
$preprocess_attached = ['#attached' => $variables['#attached']];
drupal_render($preprocess_attached, TRUE);
}
} }
// Generate the output using either a function or a template. // Generate the output using either a function or a template.
...@@ -1946,15 +1955,8 @@ function template_preprocess_maintenance_page(&$variables) { ...@@ -1946,15 +1955,8 @@ function template_preprocess_maintenance_page(&$variables) {
$attributes['class'] = $classes; $attributes['class'] = $classes;
// @see system_page_build() // @see system_page_build()
$attached = array( $variables['#attached']['library'][] = 'core/normalize';
'#attached' => array( $variables['#attached']['library'][] = 'system/maintenance';
'library' => array(
'core/normalize',
'system/maintenance',
),
),
);
drupal_render($attached);
} }
/** /**
......
...@@ -410,6 +410,31 @@ function testDrupalRenderThemeArguments() { ...@@ -410,6 +410,31 @@ function testDrupalRenderThemeArguments() {
$this->assertEqual(drupal_render($element), $element['#foo'] . $element['#bar'], 'Passing arguments to theme functions works'); $this->assertEqual(drupal_render($element), $element['#foo'] . $element['#bar'], 'Passing arguments to theme functions works');
} }
/**
* Tests theme preprocess functions being able to attach assets.
*/
function testDrupalRenderThemePreprocessAttached() {
\Drupal::state()->set('theme_preprocess_attached_test', TRUE);
$test_element = [
'#theme' => 'common_test_render_element',
'foo' => [
'#markup' => 'Kittens!',
],
];
drupal_render($test_element);
$expected_attached = [
'library' => [
'test/generic_preprocess',
'test/specific_preprocess',
]
];
$this->assertEqual($expected_attached, $test_element['#attached'], 'All expected assets from theme preprocess hooks attached.');
\Drupal::state()->set('theme_preprocess_attached_test', FALSE);
}
/** /**
* Tests caching of an empty render item. * Tests caching of an empty render item.
*/ */
......
...@@ -142,6 +142,30 @@ function theme_common_test_empty($variables) { ...@@ -142,6 +142,30 @@ function theme_common_test_empty($variables) {
return ''; return '';
} }
/**
* Implements MODULE_preprocess().
*
* @see RenderTest::testDrupalRenderThemePreprocessAttached()
*/
function common_test_preprocess(&$variables, $hook) {
if (!\Drupal::state()->get('theme_preprocess_attached_test', FALSE)) {
return;
}
$variables['#attached']['library'][] = 'test/generic_preprocess';
}
/**
* Implements MODULE_preprocess_HOOK().
*
* @see RenderTest::testDrupalRenderThemePreprocessAttached()
*/
function common_test_preprocess_common_test_render_element(&$variables) {
if (!\Drupal::state()->get('theme_preprocess_attached_test', FALSE)) {
return;
}
$variables['#attached']['library'][] = 'test/specific_preprocess';
}
/** /**
* Implements hook_library_info_alter(). * Implements hook_library_info_alter().
*/ */
......
...@@ -159,6 +159,21 @@ ...@@ -159,6 +159,21 @@
* suggestions as input, and can change this array (adding suggestions and * suggestions as input, and can change this array (adding suggestions and
* removing them). * removing them).
* *
* @section Assets
*
* We can distinguish between two types of assets:
* 1. global assets (loaded on all pages where the theme is in use): these are
* defined in the theme's *.info.yml file.
* 2. 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 seven_preprocess_menu_local_action(array &$variables) {
* // We require Modernizr's touch test for button styling.
* $variables['#attached']['library'][] = 'core/modernizr';
* }
* @endcode
*
* @see hooks * @see hooks
* @see callbacks * @see callbacks
* @see theme_render * @see theme_render
......
...@@ -329,8 +329,7 @@ function views_preprocess_page(&$variables) { ...@@ -329,8 +329,7 @@ function views_preprocess_page(&$variables) {
unset($class[$key]); unset($class[$key]);
$attributes['class'] = $class; $attributes['class'] = $class;
$attributes['data-views-page-contextual-id'] = $variables['title_suffix']['contextual_links']['#id']; $attributes['data-views-page-contextual-id'] = $variables['title_suffix']['contextual_links']['#id'];
$attached['#attached']['library'][] = 'views/views.contextual-links'; $variables['#attached']['library'][] = 'views/views.contextual-links';
drupal_render($attached);
} }
} }
} }
......
...@@ -87,16 +87,9 @@ function bartik_preprocess_maintenance_page(&$variables) { ...@@ -87,16 +87,9 @@ function bartik_preprocess_maintenance_page(&$variables) {
if (!$variables['db_is_active']) { if (!$variables['db_is_active']) {
$variables['site_name'] = ''; $variables['site_name'] = '';
} }
// Normally we could attach libraries via hook_page_alter(), but when the
// database is inactive it's not called so we add them here. // Bartik has custom styling for the maintenance page.
$libraries = array( $variables['#attached']['library'][] = 'bartik/maintenance_page';
'#attached' => array(
'library' => array(
'bartik/maintenance_page',
),
),
);
drupal_render($libraries);
// Set the options that apply to both page and maintenance page. // Set the options that apply to both page and maintenance page.
_bartik_process_page($variables); _bartik_process_page($variables);
......
...@@ -16,7 +16,7 @@ install-page: ...@@ -16,7 +16,7 @@ install-page:
theme: theme:
css/theme/install-page.css: {} css/theme/install-page.css: {}
dependencies: dependencies:
- system/maintenance - seven/maintenance-page
drupal.nav-tabs: drupal.nav-tabs:
version: VERSION version: VERSION
......
...@@ -128,14 +128,7 @@ function seven_preprocess_menu_local_action(array &$variables) { ...@@ -128,14 +128,7 @@ function seven_preprocess_menu_local_action(array &$variables) {
$variables['link']['#options']['attributes']['class'][] = 'button--small'; $variables['link']['#options']['attributes']['class'][] = 'button--small';
// We require Modernizr's touch test for button styling. // We require Modernizr's touch test for button styling.
$libraries = array( $variables['#attached']['library'][] = 'core/modernizr';
'#attached' => array(
'library' => array(
'core/modernizr',
),
),
);
drupal_render($libraries);
} }
/** /**
...@@ -158,17 +151,8 @@ function seven_preprocess_install_page(&$variables) { ...@@ -158,17 +151,8 @@ function seven_preprocess_install_page(&$variables) {
$classes[] = 'install-background'; $classes[] = 'install-background';
$attributes['class'] = $classes; $attributes['class'] = $classes;
// Normally we could attach libraries via hook_page_alter(), but when the // Seven has custom styling for the install page.
// database is inactive it's not called so we add them here. $variables['#attached']['library'][] = 'seven/install-page';
$libraries = array(
'#attached' => array(
'library' => array(
'seven/maintenance-page',
'seven/install-page',
),
),
);
drupal_render($libraries);
} }
/** /**
...@@ -181,16 +165,8 @@ function seven_preprocess_maintenance_page(&$variables) { ...@@ -181,16 +165,8 @@ function seven_preprocess_maintenance_page(&$variables) {
$classes[] = 'maintenance-background'; $classes[] = 'maintenance-background';
$attributes['class'] = $classes; $attributes['class'] = $classes;
// // Normally we could attach libraries via hook_page_alter(), but when the // Seven has custom styling for the maintenance page.
// // database is inactive it's not called so we add them here. $variables['#attached']['library'][] = 'seven/maintenance-page';
$libraries = array(
'#attached' => array(
'library' => array(
'seven/maintenance-page',
),
),
);
drupal_render($libraries);
} }
/** /**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment