class ThemeSuggestions in Express 8
Implements hook_theme_suggestions_alter().
Plugin annotation
@BootstrapAlter("theme_suggestions");
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\bootstrap\Plugin\PluginBase
- class \Drupal\bootstrap\Plugin\Alter\ThemeSuggestions implements AlterInterface
- class \Drupal\bootstrap\Plugin\PluginBase
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of ThemeSuggestions
File
- themes/
contrib/ bootstrap/ src/ Plugin/ Alter/ ThemeSuggestions.php, line 23 - Contains \Drupal\bootstrap\Plugin\Alter\ThemeSuggestions.
Namespace
Drupal\bootstrap\Plugin\AlterView source
class ThemeSuggestions extends PluginBase implements AlterInterface {
/**
* @var array
*/
protected $bootstrapPanelTypes = [
'details',
'fieldset',
];
/**
* An element object provided in the variables array, may not be set.
*
* @var \Drupal\bootstrap\Utility\Element|false
*/
protected $element;
/**
* The theme hook invoked.
*
* @var string
*/
protected $hook;
/**
* The theme hook suggestions, exploded by the "__" delimiter.
*
* @var array
*/
protected $hookSuggestions;
/**
* The types of elements to ignore for the "input__form_control" suggestion.
*
* @var array
*/
protected $ignoreFormControlTypes = [
'checkbox',
'hidden',
'radio',
];
/**
* The original "hook" value passed via hook_theme_suggestions_alter().
*
* @var string
*/
protected $originalHook;
/**
* The array of suggestions to return.
*
* @var array
*/
protected $suggestions;
/**
* The variables array object passed via hook_theme_suggestions_alter().
*
* @var \Drupal\bootstrap\Utility\Variables
*/
protected $variables;
/**
* {@inheritdoc}
*/
public function alter(&$suggestions, &$variables = [], &$hook = NULL) {
// This is intentionally backwards. The "original" theme hook is actually
// the hook being invoked. The provided $hook (to the alter) is the watered
// down version of said original hook.
$this->hook = !empty($variables['theme_hook_original']) ? $variables['theme_hook_original'] : $hook;
$this->hookSuggestions = explode('__', $this->hook);
$this->originalHook = $hook;
$this->suggestions = $suggestions;
$this->variables = Variables::create($variables);
$this->element = $this->variables->element;
// Processes the necessary theme hook suggestions.
$this
->processSuggestions();
// Ensure the list of suggestions is unique.
$suggestions = array_unique($this->suggestions);
}
/***************************************************************************
* Dynamic alter methods.
***************************************************************************/
/**
* Dynamic alter method for "input".
*/
protected function alterInput() {
if ($this->element && $this->element
->isButton()) {
$hook = 'input__button';
if ($this->element
->getProperty('split')) {
$hook .= '__split';
}
$this
->addSuggestion($hook);
}
elseif ($this->element && !$this->element
->isType($this->ignoreFormControlTypes)) {
$this
->addSuggestion('input__form_control');
}
}
/**
* Dynamic alter method for "links__dropbutton".
*/
protected function alterLinksDropbutton() {
// Remove the 'dropbutton' suggestion.
array_shift($this->hookSuggestions);
$this
->addSuggestion('bootstrap_dropdown');
}
/**
* Dynamic alter method for "user".
*
* @see https://www.drupal.org/node/2828634
* @see https://www.drupal.org/node/2808481
* @todo Remove/refactor once core issue is resolved.
*/
protected function alterUser() {
$this
->addSuggestionsForEntity('user');
}
/***************************************************************************
* Protected methods.
***************************************************************************/
/**
* Adds suggestions based on an array of hooks.
*
* @param string|string[] $hook
* A single theme hook suggestion or an array of theme hook suggestions.
*/
protected function addSuggestion($hook) {
$hooks = (array) $hook;
foreach ($hooks as $hook) {
$suggestions = $this
->buildSuggestions($hook);
foreach ($suggestions as $suggestion) {
$this->suggestions[] = $suggestion;
}
}
}
/**
* Adds "bundle" and "view mode" suggestions for an entity.
*
* This is a helper method because core's implementation of theme hook
* suggestions on entities is inconsistent.
*
* @see https://www.drupal.org/node/2808481
*
* @param string $entity_type
* Optional. A specific type of entity to look for.
* @param string $prefix
* Optional. A prefix (like "entity") to use. It will automatically be
* appended with the "__" separator.
*
* @todo Remove/refactor once core issue is resolved.
*/
protected function addSuggestionsForEntity($entity_type = 'entity', $prefix = '') {
// Immediately return if there is no element.
if (!$this->element) {
return;
}
// Extract the entity.
if ($entity = $this
->getEntityObject($entity_type)) {
$entity_type_id = $entity
->getEntityTypeId();
$suggestions = [];
// Only add the entity type identifier if there's a prefix.
if (!empty($prefix)) {
$prefix .= '__';
$suggestions[] = $prefix . '__' . $entity_type_id;
}
// View mode.
if ($view_mode = preg_replace('/[^A-Za-z0-9]+/', '_', $this->element
->getProperty('view_mode'))) {
$suggestions[] = $prefix . $entity_type_id . '__' . $view_mode;
// Bundle.
if ($entity
->getEntityType()
->hasKey('bundle')) {
$suggestions[] = $prefix . $entity_type_id . '__' . $entity
->bundle();
$suggestions[] = $prefix . $entity_type_id . '__' . $entity
->bundle() . '__' . $view_mode;
}
}
// Add suggestions.
if ($suggestions) {
$this
->addSuggestion($suggestions);
}
}
}
/**
* Builds a list of suggestions.
*
* @param string $hook
* The theme hook suggestion to build.
*
* @return array
*/
protected function buildSuggestions($hook) {
$suggestions = [];
$hook_suggestions = $this->hookSuggestions;
// Replace the first hook suggestion with $hook.
array_shift($hook_suggestions);
array_unshift($suggestions, $hook);
$suggestions = [];
while ($hook_suggestions) {
$suggestions[] = $hook . '__' . implode('__', $hook_suggestions);
array_pop($hook_suggestions);
}
// Append the base hook.
$suggestions[] = $hook;
// Return the suggestions, reversed.
return array_reverse($suggestions);
}
/**
* Retrieves the methods to invoke to process the theme hook suggestion.
*
* @return array
* An indexed array of methods to be invoked.
*/
protected function getAlterMethods() {
// Retrieve cached theme hook suggestion alter methods.
$cache = $this->theme
->getCache('theme_hook_suggestions');
if ($cache
->has($this->hook)) {
return $cache
->get($this->hook);
}
// Uppercase each theme hook suggestion to be used in the method name.
$hook_suggestions = $this->hookSuggestions;
foreach ($hook_suggestions as $key => $suggestion) {
$hook_suggestions[$key] = Unicode::ucfirst($suggestion);
}
$methods = [];
while ($hook_suggestions) {
$method = 'alter' . implode('', $hook_suggestions);
if (method_exists($this, $method)) {
$methods[] = $method;
}
array_pop($hook_suggestions);
}
// Reverse the methods.
$methods = array_reverse($methods);
// Cache the methods.
$cache
->set($this->hook, $methods);
return $methods;
}
/**
* Extracts the entity from the element(s) passed in the Variables object.
*
* @param string $entity_type
* Optional. The entity type to attempt to retrieve.
*
* @return \Drupal\Core\Entity\EntityInterface|null
* The extracted entity, NULL if entity could not be found.
*/
protected function getEntityObject($entity_type = 'entity') {
// Immediately return if there is no element.
if (!$this->element) {
return NULL;
}
// Attempt to retrieve the provided element type.
$entity = $this->element
->getProperty($entity_type);
// If the provided entity type doesn't exist, check to see if a generic
// "entity" property was used instead.
if ($entity_type !== 'entity' && (!$entity || !$entity instanceof EntityInterface)) {
$entity = $this->element
->getProperty('entity');
}
// Only return the entity if it's the proper object.
return $entity instanceof EntityInterface ? $entity : NULL;
}
/**
* Processes the necessary theme hook suggestions.
*/
protected function processSuggestions() {
// Add special hook suggestions for Bootstrap panels.
if (in_array($this->originalHook, $this->bootstrapPanelTypes) && $this->element && $this->element
->getProperty('bootstrap_panel', TRUE)) {
$this
->addSuggestion('bootstrap_panel');
}
// Retrieve any dynamic alter methods.
$methods = $this
->getAlterMethods();
foreach ($methods as $method) {
$this
->{$method}();
}
}
/***************************************************************************
* Deprecated methods (DO NOT USE).
***************************************************************************/
/**
* Adds "bundle" and "view mode" suggestions for an entity.
*
* @param array $suggestions
* The suggestions array, this is ignored.
* @param \Drupal\bootstrap\Utility\Variables $variables
* The variables object, this is ignored.
* @param string $entity_type
* Optional. A specific type of entity to look for.
* @param string $prefix
* Optional. A prefix (like "entity") to use. It will automatically be
* appended with the "__" separator.
*
* @deprecated Since 8.x-3.2. Will be removed in a future release.
*
* @see \Drupal\bootstrap\Plugin\Alter\ThemeSuggestions::addSuggestionsForEntity
*/
public function addEntitySuggestions(array &$suggestions, Variables $variables, $entity_type = 'entity', $prefix = '') {
Bootstrap::deprecated();
$this
->addSuggestionsForEntity($entity_type, $prefix);
}
/**
* Extracts the entity from the element(s) passed in the Variables object.
*
* @param \Drupal\bootstrap\Utility\Variables $variables
* The Variables object, this is ignored.
* @param string $entity_type
* Optional. The entity type to attempt to retrieve.
*
* @return \Drupal\Core\Entity\EntityInterface|null
* The extracted entity, NULL if entity could not be found.
*
* @deprecated Since 8.x-3.2. Will be removed in a future release.
*
* @see \Drupal\bootstrap\Plugin\Alter\ThemeSuggestions::getEntityObject
*/
public function getEntity(Variables $variables, $entity_type = 'entity') {
Bootstrap::deprecated();
return $this
->getEntityObject($entity_type);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
protected | property | The currently set theme object. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
PluginBase:: |
public | function |
Constructs a \Drupal\Component\Plugin\PluginBase object. Overrides PluginBase:: |
1 |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
ThemeSuggestions:: |
protected | property | ||
ThemeSuggestions:: |
protected | property | An element object provided in the variables array, may not be set. | |
ThemeSuggestions:: |
protected | property | The theme hook invoked. | |
ThemeSuggestions:: |
protected | property | The theme hook suggestions, exploded by the "__" delimiter. | |
ThemeSuggestions:: |
protected | property | The types of elements to ignore for the "input__form_control" suggestion. | |
ThemeSuggestions:: |
protected | property | The original "hook" value passed via hook_theme_suggestions_alter(). | |
ThemeSuggestions:: |
protected | property | The array of suggestions to return. | |
ThemeSuggestions:: |
protected | property | The variables array object passed via hook_theme_suggestions_alter(). | |
ThemeSuggestions:: |
public | function | Adds "bundle" and "view mode" suggestions for an entity. | |
ThemeSuggestions:: |
protected | function | Adds suggestions based on an array of hooks. | |
ThemeSuggestions:: |
protected | function | Adds "bundle" and "view mode" suggestions for an entity. | |
ThemeSuggestions:: |
public | function |
Alters data for a specific hook_TYPE_alter() implementation. Overrides AlterInterface:: |
|
ThemeSuggestions:: |
protected | function | Dynamic alter method for "input". | |
ThemeSuggestions:: |
protected | function | Dynamic alter method for "links__dropbutton". | |
ThemeSuggestions:: |
protected | function | Dynamic alter method for "user". | |
ThemeSuggestions:: |
protected | function | Builds a list of suggestions. | |
ThemeSuggestions:: |
protected | function | Retrieves the methods to invoke to process the theme hook suggestion. | |
ThemeSuggestions:: |
public | function | Extracts the entity from the element(s) passed in the Variables object. | |
ThemeSuggestions:: |
protected | function | Extracts the entity from the element(s) passed in the Variables object. | |
ThemeSuggestions:: |
protected | function | Processes the necessary theme hook suggestions. |