Сниппет для вывода всех TV параметров ресурса

Всем привет,
долгое время занимаюсь сайтами на MODx, но в большинстве случаев все сводится к верстке и настройке всех сниппетов, без написания чего-либо.

Часто сталкиваюсь с задачей вывода TV параметров и их заголовков. Для текущей задачи встал вопрос разделения всех полей еще и на блоки-категории.


— Категория 1
— — Поле 1: Содержимое поля 1
— — Поле 2: Содержимое поля 2

— Категория 2
— — Поле 3: Содержимое поля 3
— -Поле 4: Содержимое поля 4

Как бы в шаблоне это делается без проблем, но тогда придется вписывать каждое поле ручками, в нужный блок. Это удобно для разработчика, но неприемлемо для заказчика, а сидеть и добавлять по одному полю, менять его заголовок или переносить поля в разные категории и так далее когда у заказчика что-то там засвербит или он прочитает очередную статью по А/Б тестированию, ну вообще нервов не хватит.

В итоге, вооружившись гуглом, родился небольшой сниппет, выводящий список TV разделенных на категории.
Я уверен что есть варианты получше, код почище и алгоритм логичнее, но мои знания ограничены echo «пыщь-пыщь», Посему буду признателен за конструктивную критику и наставление на путь истинный.

Выложил на гитхаб (не судите строго, с ним я тоже не знаком)

Описание:
Сниппет выводит все TV значения для текущего ресурса

Свойства:

&tplWrapper — внешняя обертка
По умолчанию:
@INLINE  <ul>[[+fieldsResult]]</ul>

&tplCat — чанк для категории с её полями
По умолчанию:
@INLINE  <li><h4>[[+category]]</h4> <ul>[[+rows]]</ul></li>

Доступные поля:
[[+category]] — Наименование категории
[[+rows]] — массив всех полей

&tplRow чанк для одного ряда полей
По умолчанию:
@INLINE <li>[[+name]]: [[+caption]] - [[+value]]</li>

Доступные поля:

[[+id]] — id TV
[[+default]] — значение TV по умолчанию
[[+description]] — описание TV поля
[[+name]] — имя TV (как храниться в базе данных)
[[+value]] — значение TV
[[+caption]] — заголовок TV

Параметры:

&id — id ресурса, по умолчанию берется текущий документ
&includeTv — список id необходимых TV полей через запятую
&excludeTv — список id TV полей через запятую? которые НЕ надо выводить
&includeCat — список id необходимых категорий через запятую (категории и её поля)
&excludeCat — список id категорий через запятую, которые НЕ надо выводить (категории и её поля)

При установленном pdoTools ПОДДЕРЖИВАЕТ INLINE чанки, без него — НЕ поддерживает, только tpl

ИСПОЛЬЗОВАНИЕ:

[[!showTvList?     
       &excludeTv = `1,2` 
       &includeTv = `4,3` 
       &tplWrapper = `tpl.fieldsWrapper`
       &tplCat = `tpl.fieldsCat`
       &tplRow = `tpl.fieldsRow`
    ]]

Код сниппета:
<?php
if (empty($tplWrapper)) {$tplWrapper = '@INLINE  <ul>[[+fieldsResult]]</ul>';}
if (empty($tplCat)) {$tplCat = '@INLINE  <li><h4>[[+category]]</h4> <ul>[[+rows]]</ul></li>';}
if (empty($tplRow)) {$tplRow = '@INLINE  <li>[[+name]]: [[+caption]] - [[+value]]</li>';}
if (!empty($excludeTv)) { $excludeTv = explode(",", $excludeTv); } 
if (!empty($includeTv)) { $includeTv = explode(",", $includeTv); } 
if (!empty($excludeCat)) { $excludeCat = explode(",", $excludeCat); }  
if (!empty($includeCat)) { $includeCat = explode(",", $includeCat); } 
if (empty($id)) { $id = $modx->resource->get('id'); } 

// подключаем pdoTools для работы INLINE чанков 
if (file_exists(MODX_CORE_PATH . 'components/pdotools')) {
    $pdoTools = $modx->getService('pdoTools');
}
  
$outputRow = '';
$outputCat = '';
$tvs = array(); 

$tv_query = $modx->newQuery('modTemplateVarResource');
$tv_query->leftJoin('modTemplateVar','modTemplateVar',array("modTemplateVar.id = modTemplateVarResource.tmplvarid"));
$tv_query->leftJoin('modCategory','modCategory',array("modCategory.id = modTemplateVar.category"));
$tv_query->leftJoin('modTemplateVarTemplate','modTemplateVarTemplate',array("modTemplateVarTemplate.tmplvarid = modTemplateVarResource.tmplvarid"));

