Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Usagov 1789 wizard datalayer #2046

Merged
merged 9 commits into from
Nov 6, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@

use Drupal\Core\Breadcrumb\BreadcrumbManager;
use Drupal\Core\Entity\EntityMalformedException;
use Drupal\Core\Routing\CurrentRouteMatch;
use Drupal\node\Entity\Node;

/**
* Builds a datalayer array we can serialize to JSON in our twig template.
*/
class TaxonomyDatalayerBuilder {

private const HOME_TITLE_EN = "Home";
private const HOME_URL_EN = "/";
public const HOME_TITLE_EN = "Home";
public const HOME_URL_EN = "/";

private const HOME_TITLE_ES = "Página principal";
private const HOME_URL_ES = "/es/";
public const HOME_TITLE_ES = "Página principal";
public const HOME_URL_ES = "/es/";

private const ABOUT_GOVT_EN = "About the U.S. and its government";
private const ABOUT_URL_EN = "/about-the-us";
Expand Down Expand Up @@ -47,6 +48,7 @@ class TaxonomyDatalayerBuilder {
private string $isFront;

public function __construct(
private CurrentRouteMatch $routeMatch,
private BreadcrumbManager $breadcrumbManager,
public Node $node,
bool $isFront,
Expand Down Expand Up @@ -129,7 +131,7 @@ public function build(): array {
public function fromBreadcrumb(): array {
// For all other pages, we need the breadcrumb to pass as taxonomy.
// This mimics the system breadcrumb block plugin, without rendering it.
$crumbs = $this->breadcrumbManager->build(\Drupal::routeMatch());
$crumbs = $this->breadcrumbManager->build($this->routeMatch);
$taxonomy = [];

foreach ($crumbs->getLinks() as $index => $crumb) {
Expand Down
1 change: 1 addition & 0 deletions web/modules/custom/usa_twig_vars/usa_twig_vars.module
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ function usa_twig_vars_preprocess(&$variables, $hook) {

// Data to be sent to GTM.
$datalayer = new TaxonomyDatalayerBuilder(
routeMatch: \Drupal::routeMatch(),
breadcrumbManager: \Drupal::service('breadcrumb'),
node: $node,
isFront: $isFront,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php

namespace Drupal\usagov_wizard\EventSubscriber;

use Drupal\Core\Breadcrumb\BreadcrumbManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Routing\CurrentRouteMatch;
use Drupal\Core\Url;
use Drupal\taxonomy\Entity\Term;
use Drupal\usa_twig_vars\Event\DatalayerAlterEvent;
use Drupal\usagov_wizard\MenuChecker;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
* Add taxonomy scan wizard info to datalayer.
*/
class DatalayerAlterSubscriber implements EventSubscriberInterface {

public function __construct(
private MenuChecker $menuChecker,
private BreadcrumbManager $breadcrumbManager,
private CurrentRouteMatch $currentRouteMatch,
private EntityTypeManagerInterface $entityTypeManager,
) {}

/**
* {@inheritDoc}
*/
public static function getSubscribedEvents() {
return [
DatalayerAlterEvent::EVENT_NAME => 'onDatalayerAlter',
];
}

/**
* Adds wizard taxonomy information to the datalayer.
*/
public function onDatalayerAlter(DatalayerAlterEvent $event): void {
$term = $this->currentRouteMatch->getParameter('taxonomy_term');
if (!$term || $term->bundle() !== 'wizard') {
return;
}

$termStorage = $this->entityTypeManager->getStorage('taxonomy_term');

$isStartPage = FALSE;
$children = $termStorage->loadChildren($term->id());
$isResult = empty($children);

if ($term->hasField('parent')) {
$parentTID = $term->parent->getValue()[0]['target_id'];
if ($parentTID === '0') {
$isStartPage = TRUE;
}
}

if ($isStartPage) {
$page_type = 'wizard-start';
}
elseif ($isResult) {
$page_type = 'wizard-result';
}
else {
$page_type = 'wizard-question';
}

// keep the same order
unset($event->datalayer['hasBenefitCategory']);
// make any changes need to $event->datalayer array
$event->datalayer['taxonomyID'] = $term->id();
$event->datalayer['contentType'] = $term->bundle();
$event->datalayer['language'] = $term->language()->getId();
$event->datalayer['homepageTest'] = 'not_homepage';
$event->datalayer['basicPagesubType'] = NULL;
$event->datalayer['Page_Type'] = $page_type;
$event->datalayer['hasBenefitCategory'] = FALSE;

$rootTerm = NULL;
$parents = [];
if ($term->hasField('parent') && !$term->get('parent')->isEmpty()) {
$parents = $this->entityTypeManager
->getStorage('taxonomy_term')
->loadAllParents($term->id());
// Sort parents so "oldest ancestor" is first.
$parents = array_reverse($parents);
$rootTerm = $parents[array_key_first($parents)];
}

if ($rootTerm) {
$crumbs = usagov_wizard_get_term_breadcrumb($rootTerm);
// Here the first two items will give us the home page
// and the main scam page
$crumbs = array_slice($crumbs, 0, 2);
foreach ($crumbs as $crumb) {
$data[$crumb['url']] = $crumb['text'];
}
}

// the rest comes from the parents of this term
foreach ($parents as $parentTerm) {
$path = $parentTerm->get('path');
$termURL = $path->alias;
// pathalias field items don't prepend the language code for Spanish terms
if ($parentTerm->language()->getId() === 'es') {
$termURL = '/es' . $termURL;
}
$data[$termURL] = $parentTerm->getName();
}

$count = count($data);

$i = 0;
foreach ($data as $url => $text) {
$i++;
$urls['Taxonomy_Text_' . $i] = $text;
$urls['Taxonomy_URL_' . $i] = $url;

if ($i === 6) {
break;
}
}

if ($i < 6) {
$lastURL = array_key_last($data);
$lastText = $data[$lastURL];

for ($i = $count; $i < 6; $i++) {
$urls['Taxonomy_Text_' . ($i + 1)] = $lastText;
$urls['Taxonomy_URL_' . ($i + 1)] = $lastURL;
}
}

ksort($urls);
$event->datalayer = array_merge($event->datalayer, $urls);
}

}
55 changes: 32 additions & 23 deletions web/modules/custom/usagov_wizard/usagov_wizard.module
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use Drupal\Core\Url;
use Drupal\taxonomy\Entity\Term;
use Drupal\usa_twig_vars\TaxonomyDatalayerBuilder;
use Drupal\usagov_wizard\MenuChecker;

/**
Expand Down Expand Up @@ -299,7 +300,7 @@ function usagov_wizard_preprocess_page(&$variables) {
}

/**
* Implements hook_preprocess_HOOK().
* Implements hook_preprocess_taxonomy_term().
*
* Determine where the current page sits in the taxonomy hierarchy and send this
* information to the twig so we can decide which of the "previous, next, start
Expand Down Expand Up @@ -379,32 +380,40 @@ function usagov_wizard_preprocess_breadcrumb(&$variables) {
$rootTermTid = $parents[array_key_last($parents)];
if (isset($rootTermTid)) {
$rootTerm = Term::load($rootTermTid);
if (isset($rootTerm->field_wizard_breadcrumbs)) {
$crumbs = $rootTerm->field_wizard_breadcrumbs->getValue();
foreach ($crumbs as $crumb) {
if (isset($crumb['uri'])) {
$crumb['url'] = Url::fromUri($crumb['uri'])->toString();
}
if (isset($crumb['title'])) {
$crumb['text'] = ($crumb['title']);
}

$variables['wizard_breadcrumb'][] = $crumb;
}
$language = $taxonomy_term->langcode->value;
$home = [
'text' => $language == 'en' ? 'Home' : 'Página principal',
'url' => $language == 'en' ? '/' : '/es',
];
if ($crumbs != NULL) {
array_unshift($variables['wizard_breadcrumb'], $home);
}
}
$variables['wizard_breadcrumb'] = usagov_wizard_get_term_breadcrumb($rootTerm);
}
}
}
}

function usagov_wizard_get_term_breadcrumb(Term $rootTerm): array {
if (isset($rootTerm->field_wizard_breadcrumbs)) {
$crumbs = $rootTerm->field_wizard_breadcrumbs->getValue();
$result = [];
foreach ($crumbs as $crumb) {
if (isset($crumb['uri'])) {
$crumb['url'] = Url::fromUri($crumb['uri'])->toString();
}
if (isset($crumb['title'])) {
$crumb['text'] = ($crumb['title']);
}

$result[] = $crumb;
}
$language = $rootTerm->langcode->value;
$home = [
'text' => $language === 'en' ? TaxonomyDatalayerBuilder::HOME_TITLE_EN : TaxonomyDatalayerBuilder::HOME_TITLE_ES,
'url' => $language === 'en' ? TaxonomyDatalayerBuilder::HOME_URL_EN : TaxonomyDatalayerBuilder::HOME_URL_ES,
];
if ($crumbs != NULL) {
array_unshift($result, $home);
}
return $result;
}

return [];
}

/**
* Implements hook_preprocess_HOOK().
*/
Expand All @@ -421,7 +430,7 @@ function usagov_wizard_preprocess_views_view_field__wizard_options(&$variables)
}

/**
* Implements hook_preprocess_HOOK().
* Implements hook_preprocess_views_view_unformatted().
*/
function usagov_wizard_preprocess_views_view_unformatted(&$variables) {
$taxonomy_term = \Drupal::routeMatch()->getParameter('taxonomy_term');
Expand Down
5 changes: 5 additions & 0 deletions web/modules/custom/usagov_wizard/usagov_wizard.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ services:
arguments:
- '@entity_type.manager'
- '@current_route_match'
usagov_wizard_datalayer_alter_subscriber:
class: '\Drupal\usagov_wizard\EventSubscriber\DatalayerAlterSubscriber'
arguments: ['@usagov_wizard.menu_checker', '@breadcrumb', '@current_route_match', '@entity_type.manager']
tags:
- { name: 'event_subscriber' }
Original file line number Diff line number Diff line change
Expand Up @@ -15,103 +15,3 @@
{{ header_html|raw }}
{% endif %}
{% endblock %}

{% block taxonomy_data %}
{% set titleCounter = 4 %}
{% set urlCounter = 4 %}
{% if start_page %}
{% set page_type = 'wizard-start' %}
{% set titleCounter = 2 %}
{% set urlCounter = 2 %}
{% elseif not has_child %}
{% set page_type = 'wizard-result' %}
{% else %}
{% set page_type = 'wizard-question' %}
{% endif %}
<script id="taxonomy-data">
{# passing this info from the preprocess_hook doesn't work due to how the
page loads this template, so just load the breadcrumb block in the template,
and then use twig magic to get all the info we need. #}
{% set breadcrumb_block = drupal_block('system_breadcrumb_block') %}
{# this is hard to to explain, but basically since the breadcrumb block
doesn't give us a link to the current page, we need to use logic from the
preprocess hook to print the current page info. We also need to print
information about the basic page landing page this is linked to from, and
we need to number both entries in the datalayer correctly.

E.g all the pages should have 'Taxonomy_Text_1' be the homepage, and
'Taxonomy_Text_2' be 'scams and fraud', but only the first page in the
wizard has these links dynamically generated from the breadcrumb block,
so this means that we need to manually enter those on the other pages,
while keeping in mind that the loop index cannot be relied on for the first
couple of pages to determine what numbering system to use for the last tag,
since the breadcrumb_block has 3 links on the first page, and 2 on the
second. #}

{# this part is sort of straightforward, just variables set above or in
the preprocess hook. #}
dataLayer = [{
{{'taxonomyID'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{tid|json_encode(constant('JSON_PRETTY_PRINT'))|raw }},
{{'contentType'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{vid|json_encode(constant('JSON_PRETTY_PRINT'))|raw }},
{{'language'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{language|json_encode(constant('JSON_PRETTY_PRINT'))|raw }},
{{'homepageTest'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{front|json_encode(constant('JSON_PRETTY_PRINT'))|raw }},
{{'basicPagesubType'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{pagetype|json_encode(constant('JSON_PRETTY_PRINT'))|raw }},
{{'Page_Type'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{page_type|json_encode(constant('JSON_PRETTY_PRINT'))|raw }},
{{'hasBenefitCategory'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{datalayer_hasBenefitCategories|json_encode(constant('JSON_PRETTY_PRINT'))|raw }},
{# do some weird stuff with the indentation here to make it appear correctly in the DOM #}
{% for link in breadcrumb_block['content']['#links'] %}
{% if loop.first %}
{{ 'Taxonomy_Text_1'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{ link.text|json_encode(constant('JSON_UNESCAPED_UNICODE') b-or constant('JSON_UNESCAPED_SLASHES') b-or constant('JSON_PRETTY_PRINT'))|raw }},
{% if page_type == 'wizard-start' %}
{% set titleCounter = titleCounter + 1 %}
{% endif %}
{% elseif loop.index == 2 %}
{{ 'Taxonomy_Text_2'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{ wizardTitle|json_encode(constant('JSON_UNESCAPED_UNICODE') b-or constant('JSON_UNESCAPED_SLASHES') b-or constant('JSON_UNESCAPED_SLASHES'))|raw }},
{% if page_type != 'wizard-start' %}
{{ 'Taxonomy_Text_3'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{ link.text|json_encode(constant('JSON_UNESCAPED_UNICODE') b-or constant('JSON_UNESCAPED_SLASHES') b-or constant('JSON_UNESCAPED_SLASHES'))|raw }},
{% endif %}
{% elseif loop.index <= 5 %}
{% set textTag = 'Taxonomy_Text_' ~ titleCounter %}
{% set titleCounter = titleCounter + 1 %}
{{ textTag|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{ link.text|json_encode(constant('JSON_UNESCAPED_UNICODE') b-or constant('JSON_UNESCAPED_SLASHES') b-or constant('JSON_UNESCAPED_SLASHES'))|raw }},
{% endif %}
{% endfor %}
{% for i in range(1, 6) %}
{% if titleCounter <= 6 %}
{% set lastText = 'Taxonomy_Text_' ~ titleCounter %}
{{ lastText|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{ name|json_encode(constant('JSON_UNESCAPED_UNICODE') b-or constant('JSON_UNESCAPED_SLASHES') b-or constant('JSON_PRETTY_PRINT'))|raw }},
{% endif %}
{% set titleCounter = titleCounter + 1 %}
{% endfor %}
{% for link in breadcrumb_block['content']['#links'] %}
{% if loop.first %}
{{ 'Taxonomy_URL_1'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{ link.url.toString|json_encode(constant('JSON_UNESCAPED_SLASHES'))|raw }},
{% if page_type == 'wizard-start' %}
{% set urlCounter = urlCounter + 1 %}
{% endif %}
{% elseif loop.index == 2 %}
{{ 'Taxonomy_URL_2'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{ wizardTitleUrl|json_encode(constant('JSON_UNESCAPED_SLASHES'))|raw }},
{% if wizardTitleUrl != link.url.toString %}
{{ 'Taxonomy_URL_3'|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{ link.url.toString|json_encode(constant('JSON_UNESCAPED_SLASHES'))|raw }},
{% endif %}
{% elseif loop.index <= 5 %}
{% set urlTag = 'Taxonomy_URL_' ~ urlCounter %}
{% set urlCounter = urlCounter + 1 %}
{% if page_type == 'wizard-start' %}
{{ urlTag|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{ currentPath|json_encode(constant('JSON_UNESCAPED_SLASHES'))|raw }},
{% else %}
{{ urlTag|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{ link.url.toString|json_encode(constant('JSON_UNESCAPED_SLASHES'))|raw }},
{% endif %}
{% endif %}
{% endfor %}
{% for i in range(1, 6) %}
{% if urlCounter <= 6 %}
{% set lastUrlCounter = 'Taxonomy_URL_' ~ urlCounter %}
{{ lastUrlCounter|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}: {{ currentPath|json_encode(constant('JSON_UNESCAPED_SLASHES'))|raw }}{% if urlCounter < 6 %},
{% endif %}
{% endif %}
{% set urlCounter = urlCounter + 1 %}
{% endfor %}
}];
</script>
{% endblock %}
Loading