Вывод ТВ со своим оформлением

Есть задача: сделать раздел вакансий, в котором у каждой вакансии 3 списка: требования, ответственность, условия. Конечно, менеджеру должно быть удобно и html теги он писать не собирается.

Использовать для этого TinyMCE не хочется - слишком просто в нем сломать верстку. Поэтому я решил использовать ТВ и выводить их в нужном мне виде простым сниппетом.

**Сниппет getTVlist**
<?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));
}
← Предыдущая заметка
Переключение контекстов в зависимости от URL
Следующая заметка →
Плоское меню из категорий товаров
Комментарии (9)
Сергей
29.10.2013 21:54

Только на днях сделал примерно такой же сниппит, правда получилось более уродливо и без чанков, использовал его для одного из полей в minishop2.


<?php
$tracks =  $scriptProperties['tracks'];
$tracks_array = explode("\n", $tracks);
if(count($tracks_array) == 1 && empty($tracks_array[0])) return;
$result = '<ol>';
foreach($tracks_array as $track) {
    $result .= '<li>'.$track.'</li>';
}
$result .= '</ol>';

return $result;
De-RibaskinDe Ribaskin
30.10.2013 02:02

Ну и понятно, что если ТВ не заполнен, то чанк-обертка выводиться не будет. Использовать такой сниппет значительно удобнее и быстрее, чем фильтр [[+tv.requirements:notempty=...]].

Я думаю что удобнее сделать так

[[*mytv1:notempty=`<h4>Требования</h4><ul>[[*mytv1:nl2br]]</ul>`]]
[[*mytv2:notempty=`<h4>Ответственность</h4><ul>[[*mytv2:nl2br]]</ul>`]]
[[*mytv3:notempty=`<h4>Условия</h4><ul>[[*mytv3:nl2br]]</ul>`]]

А быстрее сниппетом. Ради эксперимента попробовал оба варианта - у меня выигрыш в 5 тысячных секунды. По моему несущественно.

bezumkinВасилий Наумкин
30.10.2013 08:26

nl2br - это замена переноса строк на br, а не на li.

Вывести фильтрами с таким оформлением, как мне было нужно, просто не получится.

De-RibaskinDe Ribaskin
30.10.2013 10:51

можно сделать свой фильтр nl2li, мне просто было лень делать. :) что то типа такого:

$li = explode("\n", $input);
foreach ($li as $value) {
    if (empty($value)) {continue;}
    $li .= '<li>'.$value.'</li>';
}
return $li;
bezumkinВасилий Наумкин
30.10.2013 10:57

И в чем теперь отличие от сниппета?

В том, что нельзя поменять оформление прямо при вызове? Не могу назвать это удобством, учитывая, что у меня много где нужно так выводить данные.

К примеру, вот:

Ну и мой сниппет тоже можно использовать как фильтр - он смотрит в input.

De-RibaskinDe Ribaskin
30.10.2013 11:24

Отличия - вызывать сниппет или фильтр. На самом деле все зависит от стоящей задачи. Для единоразового решения мне удобнее использовать фильтры, и просто лень писать больше кода чем это необходимо,

Кстати Василий, есть еще вариант сделать Custom TV Output Type, в котором можно сразу задавать оформление. Это наверное будет самым универсальным и удобным способом.

bezumkinВасилий Наумкин
30.10.2013 11:33

Обрати внимание на вот эту строку:

$tv = !empty($input) ? trim($input) : trim($modx->resource->getTVValue($tv));

Видишь, сниппет проверяет $input - а значит, может работать как фильтр.

Custom TV Output Type - не мое. Сниппет на php умеет больше и работает быстрее.

De-RibaskinDe Ribaskin
07.02.2014 13:38
$tmp = array_map('trim', explode("\\n", $tv));

В этой строке ошибка с двойным слешем.

RealetiveГанин Роман
07.02.2014 14:07

Сделал то же самое, используя Jevix:


[[Jevix?
   &input=`[[*ваш_TV]]`
   &cfgAllowTags=`a,sup`
   &cfgSetAutoBrMode=`0`
   &cfgSetTagNoAutoBr=`li`
   &cfgSetTagBlockType=`li`
   &cfgSetAutoPregReplace=`[["/^[-*]?(.+)$/im"],["<li>$1"]]`
   &logErrors=`0`
]]

Новая строка обозначает элемент списка (li) и может начинаться с дефиса или звёздочки — они будут вырезаны, а на выходе оформлены через css (list-style-image: url(…);): http://www.bvmedia.ru/vacancy/4869

bezumkin
Василий Наумкин
09.04.2024 01:45
Ошибка 500 Это не похоже на ошибку Nginx, это скорее всего ошибка PHP - надо смотреть его логи. Во...
futuris
Futuris
04.04.2024 05:56
Я просто немного запутался. Когда в абзаце &quot;Vesp/Core&quot; ты пишешь про &quot;новый trait Fil...
bezumkin
Василий Наумкин
20.03.2024 18:21
Volledig!
Андрей
14.03.2024 10:47
Василий! Как всегда очень круто! Моё почтение!
russelgal
russel gal
09.03.2024 17:17
А этот стоило написать хотя бы затем, чтобы получить комментарий от юзера, который ничего не писал ...
inetlover
Александр Наумов
27.01.2024 00:06
Василий, спасибо! Извини, тупанул.
bezumkin
Василий Наумкин
22.01.2024 04:43
Давай-давай!
bezumkin
Василий Наумкин
24.12.2023 11:26
Спасибо!
bezumkin
Василий Наумкин
27.11.2023 02:43
Ура!
bezumkin
Василий Наумкин
25.11.2023 08:30
Vesp тянет 2 зависимости: vesp-frontent для фронта и vesp-core для бэкенда. Их можно обновлять, но э...