Nedávno jsem řešil zajímavý problém. V šabloně jistého content typu byla definovaná ikona – tedy cesta k obrázku:
<img src="/{{ base_path ~ directory }}/img/trainings/{{ node.field_course_level.value }}.png" class="training-icon">
což ve výsledku vygeneruje cestu např. /themes/custom/mojetema/img/trainings/basic.png
Problém nastal, když se obrázek nahradil novou verzí, ale v prohlížeči se stále ukazovala původní. Ukázalo se, že původní obrázek má prohlížeč stále ve svojí paměti díky HTTP hlavičkám. Jak ho tedy přinutit zobrazit nový soubor?
Řešení
Samozřejmě nejjednodušší je vymazat cache prohlížeče, to ale bude fungovat jen u jednoho konkrétního uživatele, my ale potřebujeme řešení funkční pro všechny návštěvníky. Jednoduché řešení pro podobné případy je přidat do cesty k souboru za otazník nějaký unikátní parametr, třeba časové razítko (= timestamp) nebo nějaký token, tak jak to například dělá standardně Drupal pro vložené obrázky v obsahu (equalopp.png?itok=r-01vE-R). S timestamp tedy např. takto {{ node.field_course_level.value }}.png?1739288062
Ještě chytřejší - než vkládat ručně nějaký timestamp - by bylo, aby se to dělalo automaticky. Jako ideální časové razítko můžeme vlastně použít datum vytvoření souboru - pokud nahrajeme nový soubor, tato hodnota se změní.
Jenže jak to udělat automaticky pomocí twigu? Twig si můžeme rozšířit pomocí vlastních filtrů nebo funkcí. V tomto případě si nadefinujeme vlastní filtr, který zjistí zjistí čas vytvoření souboru a v šabloně tento filtr pak použijeme jako atribut v cestě souboru.
Vlastní TWIG filtr (TwigFilter)
Nejdříve si připravíme nějaký modul. V něm si pak vytvoříme soubor jmenomodulu.services.yml
services:
jmenomodulu.twig_extension:
class: Drupal\jmenomodulu\TwigExtension\CustomTwigExtensions
tags:
- { name: twig.extension }
samotnou třídu si definuje v souboru src/TwigExtension/CustomTwigExtensions.php a to následovně?
<?php
namespace Drupal\jmenomodulu\TwigExtension;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class CustomTwigExtensions extends AbstractExtension
{
public function getFilters()
{
return [
new TwigFilter('file_modified', [$this, 'getFileModified']),
];
}
public function getFileModified($filePath)
{
if (file_exists(DRUPAL_ROOT . $filePath)) {
return filemtime(DRUPAL_ROOT . $filePath);
}
return time();
}
}
Nyní tento TWIG filter můžeme použít v šabloně následovně:
{% set file_ts = 'cesta/k/souboru.png' | file_modified %}
Novou proměnnou pak přidáme za cestku k souboru
<img src="/{{ base_path ~ directory }}/img/trainings/{{ node.field_course_level.value }}.png?{{ file_ts }}" class="training-icon">
Závěr
Poslední věc bude pravděpodobně vyčistit Drupal cache. Díky tomu se nám z upravené šablony vygeneruje nový HTML soubor, kde už bude upravená cesta k obrázku včetně timestampu. Tyto novu URL pak načtě prohlížeč, který tak zobrazí aktuální verzi obrázku.
Pozn.: velmi podobně se pak pracuje s TWIG funkcemi (TwigFunction) https://www.tothenew.com/blog/enhancing-drupal-with-custom-twig-functio…