function ds_theme_registry_alter in Display Suite 8.4
Same name and namespace in other branches
- 8.2 ds.module \ds_theme_registry_alter()
- 8.3 ds.module \ds_theme_registry_alter()
- 7.2 ds.module \ds_theme_registry_alter()
- 7 ds.module \ds_theme_registry_alter()
Implements hook_theme_registry_alter().
File
- ./
ds.module, line 77 - Display Suite core functions.
Code
function ds_theme_registry_alter(&$theme_registry) {
$layouts = Ds::getLayouts();
$layout_theme_hooks = [];
/** @var \Drupal\Core\Layout\LayoutDefinition $info */
foreach ($layouts as $info) {
if (is_a($info
->getClass(), DsLayout::class, TRUE)) {
$layout_theme_hooks[$info
->getThemeHook()] = 'layout';
}
}
// Only add preprocess functions if entity exposes theme function, and this
// layout is using the Display Suite layout class.
foreach ($theme_registry as $theme_hook => $info) {
if (array_key_exists($theme_hook, $layout_theme_hooks) || !empty($info['base hook']) && array_key_exists($info['base hook'], $layout_theme_hooks)) {
$theme_registry[$theme_hook]['preprocess functions'][] = 'ds_preprocess_ds_layout';
}
}
// Check preprocess functions for ds fields.
$field_theme_hooks = [];
if (\Drupal::config('ds.settings')
->get('field_template')) {
$field_layouts = \Drupal::service('plugin.manager.ds.field.layout')
->getDefinitions();
foreach ($field_layouts as $key => $plugin) {
if ($key != 'default') {
// Get the hook name.
$hook_field_name = 'field__' . $plugin['theme'];
if (isset($theme_registry[$hook_field_name])) {
// Store for suggestions later.
$field_theme_hooks[$hook_field_name] = 'field';
// Variable holding the preprocess functions to add later.
$preprocess_functions_to_add = [];
// Overrides don't get the template_preprocess_field function.
if (!in_array('template_preprocess_field', $theme_registry[$hook_field_name]['preprocess functions'])) {
$preprocess_functions_to_add[] = 'template_preprocess_field';
}
// Overrides don't get the ds_preprocess_field function.
if (!in_array('ds_preprocess_field', $theme_registry[$hook_field_name]['preprocess functions'])) {
$preprocess_functions_to_add[] = 'ds_preprocess_field';
}
// We need to make sure the function runs asap as the dedicated field
// preprocess function might need ds information, e.g.
// template_preprocess_field__ds_field_expert().
// template_preprocess() will be available, so put them right after.
if (!empty($preprocess_functions_to_add)) {
$preprocess_functions = $theme_registry[$hook_field_name]['preprocess functions'];
array_splice($preprocess_functions, 1, 0, $preprocess_functions_to_add);
$theme_registry[$hook_field_name]['preprocess functions'] = $preprocess_functions;
}
}
}
}
}
// ------------------------------------------------------------------------
// Workaround to get theme suggestions working for templates using the
// the Display Suite class. It's borderline insane, but gets the job done.
//
// Note that this currently only works for Twig, but I assume, there isn't
// any other engine out there yet for Drupal 8.
//
// Code based on drupal_find_theme_templates().
//
// @see
// - https://www.drupal.org/node/2862683 (core queue)
// - https://www.drupal.org/node/2802429 (DS queue)
// (and maybe others)
// ------------------------------------------------------------------------
// Merge layout and field hooks.
$all_ds_theme_hooks = $layout_theme_hooks + $field_theme_hooks;
$engine = \Drupal::theme()
->getActiveTheme()
->getEngine();
if ($engine == 'twig') {
$extension = '.html.twig';
$theme_path = \Drupal::theme()
->getActiveTheme()
->getPath();
// Escape the periods in the extension.
$regex = '/' . str_replace('.', '\\.', $extension) . '$/';
// Get a listing of all template files in the path to search.
$files = \Drupal::service('file_system')
->scanDirectory($theme_path, $regex, [
'key' => 'filename',
]);
$patterns = array_keys($files);
$implementations = [];
foreach ($all_ds_theme_hooks as $hook => $base_hook) {
// Ignored if not registered (which would be weird).
if (!isset($theme_registry[$hook])) {
continue;
}
$pattern = isset($info['pattern']) ? $info['pattern'] : $hook . '__';
if (!empty($pattern)) {
// Transform _ in pattern to - to match file naming scheme
// for the purposes of searching.
$pattern = strtr($pattern, '_', '-');
$matches = preg_grep('/^' . $pattern . '/', $patterns);
if ($matches) {
foreach ($matches as $match) {
$file = $match;
// Remove the extension from the filename.
$file = str_replace($extension, '', $file);
// Put the underscores back in for the hook name and register this
// pattern.
$info = $theme_registry[$hook];
$arg_name = isset($info['variables']) ? 'variables' : 'render element';
$new_hook = strtr($file, '-', '_');
$implementations[$new_hook] = [
'template' => $file,
'path' => dirname($files[$match]->uri),
$arg_name => $info[$arg_name],
'base hook' => $base_hook,
'type' => 'theme_engine',
'theme path' => $theme_path,
];
if (isset($theme_registry[$hook]['preprocess functions'])) {
$implementations[$new_hook]['preprocess functions'] = $theme_registry[$hook]['preprocess functions'];
}
}
}
}
}
if (!empty($implementations)) {
$theme_registry += $implementations;
}
}
// ------------------------------------------------------------------------
// End of workaround, hopefully we can kill this one day.
// ------------------------------------------------------------------------
// Run field group preprocess before ds_entity_view.
if (function_exists('field_group_build_entity_groups')) {
array_unshift($theme_registry['ds_entity_view']['preprocess functions'], 'field_group_build_entity_groups');
}
// Remove ds_preprocess_field in case field templates is not enabled.
if (!\Drupal::config('ds.settings')
->get('field_template')) {
$key = array_search('ds_preprocess_field', $theme_registry['field']['preprocess functions']);
if (!empty($key)) {
unset($theme_registry['field']['preprocess functions'][$key]);
}
}
}