[EVO] Переключение шаблона на лету с кэшированием, а так же предложения по расширению API MODX по части кеширования

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

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

А как было бы удобно просто добавить еще 1 поле для выбора шаблона(шаблонов для телефона планшета), это бы дало возможность легко работать с другим отображением сайта.

В целом для решение поставленной задачи нужно решить 2 этапа:
1 КЕШ.
Давно хотелось его научить умным вещам, последнее чему его учили это запоминание в кеш с учетом ГЕТ параметов, тут все ок, только после использования стал вопрос а почему только GET? да и почему все параметры а не только указанные, ведь порой удобно кешировать в зависимости от определенных параметров + в идеале от параметров которые или по умолчанию или указанны в конкретном документе.

итого задача 1: Вынести в настройки выбор параметров от которых зависит кеш

так же если уж ковырять кеш то очень хотелось бы научить MODX сбрасывать не весь кеш а только определенный, ибо если мы добавляем новости то зачем нам трогать каталог? где нет новостей?
тут тоже все довольно просто достаточно расширить api modx->clearCache добавив возможность не только удалять все но и удалять выбранные документы к примеру так:

modx->clearCache(array('1','4')); — тоесть если получаем масив то там список id которые чистим.

Таким образом мы расширим функционал Кеширования что даст больше гибкости в работе.

2 Плагин MOBILE-template
— как только у нас будет решена задача по части Кеша то написать данный плагин даже на базе существующих решений будет уже не проблемой, просто добавляем параметр к примеру $_SESSION['mobile'] к кешированию и в зависимости от него уже кешируем документ. таким образом у нас в кеше будет 2 файлика 1 под десктом второй под mobile.

Думаю это было бы очень актуально. В целом свободного времени пока мало :( потому есть идея попробовать решить эти задачки в рабочем порядке. Собрав под это дело немного денег :)

Пишите в коментах сколько готовы закинуть :) как соберется приятная сумма то сделаю указанный выше функционал. Так же если есть пожелания предложения касающиеся данной темы так же пишите

12 комментариев

avatar
Но тут сразу сталкиваемся с вопросом что это работает только при условии не кеширования страниц что не всегда есть хорошо.
Работает при кешировании с учетом GET.

modx->clearCache(array('1','4')); — тоесть если получаем масив то там список id которые чистим.
Это банальная функция на базе того же glob. В DocLister уже давно висит эта здачка, но походу пришло время ее решить. Правда это все актуально для тех, кто уже использует DL. Ну а для тех, кто так и не смог пересесть с Ditto/CatalogView, на мой взгляд, подобный функционал не актуален…

2 Плагин MOBILE-template
Если кеширование с учетом GET не канает, то всегда можно решить этот вопрос чуть более сложным плагином на базе CustomRoute.
Комментарий отредактирован 2015-02-24 12:28:03 пользователем Agel_Nash
avatar
Это банальная функция на базе того же glob. В DocLister уже давно висит эта здачка, но походу пришло время ее решить.
Собственно как я и говорил, тут нет ничего сложного. А использование теперь такое

include_once(MODX_BASE_PATH . "assets/lib/MODxAPI/modResource.php");
$modResource = new modResource($modx);

//Полый сброс кеша без вызова события OnSiteRefresh
$modResource->clearCache(false); 

//Полый сброс кеша с вызовом события OnSiteRefresh
$modResource->clearCache(false);

//В случае, если нет необходимости вызывать событие OnSiteRefresh
$modResource->clearCache(false, array(60, 59, 90, 91, 95));

//Будет вызвано событие OnSiteRefresh в которое дополнительно передастся список ID тех документов (<em>через параметр IDs</em>), кеш которых был сброшен.
$modResource->clearCache(true, array(60, 59, 90, 91, 95));
avatar
А Agel Nash под доклистер денег не собирал. Донатили уже после ;)
avatar
Я ж написал причину что в связи с жизненными обстоятельствами(в личной жизни) работать вообще не хочется. Надо себя хоть как то стимулировать:)
avatar
Вчера удалось по быстрому поиграться с кешем офф. сборки на реальном проекте. В общем ситуация следующая:
— Было бы здорово добавить вызов события (например, OnCheckWebPageCache) в метод DocumentParser::checkCache, чтобы через плагин на этом событии можно было подменить способ чтения данных из кеша. Ну и как следствие, доработать событие OnBeforeSaveWebPageCache, чтобы не только чтение, но и запись можно было переопределить. А чтобы картина была полной, то потребуется еще и событие OnFullClearCache в методе DocumentParser::clearCache(), которое срабатывать и в методе synccache::emptyCache()
— Вынести в настройки MODX галочку, которой определять необходимость создания $modx->documentMap. А так же, добавить к элементам (чанки/сниппеты) галочку которой определять складывать ли исходники в кеш или загружать код из базы. Правда потребуется доработка метода DocumentParser::getChunk(), чтобы при отсутствии данных выполнялась проверка наличия записи в базе данных (собственно код метода getChunk можно взять из CustomEvo). Отключать кеширование плагинов не стоит, т.к. событий в MODX много и с отключеным кешем это приведет к огромному числу лишних запросов.
— Удалить из штатного файла siteCache.idx.php переносы строк и лишние пробелы. Например, следующий код:

$tmpPHP .= '$this->aliasListing = array();' . "\n";
$tmpPHP .= '$a = &$this->aliasListing;' . "\n";
$tmpPHP .= '$d = &$this->documentListing;' . "\n";
$tmpPHP .= '$m = &$this->documentMap;' . "\n";
$tmpPHP .= '$a[' . $tmp1['id'] . ']' . " = array('id' => " . $tmp1['id'] . ", 'alias' => '" . $this->escapeSingleQuotes($tmp1['alias']) . "', 'path' => '" . $this->escapeSingleQuotes($tmpPath) . "', 'parent' => " . $tmp1['parent'] . ", 'isfolder' => " . $tmp1['isfolder'] . ");\n";

заменить на:

$tmpPHP .= '$this->aliasListing=array();';
$tmpPHP .= '$a=&$this->aliasListing;';
$tmpPHP .= '$d=&$this->documentListing;';
$tmpPHP .= '$m=&$this->documentMap;';
$tmpPHP .= '$a['.$tmp1['id'].']'."=array('id'=>".$tmp1['id'].",'alias'=>'".$this->escapeSingleQuotes($tmp1['alias'])."','path'=>'".$this->escapeSingleQuotes($tmpPath)."','parent'=>".$tmp1['parent'].",'isfolder'=>".$tmp1['isfolder'].");";

Это позволит уменьшит на несколько Кбайт (при штатных настройках) общий размер основного кеша, от чего легче станет и харду, и оперативной памяти при чтении кеша.

И главное — обернуть код класса synccache в проверку
if(!class_exists('synccache')){ .... }

Это позволит без особых заморочек подменить класс кешера уже сегодня. Аналогичную обертку было бы здорово добавить и к классу DocumentParser, но предварительно вынести из файла document.parser.class.inc.php код класса SystemEvent в другой файл, а сам DocumentParser переименовать в coreModx, например. В файле document.parser.class.inc.php оставить код в стиле
include_once("coreModx.class.php");
include_once("SystemEvent.class.php");
if(!class_exists('DocumentParser')){
 class DocumentParser extends coreModx{}
}

Таким образом, мы прямо в config.inc.php сможем подключить произвольный файл в котором будет объявлен DocumentParser класс и подменены методы/добавлены события при необходимости.
avatar
Основная проблема, насколько я понимаю, не в том, чтобы удалить кэш конкретной страницы (это можно сделать достаточно просто), а в том, что данная страница все равно останется в кэшированных вызовах сниппетов тех страниц, кэш которых мы не удалим :)
Т.е. удаление какой-нибудь новости, грубо говоря, вместе с кэшем конкретной страницы, не удаляет эту новость из кэшированного вызова сниппета на кэшированной странице «список новостей», а также из какого-нибудь сквозного блока «последние новости» (который вызван также кэшированным сниппетом и размещен на всех страницах сайта). Как с этим быть?
avatar
В этом случае, я при помощи MODxAPI в событие OnSiteRefresh передаю список ID тех документов, кеш которых был сброшен. Таким образом можно подключиться плагином к этому событию и дальше уже закладывать свою логику. Пройтись по списку ID, получить их родителей/шаблоны, ну и пытаться цепной реакцией вызвать очередной MODxAPI::clearCache() уже с новым набором документов.
avatar
Думаю, что кэш родительских документов стоит всегда сбрасывать на уровне ядра (удаляем кэш документа, кэш родительских удаляется автоматом). Это покроет подавляющее большинство проблем (следовательно, в ряде случаев вообще ни о чём заботиться дополнительно не придётся). Тем более, что родителей, как правило, не очень много, так что ресурсов особо не съест. Если всё же есть опасения по ресурсам, можно сделать параметрально (но чтобы по умолчанию кэш родителей удалялся конечно же).
avatar
Ну как, нашлись инвесторы в итоге?
avatar
Да, нашлись или нет?
Готов принять участие в донате, но хотелось бы знать, что есть «приятная сумма»? )
avatar
Неа все так же глухо:)
avatar
Ну, я пару раз по 500 р. с перерывом в неделю готов закинуть.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.