Skip to content
Snippets Groups Projects
uw_fdsu_theme_resp.theme 25.61 KiB
<?php

/**
 * @file
 * Theme file for uw_fdsu_theme_resp.
 */

use Drupal\Core\Url;
use Drupal\file\Plugin\Field\FieldType\FileFieldItemList;
use Drupal\image\Plugin\Field\FieldType\ImageItem;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\Entity\Node;

/**
 * @file
 * Functions to support theming.
 */

require_once dirname(__FILE__) . '/includes/views.inc';

/**
 * Implements hook_preprocess_HOOK().
 *
 * Setting the faculty class colour and favicon information.
 */
function uw_fdsu_theme_resp_preprocess_html(&$variables) {

  // Adding the faculty colour class to the body.
  $variables['attributes']['class'][] = theme_get_setting('wcms_colour_scheme', 'uw_fdsu_theme_resp') ? theme_get_setting('wcms_colour_scheme', 'uw_fdsu_theme_resp') : 'org-default';
  $variables['uw_admin_page'] = \Drupal::service('uw_cfg_common.uw_analytics')->administrationPage();

  // Add the fav icons.
  _uw_fdsu_theme_resp_add_favicons($variables);

  // Get the route name.
  $route_name = \Drupal::routeMatch()->getRouteName();

  // Perform actions based on the route.
  switch ($route_name) {

    // Add Javascript only on the user login page.
    case 'user.login':
      $variables['#attached']['library'][] = 'uw_fdsu_theme_resp/user.login';
      break;

    // The header/page title on contributors listing page browser
    // tab shows "Reference author: " in front of the author's name.
    case 'entity.bibcite_contributor.canonical':
      $variables['head_title']['title'] = t('Reference author:') . ' ' . $variables['head_title']['title'];
      break;

    // The header/page title on keywords listing page browser
    // tab shows "Reference keyword: " in front of the keyword.
    case 'entity.bibcite_keyword.canonical':
      $variables['head_title']['title'] = t('Reference keyword:') . ' ' . $variables['head_title']['title'];
      break;

    // Adding the alternate link to listing pages.
    case 'view.uw_view_blogs.blog_page':
    case 'view.uw_view_events.event_page':
    case 'view.uw_view_news_items.news_page':

      // Get the alternate link based on the route.
      switch ($route_name) {

        case 'view.uw_view_blogs.blog_page':
          $link = _uw_fdsu_theme_resp_get_alternate_link(
            'uw_view_blogs',
            'uw_public_blog_feed',
            'Blogs feed'
          );
          break;

        case 'view.uw_view_events.event_page':
          $link = _uw_fdsu_theme_resp_get_alternate_link(
            'uw_view_events',
            'uw_public_event_feed',
            'Events feed'
          );
          break;

        case 'view.uw_view_news_items.news_page':
          $link = _uw_fdsu_theme_resp_get_alternate_link(
            'uw_view_news_items',
            'uw_public_news_feed',
            'News feed'
          );
          break;
      }

      // Add the alternate link to the page.
      $variables['#attached']['html_head_link'][] = $link;
      break;
  }

  // Get the current path.
  $parts = explode('/', \Drupal::service('path.current')->getPath());

  // If the last in the array parts is not layout,
  // add a class so that we traget anything but
  // the layout pages.
  if (end($parts) !== 'layout') {
    $variables['attributes']['class'][] = 'not-layout-page';
  }
  else {
    $variables['attributes']['class'][] = 'layout-page';
  }

  // Add UW to page title, if not already there.
  _uw_add_page_title($variables);
}

/**
 * Function to get the alternate link.
 *
 * @param string $view_machine_name
 *   The machine name of the view.
 * @param string $view_display_name
 *   The display name of the view.
 * @param string $title
 *   The title of the alternate link.
 */
function _uw_fdsu_theme_resp_get_alternate_link(
  string $view_machine_name,
  string $view_display_name,
  string $title
) {

  // Get the URL to RSS feed.
  $url = Url::fromRoute('view.' . $view_machine_name . '.' . $view_display_name);
  $url->setOptions(['query' => \Drupal::request()->query->all()]);

  // Return the link for the alternate.
  return [
    [
      'rel' => 'alternate',
      'href' => $url->toString(),
      'title' => $title,
      'type' => 'application/rss+xml',
    ],
  ];
}

