logo

Extra Block Types (EBT) - Nueva experiencia con Layout Builder❗

Extra Block Types (EBT): tipos de bloques con estilo y personalizables: Presentaciones de diapositivas, Pestañas, Tarjetas, Acordeones y muchos más. Configuraciones integradas para fondo, DOM Box y plugins de JavaScript. Experimenta hoy el futuro de la construcción de diseños.

Módulos de demostración EBT Descargar módulos EBT

❗Extra Paragraph Types (EPT) - Nueva experiencia con Paragraphs

Extra Paragraph Types (EPT): conjunto de módulos basado en párrafos de forma análoga.

Módulos de demostración EPT Descargar módulos EPT

Scroll
19/06/2025, by Ivan
Cache de contextos = dependencias contextuales (de la solicitud)
Los contextos de caché son análogos al encabezado HTTP Vary.

¿Por qué?

Los contextos de caché definen cómo crear variantes dependientes del contexto de algo que necesita ser cacheado. El código que crea cachés se vuelve más fácil de leer, y no es necesario repetir la misma lógica en cada lugar donde se requieren los mismos cambios de contexto.

Ejemplos:

  • La salida de ciertos datos depende del tema activo y se muestran diferentes resultados para diferentes temas. Entonces, usarás caché dependiente del contexto de caché del tema.
  • Al construir un array de renderizado que muestra un mensaje personalizado, el renderizado depende del usuario. Entonces la caché dependerá del contexto de caché del usuario.
  • Generalmente: cuando cierta información costosa de calcular depende del entorno del servidor, para ello también se usa un contexto de caché.

¿Cómo?

Un contexto de caché es una cadena que hace referencia a uno de los servicios disponibles de contexto de caché (ver más abajo).

Los contextos de caché se pasan como conjuntos (el orden no importa) de cadenas, por lo que se imprimen como string[]. Son conjuntos porque un elemento de caché puede depender (variar) de muchos contextos de caché.

Normalmente los contextos de caché se obtienen del objeto de contexto de la solicitud (es decir, de la petición). Gran parte del entorno para la aplicación web se obtiene del contexto de la solicitud. Finalmente, las respuestas HTTP se generan en gran medida basándose en las propiedades de las solicitudes HTTP que las originaron.

Pero eso no significa que los contextos de caché deban venir solo de la solicitud: también pueden depender de código desplegado, por ejemplo, del contexto deployment_id.

Además, los contextos de caché se describen como una jerarquía. El ejemplo más simple: cuando algo varía para cada usuario, ya no necesitamos usar solo los permisos de acceso, porque hay diferencias para cada usuario. Para el conjunto de permisos de acceso se usa caché para cada permiso de acceso. Si una parte de la página varía para cada usuario y otra para los permisos, Drupal debe ser lo suficientemente inteligente para usar las diferencias solo para cada usuario. Aquí Drupal puede usar la información de la jerarquía para evitar cambios innecesarios en la caché.

Sintaxis

  • Los puntos separan elementos padre de elementos hijo.
  • El nombre del contexto en plural indica que se puede usar un parámetro: agregue dos puntos seguido del parámetro deseado (si no se especifica, se toman todos los parámetros posibles, por ejemplo, todos los argumentos de la consulta).

Contextos de caché del núcleo de Drupal 8

El núcleo de Drupal 8 incluye la siguiente jerarquía de contextos de caché:

cookies
  :name
headers
  :name
ip
languages
  :type
protocol_version // Disponible en 8.9.x o superior.
request_format
route
  .book_navigation
  .menu_active_trails
    :menu_name
  .name
session
  .exists
theme
timezone
url
  .path
    .is_front // Disponible en 8.3.x o superior.
    .parent
  .query_args
    :key
    .pagers
      :pager_id
  .site
user
  .is_super_user
  .node_grants
    :operation
  .permissions
  .roles
    :role

Nota. Para usar el contexto de caché url.path.is_front en ramas/lanzamientos anteriores, vea la nota del cambio.

Dondequiera que se usen contextos de caché, se indica toda esta jerarquía, que tiene 3 ventajas:

  • No hay ambigüedad: queda claro cuál es el contexto padre sin importar dónde se use.
  • La comparación (y compresión) de contextos de caché es más simple: si están presentes tanto a.b.c como a.b, es obvio que a.b incluye a.b.c, y por lo tanto se entiende por qué a.b.c puede omitirse y “comprimirse” en el objeto padre.
  • No hay necesidad de preocuparse por que cada nivel del árbol sea único en todo el árbol.

Ejemplos de contextos de caché de esta jerarquía:

  • theme (depende del tema activo)
  • user.roles (depende de la combinación de roles)
  • user.roles:anonymous (depende de si el usuario actual tiene el rol "anónimo" o no, es decir, "es usuario anónimo")
  • languages (varía para todos los tipos de idiomas: interfaz, contenido…)
  • languages:language_interface (depende del idioma de la interfaz - LanguageInterface::TYPE_INTERFACE)
  • languages:language_content (depende del idioma del contenido - LanguageInterface::TYPE_CONTENT)
  • url (depende de toda la URL)
  • url.query_args (depende de toda la cadena de consulta)
  • url.query_args:foo (depende del argumento de consulta foo)
  • protocol_version (depende de HTTP 1 contra 2)

Optimización / compresión / combinación / simplificación de contextos de caché

Drupal usa automáticamente la información de jerarquía para simplificar al máximo los contextos de caché. Por ejemplo, cuando una parte de la página cambia para el usuario (contexto user), y otra parte para los permisos (contexto user.permissions), entonces no tiene sentido variar el resultado final en los permisos porque el cambio es para cada usuario individual.
En otras palabras: optimize([user, user.permissions]) = [user].

Incluso si el usuario realmente implica user.permissions, porque es más específico, al optimizar user.permissions, cualquier cambio en los permisos ya no hace que el contexto de caché user.permissions se cargue para cada página. Esto significa que si los permisos cambian, seguimos usando la misma versión cacheada aunque debería cambiarse con cada cambio en permisos.

Por eso los contextos de caché que dependen de configuración que puede cambiar en el tiempo pueden enlazar metadatos cacheables: etiquetas de caché y max-age. Cuando un contexto de caché así se optimiza, sus etiquetas de caché se asocian con el elemento de caché. Por lo tanto, cada vez que cambian los permisos asignados, el elemento de caché también se invalida.

(Recuerde que “cachear” es esencialmente “evitar cálculos innecesarios”. Por ello la optimización del contexto puede considerarse cachear el resultado del método getContext() del servicio de contexto. En este caso es un caché implícito (el valor se descarta en vez de almacenarse), pero el efecto es el mismo: cuando se acierta en caché, no se llama getContext(), por lo tanto se evitan cálculos. Y cuando cacheamos algo, enlazamos la cacheabilidad de esa cosa, así que en caso de contextos cacheables enlazamos etiquetas y max-age.)

Un ejemplo similar pero más complicado son los node grants. Los node grants se aplican a un usuario concreto, por lo que el contexto de caché de permisos de nodo es user.node_grants. Excepto que los permisos de nodo pueden ser extremadamente dinámicos (por ejemplo, pueden depender del tiempo y cambiar cada pocos minutos). Depende de las implementaciones de hooks de node grant presentes en el sitio. Por tanto, es mejor usar el contexto de caché node grants con max-age = 0, que significa que no puede ser cacheado (es decir, optimizado). Por lo tanto, optimize([user, user.node_grants]) = [user, user.node_grants].

Algunos sitios pueden sobreescribir la implementación por defecto del contexto de caché de permisos de nodo y en cambio establecer max-age = 3600, indicando que todos sus interceptores de permisos de nodo permiten cachear los resultados de acceso por hasta una hora. En tales sitios optimize([user, user.node_grants]) = [user].

¿Cómo reconocer, definir y crear?

Los contextos de caché son servicios etiquetados con cache.context. Así, cualquier módulo puede añadir contextos de caché. Implementan \Drupal\Core\Cache\Context\CacheContextInterface o \Drupal\Core\Cache\Context\CalculatedCacheContextInterface (para contextos de caché que aceptan parámetros, es decir, contextos de caché que aceptan un sufijo :parameter).

Por lo tanto, todo lo que necesita hacer para encontrar todos los contextos de caché disponibles para usar es ir a CacheContextInterface y CalculatedCacheContextInterface y usar su IDE para encontrar todas sus implementaciones. (En PHPStorm: Jerarquía de tipos → Jerarquía de subtipos. En NetBeans: clic derecho en el nombre de la interfaz → Buscar uso → Buscar todos los subtipos.)

Alternativamente, puede usar la consola de Drupal (drupal debug:cache:context) para mostrar todos los contextos de caché actuales para su sitio o aplicación:

$ drupal debug:cache:context
 Context ID               Label                             Class path                                               
 cookies                  HTTP-Cookies                      Drupal\Core\Cache\Context\CookiesCacheContext            
 headers                  HTTP-Header                       Drupal\Core\Cache\Context\HeadersCacheContext            
 ip                       IP-Adresse                        Drupal\Core\Cache\Context\IpCacheContext                 
 languages                Language                          Drupal\Core\Cache\Context\LanguagesCacheContext          
 request_format           Anfrageformat                     Drupal\Core\Cache\Context\RequestFormatCacheContext      
 route                    Route                             Drupal\Core\Cache\Context\RouteCacheContext              
 route.book_navigation    Buchnavigation                    Drupal\book\Cache\BookNavigationCacheContext             
 route.menu_active_trails Aktiver Menüpfad                  Drupal\Core\Cache\Context\MenuActiveTrailsCacheContext

En cada clase encontrada verá un comentario como este, ejemplo con \Drupal\Core\Cache\Context\UserCacheContext:

Cache context ID: 'user'.

Esto significa que 'user' es el contexto de caché real que puede usar en código. (Alternativamente, busque dónde se usa esta clase en un archivo *.services.yml y vea el ID del servicio. Más detalles abajo.)

Consejo: Puede obtener una lista completa y actualizada de todos los contextos de caché del núcleo de Drupal solo mirando los servicios etiquetados como cache.context!

El ID del servicio está estandarizado. Siempre empieza con cache_context. seguido por los padres del contexto y finalmente el nombre del contexto. Por ejemplo: cache_context (prefijo obligatorio) + route (padre) + book_navigation (nombre del contexto):

cache_context.route.book_navigation:
  class: Drupal\book\Cache\BookNavigationCacheContext
  arguments: ['@request_stack']
  tags:
    - { name: cache.context }

Esto define el contexto de caché route.book_navigation.

Depuración

Todo lo anterior es útil para depurar algo que está siendo cacheado. Pero hay una cosa más: digamos que algo se cachea con las claves de caché ['foo', 'bar'] y los contextos de caché ['languages:language_interface', 'user.permissions', 'route']. Entonces, el elemento de caché correspondiente se almacenará en un contenedor cache con un CID (identificador de caché) como:

foo:bar:[languages:language_interface]=en:[user.permissions]=A_QUITE_LONG_HASH:[route]=myroute.ROUTE_PARAMS_HASH

En otras palabras:

  • las claves de caché aparecen primero, en el orden dado
  • los contextos de caché aparecen segundo en orden alfabético, y se traducen en partes del CID en forma de [<nombre contexto caché>]=<valor contexto caché>
  • todas estas partes del CID se combinan con dos puntos

Esto debería facilitar el análisis y la depuración de cachés.

Encabezados (para depuración)

Y por último: es fácil ver de qué contextos de caché depende una respuesta determinada (y por tanto, varía) con solo mirar el encabezado X-Drupal-Cache-Contexts!

Nota: si no ve estos encabezados, debe configurar su instancia de Drupal para desarrollo.

Caché de página dinámica

El uso extensivo de contextos de caché en Drupal 8 permite que Drupal 8 incluya activado por defecto el caché dinámico de página (antes conocido como “Smart Cache”).

Caché interna de página

Tenga en cuenta que el caché interno de páginas asume que todas las páginas servidas a usuarios anónimos son idénticas, sin importar la implementación de contextos de caché. Si desea usar contextos de caché para alterar contenido servido a usuarios anónimos, este módulo debe desactivarse, lo que puede afectar al rendimiento.

Véase también

Source URL:

Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.