Как взять значение переменной из шаблона ноды и вставить в значение поля после создания ноды? Drupal 9

Главные вкладки

Аватар пользователя chelwolf chelwolf 22 ноября 2023 в 16:34

В шаблоне ноды типа материала есть переменная, которая по формуле складывает и умножает целые числа, которые я беру из заполненных полей ноды. Все работает исправно.

Пример, в котором переменной "result_value" в шаблоне ноды присваивается значение, высчитанное по формуле:

<?php
{% set result_value = (portfolio_result_value) * portfolio_event_status_value portfolio_participant_value portfolio_worker_value program_form_value %}
?>

На выходе я получаю число, например 180. Далее на этапе модерации я вписываю его вручную в поле "результат" типа "десятичное число".

Вопрос, как передавать значение переменной "result_value" в поле результата автоматически после создания ноды или при запуске крон?

Подскажите куда копать.

Лучший ответ

Аватар пользователя chelwolf chelwolf 24 ноября 2023 в 20:50

Правильный ответ в моём случае - либо писать свой модуль со своей логикой, который будет подставлять нужные значения в поля через хуки:

  • hook_entity_presave() - добавит при создании материала
  • hook_entity_upadte() - добавит после обновления материала

Либо использовать готовый модуль математических выражений, я использовал вот этот: https://www.drupal.org/project/field_expression

Модуль добавляет специальный тип поля, в котором, используя токены, можно подставить и посчитать значения полей материала по нужной формуле. Значение пересчитывается при каждом обновлении материала и сохраняется в базе данных, его можно выводить в шаблоне или использовать для реализации ещё какой-то логики.

В моём случае в материале я использую поле таксономии, пользователь выбирает термин из определённого словаря. У каждого термина есть числовое поле, где хранится определённый балл, это поле легко вывести через токены, а балл можно всегда лего поменять если будет необходимо.

В итогое значение поля выглядит вот так:

<?php
(5+[node:field_portfolio_result:entity:field_competitive_events_score])*[node:field_portfolio_event_status:entity:field_competitive_events_score]*[node:field_portfolio_participant_sum:value]/[node:field_portfolio_worker]/[node:field_portfolio_participat_form:entity:field_competitive_events_score]
?>

Также в одном месте мне потребовалось подставить количество элементов, на которые я ссылаюсь через reference-поле. В токенах не было возможности вывести это числом, поэтому я использовал вот этот модуль, который просто добавляет форматтер поля, который считает количество элементов и выдаёт число: https://www.drupal.org/project/field_count_formatter. Я установил его, включил для своего материала режим просмотра "Токен" и там в настройках отображения полей выбрал способ отображения нужного мне поля. В итоге у меня все работает как мне нужно.

Подобный модуль есть и для Views, чтобы была возможность проводить математические вычисления в представлении: https://www.drupal.org/project/views_simple_math_field

Также есть модуль, который позволяет складывать значения других полей Views: https://www.drupal.org/project/views_cumulative_field

Комментарии

Аватар пользователя chelwolf chelwolf 22 ноября 2023 в 20:26

Нет простого способа передать как-то значение из шаблона twig в поле, это сложная задача.

Я нашёл решение, которое больше всего подходит под мою ситуацию - вычисляемое поле: https://www.drupal.org/project/field_expression, но как быть, если в токены для вычисления надо подставлять не только готовые значения, но и условия, например если в выпадающем поле выбран определённый ключ - нужно прибивать одну цифру, если другой - цифра изменится. Также есть необходимость поставить цифру на количество нод, на которые я ссылаюсь с reference поля, для этого их нужно посчитать и вывести опять же это значение.

Тут ещё два варианта: создать свой токен для ноды как написано тут, все сделать как нужно и подставлять уже для подсчёта: https://www.rapiddg.com/article/creating-your-own-tokens-drupal-module

Либо использовать более сложный модуль для вычисляемого значения полей, где на php написать нужную логику: https://www.drupal.org/project/computed_field

Пока отложил решение задачи, но зато знаю порядок действий. Может кто-то поделится в комментариях своим способом.

