Динамические функции на замену фильтрам
Очередная модель от известного велосипедостроителя — меня.
Суть в следующем: заменить все фильтры в чанке на функции внутри сниппета, сделанного на pdoTools.
При этом, сами фильтры должны лежать как и раньше, сниппетами, а не быть жестко закодированы, чтобы их можно было удобно изменять и использовать также в в плагинах, или еще где.
Вместо обычного фильтра в чанке
Мы переносим фильтр в сниппет:
Таким образом, для n чанков сниппеты не вызывается n раз. Нет, они становятся функцией в памяти и оттуда работают гораздо быстрее.
А если у вас 10 товаров на странице и у каждого в чанке по 10 таких условий? Производительность вырастет весьма солидно.
При этом, если вы измените сниппет — ничего не сломается и вам не нужно будет бегать по 10 местам и править код.
На мой взгляд, интересный велосипед получился. Надо подумать, как сделать такую замену автоматически, в парсере pdoTools.
Суть в следующем: заменить все фильтры в чанке на функции внутри сниппета, сделанного на pdoTools.
При этом, сами фильтры должны лежать как и раньше, сниппетами, а не быть жестко закодированы, чтобы их можно было удобно изменять и использовать также в в плагинах, или еще где.
Вместо обычного фильтра в чанке
<div class="discount">[[+old_price:discount=`[[+price`]]</div>
[[+price:money_format]]
Мы переносим фильтр в сниппет:
// Тут идёт обычный вызов pdoTools с получением результатов из БД
.....
// Получаем сниппеты и создаём из них функции
if ($tmp = $modx->getObject('modSnippet', array('name' => 'discount'))) {
$discount = create_function('$input,$options', $tmp->getContent());
}
if ($tmp = $modx->getObject('modSnippet', array('name' => 'money_format'))) {
$money_format = create_function('$input', $tmp->getContent());
}
// Обрабатываем результаты в цикле
$output = null;
foreach ($rows as $k => $row) {
$row['discount'] = $discount($row['old_price'], $row['price']);
$row['price'] = $money_format($row['price']);
...
// и т.д.
Таким образом, для n чанков сниппеты не вызывается n раз. Нет, они становятся функцией в памяти и оттуда работают гораздо быстрее.
А если у вас 10 товаров на странице и у каждого в чанке по 10 таких условий? Производительность вырастет весьма солидно.
При этом, если вы измените сниппет — ничего не сломается и вам не нужно будет бегать по 10 местам и править код.
На мой взгляд, интересный велосипед получился. Надо подумать, как сделать такую замену автоматически, в парсере pdoTools.
Комментарии: 4
Как раз для DocLister'a думал как лучше сделать предварительную подготовку данных. Решение на ум примерно аналогичное пришло… Правда выглядит костыльней чем это. В общем как реализую — сравним;-)
Ну, у меня это для своего сниппета в проекте с нагруженными чанками.
Возможно, попробую вставить это в pdoTools.
Возможно, попробую вставить это в pdoTools.
То есть, в какой-то компонент я это включать не буду — просто маленькая симпатичная хитрость.Я тоже в ядро зашивать не хочу. Поэтому в @TODO и написано OR extender.
Вообще изначально я хотел чтобы все инструкции по предварительной обработке данных пользователь писал на чистом php. Потом пришло осознание, что это не каждый сможет и я так же как ты решил добавить поддержку сниппетов. Но потом подумал, что это принципиально ни чем не будет отличаться от вложенных вызовов. Тут и родилась идея с рефакторингом синтаксиса. Т.е. взять за основу родной синтаксис MODX и немного его модернизировать. Например, вместо [[Snippet? ¶m=`val`]] вызывать [{Snippet? ¶m=`val`]}. Или вообще даже сохранить оригинальный синтаксис, но в конечном счете отдавать не 30 одинаковых вызовов в ленте, а самостоятельно выполнить дублирующиеся вызовы и заранее заменить их на плейсхолдеры. В общем как сделаю — узнаешь об этом первым. И там будем уже детальней смотреть и выбирать какой подход лучше.
Не соображу, как использовать это в случае c pdoResources?
[[!pdoResources? &tpl=`Чанк с условиями`]]
Свой сниппет делать вместо pdoResources?
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.