Neither hook_cache_flush()
nor hook_rebuild()
implementation can directly add JavaScript code to a page, simply for the fact they don't get any render array as argument, nor they return a render array to the function/method invoking them.
You could add a form submission handler to the system_performance_settings form for when the Clear all caches button on that form is clicked. This won't work when the cache is cleared using other methods, for example by a module that calls drupal_flush_all_caches()
in its code.
// Put the following line on the top of the file containing this code.
use Drupal\Core\Form\FormStateInterface;
function mymodule_form_system_performance_settings_alter(&$form, FormStateInterface $form_state) {
if (isset($form['clear_cache']['clear'])) {
if ($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(array &$form, FormStateInterface $form_state) {
$form_state->setRebuild();
$form_state->setTemporaryValue('mymodule_cache_cleared', TRUE);
}
For a solution that works in all the cases drupal_flush_all_caches()
is called, and adds the JavaScript code to the first page requested after the cache is cleared, I would implement hook_cache_flush()
to set a value that is then checked in hook_page_attachments()
.
function mymodule_cache_flush() {
\Drupal::state()->set('mymodule_cache_cleared', TRUE);
}
function mymodule_page_attachments(array &$attachments) {
$state = \Drupal::state();
if ($state->get('mymodule_cache_cleared')) {
// Delete the state value to avoid the library is added to
// every page after the cache is cleared.
$state->delete('mymodule_cache_cleared');
$attachments['#attached']['library'][] = 'mymodule/cache.rebuild';
}
}
To add the JavaScript code to the first X pages requested after the cache clear, I would use the following hook implementations. (The following code attaches the library to the first three page requests.)
function mymodule_cache_flush() {
\Drupal::state()->set('mymodule_cache_cleared_count', 3);
}
function mymodule_page_attachments(array &$attachments) {
$state = \Drupal::state();
if ($count = $state->get('mymodule_cache_cleared_count')) {
$attachments['#attached']['library'][] = 'mymodule/cache.rebuild';
$state->set('mymodule_cache_cleared_count', $count - 1);
}
}
I used \Drupal::state()->get()
and \Drupal::state()->set()
because:
The value set with drupal_static()
won't be preserved between page requests. The documentation page clearly says:
All functions requiring a static variable to persist or cache data within a single page request are encouraged to use this function unless it is absolutely certain that the static variable will not need to be reset during the page request.
Setting a session value, each user would get a different value. This means the JavaScript code would be added to the next page requested after the cache is cleared only when that page is requested from the same user who was logged in when the cache has been cleared.
Add JavaScript to Your Theme or Module shows how a JavaScript library is defined from a module.