Puncte:1

Cum să invalidați cache-ul Breadcrumbs pentru nodurile copil pe graphQl

drapel gb

am de exemplu Nodul A cu alias nodul-a și Nodul B cu alias nodul-a/nodul-b asa pe al meu Nodul B Am acest pesmet Acasă > Nodul A > Nodul B

Rezultat GraphQl:

„pesmet”: [
                {
                    "text": "Acasă",
                    „url”: {
                        "cale": "/",
                        „dirutat”: adevărat
                    }
                },
                {
                    "text": "Nodul A",
                    „url”: {
                        "cale": "http://example.com/node-a",
                        „dirutat”: adevărat
                    }
                },
                {
                    "text": "Nodul B",
                    „url”: {
                        "cale": "",
                        „dirutat”: adevărat
                    }
                }
            ]

Dar când mă schimb Nodul A titlu obțin întotdeauna același rezultat (pesmetul nu s-a schimbat), dar când re-salvam nodul A sau ștergeți memoria cache pentru modificarea rezultatului graphQl.

Iată ce am încercat:

  1. Ștergeți memoria cache graphQl (rezultate și definiții) la actualizarea nodului:

     /**
     * Implementează hook_ENTITY_TYPE_update().
     */
    funcția MYMODULE_node_update(EntityInterface $entity) {
      // Ștergeți memoria cache graphql.
      /** @var \Drupal\Core\Cache\CacheBackendInterface $graphql_results_cache */
      $graphql_results_cache = \Drupal::service('cache.graphql.results');
      $graphql_results_cache->invalidateAll();
      /** @var \Drupal\Core\Cache\CacheBackendInterface $graphql_definitions_cache */
      $graphql_definitions_cache = \Drupal::service('cache.graphql.definitions');
      $graphql_definitions_cache->invalidateAll();
    }

nu merge!

  1. Ștergeți memoria cache a tuturor nodurilor copil pe actualizarea nodului astfel:

    /**
     * Implementează hook_ENTITY_TYPE_update().
     */
    funcția MYMODULE_node_update(EntityInterface $entity) {
      $baza de date = \Drupal::baza de date();
      // Obține alias-ul curent al căii nodului.
      $alias = \Drupal::service('path_alias.manager')
        ->getAliasByPath('/node/' . $entity->id());
      // Obține toate nodurile fii ale nodului curent.
      $child_nodes_alias = $database->select('path_alias', 'pa')->fields('pa', [
        'cale',
        'alias',
      ])->condition('cale', '/node/%', 'LIKE')
        ->condition('alias', $alias . '%', 'LIKE')
        ->execute()
        ->fetchAll();
      // Invalidează memoria cache pentru fiecare nod copil al nodului curent.
      foreach ($child_nodes_alias ca $alias_data) {
        $nid = explode('/', $alias_data->cale)[2] ?? NUL;
        if ($nid && $nid != $entity->id()) {
          $tags = ['nod:' . $nid];
          Cache::invalidateTags($tags);
          \Drupal::entityTypeManager()->getStorage('node')->resetCache([$nid]);
        }
      }
    }

nici nu merge

  1. Am combinat cele două moduri anterioare, nici nu funcționează.

Când șterg toate cache-urile de pe actualizarea nodului, funcționează, dar nu este cel mai bun mod în care afectează memoria cache a site-ului.


/**
 * Implementează hook_ENTITY_TYPE_update().
 */
funcția MYMODULE_node_update(EntityInterface $entity) {
  drupal_flush_all_caches();
}

Care este cel mai bun mod de a șterge cache-ul breadcrumbs sau nodurile secundare fără a șterge tot cache-ul site-ului?

Editați | ×: Mulțumesc @4K4 pentru comentariul tău, am încercat să adaug prea pe CacheTags, dar nici nu am funcționat!


/**
 * Implementează hook_system_breadcrumb_alter().
 */
function MYMODULE_system_breadcrumb_alter(Breadcrumb &$breadcrumb, RouteMatchInterface $route_match, array $context) {
  // Adăugați titlul paginii curente la breadcrumb pentru rutele non-admin.
  if ($breadcrumb && !\Drupal::service('router.admin_context')->isAdminRoute()) {
    $linkuri = $breadcrumb->getLinks();
    foreach ($linkuri ca $link) {
      $parametri = $link->getUrl()->getRouteParameters();
      if ($parametri) {
        // Asigurați-vă că breadcrumb este actualizat când titlul nodului se schimbă.
        $breadcrumb->addCacheTags(['nod:' . $parameters['node']]);
        $breadcrumb->addCacheContexts(['url']);
      }
    }
  }
}

