Здравствуйте!
На сайте есть страница "Архив (Views)" туда попадают ноды которые старше двух часов от текущего времени. Нужно чтобы при обращении к ноде через страницу Архив (Views) менялся ее url до вывода. Какой hook для этого подойдет? Спасибо!
Здравствуйте!
На сайте есть страница "Архив (Views)" туда попадают ноды которые старше двух часов от текущего времени. Нужно чтобы при обращении к ноде через страницу Архив (Views) менялся ее url до вывода. Какой hook для этого подойдет? Спасибо!
Комментарии
Непонятно.
Давайте с примером
Есть страница представления, на этой странице выводится список нод одного типа, при переходе в ноду именно с этой страницы, должен меняться url ноды, допустим url нод по умолчанию "/content/title.html" а при переходе со страницы представления менялся на "/arhiv/title.html"
А можно сделать роут events/{year}/{month}/{day}/{title} для всех мероприятий и вообще ничего с урлом не делать.
хм.. какой-то, мягко говоря, не стандартный подход к решению задачи..
может модуль VBO лучше подойдет? ( https://www.drupal.org/project/views_bulk_operations )
Он позволяет сделать вьюс, для выборки материалов..
И совершать с выбранными материалами "пакетные" операции.
Например изменить значение алиаса(url) материала..
Спасибо за подсказку! Но это не пойдет. У меня на сайте есть тип материала "Мероприятия" на главной странице через views выводятся ближайшие мероприятия которые только будут , если мероприятие уже прошло то эти мероприятия выводятся на странице архив, эта страница тоже сделанна через представление. Мне нужно чтобы к нодам которые уже относятся к архиву присвоился класс в body, чтобы через css убрать не нужные поля. Сейчас как бы в body есть классы, но так как эти ноды создаются через один тип материала и если я через эти классы скрою допустим кнопку заказать, то она скроется в ближайших мероприятиях тоже.
Нужно получается какое то условие, если мероприятие (нода) уже прошло и выводится на странице Архив, то этой ноде нужно присвоить класс допустим "arhiv", т.е именно когда переходишь в ноду со страницы архив.
В общем-то, я могу предложить три варианта, но они либо смердят, либо кодить надо.
Я просто помню на каком то проекте подобное, только это был d7, там то же была страница представления, на ней выводился список нод, при вызове ноды через эту страницу у ноды переписывался url и присваивался класс, а вот какой хук за это отвечал не помню.
Вьюха тут вообще не причем.
Истинным решением будет только следующее:
Проверка нод по крону -> по условию, изменение алиаса -> node_save (aka D7)
Думаю, через какой-нибудь scheduler и rules можно накликать.
presave (node_save) скорее всего, через node_preview или препроцесс + global redirect.
P.S. Да и по SEO, ваше решение "нехорошее", т.к. редиректы придется прикручивать с /content/title.html на /arhiv/title.html.
Всё и проще и сложнее, чем кажется. Сложнее в том плане, что только каким-то одним определённым хуком API дело не ограничится.
1. Пишете роут, обрабатывающий внутренний путь /arhiv/{node_alias}. Таким образом, на вход роута будет поступать только часть синонима ноды, содержащая (насколько я понял из задачи) транслит заголовка материала.
2. В роуте пишете EntityQuery с условиями что-то вроде (только для примера):
3. Если EntityQuery вернул NID в результате (т.е. нашёл хоть что-то, соответствующее условиям), то $node = Node::load(NID)
4. return $node;
5. Всё. При переходе с представления на /arhiv/title.html будет грузиться и рендериться нода, содержащая в синониме подстроку title.html (если будет найдена таковая).
Вместо пп.2-3 можно и как-то так:
<?php
use \Drupal\node\Entity\Node; $path = \Drupal::service('path.alias_manager')->getPathByAlias('content/' . $node_alias);
if (preg_match('/node\/(\d+)/', $path, $matches)) {
$nid = $matches[1];
$node = Node::load($nid);
}
?>
ТС, скорее всего, preprocess_node ищет, раз речь идет о классе
Тогда уж скорее hook_preprocess_html(), если в body
Да и речь же не только о классе, но и об урле (второе, как я понял, в приоритете).
Кстати, класс можно установить и из функции роута. Или даже программно вообще исключить поля из вывода ноды.
что-то всего столько нагородили-)
Я правильно понял, что всего-навсего надо материалы старше 2 часов :
1.Не показывать в одной вьюхе.
2.Показывать в другой.
3.Странице просмотра материала установить нужный html-класс?
Это уже есть!
Да, нужно внутри самой ноды которая старше 2 часов от текущего времени, присвоить класс, например "arhiv" для того чтобы в этой ноде скрыть через css кнопку "Купить" так как мероприятие уже не актуально.
Сами ноды сортируются через поле "Дата"
Получается что нужна проверка через hook по полю дата.
скрывать-показывать поля лучше при помощи разных режимов отображения материалов (view mode)
а режим отображения устанавливается как-то так:
https://drupal.stackexchange.com/questions/193319/how-to-change-display-...
(код не проверен, возможно придется отладить)
<?php
/**
* Implements hook_entity_view_mode_alter().
*/
function MYMODULE_entity_view_mode_alter(&$view_mode, Drupal\Core\Entity\EntityInterface $entity, $context) { $time_limit=time()- 2* 60*60;
if (
$entity->get('created')->value < $time_limit && $view_mode == 'full') {$view_mode = 'teaser';
}
}
?>
Спасибо! Походу то что нужно, код попробовал, ноне работает, буду разбираться) Видать условие не подхватывает.
Создайте для материала нужные Режимы отображения (view mode) и поправьте в коде их "машинные" наименования (переменная $view_mode)
Сам hook срабатывает если я его вставляю так:
<?phpfunction custom_display_entity_view_mode_alter(&$view_mode, Drupal\Core\Entity\EntityInterface $entity, $context) {
// For nodes, change the view mode when it is teaser.
if ($entity
->getEntityTypeId() == 'node' && $view_mode == 'full') {
$view_mode = 'ar';
}
}
?>
Но если вставляю ваш код сайт ругается. Я как понимаю нужно чтобы модуль подключался к бд, потому что дата и время в мероприятиях указывается в ручную через поле "Дата"
Уважаемый, не костыльте подобными способами, тем более, что код нелогичный. Лучше пересмотрите свою задачу прагматично, со стороны юзера.
Надо перебить роут ноды кастомным контроллером и там выводить, как надо. Но вот насчёт смены урла - хз. С точки зрения поисковой оптимизации это неудачное решение. Да и с логической тоже. Я бы урл оставил постоянным, а менял бы только хлебные крошки.