/**
 * Implements hook_preprocess_responsive_image().
 */
function uw_fdsu_theme_resp_preprocess_responsive_image(&$variables) {

  // Step through each of the responsive image objects and get out source info.
  foreach ($variables['sources'] as $source) {

    // Set the a variable with the actual source info that we need.
    $new_sources[] = [
      'srcset' => $source['srcset']->value(),
      'media' => $source['media']->value(),
      'type' => $source['type']->value(),
    ];
  }

  // Set the sources variable to the new sources.
  $variables['sources'] = $new_sources;
}

/**
 * Implements hook_preprocess_region().
 */
function uw_fdsu_theme_resp_preprocess_region(&$variables) {

  // Get the region from variables.
  $region = $variables['elements']['#region'];
  // Set 'search_local' variable if not set.
  if (!isset($variables['search_local'])) {
    $variables['search_show_local'] = theme_get_setting('wcms_search_show_local', 'uw_fdsu_theme_resp');
  }
  // Variables that we want to have access to regardless of region.
  $variables['branding_level'] = theme_get_setting('wcms_branding_level', 'uw_fdsu_theme_resp') ? theme_get_setting('wcms_branding_level', 'uw_fdsu_theme_resp') : 'full';
  // The menu style is set based on selection if the level is 'full'.
  if ($variables['branding_level'] == 'full') {
    $variables['branding_menu_style'] = theme_get_setting('wcms_branding_menu_style', 'uw_fdsu_theme_resp') ? theme_get_setting('wcms_branding_menu_style', 'uw_fdsu_theme_resp') : 'compressed';
  }
  // The menu style is set to 'compressed' if the level is not 'full'.
  else {
    $variables['branding_menu_style'] = 'compressed';
  }

  // If we are on the header, add the correct header classes
  // TO DO: Store the colour scheme used for the theme
  // (i.e. faculty colour and get the correct class here).
  if ($region == "header") {

    // Get the home page link.
    $variables['home_link'] = Url::fromRoute('<front>')->setAbsolute()->toString();

    // Set the main menu variable.
    $variables['main_menu'] = \Drupal::service('uw_cfg_common.uw_menu_items')->getMenuTree('main', TRUE, TRUE);

    // Set the secondary menu variable.
    $variables['secondary_menu'] = \Drupal::service('uw_cfg_common.uw_menu_items')->getMenuTree('uw-menu-audience-menu', TRUE, TRUE);

    // The class that is used for the header.
    $variables['classes'][] = 'uw-header';

    // Get the site name for placing inside the menu.
    $config = \Drupal::config('system.site');
    $variables['site_name'] = $config->get('name');
    $variables['subtitle'] = $config->get('slogan');

    $variables['faculty'] = theme_get_setting('wcms_colour_scheme', 'uw_fdsu_theme_resp') ? theme_get_setting('wcms_colour_scheme', 'uw_fdsu_theme_resp') : 'org-default';

    // Create the stream context to use with file_get_contents
    // so it times out after a certain period instead of
    // waiting indefinitely. Timeout is in seconds.
    $context = stream_context_create([
      'http' => [
        'timeout' => 3,
      ],
    ]);

    // Global message content.
    $global_message = file_get_contents('https://uwaterloo.ca/global-message.html', 0, $context);

    // If there is something to display, make sure to include css file, and
    // pass message as render array, then use render twig filter to avoid using
    // raw twig filter. Trimming message before sending to template, this
    // will remove any empty lines/spaces that message may have.
    if (!empty($global_message)) {
      $variables['global_message'] = ['#markup' => trim($global_message)];
    }
  }

  // ISTWCMS-4847.
  // If we are on the main content section, the check if not a node and add
  // appropriate classes to display proper width.
  if ($region == 'content') {

    // Get the route name.
    $route_match = \Drupal::routeMatch();

    // If we are on not on a node, add appropriate classes to show
    // proper width.
    $route_name = $route_match->getRouteName();
    $exemptions = [
      'entity.node.canonical',
      'entity.node.latest_version',
      'layout_builder.overrides.node.view',
    ];
    if (!in_array($route_name, $exemptions)) {
      $variables['classes'][] = 'layout';
      $variables['classes'][] = 'uw-contained-width';
    }
  }

  if ($region == 'footer') {
    $variables['social_media'] = \Drupal::service('uw_cfg_common.uw_menu_items')
      ->getMenuTree(
        'uw-menu-global-social-media',
        FALSE
      );

    $variables['footer_menu'] = \Drupal::service('uw_cfg_common.uw_menu_items')
      ->getMenuTree(
        'uw-menu-global-footer',
        FALSE
      );
  }

  $variables['language'] = \Drupal::languageManager()->getCurrentLanguage();
}