$tv_query->where(array( 'contentid'=>$id ));
    
if($excludeTv)  { $tv_query->where(array( 'tmplvarid:NOT IN'=> $excludeTv )); }
if($excludeCat)  { $tv_query->where(array( 'modTemplateVar.category:NOT IN'=> $excludeCat )); }
if( $includeTv[0] > 0 )  { $tv_query->where(array( 'tmplvarid:IN' => $includeTv )); }
if( $includeCat[0] > 0 ) { $tv_query->where(array( 'modTemplateVar.category:IN' => $includeCat )); }

$tv_query->sortby('modCategory.id','ASC');
$tv_query->sortby('modTemplateVarTemplate.rank','ASC');
$tv_query->select($modx->getSelectColumns('modTemplateVarResource','modTemplateVarResource','',array('id','tmplvarid','contentid','value')));
$tv_query->select($modx->getSelectColumns('modTemplateVar','modTemplateVar','',array('id', 'name', 'caption', 'default_text', 'description')));
$tv_query->select($modx->getSelectColumns('modCategory','modCategory','',array('category')));

$tvars = $modx->getCollection('modTemplateVarResource',$tv_query);

$arrTvs = array();

foreach ($tvars as $tvar) {
    $tvar = $tvar->toArray();
    
    if (!empty($tvar['value'])){ 
        $arrTvs[$tvar['category']][] = array(
            "value" =>$tvar['value'], 
            "caption"=> $tvar['caption'], 
            "name"=> $tvar['name'], 
            "id"=> $tvar['id'], 
            "default"=> $tvar['default_text'],
            "description"=> $tvar['description']
        );
    } 
    
} // foreach

foreach($arrTvs as $category=>$fields){
    
    $outputRow = '';
    
    foreach($fields as $field){ 
        
        if($pdoTools){ 
            $outputRow .= $pdoTools->getChunk( $tplRow , array(
                'id' => $field['id'],
                'caption' => $field['caption'],
                'name' => $field['name'],
                'value' => $field['value'],
                'description' => $field['description'],
                'default' => $field['default']
            ));
        }
        else{
            $outputRow .= $modx->getChunk( $tplRow , array(
                'id' => $field['id'],
                'caption' => $field['caption'],
                'name' => $field['name'],
                'value' => $field['value'],
                'description' => $field['description'],
                'default' => $field['default']
            )); 
            
        }
            
    } // foreach
    
    
    if($pdoTools){ 
        $outputCat .= $pdoTools->getChunk( $tplCat , array(
            'category' =>  $category,
            'rows' => $outputRow 
        ));
    }
    else{
        $outputCat .= $modx->getChunk( $tplCat , array(
            'category' =>  $category,
            'rows' => $outputRow 
        )); 
    }
    
} // foreach
 

if($pdoTools){ 
    $result =  $pdoTools->getChunk( $tplWrapper , array(
       'fieldsResult' => $outputCat
    )); 
}
else{
    $result =  $modx->getChunk( $tplWrapper , array(
       'fieldsResult' => $outputCat
    )); 
}

return $result;
Евгений Webinmd
25 июня 2015, 19:08
modx.pro
15
7 451
+5

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

Михаил Божко
25 июня 2015, 23:06
0
Вот это
$id = $modx->resource->get('id');
по-моему лишний запрос к базе, лучше так
$id = $modx->resource->id;
    Евгений Webinmd
    25 июня 2015, 23:33
    0
    Спасибо, поищу, потестирую
      Воеводский Михаил
      26 июня 2015, 09:31
      +1
      Посмотрите на метод xPDOObject::get() — он не генерирует запросы к базе, а выдает данные в нужном формате.
      $modx->resource->id — такого может и не быть в теории, так как создание общедоступных свойств с названиями полей из БД задается отдельной опции и, соответственно, может быть отключено.
      Andrey
      29 июня 2015, 12:39
      0
      Спасибо Евгений, как раз на днях подумал что мне такая штука нужна :) а тут раз и готово) может выложите в modstore?
        Евгений Webinmd
        29 июня 2015, 12:46
        0
        не умею собирать пакеты чисто с сниппетом и чанками, я верстальщик)) Если кто возьмется, то на здоровье.
        А если научит, то вообще молодец))
      Влад
      20 марта 2016, 15:50
      0
      То что искал!!!
      Есть пожелание:
      &includeCat выводить только те TV, которые есть непосредственно в данной категории. Было бы здорово, чтобы была настройка, которая так же выводит все TV из подкатегорий.
        Дмитрий
        04 мая 2017, 20:50
        0
        Полезный сниппет! Спасибо вам большое!
        Пригодилось для формирования json ресурсов.
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        10