Добрый день. Я занимаюсь web-разработкой и почти всем, что с этим связано.

Автоматизация изменения цифрового отпечатка URL

Когда человек впервые заходит на сайт, его браузер обычно кэширует css, js и прочую статику. Если человек перейдёт на другую страницу сайта, то браузер скорее всего не будет заново загружать то, что уже есть в кэше браузера. Это отлично экономит трафик, время и нагрузку.

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

Очень простым вариантом является изменение цифрового отпечатка URL того файла, который был изменён.

Допустим, раньше файл подключался так:

<link href="main.css" rel="stylesheet" />

Тогда для того, чтобы все посетители получили новую версию файла, нужно изменить подключение примерно таким образом:

<link href="main.css?v=2" rel="stylesheet" />

Для браузера main.css и main.css?v=2 — это разные ресурсы, хотя никаких дополнительных действий над файлами производить не требуется.

Автоматизация, способ первый

Данный вариант очень простой, но его не рекомендуется использовать в продакшене ввиду излишней нагрузки. Суть в том, чтобы генерировать цифровой отпечаток URL при каждом запросе к странице.

Итак, создаём сниппет и называем его, например, timestamp. Код следующий:

return time();

Подключение:

<link href="main.css?v=[[!time]]" rel="stylesheet" />

Автоматизация, способ второй

Когда мне надоело каждый раз лезть в чанки и изменять цифровой отпечаток, я решил написать простой плагин, который изменяет цифровой отпечаток только при изменении файлов. Итак, что нужно сделать:

Во-первых, нужно создать системную настройку assets_version.

Системные настройки MODX

Во-вторых, нужно создать плагин с любым названием и привязанным к событию OnFileManagerFileUpdate.

Код плагина:


$basePath = $modx->getOption('base_path');
$debug = false;

// Массив отслеживаемых файлов
$files = [
	'assets/templates/main/css/main.css',
];

switch($modx->event->name) {
    case 'OnFileManagerFileUpdate':        
        foreach ($files as $file) {
        	$file = trim($file, '/');
        	$filepath = rtrim($basePath, '/').'/'.$file;
	        if ($path == $filepath) {
	        	$setting = $modx->getObject('modSystemSetting', 'assets_version');
	        	if (is_object($setting)) {
					$setting->set('value', time());
					$setting->save();
					$cacheRefreshOptions = ['system_settings' => []];
					$modx->cacheManager->refresh($cacheRefreshOptions);
	        	} else {
	        		if ($debug) {
	        			$modx->log(xPDO::LOG_LEVEL_ERROR, 'setting not found');
	        		}
	        	}
				break;
	        }
        }
        break;
}

В-третьих, в массиве $files нужно перечислить файлы, изменения в которых будут отслеживаться плагином.

В-четвёртых, нужно изменить подключение файлов:

<link href="main.css?v=[[++assets_version]]" rel="stylesheet" />

Комментарии