Аватар пользователя chelwolf chelwolf 22 ноября 2023 в 21:46

Почитал (https://drupal.ru/docs/videouroki/drupalbookru/12113-huki-dlya-raboty-s-...), выглядит восхитительно. Получается я могу в .theme файле темы прописать всю логику расчёта, присвоить результат переменной и потом примерно так подставить нужное значение полю?

<?php
/**
 * Implements hook_entity_presave().
 */
function drupalbook_examples_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
  if (
$entity->getEntityTypeId() == 'node' && $entity->getType() == 'article') {
    
$entity->title->value $entity->title->value 'by ' date('d-m-Y');
  }
}
?>

Подскажите только три вещи.

1) Как достать значение поля таксономии на которое я ссылаюсь?

В твиге делаю так:

<?php
{% set portfolio_result_value node.field_portfolio_result.entity.field_competitive_events_score.value|number_format(0) %}
?>

2) Как подсчитать количество нод, на которые я ссылаюсь через reference-field?

В твиге делаю так:

<?php
{% set portfolio_worker_value content.field_portfolio_worker['#items']|length %}
?>

Как понял простое числовое поле можно достать вот так:
$Number1 = $entity->field_number->value;

3) Как осуществить подсчёт в template? Я могу там выполнить простые математические операции и подставлять переменные в формулу вида:

result=(5+$var1)*$var2*$var3/$var4/$var5

В твиге делаю так:

<?php
{% set result_value = (portfolio_result_value) * portfolio_event_status_value portfolio_participant_value portfolio_worker_value program_form_value %}
?>
Аватар пользователя gun_dose gun_dose 23 ноября 2023 в 12:16
1

chelwolf wrote: Получается я могу в .theme файле темы прописать всю логику расчёта,

Нет. Такие хуки нельзя помещать в тему. Их можно добавлять только в модуль. Хотя бы потому что сохранение ноды происходит в админской теме, а вы будете править другую.

Аватар пользователя chelwolf chelwolf 24 ноября 2023 в 20:50

Правильный ответ в моём случае - либо писать свой модуль со своей логикой, который будет подставлять нужные значения в поля через хуки:

  • hook_entity_presave() - добавит при создании материала
  • hook_entity_upadte() - добавит после обновления материала

Либо использовать готовый модуль математических выражений, я использовал вот этот: https://www.drupal.org/project/field_expression

Модуль добавляет специальный тип поля, в котором, используя токены, можно подставить и посчитать значения полей материала по нужной формуле. Значение пересчитывается при каждом обновлении материала и сохраняется в базе данных, его можно выводить в шаблоне или использовать для реализации ещё какой-то логики.

В моём случае в материале я использую поле таксономии, пользователь выбирает термин из определённого словаря. У каждого термина есть числовое поле, где хранится определённый балл, это поле легко вывести через токены, а балл можно всегда лего поменять если будет необходимо.

В итогое значение поля выглядит вот так:

<?php
(5+[node:field_portfolio_result:entity:field_competitive_events_score])*[node:field_portfolio_event_status:entity:field_competitive_events_score]*[node:field_portfolio_participant_sum:value]/[node:field_portfolio_worker]/[node:field_portfolio_participat_form:entity:field_competitive_events_score]
?>

Также в одном месте мне потребовалось подставить количество элементов, на которые я ссылаюсь через reference-поле. В токенах не было возможности вывести это числом, поэтому я использовал вот этот модуль, который просто добавляет форматтер поля, который считает количество элементов и выдаёт число: https://www.drupal.org/project/field_count_formatter. Я установил его, включил для своего материала режим просмотра "Токен" и там в настройках отображения полей выбрал способ отображения нужного мне поля. В итоге у меня все работает как мне нужно.

Подобный модуль есть и для Views, чтобы была возможность проводить математические вычисления в представлении: https://www.drupal.org/project/views_simple_math_field

Также есть модуль, который позволяет складывать значения других полей Views: https://www.drupal.org/project/views_cumulative_field