/**
 * Implements hook_FORM_ID_alter().
 *
 * Add settings for colour scheme.
 */
function uw_fdsu_theme_resp_form_system_theme_settings_alter(&$form, FormStateInterface &$form_state, $form_id = NULL) {

  // Work-around for a core bug affecting admin themes. See issue #943212.
  if (isset($form_id)) {
    return;
  }

  // Fieldset for search options.
  $form['search_options'] = [
    '#type' => 'details',
    '#open' => TRUE,
    '#title' => t('Search options'),
  ];

  // Search options checkbox field.
  $form['search_options']['wcms_search_show_local'] = [
    '#type' => 'checkbox',
    '#title' => t("Show the 'on this site' search option"),
    '#default_value' => theme_get_setting('wcms_search_show_local', 'uw_fdsu_theme_resp') ?? TRUE,
  ];

  // Fieldset for colour scheme.
  $form['colour_scheme'] = [
    '#type' => 'details',
    '#open' => TRUE,
    '#title' => t('Colour scheme'),
  ];

  // Colour scheme select list.
  $form['colour_scheme']['wcms_colour_scheme'] = [
    '#type'          => 'select',
    '#default_value' => theme_get_setting('wcms_colour_scheme', 'uw_fdsu_theme_resp') ? theme_get_setting('wcms_colour_scheme', 'uw_fdsu_theme_resp') : 'default',
    '#description'   => t("Select a color scheme to use"),
    '#options' => _uw_cfg_common_get_faculty_color_options(),
  ];

  // Fieldset for branding options.
  $form['branding_options'] = [
    '#type' => 'details',
    '#open' => TRUE,
    '#title' => t('Branding options'),
  ];

  // Branding select option.
  $form['branding_options']['wcms_branding_level'] = [
    '#type' => 'select',
    '#options' => [
      'full' => t('Full University branding'),
      'generic' => t('Generic with University wordmark'),
      'generic_barebones' => t('Fully generic'),
    ],
    '#default_value' => theme_get_setting('wcms_branding_level', 'uw_fdsu_theme_resp') ?: 'full',
  ];

  $form['branding_options']['wcms_branding_menu_style'] = [
    '#type' => 'select',
    '#options' => [
      'compressed' => t('Compressed ("jump to") global menu'),
      'full' => t('Fully visible global menu'),
    ],
    "#states" => [
      'visible' => [
        'select[name="wcms_branding_level"]' => ['value' => 'full'],
      ],
    ],
    '#default_value' => theme_get_setting('wcms_branding_menu_style', 'uw_fdsu_theme_resp') ?: 'compressed',
  ];
}

/**
 * Add favicons to the page when called from hook_preprocess_html().
 *
 * @param array $variables
 *   The variables array.
 */
function _uw_fdsu_theme_resp_add_favicons(array &$variables) {
  // Remove Drupal's favicon.
  foreach ($variables['page']['#attached']['html_head_link'] as $id => $html_head_link) {
    if (isset($html_head_link[0]['rel']) && $html_head_link[0]['rel'] == 'shortcut icon') {
      unset($variables['page']['#attached']['html_head_link'][$id]);
      break;
    }
  }

  // Specify new favicon locations.
  // Based on https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs.
  $favicon_base_path = base_path() . \Drupal::service('extension.list.theme')->getPath('uw_fdsu_theme_resp');
  $favicon = [
    'rel' => 'icon',
    'href' => $favicon_base_path . '/favicon.ico',
  ];
  $variables['page']['#attached']['html_head_link'][] = [$favicon];
  $favicon_svg = [
    'rel' => 'icon',
    'href' => $favicon_base_path . '/icon.svg',
    'type' => 'image/svg+xml',
  ];
  $variables['page']['#attached']['html_head_link'][] = [$favicon_svg];
  $favicon_apple = [
    'rel' => 'apple-touch-icon',
    'href' => $favicon_base_path . '/apple-touch-icon.png',
  ];
  $variables['page']['#attached']['html_head_link'][] = [$favicon_apple];
  // Manifest needs a full URL.
  $favicon_base_path = \Drupal::request()->getSchemeAndHttpHost() . $favicon_base_path;
  $manifest = [
    'icons' => [
      [
        'src' => $favicon_base_path . '/icon-192.png',
        'type' => 'image/png',
        'sizes' => '192x192',
      ],
      [
        'src' => $favicon_base_path . '/icon-512.png',
        'type' => 'image/png',
        'sizes' => '512x512',
      ],
    ],
  ];
  $manifest = urlencode(json_encode($manifest));
  $favicon_manifest = [
    'rel' => 'manifest',
    'href' => 'data:application/manifest+json,' . $manifest,
  ];
  $variables['page']['#attached']['html_head_link'][] = [$favicon_manifest];
}

