seven.theme 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. <?php
  2. /**
  3. * @file
  4. * Functions to support theming in the Seven theme.
  5. */
  6. use Drupal\Core\Url;
  7. use Drupal\Core\Form\FormStateInterface;
  8. use Drupal\media\MediaForm;
  9. use Drupal\views\Form\ViewsForm;
  10. use Drupal\views\ViewExecutable;
  11. /**
  12. * Implements hook_preprocess_HOOK() for HTML document templates.
  13. */
  14. function seven_preprocess_html(&$variables) {
  15. // If on a node add or edit page, add a node-layout class.
  16. $path_args = explode('/', \Drupal::request()->getPathInfo());
  17. if ($suggestions = theme_get_suggestions($path_args, 'page', '-')) {
  18. foreach ($suggestions as $suggestion) {
  19. if ($suggestion === 'page-node-edit' || strpos($suggestion, 'page-node-add') !== FALSE) {
  20. $variables['attributes']['class'][] = 'node-form-layout';
  21. }
  22. }
  23. }
  24. }
  25. /**
  26. * Implements hook_preprocess_HOOK() for menu-local-tasks templates.
  27. *
  28. * Use preprocess hook to set #attached to child elements
  29. * because they will be processed by Twig and drupal_render will
  30. * be invoked.
  31. */
  32. function seven_preprocess_menu_local_tasks(&$variables) {
  33. if (!empty($variables['primary'])) {
  34. $variables['primary']['#attached'] = [
  35. 'library' => [
  36. 'seven/drupal.nav-tabs',
  37. ],
  38. ];
  39. }
  40. elseif (!empty($variables['secondary'])) {
  41. $variables['secondary']['#attached'] = [
  42. 'library' => [
  43. 'seven/drupal.nav-tabs',
  44. ],
  45. ];
  46. }
  47. }
  48. /**
  49. * Implements hook_preprocess_HOOK() for menu-local-task templates.
  50. */
  51. function seven_preprocess_menu_local_task(&$variables) {
  52. $variables['attributes']['class'][] = 'tabs__tab';
  53. }
  54. /**
  55. * Implements hook_preprocess_HOOK() for list of available node type templates.
  56. */
  57. function seven_preprocess_node_add_list(&$variables) {
  58. if (!empty($variables['content'])) {
  59. /** @var \Drupal\node\NodeTypeInterface $type */
  60. foreach ($variables['content'] as $type) {
  61. $variables['types'][$type->id()]['label'] = $type->label();
  62. $variables['types'][$type->id()]['url'] = Url::fromRoute('node.add', ['node_type' => $type->id()])->toString();
  63. }
  64. }
  65. }
  66. /**
  67. * Implements hook_preprocess_HOOK() for block content add list templates.
  68. *
  69. * Displays the list of available custom block types for creation, adding
  70. * separate variables for the label and url.
  71. */
  72. function seven_preprocess_block_content_add_list(&$variables) {
  73. if (!empty($variables['content'])) {
  74. foreach ($variables['content'] as $type) {
  75. $variables['types'][$type->id()]['label'] = $type->label();
  76. $options = ['query' => \Drupal::request()->query->all()];
  77. $variables['types'][$type->id()]['url'] = Url::fromRoute('block_content.add_form', ['block_content_type' => $type->id()], $options)->toString();
  78. }
  79. }
  80. }
  81. /**
  82. * Implements hook_preprocess_block() for block content.
  83. *
  84. * Disables contextual links for all blocks except for layout builder blocks.
  85. */
  86. function seven_preprocess_block(&$variables) {
  87. if (isset($variables['title_suffix']['contextual_links']) && !isset($variables['elements']['#contextual_links']['layout_builder_block'])) {
  88. unset($variables['title_suffix']['contextual_links']);
  89. unset($variables['elements']['#contextual_links']);
  90. $variables['attributes']['class'] = array_diff($variables['attributes']['class'], ['contextual-region']);
  91. }
  92. }
  93. /**
  94. * Implements hook_preprocess_HOOK() for block admin page templates.
  95. */
  96. function seven_preprocess_admin_block_content(&$variables) {
  97. if (!empty($variables['content'])) {
  98. foreach ($variables['content'] as $key => $item) {
  99. $variables['content'][$key]['url'] = $item['url']->toString();
  100. }
  101. }
  102. }
  103. /**
  104. * Implements hook_preprocess_HOOK() for menu-local-action templates.
  105. */
  106. function seven_preprocess_menu_local_action(array &$variables) {
  107. $variables['link']['#options']['attributes']['class'][] = 'button--primary';
  108. $variables['link']['#options']['attributes']['class'][] = 'button--small';
  109. // We require Modernizr's touch test for button styling.
  110. $variables['#attached']['library'][] = 'core/modernizr';
  111. }
  112. /**
  113. * Implements hook_element_info_alter().
  114. */
  115. function seven_element_info_alter(&$type) {
  116. // We require Modernizr for button styling.
  117. if (isset($type['button'])) {
  118. $type['button']['#attached']['library'][] = 'core/modernizr';
  119. }
  120. }
  121. /**
  122. * Implements hook_preprocess_install_page().
  123. */
  124. function seven_preprocess_install_page(&$variables) {
  125. // Seven has custom styling for the install page.
  126. $variables['#attached']['library'][] = 'seven/install-page';
  127. }
  128. /**
  129. * Implements hook_preprocess_maintenance_page().
  130. */
  131. function seven_preprocess_maintenance_page(&$variables) {
  132. // Seven has custom styling for the maintenance page.
  133. $variables['#attached']['library'][] = 'seven/maintenance-page';
  134. }
  135. /**
  136. * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm.
  137. *
  138. * Changes vertical tabs to container.
  139. */
  140. function seven_form_node_form_alter(&$form, FormStateInterface $form_state) {
  141. $form['#theme'] = ['node_edit_form'];
  142. $form['#attached']['library'][] = 'seven/node-form';
  143. $form['advanced']['#type'] = 'container';
  144. $form['meta']['#type'] = 'container';
  145. $form['meta']['#access'] = TRUE;
  146. $form['meta']['changed']['#wrapper_attributes']['class'][] = 'container-inline';
  147. $form['meta']['author']['#wrapper_attributes']['class'][] = 'container-inline';
  148. $form['revision_information']['#type'] = 'container';
  149. $form['revision_information']['#group'] = 'meta';
  150. }
  151. /**
  152. * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\media\MediaForm.
  153. */
  154. function seven_form_media_form_alter(&$form, FormStateInterface $form_state) {
  155. // Only attach CSS from core if this form comes from Media core, and not from
  156. // the contrib Media Entity 1.x branch.
  157. if (\Drupal::moduleHandler()->moduleExists('media') && $form_state->getFormObject() instanceof MediaForm) {
  158. // @todo Revisit after https://www.drupal.org/node/2892304 is in. It
  159. // introduces a footer region to these forms which will allow for us to
  160. // display a top border over the published checkbox by defining a
  161. // media-edit-form.html.twig template the same way node does.
  162. $form['#attached']['library'][] = 'seven/media-form';
  163. }
  164. }
  165. /**
  166. * Implements hook_form_FORM_ID_alter() for language_content_settings_form().
  167. */
  168. function seven_form_language_content_settings_form_alter(array &$form, FormStateInterface $form_state) {
  169. $form['#attached']['library'][] = 'seven/layout_builder_content_translation_admin';
  170. }
  171. /**
  172. * Implements hook_preprocess_views_view_fields().
  173. *
  174. * This targets each rendered media item in the grid display of the media
  175. * library's modal dialog.
  176. */
  177. function seven_preprocess_views_view_fields__media_library(array &$variables) {
  178. // Add classes to media rendered entity field so it can be targeted for
  179. // styling. Adding this class in a template is very difficult to do.
  180. if (isset($variables['fields']['rendered_entity']->wrapper_attributes)) {
  181. $variables['fields']['rendered_entity']->wrapper_attributes->addClass('media-library-item__click-to-select-trigger');
  182. }
  183. }
  184. /**
  185. * Implements hook_form_alter().
  186. */
  187. function seven_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  188. $form_object = $form_state->getFormObject();
  189. if ($form_object instanceof ViewsForm && strpos($form_object->getBaseFormId(), 'views_form_media_library') === 0) {
  190. if (isset($form['header'])) {
  191. $form['header']['#attributes']['class'][] = 'media-library-views-form__header';
  192. $form['header']['media_bulk_form']['#attributes']['class'][] = 'media-library-views-form__bulk_form';
  193. }
  194. $form['actions']['submit']['#attributes']['class'] = ['media-library-select'];
  195. }
  196. // Add after build to add a CSS class to the form actions.
  197. if ($form_id === 'views_exposed_form' && strpos($form['#id'], 'views-exposed-form-media-library-widget') === 0) {
  198. $form['actions']['#attributes']['class'][] = 'media-library-view--form-actions';
  199. }
  200. }
  201. /**
  202. * Implements hook_form_BASE_FORM_ID_alter().
  203. */
  204. function seven_form_media_library_add_form_alter(array &$form, FormStateInterface $form_state) {
  205. $form['#attributes']['class'][] = 'media-library-add-form';
  206. $form['#attached']['library'][] = 'seven/media_library';
  207. // If there are unsaved media items, apply styling classes to various parts
  208. // of the form.
  209. if (isset($form['media'])) {
  210. $form['#attributes']['class'][] = 'media-library-add-form--with-input';
  211. // Put a wrapper around the informational message above the unsaved media
  212. // items.
  213. $form['description']['#template'] = '<p class="media-library-add-form__description">{{ text }}</p>';
  214. }
  215. else {
  216. $form['#attributes']['class'][] = 'media-library-add-form--without-input';
  217. }
  218. }
  219. /**
  220. * Implements hook_form_FORM_ID_alter().
  221. */
  222. function seven_form_media_library_add_form_upload_alter(array &$form, FormStateInterface $form_state) {
  223. $form['#attributes']['class'][] = 'media-library-add-form--upload';
  224. if (isset($form['container'])) {
  225. $form['container']['#attributes']['class'][] = 'media-library-add-form__input-wrapper';
  226. }
  227. }
  228. /**
  229. * Implements hook_form_FORM_ID_alter().
  230. */
  231. function seven_form_media_library_add_form_oembed_alter(array &$form, FormStateInterface $form_state) {
  232. $form['#attributes']['class'][] = 'media-library-add-form--oembed';
  233. // If no media items have been added yet, add a couple of styling classes
  234. // to the initial URL form.
  235. if (isset($form['container'])) {
  236. $form['container']['#attributes']['class'][] = 'media-library-add-form__input-wrapper';
  237. $form['container']['url']['#attributes']['class'][] = 'media-library-add-form-oembed-url';
  238. $form['container']['submit']['#attributes']['class'][] = 'media-library-add-form-oembed-submit';
  239. }
  240. }
  241. /**
  242. * Implements hook_preprocess_item_list__media_library_add_form_media_list().
  243. *
  244. * This targets each new, unsaved media item added to the media library, before
  245. * they are saved.
  246. */
  247. function seven_preprocess_item_list__media_library_add_form_media_list(array &$variables) {
  248. foreach ($variables['items'] as &$item) {
  249. $item['value']['preview']['#attributes']['class'][] = 'media-library-add-form__preview';
  250. $item['value']['fields']['#attributes']['class'][] = 'media-library-add-form__fields';
  251. $item['value']['remove_button']['#attributes']['class'][] = 'media-library-add-form__remove-button';
  252. // #source_field_name is set by AddFormBase::buildEntityFormElement()
  253. // to help themes and form_alter hooks identify the source field.
  254. $fields = &$item['value']['fields'];
  255. $source_field_name = $fields['#source_field_name'];
  256. if (isset($fields[$source_field_name])) {
  257. $fields[$source_field_name]['#attributes']['class'][] = 'media-library-add-form__source-field';
  258. }
  259. }
  260. }
  261. /**
  262. * Implements hook_preprocess_media_library_item__widget().
  263. *
  264. * This targets each media item selected in an entity reference field.
  265. */
  266. function seven_preprocess_media_library_item__widget(array &$variables) {
  267. $variables['content']['remove_button']['#attributes']['class'][] = 'media-library-item__remove';
  268. }
  269. /**
  270. * Implements hook_preprocess_media_library_item__small().
  271. *
  272. * This targets each pre-selected media item selected when adding new media in
  273. * the modal media library dialog.
  274. */
  275. function seven_preprocess_media_library_item__small(array &$variables) {
  276. $variables['content']['select']['#attributes']['class'][] = 'media-library-item__click-to-select-checkbox';
  277. }
  278. /**
  279. * @todo Remove this when https://www.drupal.org/project/drupal/issues/2999549
  280. * lands.
  281. *
  282. * @see \Drupal\media_library\Plugin\Field\FieldWidget\MediaLibraryWidget::formElement()
  283. */
  284. function seven_preprocess_fieldset__media_library_widget(array &$variables) {
  285. if (isset($variables['prefix']['weight_toggle'])) {
  286. $variables['prefix']['weight_toggle']['#attributes']['class'][] = 'media-library-widget__toggle-weight';
  287. }
  288. if (isset($variables['suffix']['open_button'])) {
  289. $variables['suffix']['open_button']['#attributes']['class'][] = 'media-library-open-button';
  290. }
  291. }
  292. /**
  293. * Implements hook_views_pre_render().
  294. */
  295. function seven_views_pre_render(ViewExecutable $view) {
  296. $add_classes = function (&$option, array $classes_to_add) {
  297. $classes = preg_split('/\s+/', $option);
  298. $classes = array_filter($classes);
  299. $classes = array_merge($classes, $classes_to_add);
  300. $option = implode(' ', array_unique($classes));
  301. };
  302. if ($view->id() === 'media_library') {
  303. if ($view->display_handler->options['defaults']['css_class']) {
  304. $add_classes($view->displayHandlers->get('default')->options['css_class'], ['media-library-view']);
  305. }
  306. else {
  307. $add_classes($view->display_handler->options['css_class'], ['media-library-view']);
  308. }
  309. if ($view->current_display === 'page') {
  310. if (array_key_exists('media_bulk_form', $view->field)) {
  311. $add_classes($view->field['media_bulk_form']->options['element_class'], ['media-library-item__click-to-select-checkbox']);
  312. }
  313. if (array_key_exists('rendered_entity', $view->field)) {
  314. $add_classes($view->field['rendered_entity']->options['element_class'], ['media-library-item__content']);
  315. }
  316. if (array_key_exists('edit_media', $view->field)) {
  317. $add_classes($view->field['edit_media']->options['alter']['link_class'], ['media-library-item__edit']);
  318. }
  319. if (array_key_exists('delete_media', $view->field)) {
  320. $add_classes($view->field['delete_media']->options['alter']['link_class'], ['media-library-item__remove']);
  321. }
  322. }
  323. elseif (strpos($view->current_display, 'widget') === 0) {
  324. if (array_key_exists('rendered_entity', $view->field)) {
  325. $add_classes($view->field['rendered_entity']->options['element_class'], ['media-library-item__content']);
  326. }
  327. if (array_key_exists('media_library_select_form', $view->field)) {
  328. $add_classes($view->field['media_library_select_form']->options['element_wrapper_class'], ['media-library-item__click-to-select-checkbox']);
  329. }
  330. if ($view->display_handler->options['defaults']['css_class']) {
  331. $add_classes($view->displayHandlers->get('default')->options['css_class'], ['media-library-view--widget']);
  332. }
  333. else {
  334. $add_classes($view->display_handler->options['css_class'], ['media-library-view--widget']);
  335. }
  336. }
  337. }
  338. }
  339. /**
  340. * Prepares variables for update version templates.
  341. *
  342. * Default template: update-version.html.twig.
  343. *
  344. * @param array $variables
  345. * An associative array containing:
  346. * - version: An array of information about the release version.
  347. */
  348. function seven_preprocess_update_version(array &$variables) {
  349. $variables['#attached']['library'][] = 'seven/update-report';
  350. }