hook_library_alter() is a hook that executes during run-time in order to make adjustments to asset library definitions. (hook_library() in Drupal 7, libraries.yml in Drupal 8).
Using it is sub-optimal because:
- it violates the principle that libraries are declarative, because it effectively makes them different depending on the request
- it causes performance problems, due to the invoking of
hook_library_alter()on each page load, for every single library, for as many implementations of the hook there are - (practical example of point 1) it encourages (or at least allows) for things that actually belong in
drupalSettings(such as modifying configuration based on the current site language like locale_library_alter()) - it creates confusion with
hook_library_info_alter(), a similar hook that executes at cache rebuild time instead, for better performance.
Since Drupal 8 now supports a JS settings asset type, and a corresponding hook_js_settings_alter() to alter JS settings for the current request), we no longer require this hook in order for libraries to react dynamically. Therefore, modules should no longer use hook_library_alter(), opting instead for hook_library_info_alter(), perhaps in combination with hook_js_settings_alter(), as appropriate.
Drupal 7
function locale_library_alter(&$libraries, $module) {
if ($module == 'system' && isset($libraries['ui.datepicker'])) {
global $language;
// locale.datepicker.js should be added in the JS_LIBRARY group, so that
// this attach behavior will execute early. JS_LIBRARY is the default for
// hook_library_info_alter(), thus does not have to be specified explicitly.
$datepicker = drupal_get_path('module', 'locale') . '/locale.datepicker.js';
$libraries['ui.datepicker']['js'][$datepicker] = array();
$libraries['ui.datepicker']['js'][] = array(
'data' => array(
'jquery' => array(
'ui' => array(
'datepicker' => array(
'isRTL' => $language->direction == LANGUAGE_RTL,
'firstDay' => variable_get('date_first_day', 0),
),
),
),
),
'type' => 'setting',
);
}
}
Drupal 8
The first alter hook changes the definition of the library. The second then replaces the placeholder values for the drupalSettings stored in the library definition for each request.
/**
* Implements hook_library_info_alter().
*
* Provides the language support for the jQuery UI Date Picker.
*/
function locale_library_info_alter(array &$libraries, $module) {
if ($module === 'core' && isset($libraries['jquery.ui.datepicker'])) {
$libraries['jquery.ui.datepicker']['dependencies'][] = 'locale/drupal.locale.datepicker';
$libraries['jquery.ui.datepicker']['drupalSettings']['jquery']['ui']['datepicker'] = [
'isRTL' => NULL,
'firstDay' => NULL,
];
}
}
/**
* Implements hook_js_settings_alter().
*
* Generates the values for the altered core/jquery.ui.datepicker library.
*/
function locale_js_settings_alter(&$settings) {
if (isset($settings['jquery']['ui']['datepicker'])) {
$language_interface = \Drupal::languageManager()->getCurrentLanguage();
$settings['jquery']['ui']['datepicker']['isRTL'] = $language_interface->getDirection() == LanguageInterface::DIRECTION_RTL;
$settings['jquery']['ui']['datepicker']['firstDay'] = \Drupal::config('system.date')->get('first_day');
}
}