/**
 * Get the specified field value from a paragraph.
 *
 * @param object $paragraph
 *   The paragraph object.
 * @param string $field
 *   The name of the field.
 *
 * @return mixed
 *   The field value.
 */
function _uw_fdsu_theme_resp_get_field_value_from_paragraph($paragraph, $field) {

  // Get the field value.
  $field_value = $paragraph->get($field)->first();

  return $field_value->getValue()['value'];
}
/**
 * Set the variables required for a responsive image.
 *
 * @param array $variables
 *   The variables array.
 * @param \Drupal\image\Plugin\Field\FieldType\ImageItem $field
 *   The field object.
 * @param string $responsive_image_style
 *   The ID of the responsive image style.
 *
 * @return array|null
 *   An array with keys:
 *    - sources: An array of image sources.
 *    - alt: The alternative text.
 */
function _uw_fdsu_theme_resp_add_responsive_image_variables(array &$variables, ImageItem $field, string $responsive_image_style) : ?array {

  // If there is a file present, set responsive image variables.
  if ($file = $field->entity) {

    // Set uri and image style id.
    $variables['uri'] = $file->getFileUri();
    $variables['responsive_image_style_id'] = $responsive_image_style;

    // Call template function from responsive image core module.
    // It sets variables for srcset, media, type and img_element
    // for the responsive image style.
    template_preprocess_responsive_image($variables);

    // Step through each source and get string values.
    $sources = [];

    foreach ($variables['sources'] as $source) {

      $sources[] = [
        'srcset' => $source['srcset']->value(),
        'media' => $source['media']->value(),
        'type' => $source['type']->value(),
      ];
    }

    return [
      'sources' => $sources,
      'alt' => $field->get('alt')->getValue(),
    ];
  }
  return NULL;
}

/**
 * Get image properties from an image field.
 *
 * @param \Drupal\file\Plugin\Field\FieldType\FileFieldItemList $field
 *   The image field.
 *
 * @return array|null
 *   An array of image properties or NULL if $field does not contain the
 *   required information.
 */
function _uw_fdsu_theme_resp_get_image_info(FileFieldItemList $field) {

  // If there is an image, process it.
  if ($img_entity = $field->first()) {

    // If we can load a file, grab the info about the file.
    if ($file_entity = $img_entity->get('entity')->getTarget()) {

      return [
        'src' => \Drupal::service('file_url_generator')->generateAbsoluteString($file_entity->get('uri')->getString()),
        'alt' => $img_entity->get('alt')->getString(),
      ];
    }
  }
}

/**
 * Implements hook_preprocess_node().
 *
 * Set variables for node and teaser.
 */
function uw_fdsu_theme_resp_preprocess_node(&$variables) {

  // The UW service object.
  $uwService = \Drupal::service('uw_cfg_common.uw_service');

  $nodeContent = \Drupal::service('uw_cfg_common.uw_node_content');

  // The types of nodes the need preprocessing.
  $nodes_to_preprocess = $uwService->uwGetNodePreprocessing('full');

  // Teaser to be preprocessed.
  $teasers_to_preprocess = $uwService->uwGetNodePreprocessing('teaser');

  // If there is a node that needs preprocessing,
  // set the appropriate variables.
  if (in_array($variables['node']->getType(), $nodes_to_preprocess) ||
    in_array($variables['node']->getType(), $teasers_to_preprocess)) {

    // If on a teaser page get the variables for teaser.
    if ($variables['view_mode'] == 'teaser' &&
      in_array($variables['node']->getType(), $teasers_to_preprocess)) {
      $variables['teaser'] = $nodeContent->getNodeContent($variables['node'], 'teaser', 'all');
    }

    // If on a node page get the variables for now.
    if ($variables['view_mode'] == 'full' &&
      in_array($variables['node']->getType(), $nodes_to_preprocess
    )) {
      $variables['node_data'] = $nodeContent->getNodeContent($variables['node'], 'full', 'all');
      $variables['node_data']['content'] = $variables['content'];
    }

    // Unset the content variable, so that we do not get
    // a second print of all the content.
    unset($variables['content']);
  }
}

