Рейтинг:0

Как мне использовать hook_cache_flush() или hook_rebuild() в пользовательском модуле для выполнения кода JavaScript при очистке кеша?

флаг jp

Я пытаюсь создать модуль, который выполняет некоторый код JavaScript при очистке кеша (через меню администратора или иным образом). Я считаю, что могу реализовать либо hook_cache_flush() или же hook_rebuild(), но я не совсем уверен, как это сделать. Я не обязательно ищу, чтобы это сделали за меня, но если бы мне дали отправную точку и направление движения, это было бы здорово.

Рейтинг:1
флаг us

Ни один hook_cache_flush() ни hook_rebuild() Реализация может напрямую добавлять код JavaScript на страницу просто потому, что они не получают никакого массива рендеринга в качестве аргумента и не возвращают массив рендеринга вызывающей их функции/методу. Вы можете добавить обработчик отправки формы в system_performance_settings форма, когда Очистить все кеши кнопка на этой форме нажата. Это не сработает, если кеш очищается другими методами, например модулем, который вызывает drupal_flush_all_caches() в его коде.

// Поместите следующую строку в начало файла, содержащего этот код.
используйте Drupal\Core\Form\FormStateInterface;

функция mymodule_form_system_performance_settings_alter(&$form, FormStateInterface $form_state) {
  если (isset($form['clear_cache']['clear'])) {
    если ($form_state->getTemporaryValue('mymodule_cache_cleared')) {
      $form['#attached']['library'][] = 'mymodule/cache.rebuild';
    }
    $form['clear_cache']['clear']['#submit'][] = 'mymodule_system_performance_settings_submit';
  }
}

function mymodule_system_performance_settings_submit (массив и $ форма, FormStateInterface $ form_state) {
  $form_state->setRebuild();
  $form_state->setTemporaryValue('mymodule_cache_cleared', TRUE);
}

Для решения, которое работает во всех случаях drupal_flush_all_caches() вызывается и добавляет код JavaScript на первую запрошенную страницу после очистки кеша, я бы реализовал hook_cache_flush() чтобы установить значение, которое затем проверяется hook_page_attachments().

функция mymodule_cache_flush() {
  \Drupal::state()->set('mymodule_cache_cleared', TRUE);
}

функция mymodule_page_attachments (массив и $ вложения) {
  $state = \Drupal::state();
  если ($state->get('mymodule_cache_cleared')) {
    // Удаляем значение состояния, чтобы избежать добавления библиотеки в
    // каждую страницу после очистки кеша.
    $state->delete('mymodule_cache_cleared');

    $attachments['#attached']['library'][] = 'mymodule/cache.rebuild';
  }
}

Чтобы добавить код JavaScript в первый Икс страницы, запрошенные после очистки кеша, я бы использовал следующие реализации ловушек. (Следующий код прикрепляет библиотеку к первым трем запросам страниц.)

функция mymodule_cache_flush() {
  \Drupal::state()->set('mymodule_cache_cleared_count', 3);
}

функция mymodule_page_attachments (массив и $ вложения) {
  $state = \Drupal::state();
  если ($ count = $state->get('mymodule_cache_cleared_count')) {
    $attachments['#attached']['library'][] = 'mymodule/cache.rebuild';
    $state->set('mymodule_cache_cleared_count', $count - 1);
  }
}

я использовал \Drupal::state()->получить() и \Drupal::state()->set() так как:

  • Значение, установленное с друпал_статический() не будет сохраняться между запросами страниц. На странице документации четко сказано:

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

  • Установив значение сеанса, каждый пользователь получит свое значение. Это означает, что код JavaScript будет добавлен к следующей запрошенной странице после очистки кеша только тогда, когда эта страница запрашивается от того же пользователя, который вошел в систему, когда кеш был очищен.

Добавьте JavaScript в свою тему или модуль показывает, как библиотека JavaScript определяется из модуля.

флаг jp
Я хотел использовать одну из перечисленных функций, чтобы код выполнялся каждый раз при вызове одной из этих функций. Таким образом, да, кнопка в настройках производительности сделает это, но также, если у кого-то установлен модуль меню администратора и он таким образом очистит свой кеш, он все равно будет выполняться. Разве нет способа выполнить JS, когда используется определенный хук, независимо от его аргументов или того, что он возвращает?
apaderno avatar
флаг us
Единственный хук, который сможет изменить массив рендеринга для страницы, будет вызываться для каждой страницы, и он не сможет понять, очищен ли кеш.
флаг jp
Я знаю, о каком крючке вы говорите, и вы правы. Что касается JS, я не буду спрашивать, как сделать то, что я особенно хочу сделать, но если бы я хотел добавить что-то простое, например, предупреждение, просто для проверки моей библиотеки, не могли бы вы дать мне подсказку, как это сделать? что? Я прочитал документацию, на которую вы ссылались, и не нашел решения, которое сработало для меня.
флаг cn
Вы всегда можете установить статическую переменную в хуке и снова подобрать ее в `hook_preprocess_page()` (см. [`drupal_static()`](https://api.drupal.org/api/drupal/core%21includes%21bootstrap .inc/function/drupal_static/9.3.x) для используемого шаблона). Но это не будет работать во всех контекстах; например, когда вы очищаете кеш из меню администратора, он перенаправляет обратно на страницу, с которой он пришел, поэтому у вас нет возможности прикрепить библиотеки к странице. Вы можете обойти это, используя сеанс или временное хранилище, но это требует больше усилий и может привести к беспорядку, если, например, перенаправление страницы не удается.
4uk4 avatar
флаг cn
@Clive, это хорошая идея - установить значение сеанса, например, вы можете установить сообщение для следующей полной загрузки страницы.Чтобы прочитать и очистить это значение сеанса, вы не можете использовать хук предварительной обработки страницы, хотя страницы кэшируются. Вы можете использовать подписчика событий ответа после извлечения страницы из кеша или некэшируемого блока с максимальным возрастом кеша 0, который всегда кэшируется как заполнитель и выполняется при каждом запросе страницы.
apaderno avatar
флаг us
@Joseph Джозеф Я добавил еще решение, так как то, что сообщается в комментариях, не совсем верно.
apaderno avatar
флаг us
@ 4uk4 Это хорошая идея, если OP требует разных значений для каждого пользователя. Если OP необходимо установить значение при очистке кеша и использовать это значение для добавления кода JavaScript на следующую требуемую страницу, независимо от пользователя, который обращается к этой странице, сеанс нельзя использовать.
4uk4 avatar
флаг cn
Хорошо, но очистка кеша в почтовом запросе, непосредственно перенаправляющем на обычную загрузку страницы (тогда, конечно, с тем же файлом cookie сеанса), является наиболее вероятным вариантом использования drupal_flush_all_caches() в соответствии с документами. Если есть браузер. В противном случае javascript не имеет особого смысла.
apaderno avatar
флаг us
@ 4uk4 Я тоже не понимаю, какова цель запуска кода JavaScript при очистке кэша Drupal. Я бы подумал, что ОП пытается что-то изменить на уровне браузера, но это всего лишь предположение. Вот почему я избегал говорить что-либо о том, является ли использование JavaScript хорошей или плохой идеей.

Ответить или комментировать

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