You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
714 lines
27 KiB
714 lines
27 KiB
<?php |
|
|
|
/** |
|
* @file |
|
* Functions to support theming in the Olivesdocs theme. |
|
*/ |
|
|
|
use Drupal\olivesdocs\OlivesdocsPreRender; |
|
use Drupal\Component\Utility\Html; |
|
use Drupal\Core\Form\FormStateInterface; |
|
use Drupal\Core\Template\Attribute; |
|
use Drupal\Core\Render\Element; |
|
use Drupal\user\UserInterface; |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK() for HTML document templates. |
|
* |
|
* Adds body classes if certain regions have content. |
|
*/ |
|
function olivesdocs_preprocess_html(&$variables) { |
|
if (theme_get_setting('mobile_menu_all_widths') === 1) { |
|
$variables['attributes']['class'][] = 'is-always-mobile-nav'; |
|
} |
|
|
|
// Convert custom hex to hsl so we can use the hue value |
|
$brand_color_hex = theme_get_setting('base_primary_color') ?? '#1b9ae4'; |
|
[$h, $s, $l] = _olivesdocs_hex_to_hsl($brand_color_hex); |
|
|
|
$variables['html_attributes']->setAttribute('style', "--color--primary-hue:$h;--color--primary-saturation:$s%;--color--primary-lightness:$l"); |
|
|
|
// So fonts can be preloaded from base theme in the event Olivesdocs is used as a subtheme. |
|
$variables['olivesdocs_path'] = \Drupal::request()->getBasePath() . '/' . \Drupal::service('extension.list.theme')->getPath('olivesdocs'); |
|
|
|
$query_string = \Drupal::state()->get('system.css_js_query_string') ?: '0'; |
|
|
|
// Create render array with noscript tag to output non-JavaScript |
|
// stylesheet for primary menu. |
|
$variables['noscript_styles'] = [ |
|
'#type' => 'html_tag', |
|
'#noscript' => TRUE, |
|
'#tag' => 'link', |
|
'#attributes' => [ |
|
'rel' => 'stylesheet', |
|
'href' => $variables['olivesdocs_path'] . '/css/components/navigation/nav-primary-no-js.css?' . $query_string, |
|
], |
|
]; |
|
} |
|
|
|
|
|
/** |
|
* Implements hook_preprocess_HOOK() for page title templates. |
|
*/ |
|
function olivesdocs_preprocess_page_title(&$variables) { |
|
// Since the title and the shortcut link are both block level elements, |
|
// positioning them next to each other is much simpler with a wrapper div. |
|
if (!empty($variables['title_suffix']['add_or_remove_shortcut']) && $variables['title']) { |
|
// Add a wrapper div using the title_prefix and title_suffix render |
|
// elements. |
|
$variables['title_prefix']['shortcut_wrapper'] = [ |
|
'#markup' => '<div class="shortcut-wrapper">', |
|
'#weight' => 100, |
|
]; |
|
$variables['title_suffix']['shortcut_wrapper'] = [ |
|
'#markup' => '</div>', |
|
'#weight' => -99, |
|
]; |
|
|
|
// Make sure the shortcut link is the first item in title_suffix. |
|
$variables['title_suffix']['add_or_remove_shortcut']['#weight'] = -100; |
|
} |
|
|
|
// Unset shortcut link on front page. |
|
$variables['is_front'] = \Drupal::service('path.matcher')->isFrontPage(); |
|
if ($variables['is_front'] === TRUE) { |
|
unset($variables['title_suffix']['add_or_remove_shortcut']); |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK() for maintenance-page.html.twig. |
|
*/ |
|
function olivesdocs_preprocess_maintenance_page(&$variables) { |
|
// By default, site_name is set to Drupal if no db connection is available |
|
// or during site installation. Setting site_name to an empty string makes |
|
// the site and update pages look cleaner. |
|
// @see template_preprocess_maintenance_page |
|
if (!$variables['db_is_active']) { |
|
$variables['site_name'] = ''; |
|
} |
|
|
|
// Olivesdocs has custom styling for the maintenance page. |
|
$variables['#attached']['library'][] = 'olivesdocs/maintenance-page'; |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK() for node.html.twig. |
|
*/ |
|
function olivesdocs_preprocess_node(&$variables) { |
|
// Remove the "Add new comment" link on teasers or when the comment form is |
|
// displayed on the page. |
|
if ($variables['teaser'] || !empty($variables['content']['comments']['comment_form'])) { |
|
unset($variables['content']['links']['comment']['#links']['comment-add']); |
|
} |
|
|
|
// Apply custom date formatter to "date" field. |
|
if (!empty($variables['date']) && !empty($variables['display_submitted']) && $variables['display_submitted'] === TRUE) { |
|
$variables['date'] = \Drupal::service('date.formatter')->format($variables['node']->getCreatedTime(), 'olivesdocs_medium'); |
|
} |
|
|
|
// Pass layout variable to template if content type is article in full view |
|
// mode. This is then used in the template to create a BEM style CSS class to |
|
// control the layout. |
|
if ($variables['node']->bundle() === 'article' && $variables['view_mode'] === 'full') { |
|
$variables['layout'] = 'content-narrow'; |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK() for block.html.twig. |
|
*/ |
|
function olivesdocs_preprocess_block(&$variables) { |
|
if (!empty($variables['elements']['#id'])) { |
|
/** @var \Drupal\block\BlockInterface $block */ |
|
$block = \Drupal::entityTypeManager() |
|
->getStorage('block') |
|
->load($variables['elements']['#id']); |
|
if ($block) { |
|
$region = $block->getRegion(); |
|
|
|
if ($variables['base_plugin_id'] === 'system_menu_block') { |
|
$variables['content']['#attributes']['region'] = $region; |
|
if ($region === 'sidebar') { |
|
$variables['#attached']['library'][] = 'olivesdocs/menu-sidebar'; |
|
} |
|
} |
|
|
|
if ($variables['base_plugin_id'] === 'search_form_block') { |
|
if ($region === 'primary_menu') { |
|
$variables['#attached']['library'][] = 'olivesdocs/search-narrow'; |
|
$variables['content']['actions']['submit']['#theme_wrappers'] = ['input__submit__header_search']; |
|
} |
|
elseif ($region === 'secondary_menu') { |
|
$variables['#attached']['library'][] = 'olivesdocs/search-wide'; |
|
$variables['content']['actions']['submit']['#theme_wrappers'] = ['input__submit__header_search']; |
|
} |
|
} |
|
} |
|
} |
|
|
|
if ($variables['plugin_id'] === 'system_branding_block') { |
|
$site_branding_color = theme_get_setting('site_branding_bg_color'); |
|
if ($site_branding_color && $site_branding_color !== 'default') { |
|
$variables['attributes']['class'][] = 'site-branding--bg-' . $site_branding_color; |
|
} |
|
} |
|
|
|
// Add a primary-nav class to main menu navigation block. |
|
if ($variables['plugin_id'] === 'system_menu_block:main') { |
|
$variables['attributes']['class'][] = 'primary-nav'; |
|
} |
|
|
|
if ($variables['plugin_id'] === 'mirador_block') { |
|
|
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_theme_suggestions_HOOK_alter() for menu. |
|
*/ |
|
function olivesdocs_theme_suggestions_menu_alter(&$suggestions, array $variables) { |
|
if (isset($variables['attributes']['region'])) { |
|
$suggestions[] = 'menu__' . $variables['attributes']['region']; |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK(). |
|
*/ |
|
function olivesdocs_preprocess_menu(&$variables) { |
|
if (isset($variables['attributes']['region'])) { |
|
if ($variables['attributes']['region'] === 'sidebar') { |
|
$variables['attributes']['class'][] = 'menu--sidebar'; |
|
} |
|
unset($variables['attributes']['region']); |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_theme_suggestions_HOOK_alter() for form templates. |
|
*/ |
|
function olivesdocs_theme_suggestions_form_alter(array &$suggestions, array $variables) { |
|
if ($variables['element']['#form_id'] === 'search_block_form') { |
|
$suggestions[] = 'form__search_block_form'; |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_form_alter() for adding classes and placeholder text to the search forms. |
|
*/ |
|
function olivesdocs_form_alter(&$form, FormStateInterface $form_state, $form_id) { |
|
if (isset($form['actions']['submit']) && (count($form['actions'])) <= 2) { |
|
$form['actions']['submit']['#attributes']['class'][] = 'button--primary'; |
|
} |
|
|
|
switch ($form_id) { |
|
case 'search_block_form': |
|
// Add placeholder text to keys input. |
|
$form['keys']['#attributes']['placeholder'] = t('Search by keyword or phrase.'); |
|
|
|
// Add classes to the search form submit input. |
|
$form['actions']['submit']['#attributes']['class'][] = 'search-form__submit'; |
|
break; |
|
|
|
case 'search_form': |
|
$form['basic']['keys']['#attributes']['placeholder'] = t('Search by keyword or phrase.'); |
|
$form['basic']['submit']['#attributes']['class'][] = 'button--primary'; |
|
$form['advanced']['submit']['#attributes']['class'][] = 'button--primary'; |
|
break; |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_theme_suggestions_HOOK_alter() for block(). |
|
*/ |
|
function olivesdocs_theme_suggestions_block_alter(&$suggestions, array $variables) { |
|
if (!empty($variables['elements']['#id'])) { |
|
|
|
/** @var \Drupal\block\BlockInterface $block */ |
|
$block = \Drupal::entityTypeManager() |
|
->getStorage('block') |
|
->load($variables['elements']['#id']); |
|
if ($block) { |
|
|
|
// Add region-specific block theme suggestions. |
|
$region = $block |
|
->getRegion(); |
|
|
|
$suggestions[] = 'block__' . $region; |
|
$suggestions[] = 'block__' . $region . '__' . 'plugin_id' . '__' . $variables['elements']['#plugin_id']; |
|
$suggestions[] = 'block__' . $region . '__' . 'id' . '__' . $variables['elements']['#id']; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK() for menu-local-tasks templates. |
|
*/ |
|
function olivesdocs_preprocess_menu_local_tasks(&$variables) { |
|
foreach (Element::children($variables['primary']) as $key) { |
|
$variables['primary'][$key]['#level'] = 'primary'; |
|
} |
|
foreach (Element::children($variables['secondary']) as $key) { |
|
$variables['secondary'][$key]['#level'] = 'secondary'; |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_form_element(). |
|
*/ |
|
function olivesdocs_preprocess_form_element(&$variables) { |
|
if (in_array($variables['element']['#type'] ?? FALSE, ['checkbox', 'radio'], TRUE)) { |
|
$variables['attributes']['class'][] = 'form-type-boolean'; |
|
} |
|
|
|
if (!empty($variables['description']['attributes'])) { |
|
$variables['description']['attributes']->addClass('form-item__description'); |
|
} |
|
|
|
if ($variables['disabled']) { |
|
$variables['label']['#attributes']['class'][] = 'is-disabled'; |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK(). |
|
*/ |
|
function olivesdocs_preprocess_form_element_label(&$variables) { |
|
$variables['attributes']['class'][] = 'form-item__label'; |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK(). |
|
*/ |
|
function olivesdocs_preprocess_input(&$variables) { |
|
if ( |
|
!empty($variables['element']['#title_display']) && |
|
$variables['element']['#title_display'] === 'attribute' && |
|
!empty((string) $variables['element']['#title']) |
|
) { |
|
$variables['attributes']['title'] = (string) $variables['element']['#title']; |
|
} |
|
|
|
$type_api = $variables['element']['#type']; |
|
$type_html = $variables['attributes']['type']; |
|
$text_types_html = [ |
|
'text', |
|
'email', |
|
'tel', |
|
'number', |
|
'search', |
|
'password', |
|
'date', |
|
'time', |
|
'file', |
|
'color', |
|
'datetime-local', |
|
'url', |
|
'month', |
|
'week', |
|
]; |
|
|
|
if (in_array($type_html, $text_types_html, TRUE)) { |
|
$variables['attributes']['class'][] = 'form-element'; |
|
$variables['attributes']['class'][] = Html::getClass('form-element--type-' . $type_html); |
|
$variables['attributes']['class'][] = Html::getClass('form-element--api-' . $type_api); |
|
|
|
// This logic is functioning as expected, but there is nothing in the theme that renders the result. |
|
// As a result it can't currently be covered by a functional test. |
|
if (!empty($variables['element']['#autocomplete_route_name'])) { |
|
$variables['autocomplete_message'] = t('Loading…'); |
|
} |
|
} |
|
|
|
if (in_array($type_html, ['checkbox', 'radio'], TRUE)) { |
|
$variables['attributes']['class'][] = 'form-boolean'; |
|
$variables['attributes']['class'][] = Html::getClass('form-boolean--type-' . $type_html); |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK(). |
|
*/ |
|
function olivesdocs_preprocess_textarea(&$variables) { |
|
$variables['attributes']['class'][] = 'form-element'; |
|
$variables['attributes']['class'][] = 'form-element--type-textarea'; |
|
$variables['attributes']['class'][] = 'form-element--api-textarea'; |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK(). |
|
*/ |
|
function olivesdocs_preprocess_select(&$variables) { |
|
$variables['attributes']['class'][] = 'form-element'; |
|
$variables['attributes']['class'][] = $variables['element']['#multiple'] ? |
|
'form-element--type-select-multiple' : |
|
'form-element--type-select'; |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK(). |
|
*/ |
|
function olivesdocs_preprocess_checkboxes(&$variables) { |
|
$variables['attributes']['class'][] = 'form-boolean-group'; |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK(). |
|
*/ |
|
function olivesdocs_preprocess_radios(&$variables) { |
|
$variables['attributes']['class'][] = 'form-boolean-group'; |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK(). |
|
*/ |
|
function olivesdocs_preprocess_field(&$variables) { |
|
$rich_field_types = ['text_with_summary', 'text', 'text_long']; |
|
|
|
if (in_array($variables['field_type'], $rich_field_types, TRUE)) { |
|
$variables['attributes']['class'][] = 'text-content'; |
|
} |
|
|
|
if ($variables['field_type'] == 'image' && $variables['element']['#view_mode'] == 'full' && !$variables["element"]["#is_multiple"] && $variables['field_name'] !== 'user_picture') { |
|
$variables['attributes']['class'][] = 'wide-image'; |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK(). |
|
*/ |
|
function olivesdocs_preprocess_field_multiple_value_form(&$variables) { |
|
// Make disabled available for the template. |
|
$variables['disabled'] = !empty($variables['element']['#disabled']); |
|
|
|
if (!empty($variables['multiple'])) { |
|
// Add an additional CSS class for the field label table cell. |
|
// This repeats the logic of template_preprocess_field_multiple_value_form() |
|
// without using '#prefix' and '#suffix' for the wrapper element. |
|
// |
|
// If the field is multiple, we don't have to check the existence of the |
|
// table header cell. |
|
// |
|
// @see template_preprocess_field_multiple_value_form(). |
|
$header_attributes = ['class' => ['form-item__label', 'form-item__label--multiple-value-form']]; |
|
if (!empty($variables['element']['#required'])) { |
|
$header_attributes['class'][] = 'js-form-required'; |
|
$header_attributes['class'][] = 'form-required'; |
|
} |
|
// Using array_key_first() for addressing the first header cell would be |
|
// more elegant here, but we can rely on the related theme.inc preprocess. |
|
// @todo change this after https://www.drupal.org/node/3099026 has landed. |
|
$variables['table']['#header'][0]['data'] = [ |
|
'#type' => 'html_tag', |
|
'#tag' => 'h4', |
|
'#value' => $variables['element']['#title'], |
|
'#attributes' => $header_attributes, |
|
]; |
|
|
|
if ($variables['disabled']) { |
|
$variables['table']['#attributes']['class'][] = 'tabledrag-disabled'; |
|
$variables['table']['#attributes']['class'][] = 'js-tabledrag-disabled'; |
|
|
|
// We will add the 'is-disabled' CSS class to the disabled table header |
|
// cells. |
|
$header_attributes['class'][] = 'is-disabled'; |
|
foreach ($variables['table']['#header'] as &$cell) { |
|
if (is_array($cell) && isset($cell['data'])) { |
|
$cell = $cell + ['class' => []]; |
|
$cell['class'][] = 'is-disabled'; |
|
} |
|
else { |
|
// We have to modify the structure of this header cell. |
|
$cell = [ |
|
'data' => $cell, |
|
'class' => ['is-disabled'], |
|
]; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK() for menu-local-task templates. |
|
*/ |
|
function olivesdocs_preprocess_menu_local_task(&$variables) { |
|
$variables['link']['#options']['attributes']['class'][] = 'tabs__link'; |
|
$variables['link']['#options']['attributes']['class'][] = 'js-tabs-link'; |
|
|
|
// Ensure is-active class is set when the tab is active. The generic active |
|
// link handler applies stricter comparison rules than what is necessary for |
|
// tabs. |
|
if (isset($variables['is_active']) && $variables['is_active'] === TRUE) { |
|
$variables['link']['#options']['attributes']['class'][] = 'is-active'; |
|
} |
|
|
|
if (isset($variables['element']['#level'])) { |
|
$variables['level'] = $variables['element']['#level']; |
|
} |
|
} |
|
|
|
/** |
|
* Implements template_preprocess_HOOK() for fieldset. |
|
*/ |
|
function olivesdocs_preprocess_fieldset(&$variables) { |
|
$element = $variables['element']; |
|
$composite_types = ['checkboxes', 'radios']; |
|
|
|
if (!empty($element['#type']) && in_array($element['#type'], $composite_types) && !empty($variables['element']['#children_errors'])) { |
|
$variables['legend_span']['attributes']->addClass('has-error'); |
|
} |
|
|
|
if (!empty($element['#disabled'])) { |
|
$variables['legend_span']['attributes']->addClass('is-disabled'); |
|
|
|
if (!empty($variables['description']) && !empty($variables['description']['attributes'])) { |
|
$variables['description']['attributes']->addClass('is-disabled'); |
|
} |
|
} |
|
|
|
// Remove 'container-inline' class from the main attributes and add a flag |
|
// instead. |
|
// @todo remove this after https://www.drupal.org/node/3059593 has been |
|
// resolved. |
|
if (!empty($variables['attributes']['class'])) { |
|
$container_inline_key = array_search('container-inline', $variables['attributes']['class']); |
|
|
|
if ($container_inline_key !== FALSE) { |
|
unset($variables['attributes']['class'][$container_inline_key]); |
|
$variables['inline_items'] = TRUE; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_theme_suggestions_HOOK_alter(). |
|
*/ |
|
function olivesdocs_theme_suggestions_user_alter(&$suggestions, $variables) { |
|
$suggestions[] = 'user__' . $variables['elements']['#view_mode']; |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK(). |
|
*/ |
|
function olivesdocs_preprocess_field__node__created(&$variables) { |
|
foreach (Element::children($variables['items']) as $item) { |
|
unset($variables['items'][$item]['content']['#prefix']); |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK() for setting classes. |
|
*/ |
|
function olivesdocs_preprocess_filter_caption(&$variables) { |
|
$variables['classes'] = isset($variables['classes']) && !empty($variables['classes']) ? $variables['classes'] . ' caption' : 'caption'; |
|
} |
|
|
|
/** |
|
* Implements hook_form_FORM_ID_alter(). |
|
*/ |
|
function olivesdocs_form_node_preview_form_select_alter(&$form, FormStateInterface $form_state, $form_id) { |
|
$form['backlink']['#options']['attributes']['class'][] = 'button'; |
|
$form['backlink']['#options']['attributes']['class'][] = 'button--small'; |
|
$form['backlink']['#options']['attributes']['class'][] = 'button--icon-back'; |
|
$form['backlink']['#options']['attributes']['class'][] = 'button--primary'; |
|
$form['view_mode']['#attributes']['class'][] = 'form-element--small'; |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK() for comment.html.twig. |
|
*/ |
|
function olivesdocs_preprocess_comment(&$variables) { |
|
// Getting the node creation time stamp from the comment object. |
|
$date = $variables['comment']->getCreatedTime(); |
|
// Formatting "created" as "X days ago". |
|
$variables['created'] = t('@time ago', ['@time' => \Drupal::service('date.formatter')->formatInterval(\Drupal::time()->getRequestTime() - $date)]); |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_HOOK() for field--comment.html.twig. |
|
*/ |
|
function olivesdocs_preprocess_field__comment(&$variables) { |
|
// Add a comment_count. |
|
$variables['comment_count'] = count(array_filter($variables['comments'], 'is_numeric', ARRAY_FILTER_USE_KEY)); |
|
|
|
// Add user.compact to field-comment if profile's avatar of current user |
|
// exist. |
|
$user = \Drupal::currentUser(); |
|
if ($user->isAuthenticated() && $user instanceof UserInterface) { |
|
if ($user->hasField('user_picture') && !$user->get('user_picture')->isEmpty()) { |
|
$variables['user_picture'] = \Drupal::entityTypeManager() |
|
->getViewBuilder('user') |
|
->view($user, 'compact'); |
|
} |
|
|
|
$variables['#cache']['contexts'][] = 'user'; |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_element_info_alter(). |
|
*/ |
|
function olivesdocs_element_info_alter(&$info) { |
|
if (array_key_exists('text_format', $info)) { |
|
$info['text_format']['#pre_render'][] = [OlivesdocsPreRender::class, 'textFormat']; |
|
} |
|
|
|
if (isset($info['status_messages'])) { |
|
$info['status_messages']['#pre_render'][] = [OlivesdocsPreRender::class, 'messagePlaceholder']; |
|
} |
|
} |
|
|
|
/** |
|
* Implements template_preprocess_text_format_wrapper(). |
|
* |
|
* @todo Remove when https://www.drupal.org/node/3016343 is fixed. |
|
*/ |
|
function olivesdocs_preprocess_text_format_wrapper(&$variables) { |
|
$description_attributes = []; |
|
if (!empty($variables['attributes']['id'])) { |
|
$description_attributes['id'] = $variables['attributes']['aria-describedby'] = $variables['attributes']['id']; |
|
unset($variables['attributes']['id']); |
|
} |
|
$variables['description_attributes'] = new Attribute($description_attributes); |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_search_result(). |
|
*/ |
|
function olivesdocs_preprocess_search_result(&$variables) { |
|
// Apply custom date formatter to "date" field. |
|
if (!empty($variables['result']['date'])) { |
|
$variables['info_date'] = \Drupal::service('date.formatter')->format($variables['result']['node']->getCreatedTime(), 'olivesdocs_medium'); |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_links__comment(). |
|
*/ |
|
function olivesdocs_preprocess_links__comment(&$variables) { |
|
foreach ($variables['links'] as &$link) { |
|
$link['link']['#options']['attributes']['class'][] = 'comment__links-link'; |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_preprocess_table(). |
|
*/ |
|
function olivesdocs_preprocess_table(&$variables) { |
|
// Mark the whole table and the first cells if rows are draggable. |
|
if (!empty($variables['rows'])) { |
|
$draggable_row_found = FALSE; |
|
foreach ($variables['rows'] as &$row) { |
|
/** @var \Drupal\Core\Template\Attribute $row['attributes'] */ |
|
if (!empty($row['attributes']) && $row['attributes']->hasClass('draggable')) { |
|
if (!$draggable_row_found) { |
|
$variables['attributes']['class'][] = 'draggable-table'; |
|
$draggable_row_found = TRUE; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Implements hook_form_views_exposed_form_alter(). |
|
*/ |
|
function olivesdocs_form_views_exposed_form_alter(&$form) { |
|
$form['#attributes']['class'][] = 'form--inline'; |
|
} |
|
|
|
/** |
|
* Converts hex color strings to array of HSL values. |
|
* |
|
* @param string $hex_string |
|
* The 6-character hexadecimal color code, optionally with a leading hash |
|
* |
|
* @return array |
|
* Array containing hue, saturation, and lightness values. |
|
* $hue: integer of value 0-360 indicating the hue on a color wheel. |
|
* $saturation: string of saturation as a percentage (0% all gray, 100% full color). |
|
* $lightness: string of lightness as a percentage (0% darkened to black, 50% full color, 100% lightened to white). |
|
* |
|
* @see https://css-tricks.com/converting-color-spaces-in-javascript |
|
* Code based on JS version. |
|
* @see https://www.rapidtables.com/convert/color/rgb-to-hsl.html |
|
* Mathematical formula for rgb-to-hsl conversion. |
|
* |
|
* @internal |
|
*/ |
|
function _olivesdocs_hex_to_hsl(string $hex_string) { |
|
// Convert hexcode pairs to rgb values (0-255). |
|
$hex_val = trim($hex_string, '#'); |
|
$r0 = hexdec($hex_val[0] . $hex_val[1]); |
|
$g0 = hexdec($hex_val[2] . $hex_val[3]); |
|
$b0 = hexdec($hex_val[4] . $hex_val[5]); |
|
|
|
// Convert rgb's 0-255 to decimal values. |
|
$r = fdiv($r0, 255); |
|
$g = fdiv($g0, 255); |
|
$b = fdiv($b0, 255); |
|
|
|
// Calculate Hue. |
|
$c_min = min($r, $g, $b); |
|
$c_max = max($r, $g, $b); |
|
$delta = $c_max - $c_min; |
|
|
|
if ($delta == 0) { |
|
$h = 0; |
|
} |
|
else { |
|
switch ($c_max) { |
|
case $r: |
|
$h = fmod((($g - $b) / $delta), 6); |
|
break; |
|
|
|
case $g: |
|
$h = (($b - $r) / $delta) + 2; |
|
break; |
|
|
|
case $b: |
|
$h = (($r - $g) / $delta) + 4; |
|
break; |
|
|
|
default: |
|
$h = 0; |
|
break; |
|
} |
|
} |
|
|
|
$h = round($h * 60); |
|
|
|
// Shift hue range from [-60 - 300] to [0 - 360]. |
|
if ($h < 0) { |
|
$h += 360; |
|
} |
|
|
|
// Calculate Lightness. |
|
$l = ($c_max + $c_min) / 2; |
|
|
|
// Calculate Saturation. |
|
$s = $delta == 0 ? 0 : $delta / (1 - abs((2 * $l) - 1)); |
|
|
|
// Convert Saturation and Lightness to percentages. |
|
$s = round($s * 100); |
|
$l = round($l * 100); |
|
|
|
return [$h, $s, $l]; |
|
} |
|
|
|
|
|
function mytheme_preprocess_field(&$variables, $hook) { |
|
// Check if this is the title field for the landing_page content type. |
|
if ($variables['element']['#field_name'] == 'title' && $variables['element']['#bundle'] == 'landing_page') { |
|
// Define the SVG code. |
|
$svg_code = '<svg viewBox="0 0 1280 1213" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M637 30.4c0 .3-6.5 20.7-14.5 45.3-8 24.6-14.5 45.8-14.5 47.1 0 3 9.7 41.5 11.6 46.1 1.7 4.1 1.9 21.9.3 25.5-1.3 2.7-3.5 3.6-9.4 3.6-6.1 0-11.1-2.9-20.8-11.8-12.9-11.8-29.1-19.1-49.7-22.6-20.6-3.4-53.6-4.6-71.5-2.6-26.2 3-40.4 7.5-121 38.8-56.8 22-70.5 25.5-100 25.6-16.3.1-17.2 0-23.3-2.6-3.5-1.5-9-3.2-12.2-3.9-5-1-6.1-.9-8.5.7-3.7 2.4-4.9 5.8-3.1 9.3 1.5 2.9 6.9 5.8 22.4 12.2 9.3 3.8 12.8 6.4 13.8 10.4.5 2.1-19.8 59.2-89.6 252.3C97.3 641.1 53.5 762.3 49.7 773c-3.9 10.7-7.9 20.7-8.9 22.2s-3.6 3.2-6.1 4c-6.6 2.1-5.9 4.6 4.6 16.6 9.7 11.1 29.6 30.6 41.5 40.8 32.3 27.6 73.1 43.4 133.2 51.6 5.9.8 19.7 1.3 36.5 1.2 22.4 0 29.3-.4 40.5-2.1 52.7-8.2 101.9-28.3 134.5-54.7 15.6-12.7 29-26.6 39.7-41.3 6.3-8.7 6.2-9.7-.9-11.3-7.5-1.6-9-2.4-10.9-6.1-1.3-2.7-37.5-101.5-166.3-454.1-18.6-50.8-29.1-81-29.1-83.4v-3.7l12.3.6c36.6 2 66.5 2.8 76.2 2.3 6.1-.3 21.1-2.2 33.5-4.1 12.4-2 29.7-4.7 38.5-6.1 19.6-3.1 42.3-4 61.1-2.5 24.5 1.9 36.9 6.4 46.6 16.9 6.3 6.9 13.1 19.5 17.8 32.9l3.3 9.3H620v6.2c0 22.2-5 52.6-16.4 99.8-10.7 44.7-13.7 66.1-13.9 100.5-.1 20.7.2 25.9 2.1 38 3.2 19.6 8.5 40.3 14.4 56.9 10.7 30.2 12.2 37.6 12.1 61.1-.1 28.4-3.5 47.1-14.8 81.7-10.6 32.4-13.6 50.7-13.5 83.2 0 31.6 1.7 43.5 14.2 97.6l7 30.5-2.4 1.4c-1.2.8-5.5 4.6-9.4 8.5C587.3 979.6 582 994 582 1015c0 13.4 1.1 17.9 7.5 31 5.1 10.5 6.1 15.2 4.5 21.1-3.7 13.8-30.7 25.5-68 29.4-23.5 2.5-48.9 1.7-78-2.6-26.7-3.9-35.8-4.9-52.8-5.8-21.3-1-39.9.1-52.5 3.3-28.6 7.3-36.6 19.6-36.7 55.9 0 18.9.5 20.6 9.3 29.4l6.1 6.3h639.2l2.6-2.7c6.2-6.7 9.7-17.9 10.5-33.5 1.3-26.2-6.1-41.4-24.2-49.9-16.5-7.7-34.9-10.3-63.7-8.8-19.1.9-26.9 1.8-50.9 5.9-27.2 4.5-43.4 5.5-70.9 4.4l-23.5-1-12.5-4.2c-17.5-5.9-33.9-14.1-40-20-4.8-4.7-5-5-5-10.4 0-7.5 1.9-13.3 7.3-22 2.5-4 5.2-9.7 6.1-12.7 2-6.9 2.1-22.5.1-30.9-2.9-12.1-11.4-25.6-22-34.9-3-2.6-5.5-5.6-5.5-6.6s1.8-9 4-17.7c15.6-62 18.5-103.6 10.4-148-1.4-7.4-5.1-24.5-8.4-38-12.1-50.4-15.1-73.8-13.1-100.7 1.3-17.1 3.6-28.1 13.1-64.3 14.1-53.3 16.4-68.9 14.8-100.7-1.1-22.9-4.9-41.7-14.3-69.6-13.1-39.1-17.8-68.7-16-101l.7-13.7H695c26.6 0 35-.3 35.8-1.3.6-.6 3.7-7.1 7-14.4 12.9-28.4 22.9-38.3 43-41.9 11.6-2 46.6-2.9 59.2-1.5 5.8.7 24.8 3.4 42.3 6.1 46.4 7.2 51.2 7.5 84.8 6.1 15.6-.6 33.7-1.4 40.2-1.8l11.7-.6v2.8c0 1.6-12.6 37.8-27.9 80.4-15.4 42.7-58.6 162.9-96.1 267.1-37.5 104.2-68.8 191-69.5 192.7-1 2.2-2.1 3.3-3.5 3.3-1.1 0-5 .6-8.5 1.2-4.6.9-6.5 1.7-6.5 2.8 0 2.1 34.5 35.9 46.5 45.6 46.5 37.2 91.6 55.4 150 60.4 47.6 4 93.8-3.5 141.7-23.1 43-17.6 80.3-45.7 100.8-75.9 5.2-7.6 5.2-9 0-9-5.1 0-8.8-1.8-10.5-5.1-.8-1.4-24.4-66-52.5-143.5-28.2-77.5-64-176.2-79.7-219.4-56.4-155.4-65.3-180.1-65.3-181.4 0-2.5 3.8-4.6 17.8-9.9 7.8-3 15.3-6.2 16.8-7.2 5.3-3.5 6.8-13.2 2.3-15.6-2.6-1.3-9.9-.3-17.4 2.6-3.3 1.3-7.8 2.8-10 3.4-9.6 2.6-36.2.5-56.2-4.4-12.4-3-38.7-12.3-79.8-28.3-74.7-29-85.2-31.7-124.5-31.6-33.8 0-53.3 3.1-76 11.8-10.8 4.2-14.5 6.5-23.8 14.9-16.3 14.6-31.2 12.5-31.2-4.4 0-2.3 3.6-17.1 8-32.8l7.9-28.6L656.1 76c-11.3-32.4-16.3-45.6-17.5-45.8-.9-.2-1.6-.1-1.6.2zM289.9 425.6c78.7 216.9 121.9 336 127 349.9 3.5 9.5 5.1 15.5 5.1 18.7v4.8H71.8l.4-2.3c.4-1.7 171-476.5 174.4-485.1.6-1.5.8-1.6 1.5-.4.4.8 19.2 52.3 41.8 114.4zm756.4-70.6c8.5 23.4 48.3 131.8 88.3 241 40 109.2 72.9 199.5 73.2 200.7l.4 2.3H1031c-168.3 0-177.2-.1-176.8-1.8.3-.9 33.2-92.4 73.2-203.2 40-110.8 79.4-219.8 87.4-242.2 8.1-22.4 15-40.4 15.3-40 .4.4 7.7 19.8 16.2 43.2z" fill="#786554" fill-rule="nonzero"></path></svg>'; |
|
|
|
// Add the SVG code as a Twig variable. |
|
$variables['svg_image'] = [ |
|
'#markup' => $svg_code, |
|
'#allowed_tags' => ['svg', 'path'], |
|
]; |
|
} |
|
}
|
|
|