file BootstrapPanel.php

Namespace

Drupal\bootstrap\Plugin\Preprocess
  1. <?php
  2. namespace Drupal\bootstrap\Plugin\Preprocess;
  3. use Drupal\bootstrap\Utility\Element;
  4. use Drupal\bootstrap\Utility\Variables;
  5. use Drupal\Component\Render\MarkupInterface;
  6. use Drupal\Component\Utility\Html;
  7. /**
  8. * Pre-processes variables for the "bootstrap_panel" theme hook.
  9. *
  10. * @ingroup plugins_preprocess
  11. *
  12. * @BootstrapPreprocess("bootstrap_panel")
  13. */
  14. class BootstrapPanel extends PreprocessBase implements PreprocessInterface {
  15. /**
  16. * {@inheritdoc}
  17. */
  18. protected function preprocessElement(Element $element, Variables $variables) {
  19. // Assign the ID, if not already set.
  20. $element->map(['id']);
  21. // Add necessary classes.
  22. $element->addClass([
  23. 'form-item',
  24. 'js-form-item',
  25. 'form-wrapper',
  26. 'js-form-wrapper',
  27. ]);
  28. $body = [];
  29. $properties = ['field_prefix', 'body', 'children'];
  30. // Only add the #value property if it's a "details" or "fieldset" element
  31. // type. Some form elements may use "CompositeFormElementTrait" which
  32. // will inadvertently and eventually become preprocessed here and #value
  33. // may actually be the element's value instead of a renderable element.
  34. if ($element->isType(['details', 'fieldset'])) {
  35. $properties[] = 'value';
  36. }
  37. // Add the "#field_suffix" property.
  38. $properties[] = 'field_suffix';
  39. // Merge all possible content from the element into a single render array.
  40. foreach ($properties as $property) {
  41. $body[$property] = Element::create($element->getProperty($property, []))->getArray();
  42. }
  43. $variables['body'] = array_filter($body);
  44. $map = [
  45. 'attributes' => 'attributes',
  46. 'body_attributes' => 'body_attributes',
  47. 'content_attributes' => 'body_attributes',
  48. 'description' => 'description',
  49. 'description_attributes' => 'description_attributes',
  50. 'description_display' => 'description_display',
  51. 'errors' => 'errors',
  52. 'footer' => 'footer',
  53. 'required' => 'required',
  54. 'panel_type' => 'panel_type',
  55. 'title' => 'heading',
  56. 'title_attributes' => 'heading_attributes',
  57. ];
  58. // Handle specific "details" elements.
  59. if ($element->isType('details')) {
  60. // Details are always collapsible per the HTML5 spec.
  61. // @see https://www.drupal.org/node/1852020
  62. $variables['collapsible'] = TRUE;
  63. // Determine the collapsed state.
  64. $variables['collapsed'] = !$element->getProperty('open', TRUE);
  65. // Remove the unnecessary details attribute.
  66. $element->removeAttribute('open');
  67. }
  68. // Handle specific "fieldset" elements.
  69. elseif ($element->isType('fieldset')) {
  70. // Override variables to mimic the default "fieldset" element info.
  71. // They will be mapped below if they exist on the element.
  72. unset($variables['collapsible'], $variables['collapsed']);
  73. $map['collapsed'] = 'collapsed';
  74. $map['collapsible'] = 'collapsible';
  75. }
  76. // Map the element properties to the variables array.
  77. $variables->map($map);
  78. }
  79. /**
  80. * {@inheritdoc}
  81. */
  82. protected function preprocessVariables(Variables $variables) {
  83. // Retrieve the ID, generating one if needed.
  84. $id = $variables->getAttribute('id', Html::getUniqueId($variables->offsetGet('id', 'bootstrap-panel')));
  85. unset($variables['id']);
  86. // Handle collapsible state.
  87. if ($variables['heading'] && $variables['collapsible']) {
  88. // Retrieve the body ID attribute.
  89. if ($body_id = $variables->getAttribute('id', "$id--content", 'body_attributes')) {
  90. // Ensure the target is set.
  91. if ($variables['target'] = $variables->offsetGet('target', "#$body_id")) {
  92. // Set additional necessary attributes to the heading.
  93. $variables->setAttributes([
  94. 'aria-controls' => preg_replace('/^#/', '', $variables['target']),
  95. 'aria-expanded' => !$variables['collapsed'] ? 'true' : 'false',
  96. 'aria-pressed' => !$variables['collapsed'] ? 'true' : 'false',
  97. 'data-toggle' => 'collapse',
  98. 'role' => 'button',
  99. ], 'heading_attributes');
  100. }
  101. }
  102. }
  103. // Ensure we render HTML from heading.
  104. $heading = $variables->offsetGet('heading');
  105. if ($heading && (is_string($heading) || ($heading instanceof MarkupInterface))) {
  106. $variables->offsetSet('heading', ['#markup' => $heading]);
  107. }
  108. // Ensure there is a valid panel state.
  109. if (!$variables->offsetGet('panel_type')) {
  110. $variables->offsetSet('panel_type', 'default');
  111. }
  112. // Convert the description variable.
  113. $this->preprocessDescription();
  114. // Ensure all attributes are proper objects.
  115. $this->preprocessAttributes();
  116. }
  117. }

Classes

Name Description
BootstrapPanel Pre-processes variables for the "bootstrap_panel" theme hook.