Способность к анализу не следует смешивать с простой изобретательностью, ибо аналитик всегда изобретателен, тогда как не всякий изобретательный человек способен к анализу.
Эдгар Аллан По
Введение
Существуют два способа решения данной задачи: на уровне темы или на уровне модуля, чем они отличаются? В данной статье мы постараемся разобраться, а так же подчеркну, что данный способ подходит и для других трекер-сервисов.
На уровне темы оформления трекеры будут работать только в её пределах, то есть при включении другой темы оформления или переходе (например в админку сайта) трекеры уже работать не будут, либо для каждой темы оформления нужно будет делать настройки.
На уровне модуля - трекеры будут интегрироваться в любую тему оформления.
Выбор способа реализации зависит исключительно от Ваших потребностей, если Вам достаточно отслеживать главную и типовые страницы - то Вам подойдет первый способ, если же Вы хотите отслеживать действия зарегистрированных пользователей, модераторов и администраторов - то Вам лучше подойдет второй способ.
В теме оформления
Для начала добавим код в тему оформления Вашего сайта:
your_theme.theme
/**
* Implements hook_preprocess_html().
*/
function your_theme_preprocess_html(&$variables) {
$account = \Drupal::currentUser();
$roles = $account->getRoles();
foreach ($roles as $role) {
$variables['curretn_user_roles'][] = $role;
$variables['attributes']['class'][] = 'role-' . $role;
}
$roles = \Drupal::entityTypeManager()->getStorage('user_role')->loadMultiple();
$roles_names = array_combine(array_keys($roles), array_map(function($a){ return $a->label();}, $roles));
foreach ($roles_names as $role => $name) {
$variables['tracker_roles'][$role] = theme_get_setting($role);
}
$variables['top_traker'] = theme_get_setting('top_traker');
$variables['bottom_traker'] = theme_get_setting('bottom_traker');
}
/**
* Implements hook_form_system_theme_settings_alter().
*/
function your_theme_form_system_theme_settings_alter(&$form, FormStateInterface &$form_state, $form_id = NULL) {
$roles = \Drupal::entityTypeManager()->getStorage('user_role')->loadMultiple();
$roles_names = array_combine(array_keys($roles), array_map(function($a){ return $a->label();}, $roles));
$form['tracker_roles'] = [
'#type' => 'details',
'#title' => t('Отслеживание трекером'),
'#open' => TRUE,
'#description' => t('Выберите роли которые будут отслеживаться трекерами.'),
];
foreach ($roles_names as $role => $name) {
$form['tracker_roles'][$role] = [
'#type' => 'checkbox',
'#title' => t($name),
'#default_value' => theme_get_setting($role),
];
}
$form['tracker_roles']['top_traker'] = [
'#type' => 'textarea',
'#title' => t('Трекер в HEAD'),
'#default_value' => theme_get_setting('top_traker'),
'#description' => t("Введите JS или HTML код трекера."),
];
$form['tracker_roles']['bottom_traker'] = [
'#type' => 'textarea',
'#title' => t('Трекер внизу BODY'),
'#default_value' => theme_get_setting('bottom_traker'),
'#description' => t("Введите JS или HTML код трекера."),
];
}
Теперь у нас в настройках темы появились необходимые поля и чекбоксы, отметьте те роли за которыми будет вестись отслеживание и введите коды трекеров:
Далее создадим или отредактируем файл html.html.twig в Вашей теме:
html.html.twig
{% set tracker_enable = 0 %} {# добавляемая строка #}
{% for role, status in tracker_roles %} {# добавляемая строка #}
{% if status == 1 and role in curretn_user_roles %} {# добавляемая строка #}
{% set tracker_enable = 1 %} {# добавляемая строка #}
{% endif %} {# добавляемая строка #}
{% endfor %} {# добавляемая строка #}
<!DOCTYPE html>
<html{{ html_attributes }}>
<head>
<meta name="yandex-verification" content="237db23dff154515">
<head-placeholder token="{{ placeholder_token }}">
<title>{{ head_title|safe_join(' | ') }}</title>
<css-placeholder token="{{ placeholder_token }}">
<js-placeholder token="{{ placeholder_token }}">
{% if tracker_enable == 1 %} {# добавляемая строка #}
{{ top_traker|raw }} {# добавляемая строка #}
{% endif %} {# добавляемая строка #}
</head>
<body{{ attributes.addClass(body_classes) }}>
{{ page_top }}
{{ page }}
{{ page_bottom }}
<js-bottom-placeholder token="{{ placeholder_token }}">
{% if tracker_enable == 1 %} {# добавляемая строка #}
{{ bottom_traker|raw }} {# добавляемая строка #}
{% endif %} {# добавляемая строка #}
</body>
</html>
В модуле
your_module.info.yml
name: YOUR Module
description: Your Module.
package: Administration # указываем группу модуля в которой он будет отображаться на страницеуправления модулями.
type: module
core: 8.x
core_version_requirement: ^8 || ^9 # указываем режим совместимости.
your_module.links.menu.yml
your_module.admin_settings_form: # задаем параметры ссылки в админке для модуля.
title: 'YOUR настройки'
route_name: your_module.admin_settings_form
description: 'Настройки YOUR модуля'
parent: system.admin_config
weight: 99
your_module.routing.yml
your_module.admin_settings_form:
path: '/admin/config/your_module/settings' # путь до страницы с настройками модуля.
defaults:
_form: '\Drupal\iqis_module\Form\SettingsYourModuleForm' # форма с настройками модуля.
_title: 'Настройки YOUR модуля'
requirements:
_permission: 'access administration pages' # даем возможность на правку и просмотр только Администраторам.
options:
_admin_route: TRUE
your_module.module
<?php
/**
* @file
* Your Module.
*/
/**
* Implements hook_page_attachments().
*/
function your_module_page_attachments(array &$page) {
$account = \Drupal::currentUser(); // получаем данные о текущем пользователе
$userRoles = $account->getRoles(); // получаем все роли назначенные пользователю
$javascript_header = \Drupal::config('your_module.settings')->get('traker_top'); // загружаем код трекера для HEAD
$roles = \Drupal::config('your_module.settings')->get('traker'); // загружаем список ролей которые будут отслеживаться
$roles = \Drupal::entityTypeManager()->getStorage('user_role')->loadMultiple(); // получаем весь список ролей на сайте
$roles_names = array_combine(array_keys($roles), array_map(function($a){ return $a->label();}, $roles)); // формируем массив с названиями ролей
foreach ($roles_names as $role => $name) {
$allowedRoles[$role ] = \Drupal::config('your_module.settings')->get($name);
}
$enebleTraker = 0; // устанавливаем переменную для контроля инициализации трекера
foreach ($allowedRoles as $role => $name) { // перебираем массив с ролями и при совпадении устанавливаем переменную для контроля трекера в значение 1
if (in_array($role, $userRoles) && $name == 1) {
$enebleTraker = 1;
}
}
if ($enebleTraker == 1) { // если переменная для контроля трекера равна 1 включаем код трекера в HEAD
$page['#attached']['html_head'][] = [
[
'#tag' => 'script',
'#value' => $javascript_header,
'#weight' => 1,
],
'traker'
];
}
}
/**
* Implements hook_preprocess_html().
*/
function your_module_preprocess_html(array &$variables) {
$account = \Drupal::currentUser(); // получаем данные о текущем пользователе
$userRoles = $account->getRoles(); // получаем все роли назначенные пользователю
$javascript_footer = \Drupal::config('your_module.settings')->get('traker_bottom'); // загружаем код трекера для BODY
$roles = \Drupal::config('your_module.settings')->get('traker'); // загружаем список ролей которые будут отслеживаться
$roles = \Drupal::entityTypeManager()->getStorage('user_role')->loadMultiple(); // получаем весь список ролей на сайте
$roles_names = array_combine(array_keys($roles), array_map(function($a){ return $a->label();}, $roles)); // формируем массив с названиями ролей
foreach ($roles_names as $role => $name) {
$allowedRoles[$role ] = \Drupal::config('your_module.settings')->get($name);
}
$enebleTraker = 0; // устанавливаем переменную для контроля инициализации трекера
foreach ($allowedRoles as $role => $name) { // перебираем массив с ролями и при совпадении устанавливаем переменную для контроля трекера в значение 1
if (in_array($role, $userRoles) && $name == 1) {
$enebleTraker = 1;
}
}
if ($enebleTraker == 1) { // если переменная для контроля трекера равна 1 включаем код трекера в BODY
$variables['page_bottom'] = \Drupal\Core\Render\Markup::create($javascript_footer);
}
}
Создаем папки src в ней создаем папку Form и уже в ней создаем файл SettingsYourModuleForm.php
SettingsYourModuleForm.php
<?php
namespace Drupal\your_module\Form;
/**
* @file
* Contains Drupal\your_module\Form\SettingsYourModuleForm.
*/
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* SettingsYourModuleForm().
*/
class SettingsYourModuleForm extends ConfigFormBase {
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
'your_module.settings',
];
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'your_module_form';
}
/**
* {@inheritdoc} конструируем форму с нужными нам полями.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('your_module.settings');
$roles = \Drupal::entityTypeManager()->getStorage('user_role')->loadMultiple();
$roles_names = array_combine(array_keys($roles), array_map(
function ($a) {
return $a->label();
},
$roles));
$form['tracker_roles'] = [
'#type' => 'details',
'#title' => $this->t('Отслеживание трекером'),
'#open' => TRUE,
'#description' => t('Выберите роли которые будут отслеживаться трекерами.'),
];
foreach ($roles_names as $role => $name) {
$form['tracker_roles'][$role] = [
'#type' => 'checkbox',
'#title' => $name,
'#default_value' => $config->get($name),
];
}
$form['tracker_roles']['traker_top'] = [
'#type' => 'textarea',
'#title' => $this->t('Трекер в HEAD'),
'#default_value' => $config->get('traker_top'),
'#description' => $this->t("Введите JS или HTML код трекера."),
];
$form['tracker_roles']['traker_bottom'] = [
'#type' => 'textarea',
'#title' => $this->t('Трекер в BODY'),
'#default_value' => $config->get('traker_bottom'),
'#description' => $this->t("Введите JS или HTML код трекера."),
];
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc} сохраняем значения полей в форме.
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$roles = \Drupal::entityTypeManager()->getStorage('user_role')->loadMultiple();
$roles_names = array_combine(array_keys($roles), array_map(
function ($a) {
return $a->label();
},
$roles));
$this->config('your_module.settings')->set('traker_top', $form_state->getValue('traker_top'))->save();
$this->config('your_module.settings')->set('traker_bottom', $form_state->getValue('traker_bottom'))->save();
foreach ($roles_names as $role => $name) {
$this->config('your_module.settings')->set($name, $form_state->getValue($role))->save();
}
}
}
В итоге по адресу your-site.ru/admin/config/your_module/settings Вы увидите созданную форму:
Внимание! Так как Twig обработчик будет оборачивать весь код в тег <script></script>, то Вам необходимо из кода счетчика убрать комментарии <!-- -->, первый тег <script> и последний тег </script>
Если Вы захотите использовать чистый код счетчика обернутый в <scripts> и комментарии, то вот патч который добавлет тег no_tag, и используя его '#tag' => 'script', вы сможете вставлять чистый код. Внимание! после обновления Drupal патч придется применять снова! Протестировано на Drupal 9.0.1
Комментарии