Сниппеты pdoTools работают очень круто за счет двух основных преимуществ:
1. Запросы в БД через PDO.
2. Собственный метод обработки чанков.
С первым всё понятно, а вот про второе надо рассказать.
Как работает парсер MODX Revolution
При запуске метода modX::getChunk, движок получает его содержимое и собирает в нём свои теги, регулярным выражением. Далее, он определяет класс каждого тега и создаёт его объект, после чего запускает метод process.Да, для каждого тега создаётся объект и запускается процессинг.
Это довольно медленно, но позволяет нам творить чудеса с фильтрами, вложенными параметрами и прочим, за что мы так любим MODX. Чем меньше вы используете эти прелести, тем быстрее будет работать вывод чанков.
Как работает парсер pdoTools
В pdoTools есть свой собственный метод pdoTools::getChunk, который работает несколько иначе:1. При первом запуске получает и кэширует чанк в ОЗУ.
2. Заменяет все возможные плеёсхолдеры быстрой функцией str_replace(). Если плейсхолдер указан с фильтрами или другими параметрами — он пропускается.
3. И вот дальше возможно 2 варианта, зависят от параметра fastMode:
3а. fastMode = 1. Все необработанные плейсхолдеры вырезаются. Максимальная скорость, магия MODX не работает.
3b. fastMode = 0. Запускается парсер MODX для процессинга оставшихся тегов. Обрабатывается только то, что не вышло подставить данными из БД. А это гораааздо меньший объём работы.
То есть, при любом раскладе pdoTools быстрее обработает чанк. Однако, я добавил еще возможность указывать «вложенные чанки».
Мой велосипед вложенных чанков
Что это такое? Это специальные участки кода, которые мой getChunk видит, и вырезает в специальную заначку для последующего использования вашим сниппетом.Вот пример такого чанка:
<div class="section"> ... <i class="icon black icon-comment"></i> [[+comments]] [[+new_comments]]</a></div> ... </div> <!--ticket_new_comments <span class="green">+[[+new_comments]]</span>-->Здесь вы видите внизу закомментированный кусок, который начинается с префикса ticket_ (префикс настраивается). При первой загрузке чанка pdoTools выделит этот кусок и сохранит себе в pdoTools::elements[имя чанка]['placeholders']['new_comments'].
Смекаете? Дальше вашему сниппету останется организовать логику и подставить значение в плейсхолдер, который находится в нзакомментированной части (там он без префикса). Внимание, в версии 1.2.0 это уже автоматизировано!
Например, вот так:
... $v['new_comments'] = $modx->getCount('TicketComment', $q); } if (!empty($pdoFetch->elements[$tpl]['placeholders']['new_comments']) && !empty($v['new_comments'])) { $pl = $pdoFetch->makePlaceholders(array('new_comments' => $v['new_comments'])); $v['new_comments'] = str_replace($pl['pl'], $pl['vl'], $pdoFetch->elements[$tpl]['placeholders']['new_comments']); } else {$v['new_comments']= '';}
Таким образом, мы сделали вывод непрочитанных комментариев без фильтра, на чистом php. Это, опять же, гораздо быстрее.
Кстати, теги лексикона [[%key]] тоже обрабатываются по ускоренной схеме, если указаны без параметров и загружен нужный лексикон. Тогда все [[%key]] заменяются на результат работы $modx->lexicon($key).
Выглядит сложно, но это и не каждому надо. А если немного разобраться в теме, так и ничего сложного.
Преимущества:
— В одном чанке можно хранить кучу блоков, которые будут отображаться в зависимости от условий в php.
— Повышенная скорость из-за отсутствия фильтров.
— Экономия на обработке тегов лексикона, если они указаны без параметров.
Вообще, pdoTools рассчитан на программистов, которым нужен лёгкий и удобный инструмент. Кстати говоря, подобные фокусы я делал еще в Evolution, но оно было не так красиво и универсально, как в pdoTools.
Тесты
Вот черновой чанк от miniShop2, для вывода каталога:<div class="row ms2_product"> <div class="span2">[[+thumb:notempty=`<img src="[[+thumb]]" width="120" height="90" />`]]</div> <div class="row span10"> <p><a href="[[~[[+id]]]]">[[+pagetitle]]</a> <span class="price">[[+price]] [[%ms2_frontend_currency]]</span> [[+old_price:gt=`0`:then=`<span class="old_price">[[+old_price]] [[%ms2_frontend_currency]]</span>`:else=``]] [[+tags:notempty=`<span class="tags">[[%ms2_frontend_tags]]: [[+tags]];</span>`]] [[+color:notempty=`<span class="color">[[%ms2_frontend_color]]: [[+color]];</span>`]] [[+size:notempty=`<span class="size">[[%ms2_frontend_size]]: [[+size]];</span>`]] </p> <p><small>[[+introtext]]</small></p> <a href="#" class="ms2_link" data-action="add" data-params='{"id":[[+id]],"count":1}'><i class="icon-barcode"></i> [[%ms2_frontend_add_to_cart]]</a> [[%ms2_frontend_add_to_cart?namespace=`minishop2`]] </div> </div> <!--minishop2_tags , [[+value]]--> <!--minishop2_color , [[+value]]--> <!--minishop2_size , [[+value]]-->
Как видите, просто куча условий и тегов лексикона. Вложенные чанки еще и обрабатываются в цикле, ибо теги, цвета и размер в MS2 — это массивы.
Пользуемся встроенным логером pdoTools, (который считает время, на каждую операцию) и наблюдаем разницу при использовании getChunk от MODX и pdoTools.
pdoTools fastMode=0 0.0474360: Returning processed chunks 0.0709820: Total time MODX 0.1156840: Returning processed chunks 0.1395649: Total time
И это при выводе всего 10 товаров. Разница в 2 раза на одной обработке чанков, с одинаковым результатом.
Если вы сможете обойтись вообще без сложных тегов MODX (например, заменив [[~[[+id]]]] на [[+uri]] и т.п.), то можно включить fastMode:
pdoTools fastMode=1 0.0108371: Returning processed chunks 0.0233843: Total timeК примеру, комментарии в Tickets так и выводятся.
← Следующая заметка
miniShop2 вышел
miniShop2 вышел
Предыдущая заметка →
Tickets 0.9.1 beta
Tickets 0.9.1 beta
Жду не дождусь, когда построю свой репозиторий с магазином.
Извиняюсь, что пишу про них просто в виду плясок с бубном по поводу плагинов я грохнул тестовый сайт на котором у меня крутилась работа последних полутора месяцев и теперь пытаюсь собрать что то покусочкам, а пакетов нет
Надеюсь, завтра всё будет ок. Если не будет — выложу тут.
В чанке myProduct.content ( не много изменённый msProduct.content ) дописал:
Но ничего не выводится. В чём может быть прокол?
На сколько я понимаю — нет.
Изначально я пробовал делать так:
И выводились значения из БД: 230 0 1 (цена, популярный товар, новый товар ). То есть извлечение данных с помощью pdoTools уже есть.
Я так понял, что подстановка значений в плейсхолдер осуществляется автоматически при парсинге чанка если данные извлекаются с помощью pdoTools и код в сниппете самому писать не надо. (так как в этой статье написано «Внимание, в версии 1.2.0 это уже автоматизировано!»).
Получается я в чанке itemContent вызываю этот сниппет, а сниппет вызывает чанк myProduct.content. Сделал я это в расчёте на то, что при вызове чанка с помощью pdoTools он автоматически подставит специальные плейсхолдеры.
Но этого не произошло, всё выводится как раньше просто значениями из БД. Очевидно, я не догоняю в чём ошибка.
1. Нужно передать массив с данными в getChunk
2. Нужно префикс указать, по умолчанию он pdotools_.
Насчёт первого пункта:
В обычных условиях если, например, данные выводятся с помощью сниппета msProduct — я могу отследить и редактировать все данные поступающие в чанк просто посмотрев код сниппета. Но здесь вывод через tpl.msProduct.content и я в упор не понимаю откуда этот чанк берёт данные. В нём поидее уже есть все нужные данные:
[[+old_price]], [[+new]] и [[+popular]]. Они выводятся на странице.
То есть я не понимаю чем этот чанк обрабатывается, просто указываешь чанк в коде и он выводит информацию, а как она там появляется я не вижу потому что нет сниппета типа msProductContent или чего то подобного. Я понимаю, что туплю и скорее всего ответ у меня под носом, но уже проковырялся долго и не нашёл.
Сейчас попробую установить префикс
upd.: не помогло. Ну ладно, решил всё стандартными фильтрами чанков. В целях экономии времени. Потом вернусь к этому, надо разбираться с pdoTools и вообще поглубже покапаться в справке MODx.
Тут нет, и не должно быть pdoTools. Чанк просто вызывается на странице товара, отсюда и его название.
Значит надо извлечь данные самостоятельно с помощью pdoTools, а я всё пытался из готовых данных состряпать пирожок.
подскажите где это прописать. Спасибо.
Если что-то не так написал, подскажите, пожалуйста, что и куда прописать…
Возможно, это ограничения на хостинге, лично я ни разу такую ошибку в MySql не ловил за всю свою практику.