Cache

Displayer cache (Pro)

Displayers are cached with the service DisplayerCacheService.

The caching parameters are controlled by the content block caching strategy. That strategy can define duration and different caching keys depending on user authentication, url and others.

Cache is enabled by default when devMode is disabled, this be changed by creating the config/themes.php file :

<?php

return [
    'displayerCache' => false
];

Displayer caching use Craft internal caching dependencies, saving an entry for example will clear all the displayer caches that use this entry.

If something changes in your code (templates, theme preferences class, render events) and you're pushing to a production environment, clear the caches : craft invalidate-tags/themes::displayers.

Field displayers are cached in the template fields/_field with the token {% fielddisplayercache %}, if you override a field template that does not extend this template, you would need to add that token or caching will be skipped.

Same idea for file displayers which use the token {% filedisplayercache %}.

Each displayer method beforeRender() will be called, even for cached displayers, that can be used if you need to register asset bundles or other things.

The cache can be disabled at field or displayer level by overriding the FieldInterface::getCanBeCached(): bool method. Cache is currently disabled on :

  • MatrixField : Cache happens at the Matrix level
  • TableField : Cache happens at the Table level
  • FileFile and AssetRenderFile : Cache happens at file displayer level

Generally, any displayer that handle Assets (file displayers) should have its cache disabled, it's the file displayer themselves who should be responsible for caching. Caching such a field displayer will result in the beforeRender of file displayers to not be called.

Rules cache

Theme resolution rules will be cached by default on environments where devMode is disabled, this can be changed by creating the config/themes.php file :

<?php

return [
    'rulesCache' => false
];

If you change rules and deploy to a production environment, clear the cache : craft invalidate-tags/themes::rules.

Template cache (Pro)

Template resolution will be cached by default on environments where devMode is disabled, this can be changed by creating the config/themes.php file :

<?php

return [
    'templateCache' => false
];

If you create new templates and deploy to a production environment, clear the cache : craft invalidate-tags/themes::templates

Block cache (Pro)

Block cache will be enabled by default on environments where devMode is disabled, this can be changed by creating the config/themes.php file :

<?php

return [
    'blockCache' => false
];

Add a new strategy

Each block can have a cache strategy that defines how it will be cached.

Add a new strategy class :

<?php

use Ryssbowh\CraftThemes\Themes;
use Ryssbowh\CraftThemes\base\BlockCacheStrategy;
use Ryssbowh\CraftThemes\interfaces\BlockInterface;
use Ryssbowh\CraftThemes\models\BlockStrategyOptions;

class MyCacheStrategy extends BlockCacheStrategy
{
    const CACHE_TAG = 'themes.blockCache.myStrategy';

    /**
     * @inheritDoc
     */
    public function getHandle(): string
    {
        return 'my-strategy';
    }

    /**
     * @inheritDoc
     */
    public function getName(): string
    {
        return \Craft::t('themes', 'My strategy');
    }

    /**
     * @inheritDoc
     */
    public function getDescription(): string
    {
        return \Craft::t('themes', 'Block will be cached differently');
    }

    /**
     * @inheritDoc
     */
    public function getDuration(): ?int
    {
        return $this->options->duration * 60;
    }

    /**
     * @inheritDoc
     */
    public function buildKey(BlockInterface $block): array
    {
        $key = [self::CACHE_TAG];
        if ($this->options->cachePerAuthenticated) {
            $key[] = \Craft::$app->user ? 'auth' : 'noauth';
        }
        if ($this->options->cachePerUser and $user = \Craft::$app->user) {
            $key[] = 'user-id-' . $user->getIdentity()->id;
        }
        if ($this->options->cachePerSite) {
            $site = \Craft::$app->sites->getCurrentSite();
            $key[] = 'site-' . $site->id;
        }
        return $key;
    }

    /**
     * @inheritDoc
     */
    protected function getOptionsModel(): string
    {
        return MyCacheStrategyOptions::class;
    }
}

And an option class :

<?php

use Ryssbowh\CraftThemes\models\BlockStrategyOptions;

class MyCacheStrategyOptions extends BlockStrategyOptions
{
    /**
     * @inheritDoc
     */
    public function defineOptions(): array
    {
        return [
            'duration' => [
                'field' => 'text',
                'type' => 'number',
                'min' => 0,
                'step' => 10,
                'label' => \Craft::t('themes', 'Cache duration (minutes)'),
                'instructions' => \Craft::t('themes', '0 means forever'),
                'size' => 5
            ],
            'cachePerSite' => [
                'field' => 'lightswitch',
                'label' => \Craft::t('themes', 'Cache depends on site')
            ],
            'cachePerAuthenticated' => [
                'field' => 'lightswitch',
                'label' => \Craft::t('themes', 'Cache depends on user authentication')
            ],
            'cachePerUser' => [
                'field' => 'lightswitch',
                'label' => \Craft::t('themes', 'Cache depends on user')
            ]
        ];
    }

    /**
     * @inheritDoc
     */
    public function defineDefaultValues(): array
    {
        return [
            'cachePerSite' => true,
            'cachePerAuthenticated' => false,
            'cachePerUser' => false,
            'duration' => 0
        ];
    }

    /**
     * @inheritDoc
     */
    public function defineRules(): array
    {
        return [
            [['cachePerAuthenticated', 'cachePerUser', 'cachePerSite'], 'boolean', 'trueValue' => true, 'falseValue' => false],
            ['duration', 'integer'],
            ['duration', 'required']
        ];
    }
}

And register it by responding to the event :

Event::on(
    BlockCacheService::class,
    BlockCacheService::REGISTER_STRATEGIES,
    function (RegisterBlockCacheStrategies $event) {
        $event->add(new MyCacheStrategy);
});

Strategy classes must implement BlockCacheStrategyInterface and their options extend BlockStrategyOptions which is a configurable options class (but is not modifiable through events).

Each block can disable caching entirely by overriding the method getCanBeCached(): bool. The content block is non cacheable, but still has a caching strategy which will define displayers caching.

Block cache can be cleared with the following command : craft invalidate-tags/themes::blocks

You must enable javascript to view this website