Puncte:0

Cum ar trebui să folosesc hook_cache_flush() sau hook_rebuild() într-un modul personalizat pentru a executa cod JavaScript atunci când memoria cache este șters?

drapel jp

Încerc să creez un modul care execută un cod JavaScript atunci când memoria cache este golită (prin meniul administrator sau altfel). Cred că pot implementa oricare hook_cache_flush() sau hook_rebuild(), dar nu sunt foarte sigur cum. Nu caut neapărat ca acest lucru să fie făcut pentru mine, dar dacă mi s-ar oferi un punct de plecare și o direcție în care să mă îndrept, ar fi grozav.

Puncte:1
drapel us

Nici hook_cache_flush() nici hook_rebuild() implementarea poate adăuga direct cod JavaScript la o pagină, pur și simplu pentru faptul că nu primesc nicio matrice de randare ca argument și nici nu returnează o matrice de randare la funcția/metoda care le invocă. Puteți adăuga un handler de trimitere a formularelor la setări_performanță_sistem formular pentru când Ștergeți toate cache-urile se face clic pe butonul de pe formularul respectiv. Acest lucru nu va funcționa atunci când memoria cache este șters folosind alte metode, de exemplu printr-un modul care apelează drupal_flush_all_caches() în codul său.

// Pune următoarea linie în partea de sus a fișierului care conține acest cod.
utilizați Drupal\Core\Form\FormStateInterface;

funcția mymodule_form_system_performance_settings_alter(&$form, FormStateInterface $form_state) {
  if (isset($form['clear_cache']['clear'])) {
    dacă ($form_state->getTemporaryValue('mymodule_cache_cleared')) {
      $form['#attached']['library'][] = 'mymodule/cache.rebuild';
    }
    $form['clear_cache']['clear']['#submit'][] = 'mymodule_system_performance_settings_submit';
  }
}

funcția mymodule_system_performance_settings_submit(matrice &$form, FormStateInterface $form_state) {
  $form_state->setRebuild();
  $form_state->setTemporaryValue('mymodule_cache_cleared', TRUE);
}

Pentru o soluție care funcționează în toate cazurile drupal_flush_all_caches() este apelat și adaugă codul JavaScript la prima pagină solicitată după ștergerea cache-ului, aș implementa hook_cache_flush() pentru a seta o valoare care este apoi înregistrată hook_page_attachments().

funcția mymodule_cache_flush() {
  \Drupal::state()->set('mymodule_cache_cleared', TRUE);
}

funcția mymodule_page_attachments(array &$attachments) {
  $state = \Drupal::state();
  if ($state->get('mymodule_cache_cleared')) {
    // Ștergeți valoarea stării pentru a evita adăugarea bibliotecii
    // fiecare pagină după golirea memoriei cache.
    $state->delete('mymodule_cache_cleared');

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

Pentru a adăuga codul JavaScript la primul X paginile solicitate după ștergerea cache-ului, aș folosi următoarele implementări de cârlig. (Următorul cod atașează biblioteca la primele trei solicitări de pagini.)

funcția mymodule_cache_flush() {
  \Drupal::state()->set('mymodule_cache_cleared_count', 3);
}

funcția mymodule_page_attachments(array &$attachments) {
  $state = \Drupal::state();
  dacă ($număr = $state->get('mymodule_cache_cleared_count')) {
    $attachments['#attached']['library'][] = 'mymodule/cache.rebuild';
    $state->set('mymodule_cache_cleared_count', $count - 1);
  }
}

obisnuiam \Drupal::state()->get() și \Drupal::state()->set() deoarece:

  • Valoarea stabilită cu drupal_static() nu va fi păstrat între solicitările de pagină. Pagina de documentație spune clar:

    Toate funcțiile care necesită o variabilă statică pentru a persista sau a stoca în cache datele într-o singură pagină de solicitare sunt încurajați să folosească această funcție, cu excepția cazului în care este absolut sigur că variabila statică nu va trebui să fie resetată în timpul solicitării paginii.

  • Setarea unei valori de sesiune, fiecare utilizator va primi o valoare diferită. Aceasta înseamnă că codul JavaScript va fi adăugat la următoarea pagină solicitată după ștergerea memoriei cache numai atunci când acea pagină este solicitată de la același utilizator care a fost conectat când memoria cache a fost șters.

Adăugați JavaScript la tema sau modulul dvs arată cum este definită o bibliotecă JavaScript dintr-un modul.

drapel jp
Am vrut să folosesc una dintre funcțiile pe care le-am enumerat, astfel încât codul să se execute de fiecare dată când una dintre acele funcții a fost apelată. În acest fel, da, butonul din setările de performanță ar face-o, dar și dacă cineva ar avea instalat modulul de meniu admin și și-ar șterge memoria cache în acest fel, s-ar executa în continuare. Nu există o modalitate de a executa JS atunci când este folosit un anumit cârlig, indiferent de argumentele sale sau de ce returnează?
apaderno avatar
drapel us
Singurul cârlig care ar putea modifica matricea de randare pentru o pagină ar fi invocat pentru fiecare pagină și nu va putea înțelege dacă memoria cache este șters.
drapel jp
Știu despre ce cârlig vorbești și ai dreptate. În ceea ce privește JS, nu voi întreba cum să fac ceea ce vreau în mod special să fac, dar dacă aș vrea să adaug ceva simplu, cum ar fi o alertă, doar pentru a-mi testa biblioteca, ați putea să-mi dați un indiciu despre cum să fac acea? Am citit documentația pe care ați legat-o și nu am găsit o soluție care să funcționeze pentru mine.
drapel cn
Puteți oricând să setați o var static în hook și să o ridicați din nou în `hook_preprocess_page()` (consultați [`drupal_static()`](https://api.drupal.org/api/drupal/core%21includes%21bootstrap .inc/function/drupal_static/9.3.x) pentru modelul de utilizat). Dar nu va funcționa în toate contextele; de exemplu, când ștergeți memoria cache din meniul de administrare, aceasta redirecționează înapoi la pagina de la care a venit, astfel încât să nu aveți ocazia să atașați biblioteci la pagină. Puteți ocoli acest lucru utilizând sesiune sau stocare temporară, dar este mai mult efort și ar putea deveni dezordonat dacă o redirecționare a paginii eșuează, de exemplu
4uk4 avatar
drapel cn
@Clive, este o idee bună să setați o valoare a sesiunii, așa cum ați putea seta un mesaj pentru următoarea încărcare completă a paginii.Pentru a citi și a șterge această valoare de sesiune, nu puteți utiliza cârligul de preprocesare a paginii, totuși, paginile sunt stocate în cache. Puteți utiliza un abonat eveniment răspuns după ce pagina este preluată din cache sau un bloc care nu poate fi stocat în cache cu vârsta maximă cache 0, care este întotdeauna stocat în cache ca substituent și rulează la fiecare solicitare de pagină.
apaderno avatar
drapel us
@Joseph Am mai adăugat o soluție, deoarece ceea ce s-a raportat în comentarii nu este complet corect.
apaderno avatar
drapel us
@4uk4 Este o idee bună dacă OP are nevoie de o valoare diferită pentru fiecare utilizator. Dacă OP trebuie să seteze o valoare atunci când memoria cache este șters și să folosească acea valoare pentru a adăuga cod JavaScript la următoarea pagină necesară, independent de utilizatorul care accesează pagina respectivă, sesiunea nu poate fi utilizată.
4uk4 avatar
drapel cn
OK, dar a avea cache-ul golit într-o solicitare de postare directă către o încărcare normală a paginii (apoi, desigur, cu același cookie de sesiune) este cel mai probabil caz de utilizare a drupal_flush_all_caches() conform documentelor. Dacă este implicat un browser. Altfel, javascript nu prea are sens.
apaderno avatar
drapel us
@4uk4 Nici eu nu înțeleg care este scopul rulării codului JavaScript când este șters memoria cache Drupal. Aș crede că OP încearcă să schimbe ceva la nivel de browser, dar aceasta este doar o presupunere sălbatică. De aceea am evitat să spun ceva despre dacă folosirea JavaScript este o idee bună sau rea.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.