Динамические функции на замену фильтрам

Очередная модель от известного велосипедостроителя — меня.

Суть в следующем: заменить все фильтры в чанке на функции внутри сниппета, сделанного на 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.
Василий Наумкин
14 марта 2013, 18:36
modx.pro
3
2 348
0

Комментарии: 4

Евгений Борисов
14 марта 2013, 22:43
0
Как раз для DocLister'a думал как лучше сделать предварительную подготовку данных. Решение на ум примерно аналогичное пришло… Правда выглядит костыльней чем это. В общем как реализую — сравним;-)
    Василий Наумкин
    14 марта 2013, 22:46
    0
    Ну, у меня это для своего сниппета в проекте с нагруженными чанками.

    Возможно, попробую вставить это в pdoTools.
      Евгений Борисов
      14 марта 2013, 22:59
      0
      То есть, в какой-то компонент я это включать не буду — просто маленькая симпатичная хитрость.
      Я тоже в ядро зашивать не хочу. Поэтому в @TODO и написано OR extender.
      Вообще изначально я хотел чтобы все инструкции по предварительной обработке данных пользователь писал на чистом php. Потом пришло осознание, что это не каждый сможет и я так же как ты решил добавить поддержку сниппетов. Но потом подумал, что это принципиально ни чем не будет отличаться от вложенных вызовов. Тут и родилась идея с рефакторингом синтаксиса. Т.е. взять за основу родной синтаксис MODX и немного его модернизировать. Например, вместо [[Snippet? ¶m=`val`]] вызывать [{Snippet? ¶m=`val`]}. Или вообще даже сохранить оригинальный синтаксис, но в конечном счете отдавать не 30 одинаковых вызовов в ленте, а самостоятельно выполнить дублирующиеся вызовы и заранее заменить их на плейсхолдеры. В общем как сделаю — узнаешь об этом первым. И там будем уже детальней смотреть и выбирать какой подход лучше.
    Сергей Шлоков
    15 января 2016, 11:27
    0
    Не соображу, как использовать это в случае c pdoResources?
    [[!pdoResources? &tpl=`Чанк с условиями`]]
    Свой сниппет делать вместо pdoResources?
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      4