Автоматическая смена версии стилей при очистке кэша в MODX
Решил поделиться своим решением версионирования файлов стилей. Зачем нужно версионирование, я, наверное не буду объяснять. Вообще смена версий не такой частый процесс и зачастую он нужен не только для того, чтобы браузеры подхватывали измерения в стилях, но и для отслеживания версий сайта. Вариантов как это реализовать масса. Я состряпал наиболее подходящее для меня и решил поделиться им.
К слову, пока писал этот пост, в телеграм канале как раз подняли эту тему. :-)
Для начала создадим контекстную настройку, запускаем скрипт в консоли:
Далее создаем плагин и вешаем его на событие OnBeforeCacheUpdate. Я использую версионирование с текущей датой, мне так проще.
После фидбэка от Василия Наумкина, сделал вариант плагина который проверяет изменения в указанных файлах и при наличии таковых, заменяет версию. В плагине укажите пути к своим файлам стилей, которые необходимо проверять на наличие изменений.
У меня так же есть версия плагина с рандомной строкой, если нужно могу скинуть.
Ну и к стилям дописываем вывод значения настройки:
Конечно кто-то скажет что вариант слишком громоздкий. Но меня он вполне устраивает. Если кто-то поделится своим решением, более цивилизованным — то будет круто. Каждый подберет для себя более оптимальное решение.
К слову, пока писал этот пост, в телеграм канале как раз подняли эту тему. :-)
Шаг 1
Для начала создадим контекстную настройку, запускаем скрипт в консоли:
$contextKey = 'style_version';
if (!$contextSetting = $modx->getObject('modContextSetting', array('key' => $contextKey))) {
$contextSetting = $modx->newObject('modContextSetting');
}
$contextSetting->set('context_key', 'web');
$contextSetting->set('key', 'style_version');
$contextSetting->set('value', '');
$contextSetting->set('xtype', 'textfield');
$contextSetting->set('namespace', 'core');
$contextSetting->set('area', 'Site');
$contextSetting->save();
// Clear the cache:
$modx->cacheManager->refresh(array(
'context_settings' => array('contexts' => array('web'))
));Шаг 2
Далее создаем плагин и вешаем его на событие OnBeforeCacheUpdate. Я использую версионирование с текущей датой, мне так проще.
if ($modx->event->name == 'OnBeforeCacheUpdate') {
// Version as current date
$today = date("dmY");
// Check if we have context with key style_version
if (!$contextSetting = $modx->getObject('modContextSetting', array('key' => 'style_version', 'context_key' => 'web'))) {
return;
}
$contextSetting->set('value', $today);
$contextSetting->save();
// clear context cache
// $modx->cacheManager->refresh(array(
// 'context_settings' => array('contexts' => array('web'))
// ));
}После фидбэка от Василия Наумкина, сделал вариант плагина который проверяет изменения в указанных файлах и при наличии таковых, заменяет версию. В плагине укажите пути к своим файлам стилей, которые необходимо проверять на наличие изменений.
<?php
if ($modx->event->name == 'OnBeforeCacheUpdate') {
// which files we must check
$files = [
'public/template/css/styles.css',
'public/template/js/scripts.min.js'
];
$lastChangeTime = 0;
// check every file
foreach($files as $file){
$filepath = MODX_BASE_PATH.$file;
if (file_exists($filepath) && filemtime($filepath) > $lastChangeTime) {
$lastChangeTime = filemtime($filepath);
}
}
// Show result as date/month/year/hour/minutes/seconds
$lastChangeTime = date('dmYHis', $lastChangeTime);
// Check if we have context with key style_version
if (!$contextSetting = $modx->getObject('modContextSetting', array('key' => 'style_version', 'context_key' => 'web'))) {
return;
}
$contextSetting->set('value', $lastChangeTime);
$contextSetting->save();
// clear context cache
// $modx->cacheManager->refresh(array(
// 'context_settings' => array('contexts' => array('web'))
// ));
}У меня так же есть версия плагина с рандомной строкой, если нужно могу скинуть.
Шаг 3
Ну и к стилям дописываем вывод значения настройки:
<link rel="stylesheet" href="public/template/css/styles.css?v={$_modx->config.style_version}" type="text/css"/>
<script src="public/template/js/scripts.min.js?v={$_modx->config.style_version}" type="text/javascript"></script>Конечно кто-то скажет что вариант слишком громоздкий. Но меня он вполне устраивает. Если кто-то поделится своим решением, более цивилизованным — то будет круто. Каждый подберет для себя более оптимальное решение.
Комментарии: 17
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Лучше уж тогда своим PHP скриптом вставлять в настройку не текущую дату, а дату изменения файлов, или считать их хэш. Чтобы все файлы качались только когда хоть один из них изменился.
Ну а совсем уж идеальный вариант — собирать скрипты и стили через npm и уже там добавлять хэш каждому файлу, автоматически. Чтобы юзер качал только изменённые, а не все.
Ну а вообще да, надо бы сделать версию с функцией
Решение должно быть универсальным.
Это, как раз-таки, минус. Потому что посетитель сможет увидеть только одну правку файлов в день.
Спасибо за фидбэк!
Замени на
Это ж как нужно не читать документацию, чтобы такие велосипеды городить?!
Обновил пост, добавил версию плагина который проверяет когда последний раз изменялся файл.
И использовать его как-то так:
В принципе, можно вызывать и сниппет кэшированным
Систаксис MODX пропишет результат работы прямо в кэш страницы, и удалит при общем сбросе кэша.
Всё работает, все довольны.
Но и у файла можно читать не всё содержимое, а первые 100 байт, например. В любом случае, речь идёт о микросекундах.
В 95 процентов случаев веб разработчики делают довольно простые проекты, но стремятся наворотить туда как можно больше технологий — композеры, пайпы, варганты, докеры, препроцессоры, галпы, боуэры, энпээмы, рэст фулы, вотчеры, системы контроля версий…
На мой взгляд и вопрос с кешированием файлов стилей и скриптов также чрезмерно раздут. Прочел и ужаснулся, люди целые программы разрабатывают для этого. Разве не правильнее просто завести в каком-то своем пространстве имен свою системную настройку в которой будет лежать число. Это число и добавляеть как версию файла к стилям и скриптам. Во время разработки сайта это кеширование вообще не имеет смысла, достаточно нажать в браузере ctrl+f5 и весь кеш браузера слетел. На продакшине даже если и пришлось вносить какие то доработку в верстку или стили, зашел и в админке сменил цифру 3 на 4 в системных настройках. И все, все пользователи скачают новые файлы.
Внезапно, программисты любят писать программы и автоматизировать свой труд!
А еще лучше использовать webpack-dev-server, которому ничего и нажимать не надо, он в реальном времени отображает все изменения из IDE.
То просто выгрузил все изменения из IDE и запустил npm run build. Чтобы не ошибиться и не забыть что-то нажать в админке.
Еще недавно я так же вручную менял версию, но всё время выходило вот так:
И теперь это уже автоматизировано.
Но бывает и наоборот, когда разработчик продолжает развиваться и делает всё более сложные проекты.
@Евгений Generalov
Использование: