Есть задача: сделать раздел вакансий, в котором у каждой вакансии 3 списка: требования, ответственность, условия. Конечно, менеджеру должно быть удобно и html теги он писать не собирается.
Использовать для этого TinyMCE не хочется - слишком просто в нем сломать верстку. Поэтому я решил использовать ТВ и выводить их в нужном мне виде простым сниппетом.
<?php
// Получаем или готовый текст, или достаем указанный ТВ у ресурса
$tv = !empty($input) ? trim($input) : trim($modx->resource->getTVValue($tv));
if (empty($tv)) {return '';}
// Стандартные чанки, можно переопределить
if (empty($tpl)) {$tpl = '@INLINE <li>[[+value]]</li>';}
if (empty($tplOuter)) {$tplOuter = '@INLINE <ul>[[+rows]]</ul>';}
// Подключаем pdoTools для работы с инлайновыми чанками
$pdo = $modx->getService('pdoTools');
// Разбиваем текст по символу переноса строки
$rows = '';
$tmp = array_map('trim', explode("\n", $tv));
foreach ($tmp as $value) {
if (empty($value)) {continue;}
$rows .= $pdo->getChunk($tpl, array('value' => $value));
}
// Если есть, что выводить - выводим
if (!empty($rows)) {
return $pdo->getChunk($tplOuter, array('rows' => $rows));
}
Хочется отметить ровно одну инновацию (возможно, только для меня) - отказ от разделителя в ТВ. Работа ведется по символу переноса строки "\n". Конечно, менеджеру гораздо удобнее нажать enter, чем вспоминать про "||".
Ну и понятно, что если ТВ не заполнен, то чанк-обертка выводиться не будет. Использовать такой сниппет значительно удобнее и быстрее, чем фильтр [[+tv.requirements:notempty=...
]].
Вызываем в чанке pdoResources:
[[getTVlist?
&input=`[[+tv.requirements]]`
&tplOuter=`@INLINE <h4>Требования</h4><ul>[[+rows]]</ul>`
]]
На странице вакансии:
[[getTVlist?
&tv=`requirements`
&tplOuter=`@INLINE <h4>Требования</h4><ul>[[+rows]]</ul>`
]]
Конечно, можно заранее прописать наборы параметров и вызывать вот так:
[[getTVlist@Req]]
Вот такой маленький и удобный сниппет.
БонусПолучение ТВ с оборачиванием в чанк. Это просто замена фильтру notempty, сниппет getTV:
<?php
$tv = !empty($input) ? trim($input) : trim($modx->resource->getTVValue($tv));
if (empty($tplOuter)) {$tplOuter = '<b>Название параметра</b>[[+value]]';}
if (!empty($tv)) {
$pdo = $modx->getService('pdoTools');
return $pdo->getChunk($tplOuter, array('value' => $tv));
}
Только на днях сделал примерно такой же сниппит, правда получилось более уродливо и без чанков, использовал его для одного из полей в minishop2.
Я думаю что удобнее сделать так
А быстрее сниппетом. Ради эксперимента попробовал оба варианта - у меня выигрыш в 5 тысячных секунды. По моему несущественно.
nl2br - это замена переноса строк на br, а не на li.
Вывести фильтрами с таким оформлением, как мне было нужно, просто не получится.
можно сделать свой фильтр nl2li, мне просто было лень делать. :) что то типа такого:
И в чем теперь отличие от сниппета?
В том, что нельзя поменять оформление прямо при вызове? Не могу назвать это удобством, учитывая, что у меня много где нужно так выводить данные.
К примеру, вот:
Ну и мой сниппет тоже можно использовать как фильтр - он смотрит в input.
Отличия - вызывать сниппет или фильтр. На самом деле все зависит от стоящей задачи. Для единоразового решения мне удобнее использовать фильтры, и просто лень писать больше кода чем это необходимо,
Кстати Василий, есть еще вариант сделать Custom TV Output Type, в котором можно сразу задавать оформление. Это наверное будет самым универсальным и удобным способом.
Обрати внимание на вот эту строку:
Видишь, сниппет проверяет $input - а значит, может работать как фильтр.
Custom TV Output Type - не мое. Сниппет на php умеет больше и работает быстрее.
В этой строке ошибка с двойным слешем.
Сделал то же самое, используя Jevix:
Новая строка обозначает элемент списка (li) и может начинаться с дефиса или звёздочки — они будут вырезаны, а на выходе оформлены через css (list-style-image: url(…);): http://www.bvmedia.ru/vacancy/4869