Это решение для тех, кто устал уже читать фразы от клиентов в духе: «А у меня картинка на сайте не поменялась, а у меня аккардерон не работает, а у меня шрифт не очень зеленый до сих пор.»
Решение накидал на скорую руку, поэтому код не самый идеальный (но рабочий), если кто поправит — буду признателен)
Название — любое.
Событие — OnWebPagePrerender
$base = $modx->config['site_url'];
$files_origin = array();
$files_new = array();
$expansion='css,js,jpeg,jpg,png';
$content = $modx->Event->params['documentOutput'];
preg_match_all('/(link|href)=("|\')[^"\'>]+/i', $content, $media);
$data = preg_replace('/(link|href)("|\'|="|=\')(.*)/i', "$3", $media[0]);
foreach ($data as $url)
{
$a = substr(strrchr($url, '.'), 1);
$b = explode('?',$a);
$ex = explode('/',$b[0]);
$fo = explode('?',$url);
$file_name = str_replace($base,'',$fo[0]);
if (in_array(mb_strtolower($ex[0]),explode(',',$expansion)))
{
$fa = @stat($file_name);
if ($fa)
{
$files_origin[] = $url;
$files_new[] = $fo[0].'?v='.$fa['mtime'];
}
}
}
preg_match_all('/(script|img||src)=("|\')[^"\'>]+/i', $content, $media);
$data = preg_replace('/(script|src)("|\'|="|=\')(.*)/i', "$3", $media[0]);
foreach ($data as $url)
{
$a = substr(strrchr($url, '.'), 1);
$b = explode('?',$a);
$ex = explode('/',$b[0]);
$fo = explode('?',$url);
$file_name = str_replace($base,'',$fo[0]);
if (in_array(mb_strtolower($ex[0]),explode(',',$expansion)))
{
$fa = @stat($file_name);
if ($fa)
{
$files_origin[] = $url;
$files_new[] = $fo[0].'?v='.$fa['mtime'];
}
}
}
$content = str_replace($files_origin,$files_new,$content);
$modx->Event->output($content);
Николай 30.04.2017 01:32 #
Как по мне, более разумным (менее ресурсоёмким и не менее рабочим и кастомизируемым) способом было бы хранить кэш версий файлов (именно версий, а не файлов) где-нибудь в системе и при изменении этих файлов (css, js и пр.) менять этот кэш соответствующим образом.
Объясню на примере. Допустим, имеется небольшой (в плане количества и объёма статики) сайт (в каталоге на этом сайте которых 99%): 2-3 css-файла и 2-3 js-файла. Вполне оптимально для всех кастомных файлов (не готовых библиотек, а файлов, написанных индивидуально для сайта и поддерживаемых создателем сайта) иметь одну системную настройку, например, [(++assets_version)].
Подключаем файлы следующим образом:
Как будет изменяться содержимое этой системной настройки? Вариантов много, зависит от конкретного проекта и требований. Пусть каждый выберет для себя подходящий или предложит свой:
Алексей Либер 30.04.2017 01:53 #
/templates/css/style.css?[!if? &is=`:is:` &then=`@eval: echo time();`!]
Но если честно, не знаю что будет работать быстрее: мой код или вызов одного сниппета (зачастую вызов сниппета занимает больше ресурсов, чем само выполнение скрипта).
По моему решению есть два момента:
1) Его можно использовать до релиза, после — отключить. Т.е. использовать на время наибольших видоизменений файлов.
2) Посмотрел время генерации что с плагином, что без и честно говоря не увидел особой разницы. Тут простая математика, которая очень быстро работает.
Что же касается вашего предложения, то есть несколько, на мой взгляд, недостатков (помимо замороченности написания кода):
1) Не у всех есть крон. А у тех у кого есть порою бывает труднодоступным
2) При разработке сайта необходимо каждый раз проставлять [(++assets_version)] вручную. Можно пропустить. Можно забыть. Когда 2-3 файла, то норм, а когда нам дают верстку от темы wordpress?..
3) regClientStartupScript и иже с ним.
В заключении хочу сказать, что я выкладываю «ленивые» решения: поставил и забыл. Работают? И ладно!
Когда речь идет о более-менее серьезных проектах, то нужно подходить, конечно, ко всему индивидуально. Те же js и css вообще нужно минифицировать и сжимать в gz.
Николай 30.04.2017 02:06 #
Сниппет можно вызывать однажды. Он состоит из одной строки (return time();) и основная нагрузка идёт на парсер MODX. И то, если это дело правильно закэшируется, работать будет гораздо быстрее Вашего плагина.
«я выкладываю «ленивые» решения»
Если честно, мне было бы лень писать столько регулярок (да, можно нагуглить и всё такое, но надо ещё правильно нагуглить и прикрутить) и даже строк кода.
P. S. Улыбнул перевод слова «расширение».
Алексей Либер 30.04.2017 02:11 #
ИМХО, вот ну вообще не страшно) Правда там и страничка маленькая, но все равно, не критично.
По вашему последнему комменту:
с английским у меня всегда были проблемы, мой английский похож на английский Мутко)
На счет всего остального — действительно, можно по-разному, чем и дорог собственно MODX) Я предложил решение — нравится — пользуйтесь) Не нравится — не пользуйтесь) А на счет лени — так это прикладное решение к другой задаче) Почему бы и не переписать несколько строчек, и поделиться с сообществом? Один фик за это деньги заплатили же)
Николай 30.04.2017 02:35 #
2. Поместил плагин в отдельный php-файл.
2. Добавил измерение времени работы скрипта.
3. Время работы: 0.01-0.04 сек.
4. Очень неточные результаты регулярных выражений (9 правильных из 108 при поиске css и ~20 из ~600 при поиске js). В переменной «экспансия» я оставил «css,js». Ладно хоть есть проверка на расширение, а то бы плагин создал нехилую нагрузку на файловую систему.
PHP 7x64
На линукс-хостинге получилось быстрее, рекорд около 0.007 сек.
Алексей Либер 30.04.2017 02:38 #
Алексей Либер 30.04.2017 03:01 #
Проверил решение помимо этой страницы на других сайтах — все тоже аккуратненько работает… Допускаю что может быть ошибки в хитрых названиях файлов, но вродь не должно быть… Неоткуда)
Николай 30.04.2017 03:13 #
uploadfiles.io/yitka
Алексей Либер 30.04.2017 03:25 #
У тебя фактически сколько файлов?)))
Он находит упоминание о файле или картинке (атрибут src и href) запрашивает дату последнего изменения, подставляет. Если он файл не находит, то ничо и не делает)))
Николай 30.04.2017 03:32 #
Алексей Либер 30.04.2017 03:38 #
Но я написал же вначале: нравится — пользуйтесь, не нравится — не пользуйтесь. Лично мне проще его использовать, чем каждый раз выслушивать от клиентов что у них картинка старая или какой-то скрипт не срабатывает… Или самому при разработке не перебрасывать весь кэш страницы, а только один файл заново загружать
Николай 30.04.2017 03:37 #
Я лишь предложил менее ресурсоёмкие и надёжные решения, а также ради интереса протестировал этот плагин и добавил больше конкретики для Вас и тех, кто это будет использовать.
Алексей Либер 30.04.2017 03:41 #
Если вы оформите свое решение в пакет и дадите сообществу — вам люди только спасибо скажут. И я лично скажу спасибо)
Но для моих задач меня вполне устраивает и текущее решение.
Николай 30.04.2017 03:49 #
Алексей Либер 30.04.2017 03:52 #
Использовать или нет — каждый решит сам.
Николай 30.04.2017 04:05 #
Николай 30.04.2017 03:46 #
Андрей 30.04.2017 20:26 #
Dmi3yy 02.05.2017 13:29 #
modx.im/blog/develop/2717.html
Андрей 02.05.2017 13:45 #
А так хорошо конечно что уже есть такой инструмент.
Dmi3yy 02.05.2017 13:45 #