Extra Block Types (EBT) - New Layout Builder experience❗

Extra Block Types (EBT) - styled, customizable block types: Slideshows, Tabs, Cards, Accordions and many others. Built-in settings for background, DOM Box, javascript plugins. Experience the future of layout building today.

Demo EBT modules Download EBT modules

❗Extra Paragraph Types (EPT) - New Paragraphs experience

Extra Paragraph Types (EPT) - analogical paragraph based set of modules.

Demo EPT modules Download EPT modules

Scroll
30/04/2020, by maria

Чтобы упростить работу с метаданными кеширования (cache tags, cache contexts and max-age), в Drupal 8 есть CacheableDependencyInterface.

Почему?

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

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

В первые дни разработки Drupal 8 это имело место. Понятно, что это было ненадежно. И это было очень подвержено ошибкам.

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

Например, при создании массива рендеринга для <p>Hi, %user, welcome to %site!</p>, вы полагаетесь как на сущность User текущего пользователя, так и на конфигурацию system.site. Когда этот массив визуализации кэшируется, он имеет и эту сущность пользователя, и этот объект конфигурации в качестве своих кэшируемых зависимостей.

CacheableDependencyInterface может быть реализован любым объектом значения (то есть объектом, который представляет логическую единицу данных). Если вы посмотрите на его документацию по API, то увидите, что он реализован множеством значимых объектов в ядре Drupal 8. На самом деле, можно с уверенностью сказать, что он реализован большинством объектов, с которыми вы взаимодействуете во время написания кода на Drupal 8!

Есть два крайних противоположных случая, которые встречаются довольно часто, для которых у Drupal есть удобные черты: случай неизменяемого объекта и, следовательно, кешируемый навсегда (UnchangingCacheableDependencyTrait, который всегда возвращает max-age === permanent), и случай объекта всегда динамически вычисляется и, следовательно, никогда не кэшируется (UncacheableDependencyTrait, который всегда возвращает max-age === 0).

RefinableCacheableDependencyInterface

Но CacheableDependencyInterface способен работать только с «присущими», «каноническими» метаданными кешируемости объекта. Иногда существует несколько вариантов объекта.

Наиболее яркими примерами этого являются трансляции сущностей (это одна и та же сущность с одинаковым идентификатором сущности, только в другом переводе) и трансляции конфигурации (это один и тот же объект конфигурации с тем же именем конфигурации, но с переопределением языка).

В обоих случаях метаданные о кешируемости, которые уже существуют в исходном (непереведенном) объекте, остаются применимыми. Например, node:5 кеш-тегов). Но - в случае сущности - контекст кэша языка контента необходим ('languages:'. LanguageInterface::TYPE_CONTENT, см. Cache contexts), чтобы показать, что эта сущность является вариантом исходной сущности, которая варьируется в зависимости от того, какой контент контекст языкового кэша был согласован. Точно так же в случае объекта конфигурации необходим контекст кэширования языка интерфейса ('languages:'. LanguageInterface::TYPE_INTERFACE), чтобы передать, что этот объект конфигурации является вариантом исходного объекта конфигурации, который варьируется в зависимости от того, какой язык интерфейса контекст кеша был согласован.

Примером, выходящим за рамки перевода, может служить модуль «Пиратский день», который имеет переопределение конфигурации, которое применяется только в пиратский день, который добавляет в конфигурацию yar, har и случайных попугаев; тогда объекты конфигурации будут иметь контекст кеша pirate_day.

Во всех приведенных выше примерах нам необходимо уточнить метаданные кэшируемости наших объектов, чтобы указать загруженный вариант. По этой причине был добавлен RefinableCacheableDependencyInterface, который позволяет только это: он имеет возможность добавлять теги кеша, контексты и обновлять максимальный возраст.

Чтобы упростить реализацию этого интерфейса, есть еще одна удобная особенность: RefinableCacheableDependencyTrait.

О сущностях и объектах конфигурации

Все сущности в Drupal 8 (core, contrib & custom) реализуют интерфейс EntityInterface, который расширяет как CacheableDependencyInterface, так и RefinableCacheableDependencyInterface. Кроме того, все сущности в ядре Drupal 8 расширяют абстрактный базовый класс Entity, и contrib/custom рекомендуется делать то же самое. Это означает, что каждая отдельная сущность, с которой вы взаимодействуете в Drupal 8, автоматически имеет согласованные теги кеша (<entity type>:<entity ID>, например, node:5 и user:3) и контексты кеша для отражения перевода.

Все объекты конфигурации в ядре Drupal 8 расширяют абстрактный базовый класс ConfigBase, который реализует как CacheableDependencyInterface, так и RefinableCacheableDependencyInterface. Это означает, что каждый отдельный объект конфигурации, с которым вы взаимодействуете в Drupal 8, автоматически имеет согласованные теги кэша (в форме config:<configuration name>, например, config:system.performance) и контексты кэша для отражения переопределений конфигурации (перевод которых является единственный пример в ядре).

Наконец, все сущности и объекты конфигурации в Drupal 8 автоматически имеют контексты кэша языка контента / интерфейса (соответственно) благодаря Entitymanager::getTranslationFromContext() и LangaugeConfigFactoryOverride::getCacheableMetadata($ name).

Использование объектов, которые являются кешируемыми зависимостями

Рендеринг является наиболее распространенным примером зависимости от объекта, который является кешируемой зависимостью. Чтобы упростить это, у нас есть RendererInterface::addCacheableDependency($ build, $dependency) - где $build - это рендер-массив, который зависит от объекта $dependency; метаданные кешируемого объекта будут автоматически «поглощены» массивом рендеринга. Это означает, что массив рендеринга будет недействительным всякий раз, когда недействительный тег кеша объекта приведет к кешированию другой версии, если будет использоваться другой перевод (т. е. Контекст кеша языка контента отображается на другой язык), и автоматически истечет, если зависимость имеет максимальный возраст, который не является постоянным (бесконечным).

См. Кэшируемость массивов рендеринга - конкретный пример для полного примера.

Другим хорошим примером являются проверки доступа, которые возвращают объекты AccessResult, у которых также есть метод AccessResult::addCacheableDependency($dependency). Обратите внимание, что здесь у нас есть только параметр $dependency, потому что мы можем хранить метаданные о кешируемости передаваемых зависимостей на самом объекте результата доступа. (Рендер, с его массивами рендеринга, является исключением.)

Связанные интерфейсы и классы

 

Смотрите также