/**
 * Implements hook_preprocess_block().
 *
 * Add the admin_label and css classes if we are in layout builder.
 */
function uw_fdsu_theme_resp_preprocess_block(&$variables) {

  // Look at page title block to see if we have a featured image.
  // If we do then, set variable to not show page title.
  if ($variables['plugin_id'] == 'page_title_block') {

    // Set the media variable to no, we will only
    // change if there is a media.
    $variables['media'] = 'no';

    // Load the node.
    $node = \Drupal::routeMatch()->getParameter('node');

    // If this is a node, check for contact and set if we
    // have to hide the title.
    if ($node = \Drupal::routeMatch()->getParameter('node')) {
      // Get the media flags.
      $media_flags = \Drupal::service('uw_cfg_common.uw_service')->uwGetMediaFlags($node);

      // Set the show title flag.
      $variables['show_title'] = $media_flags['has_media'] || $media_flags['has_portrait'] ? FALSE : TRUE;
    }

    // ISTWCMS-4943: ensure that we get a node object.
    // If node is not object by this point, probably on
    // a revision page where node is an integer, so load
    // the node.
    if ($node && !is_object($node)) {
      $node = Node::load($node);
    }

    // If there is a node, check that it has a media.
    if ($node) {

      // The UW service object.
      $uwService = \Drupal::service('uw_cfg_common.uw_service');

      $variables['media'] = $uwService->uwCheckNodeForMedia($node);
    }
  }

  // If we are in layout builder (this is set much earlier in
  // the page load process), then continue to look if we need
  // to add the admin_label and css classes.
  if (isset($variables['in_layout_builder']) && $variables['in_layout_builder'] == TRUE) {

    // Get the block manager object.
    $blockManager = \Drupal::service('plugin.manager.block');

    // Get the plugin definitions for the block, using the
    // plugin_id of the block.
    $plugin_definitions = $blockManager->getDefinition($variables['plugin_id']);

    // The admin labels to exclude, these are ones that we do not
    // want the admin label to appear on the layout builder page.
    $admin_labels_to_exclude = [
      'Messages',
      'Tabs',
      'Page title',
      'Global header',
      'Main navigation',
      'Site Footer block',
    ];

    // Check if the admin_label is an object, we need to do this
    // because some admin labels are translatable and are therefore
    // translatable markup objects (usually through code way of
    // building blocks.  Others are not, if translations are not turned
    // on for this block (usually through the GUI way of creating a block,
    // where the translation option is not set).
    if (is_object($plugin_definitions['admin_label'])) {

      // The admin label is a translatable markup, so just render
      // the object to set the admin label variable..
      $admin_label = $plugin_definitions['admin_label']->render();
    }
    else {

      // The admin label is not an object so just set the
      // admin label variable.
      $admin_label = $plugin_definitions['admin_label'];
    }

    // If the admin label is not in the ones to exclude add it
    // to the template variables and set the class to be used
    // to display the admin label.
    if (!in_array($admin_label, $admin_labels_to_exclude)) {

      // ISTWCMS-6062, add publication to reference block admin
      // labels when in layout builder.
      if ($admin_label == 'Reference search') {
        $admin_label = 'Publication reference search';
      }

      if ($admin_label == 'Reference teaser') {
        $admin_label = 'Publication reference teaser';
      }

      $variables['admin_label'] = $admin_label;
      $variables['attributes']['class'][] = 'in-layout-builder';
    }
  }
}

/**
 * Implements template_preprocess_container().
 */
