
Идеального ничего не бывает.
Зачастую у нас в сайтах очень много статических страниц и даже если страницы в кэше, вы можете посмотреть, сколько у нас инклудиться файлов
if ($modx->context->key == 'mgr') break; print_r(get_declared_classes()); die;Я не буду говорить, что это самый классный способ, про который я сейчас расскажу, он сырой - но рабочий. Просто делюсь, возможно кому-то и понадобиться.>
В самом шаблоне Todc.Bootstrap я закооментил тег $Todc.Scripts ([[-$Todc.Scripts]]), так как нам для эксперемента они не нужны и в чанке Todc.Navbar удалил Breadcrumbs.
Создаём контейнер для вывода к примеру новостей и сами новости (я создал для эксперемента три новости)
в документе конейнере ставим вызов getResources:
[[getResources? &tpl=`multTplgetResources` &includeContent=`1`]]и шаблон, чанк multTplgetResources:
<code><article class="blog-article"> <div class="row"> <div class="span9"> <div class="blog-content"> <div class="blog-content-title"> <h2><a href="[[+uri]]" class="invarseColor">[[+pagetitle]]</a></h2> </div> <div class="clearfix"> <ul class="unstyled blog-content-date"> <li class="pull-left"><i class="icon-calendar"></i>[[+publishedon:strtotime:date=`%d %B, %Y`]]</li> <li class="pull-left"><i class="icon-pencil"></i> <a href="#">[[+createdby:userinfo=`fullname`]]</a></li> </ul> </div> <div class="blog-content-entry"> <p>[[+content:ellipsis=`400`]]</p> <a href="[[+uri]]">Contunie →</a> </div> </div><!--end blog-content--> </div><!--end span5--> </div><!--end row--> </article></code>В футер. чанк Todc.Footer вставил вывод времяни:
<span class="debug"><small>Processing Time: <span>[^t^] </span></small></span>
Ну попробуем по эксперементировать, т.е. я не буду сейчас расписывать выборку ресурсов, которые нам нужно кэшировать нашим способом, а которые пропускать. Просто поэксперементируем.
Итак. создаём плагин myCache, ставим галочку на событие OnWebPagePrerender и вставляем код (если у нас в плагине одно событие. не обязательно использовать $modx->event->name, но у нас ещё будут события, поэтому пока оставим так.):
switch ($modx->event->name) { case 'OnWebPagePrerender': $file_cache = false; // аолучаем с конфига параметры $cache_prefix = $modx->getOption('cache_prefix'); $cache_handler = $modx->getOption('cache_handler'); // формируем ключ кэша $file = md5($_SERVER['REQUEST_URI']); // формируем путь для нашего кэша $arrayUrl = array_filter(explode('/',$_SERVER['REQUEST_URI']),function($el){ return !empty($el);}); $pathUri = implode('/',$arrayUrl); $cache_path = 'static/'.$pathUri; // проверяем какой кэш и существует ли файл в кэше switch ($cache_handler) { case 'cache.xPDOAPCCache': if(apc_exists($cache_path.'/'.$cache_prefix.$file)) { $file_cache = true; } break; case 'xPDOFileCache': if(file_exists(MODX_CORE_PATH.'cache/'.$cache_path.'/'.$file.'.cache.php')) { $file_cache = true; } break; } // если файла нету в кэше и кэш у нас активный, то пишем вывод в кэш if($file_cache == false && $modx->getCacheManager()) { $output = &$modx->resource->_output; $time = time(); $cacheArray = array('output'=>$output, 'time'=>$time); $modx->cacheManager->set($file,$cacheArray,0,array( xPDO::OPT_CACHE_KEY => $cache_path, xPDO::OPT_CACHE_HANDLER => $modx->getOption('cache_resource_handler', null, $modx->getOption(xPDO::OPT_CACHE_HANDLER)), xPDO::OPT_CACHE_FORMAT => (integer) $modx->getOption('cache_resource_format', null, $modx->getOption(xPDO::OPT_CACHE_FORMAT, null, xPDOCacheManager::CACHE_PHP)), )); } break; }Т.е. мы сохранили вывод страницы в свой кэш, в качестве ключа использовал урл страницы, я эксперементировал только c:
- xPDOFileCache — стандартный обработчик по умолчанию, хранит кэш в файлах.
- cache.xPDOAPCCache — обработчик для расширения php-apc (не забудьте создать префикс с ключом cache_prefix в системных настройках)
<!--?php // функция для вывода времяни (можно не использовать) function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } // функция извлечения массива с файла function geFile($key) { $value= null; if (file_exists($key)) { if ($files = @fopen($key, 'rb')) { if (flock($files, LOCK_SH)) { $value= @include $key; flock($files, LOCK_UN); if ($value === null) { fclose($files); @ unlink($key); } } @fclose($files); } } return $value; } // стартуем $time_start = microtime_float(); // Получаем название ключа для кэша $file = md5($_SERVER['REQUEST_URI']); // формируем путь для нашего кэша $arrayUrl = array_filter(explode('/',$_SERVER['REQUEST_URI']),function($el){ return !empty($el);}); $pathUri = implode('/',$arrayUrl); if(strlen($pathUri) --> 0) $pathUri .= '/'; // достаём с кэша конфиг файл $system_cache_pach = MODX_CORE_PATH.'cache/system_settings/config.cache.php'; $valueFile = geFile($system_cache_pach); // берём с настроек модекса префикс кэша и время жизни кэша $cache_prefix = $valueFile['cache_prefix']; $cache_expires = intval($valueFile['cache_expires']); // проверяем. если есть файл в кэше switch ($valueFile['cache_handler']) { case 'cache.xPDOAPCCache': $cache_key = "static/$pathUri$cache_prefix$file"; // проверяем, есть ли файл в кэше if(apc_exists($cache_key)) { // получаем файл с кэша $value = apc_fetch($cache_key); // Если его время жизни ещё не прошло или cache_expires у нас нуль, то выводим if ((time() - $cache_expires) < $value['time'] || $cache_expires == 0) { // подсчитываем время $time_end = microtime_float(); $time = $time_end - $time_start; // парсим наш тег [^t^] и заменяем на время echo str_replace('[^t^]', 'APCCache: '.round($time,6).' s', $value['output']); // Выводим содержимое файла exit; } else { // удаляем файл кэша apc_delete($cache_key); } } break; case 'xPDOFileCache': $cache_file = MODX_CORE_PATH."cache/static/$pathUri$file.cache.php"; // проверяем, есть ли файл в кэше if (file_exists($cache_file)) { // получаем наш файл $value = geFile($cache_file); // Если его время жизни ещё не прошло или cache_expires у нас нуль, то выводим if ((time() - $cache_expires) < $value['time'] || $cache_expires == 0) { // подсчитываем время $time_end = microtime_float(); $time = $time_end - $time_start; // парсим наш тег [^t^] и заменяем на время echo str_replace('[^t^]', 'FileCache: '.round($time,6).' s', $value['output']); // Выводим содержимое файла exit; } else { // удаляем файл с кэша unlink($cache_file); } } break; }Подключаем наш файл в index.php примерно после строчки 39, после инклуда конфига:
....... /* this can be used to disable caching in MODX absolutely */ $modx_cache_disabled= false; /* include custom core config and define core path */ @include(dirname(__FILE__) . '/config.core.php'); if (!defined('MODX_CORE_PATH')) define('MODX_CORE_PATH', dirname(__FILE__) . '/core/'); // Пытаемся вывести содержимое кэша require_once "read_cache.php"; /* include the modX class */ .......Очищаем кэш, и пробуем. Первый вызов как обычно без кэша, а второй и последующий Processing Time: APCCache: 0.0004 s - 0.0005 s . Не плохо?
Но это ещё не всё, нам же нужно управлять нашим кэшем, а вернее, при создание или редактирование ресурса, нам нужно убивать кэш редактируемого ресурса и кэш нашего родителя. про это, если будут интерестно в следующий раз. А может кто и сам продолжит и предложит свои варианты. Буду рад.
Код не вылизанный, просто наброски для эксперемента, чтобы увидеть результат.
Посмотреть в реальности можете по адресу http://talks.artdevue.com/test-multilanguage/ (возможно работать и не будут, так как это тестовый сайт, может кто и успеет увидеть). Там правда вывод идёт с мультиязычностью, об этом тоже напишу топик и выложу код.
В кратце про мультиязычность: Это расширение, в админке добавляете нужные языки указывая к каким контекстам они активны. Для каждого языка можно добавить свои параметры (как в контекстах).
При создании ресурса, у вас будет вкладка для переводов. Всё подгоняеться под стандартные расширение, такие как Wayfinder, getResources, getPage.... т.е. никаких изминений в них не нужно делать.
4 Комментария
«не забудьте создать префикс с ключом cache_prefix в системных настройках».
Если можно поподробней вот на этом месте. Как создаётся префикс и с чем его едят. Спасибо!
Если вы используете не файловый а общий кэш (APC и т.д.), тогда нужно создать префикс, который будет идентифицировать ваш сайт в общей системе кэширования. Система -> Настройка
Фильтр по разделу — выбираем "Кеширование"
Ищем Ключ — cache_prefix
Если его нет, создать
Ключ: cache_prefix
Тип поля: текстовое поле
Пространство имён: core
Запись словаря для раздела: caching
Значение: ваш_префикс
модуль то недоработан ибо я захожу с разных браузеров и голосую по несколько раз