You are here

d8_google_optimize_hide_page.module in Drupal 8 Google Optimize Hide Page 8

File

d8_google_optimize_hide_page.module
View source
<?php

/**
 * @file
 * d8_google_optimize_hide_page.module
 */
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\d8_google_optimize_hide_page\Util\SnippetGenerator;

/**
 * Implements hook_help().
 */
function d8_google_optimize_hide_page_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'admin.config.system.d8_google_optimize_hide_page':
      return t('The <a href="@opt_url">Optimize page-hiding snippet</a> supports loading
 your Optimize container asynchronously while hiding the page until the container is ready,
 ensuring that users don\'t see the initial page content prior to it being modified by an experiment.', [
        '@opt_url' => 'https://developers.google.com/optimize/#the_page-hiding_snippet_code',
      ]);
  }
}

/**
 * Whether to use the Google Optimize page-hiding snippet.
 *
 * @return bool
 *   google_optimize_hide_page_enable
 */
function d8_google_optimize_hide_page_enabled() {
  $config = \Drupal::config('d8_google_optimize_hide_page.settings');
  return (bool) $config
    ->get('google_optimize_hide_page_enable') ?: FALSE;
}

/**
 * The Optimize container ids.
 *
 * @see https://developers.google.com/optimize/#loading_multiple_containers
 *
 * @return array
 *   d8_google_optimize_hide_page_container_ids
 */
function d8_google_optimize_hide_page_container_ids() {
  static $ids;
  if (!is_null($ids)) {
    return $ids;
  }
  $config = \Drupal::config('d8_google_optimize_hide_page.settings');
  $csv = $config
    ->get('google_optimize_hide_page_container_ids') ?: '';
  if (empty($csv)) {
    $ids = [];
  }
  else {
    $ids = str_getcsv($csv);
  }
  return $ids;
}

/**
 * The default amount of time Optimize will wait before removing.
 *
 * The .async-hide class from the <html> element.
 *
 * @see https://developers.google.com/optimize/#changing_the_timeout
 *
 * @return int
 *   d8_google_optimize_hide_page_timeout
 */
function d8_google_optimize_hide_page_timeout() {
  $config = \Drupal::config('d8_google_optimize_hide_page.settings');
  return (int) $config
    ->get('google_optimize_hide_page_timeout') ?: 4000;
}

/**
 * If the async-hide class name is already defined in your CSS.
 *
 * You can choose a different name.
 *
 * @see https://developers.google.com/optimize/#changing_the_async-hide_class_name
 *
 * @return string
 *   d8_google_optimize_hide_page_class_name
 */
function d8_google_optimize_hide_page_class_name() {
  $config = \Drupal::config('d8_google_optimize_hide_page.settings');
  return $config
    ->get('google_optimize_hide_page_class_name') ?: 'async-hide';
}

/**
 * Whether to put the snippet on the page.
 *
 * @return bool
 *   d8_google_optimize_hide_page_active
 */
function d8_google_optimize_hide_page_active() {
  if (!d8_google_optimize_hide_page_enabled()) {

    // Not enabled so do nothing.
    return FALSE;
  }
  $admin_context = \Drupal::service('router.admin_context');
  if ($admin_context
    ->isAdminRoute()) {

    // This is an admin page.
    return FALSE;
  }
  $container_ids = d8_google_optimize_hide_page_container_ids();
  if (empty($container_ids)) {

    // No container configured, so do nothing.
    return FALSE;
  }

  // See if restricted to certain pages.
  if ($pages = d8_google_optimize_hide_page_pages()) {
    $current_path = \Drupal::service('path.current')
      ->getPath();
    if (strpos($current_path, '/node/') !== FALSE) {
      $current_path = \Drupal::service('path_alias.manager')
        ->getAliasByPath($current_path);
    }
    if (!($match = \Drupal::service('path.matcher')
      ->matchPath($current_path, $pages))) {

      // Not for this page.
      return FALSE;
    }
  }

  // See if restricted to certain role(s)
  if ($roles = d8_google_optimize_hide_page_roles()) {
    $current_user = \Drupal::currentUser();
    $user_roles = $current_user
      ->getRoles();
    foreach ($user_roles as $role) {
      if (in_array($role, $roles, TRUE)) {

        // Add for this user.
        return TRUE;
      }
    }

    // Not in the list of allowed roles
    return FALSE;
  }
  return TRUE;
}

/**
 * The list of pages to add the snippet.
 *
 * @return bool
 *   google_optimize_hide_page_pages
 */
function d8_google_optimize_hide_page_pages() {
  $config = \Drupal::config('d8_google_optimize_hide_page.settings');
  return $config
    ->get('google_optimize_hide_page_pages') ?: '';
}

/**
 * The list of roles to add the snippet.
 *
 * @return array
 *   google_optimize_hide_page_roles
 */
function d8_google_optimize_hide_page_roles() {
  $config = \Drupal::config('d8_google_optimize_hide_page.settings');
  $roles = $config
    ->get('google_optimize_hide_page_roles') ?: [];
  foreach ($roles as $key => $value) {
    if (!$value) {
      unset($roles[$key]);
    }
  }
  return $roles;
}

/**
 * Whether to load the snippet as an external file.
 *
 * @return bool
 *   d8_google_optimize_hide_page_external_file
 */
function d8_google_optimize_hide_page_external_file() {
  $config = \Drupal::config('d8_google_optimize_hide_page.settings');
  return (bool) $config
    ->get('google_optimize_hide_page_external_file') ?: FALSE;
}

/**
 * Implements hook_page_attachments().
 *
 * Attach JavaScript to the appropriate scope/region of the page.
 */
function d8_google_optimize_hide_page_page_attachments(array &$attachments) {
  if (!d8_google_optimize_hide_page_active()) {
    return;
  }
  $class_name = d8_google_optimize_hide_page_class_name();
  $isExternalFile = d8_google_optimize_hide_page_external_file();
  if ($isExternalFile) {

    /** @var \Drupal\Core\Routing\UrlGeneratorInterface $urlGenerator */
    $urlGenerator = \Drupal::service('url_generator');
    $cssPath = drupal_get_path('module', 'd8_google_optimize_hide_page') . '/d8_google_optimize_hide_page.css';
    $attachments['#attached']['html_head'][] = [
      [
        '#type' => 'html_tag',
        '#tag' => 'link',
        '#attributes' => [
          'rel' => 'stylesheet',
          'href' => $cssPath,
        ],
        '#weight' => -16,
      ],
      'd8-google-optimize-hide-page-css',
    ];
    $attachments['#attached']['html_head'][] = [
      [
        '#type' => 'html_tag',
        '#tag' => 'script',
        '#attributes' => [
          'src' => $urlGenerator
            ->generateFromRoute('d8_google_optimize_hide_page.snippet'),
        ],
        '#weight' => -15,
      ],
      "d8-google-optimize-hide-page-js",
    ];
  }
  else {
    $snippet = new SnippetGenerator();
    $attachments['#attached']['html_head'][] = [
      [
        '#type' => 'html_tag',
        '#tag' => 'script',
        '#value' => $snippet
          ->getSnippet(),
        '#attributes' => [],
      ],
      'd8-google-optimize-hide-page-js',
    ];
    $css = '.' . $class_name . ' { opacity: 0 !important} ';
    $attachments['#attached']['html_head'][] = [
      [
        '#type' => 'html_tag',
        '#tag' => 'style',
        '#value' => $css,
      ],
      'd8-google-optimize-hide-page-css',
    ];
  }
}

/**
 * Implements hook_page_attachments_alter().
 *
 * Change datalayer and google_tag JS scripts weight.
 */
function d8_google_optimize_hide_page_page_attachments_alter(array &$attachments) {
  foreach ($attachments['#attached']['html_head'] as $key => $attachment) {
    if ($attachment[1] === 'datalayers-js') {
      $attachments['#attached']['html_head'][$key][0]['#weight'] = -17;
    }
    if (strpos($attachment[1], 'google_tag_script_tag') === 0) {
      $attachments['#attached']['html_head'][$key][0]['#weight'] = -14;
    }
  }
}

Functions

Namesort descending Description
d8_google_optimize_hide_page_active Whether to put the snippet on the page.
d8_google_optimize_hide_page_class_name If the async-hide class name is already defined in your CSS.
d8_google_optimize_hide_page_container_ids The Optimize container ids.
d8_google_optimize_hide_page_enabled Whether to use the Google Optimize page-hiding snippet.
d8_google_optimize_hide_page_external_file Whether to load the snippet as an external file.
d8_google_optimize_hide_page_help Implements hook_help().
d8_google_optimize_hide_page_pages The list of pages to add the snippet.
d8_google_optimize_hide_page_page_attachments Implements hook_page_attachments().
d8_google_optimize_hide_page_page_attachments_alter Implements hook_page_attachments_alter().
d8_google_optimize_hide_page_roles The list of roles to add the snippet.
d8_google_optimize_hide_page_timeout The default amount of time Optimize will wait before removing.