function uw_fdsu_theme_resp_preprocess_container(&$variables) {

  // Ensure that we are on a layout page.
  if (\Drupal::routeMatch()->getRouteName() == 'layout_builder.overrides.node.view') {

    // Ensure that we are on the first layout builder container.
    if (
      isset($variables['attributes']['class']) &&
      $variables['attributes']['class'][0] == 'layout-builder'
    ) {

      // The UW service object.
      $uwService = \Drupal::service('uw_cfg_common.uw_service');

      // The UW node content service.
      $uwNodeContent = \Drupal::service('uw_cfg_common.uw_node_content');

      // The list of content types that will have header
      // and footer in layout builder pages.
      $content_types = $uwService->uwGetNodePreprocessing('layout_container');

      // Get the node object.
      $node = \Drupal::routeMatch()->getParameter('node');

      // If there is a node object, and it is a content
      // type that has header and footer for layout pages,
      // get the header and footer.
      if ($node && in_array($node->getType(), $content_types)) {

        // Get the node object.
        $node = \Drupal::routeMatch()->getParameter('node');

        // Set variables for featured image.
        $variables['node_type'] = str_replace('_', '-', $node->getType());
        $variables['media'] = $uwService->uwCheckNodeForMedia($node);
        $variables['media_flags'] = $uwService->uwGetMediaFlags($node);

        // If there is a node object, get the header and footer data.
        if ($node) {
          $variables['header_data'] = $uwNodeContent->getNodeContent($node, 'full', 'header');
          $variables['footer_data'] = $uwNodeContent->getNodeContent($node, 'full', 'footer');

          // If this is an event, add the ical url so that it displays
          // inside of layout builder.
          if ($node->getType() == 'uw_ct_event') {
            $variables['header_data']['ical'] = _uw_ct_event_get_ical_link($node->id());
          }
        }
      }
    }
  }
}

/**
 * Implements template_preprocess_details().
 */
function uw_fdsu_theme_resp_preprocess_details(&$variables) {

  // ISTWCMS-6711: this comes from the label not having the
  // correct for in it.  So we are going to check if this is
  // a better exposed filter and if so then add the correct
  // based on the type of exposed filter it is.  The date
  // filter needs special treatment, since it is using the
  // wrapper as the data drupal selector, and we need it to
  // use the -value.  If it is not a bef, then check if there
  // is a data drupal selector and use it as the form field id.
  if (
    isset($variables['element'][0]['#context']['#plugin_type']) &&
    $variables['element'][0]['#context']['#plugin_type'] == 'bef'
  ) {

    // If this is a date picker, then change the form field id
    // to use -value instead of -wrapper.  If not then just use
    // the straight data drupal selector.
    if ($variables['element'][0]['#context']['#plugin_id'] == 'bef_datepicker') {
      $variables['form_field_id'] = str_replace(
        '-wrapper',
        '-value',
        $variables['element'][0]['#attributes']['data-drupal-selector']
      );
    }
    else {
      $variables['form_field_id'] = $variables['element'][0]['#attributes']['data-drupal-selector'];
    }
  }
  else {

    // Search input needs a special form id, so setting that, if not
    // We continue the old fix.
    if (isset($variables['element']['search'])) {
      $variables['form_field_id'] = $variables['element']['search']['#attributes']['id'];
    }
    else {

      // If there is an element, process it.
      if (isset($variables['element'])) {

        // Step through each of the indexes and ensure that we
        // have an actual element, which means it will be an array.
        foreach ($variables['element'] as $index => $value) {

          // If this is an array, then we have an element to look at.
          if (is_array($value)) {

            // One more check to ensure that we have an element.
            if (isset($variables['element'][$index]['#type'])) {

              // Get the id based on where the id is stored, either it
              // is by itself or within the attributes.
              if (isset($variables['element'][$index]['#id'])) {
                $variables['form_field_id'] = $variables['element'][$index]['#id'];
              }
              elseif (isset($variables['element'][$index]['#attributes']['id'])) {
                $variables['form_field_id'] = $variables['element'][$index]['#attributes']['id'];
              }

              // Break out of the loop to save computational time.
              break;
            }
          }
        }
      }
      // If there is a data drupal selector use it for form field id.
      elseif (isset($variables['element'][0]['#attributes']['data-drupal-selector'])) {
        $variables['form_field_id'] = $variables['element'][0]['#attributes']['data-drupal-selector'];
      }
    }
  }
}