Notă: Pesmet ușor modul instalat.

Kevin avatar
drapel in
Sunt chiar legate în meniu? Cum sunt ele conectate altfel? Aliasurile nu implică dependențe de cache.
4uk4 avatar
drapel cn
În mod normal, nu rezolvați problemele de stocare în cache în hook_node_update(). Pluginul GraphQL care construiește breadcrumb trebuie să adauge etichetele cache și apoi acestea sunt invalidate automat când un nod este salvat.
berramou avatar
drapel gb
Am încercat să adaug un nod cachetag la breadcrumb așa cum am menționat în editarea mea și nu a funcționat, poate ar trebui să adaug un alt cacheTag, ce îmi lipsește?
berramou avatar
drapel gb
@Kevin nu, nu sunt legate în meniu, pesmeturi generate automat folosind modulul Easy Breadcrumb
4uk4 avatar
drapel cn
OK, cu condiția ca pesmeturile să aibă toate etichetele de cache necesare, încă nu este clar care cod generează rezultatul GraphQL. Nu am putut găsi un astfel de plugin în modulul principal. Ai un modul suplimentar pentru asta?
berramou avatar
drapel gb
Nu există un modul suplimentar pentru breadcrumbs, folosesc modulul qraphQl officiel versiunea 3.X Am găsit câmpul Breadcrumb definit aici **graphql/modules/graphql_core/src/Plugin/GraphQL/Fields/Breadcrumbs/Breadcrumbs.php**
4uk4 avatar
drapel cn
Aceasta este versiunea anterioară.[Cea mai recentă actualizare](https://git.drupalcode.org/project/graphql/-/commit/58a9b7464bc6cf4aa78632a0efee83f911c8522e) pentru acest obiect cod a abordat exact această problemă, dar nu știu dacă această actualizare a avut succes. Puteți înregistra o problemă dacă puteți reproduce etichetele de cache lipsă și această versiune este încă menținută.
berramou avatar
drapel gb
Da, am această actualizare, este ultima versiune 3.X instalată!
4uk4 avatar
drapel cn
Puteți confirma că actualizarea a avut succes? De exemplu, verificând dacă etichetele cache pe care le-ați adăugat la breadcrumbs ajung în răspunsul stocat în cache.
Puncte:0
drapel cn

Nu cunosc implementarea în cache a pluginurilor de câmp GraphQL 3.x, dar din câte pot spune acest cod (chiar și după ultima actualizare din 2018) nu colectează metadatele breadcrumb deoarece primește doar linkurile:

funcția protejată resolveValues($valoare, matrice $args, ResolveContext $context, ResolveInfo $info) {
    if ($valoare instanță de URL) {
      $resolve = $this->subRequestBuffer->add($value, function () {
        $linkuri = $this->breadcrumbManager->build($this->routeMatch)->getLinks();
        returnează $linkuri;
      });

      funcția de returnare ($valoare, matrice $args, ResolveContext $context, ResolveInfo $info) utilizare ($resolve) {
        /** @var \Drupal\graphql\GraphQL\Cache\CacheableValue $răspuns */
        $răspuns = $rezolvare();
        $linkuri = $response->getValue();

        foreach ($linkuri ca $link) {
          produce un nou CacheableValue($link, [$response]);
        }
      };
    }
  }

Nu ar trebui să obțină obiectul breadcrumb să adauge metadatele care pot fi stocate în cache?

funcția protejată resolveValues($valoare, matrice $args, ResolveContext $context, ResolveInfo $info) {
    if ($valoare instanță de URL) {
      $resolve = $this->subRequestBuffer->add($value, function () {
        $breadcrumb = $this->breadcrumbManager->build($this->routeMatch);
        returnează $breadcrumb;
      });

      funcția de returnare ($valoare, matrice $args, ResolveContext $context, ResolveInfo $info) utilizare ($resolve) {
        /** @var \Drupal\graphql\GraphQL\Cache\CacheableValue $răspuns */
        $răspuns = $rezolvare();
        $breadcrumb = $răspuns->getValue();
        $linkuri = $breadcrumb->getLinks();

        foreach ($linkuri ca $link) {
          produce un nou CacheableValue($link, [$response, $breadcrumb]);
        }
      };
    }
  }

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.