Как сделать вложенные TV MIGx и как это потом вывести с помощью fenom
Доброе утро сообщество!
Сегодня у меня день рождения, а значит замечательный день чтобы написать новую заметку =)
Итак, буквально недавно столкнулся с задачей вывести несколько аккордеонов подряд, причем каждый их которых должен иметь собственный заголовок. Решено для этого было использовать вложенные TV типа MIGx. Подробности под катом.На моём примере использовалось 2 уровня вложенности. То есть внутри одного TV был вложен только один TV. Но я не исключаю, что можно сколько угодно больше уровней вложенности делать, просто пока не проверял. Далее по порядку:
Сегодня у меня день рождения, а значит замечательный день чтобы написать новую заметку =)
Итак, буквально недавно столкнулся с задачей вывести несколько аккордеонов подряд, причем каждый их которых должен иметь собственный заголовок. Решено для этого было использовать вложенные TV типа MIGx. Подробности под катом.
- Создаем MIGx конфигурацию AccordionItems, тот что на втором уровне.
Показываю в редакторе MIGx полей для понимания:
- Далее настроил форму, причем в поле description в качестве inputTV можно было ничего не указывать, я указал созданный заранее простой TV с визуальным редактором TinyMCE чтобы было удобно наполнять текстом. Если бы не указал, то было бы простое текстовое поле:
- И колонки, тут все просто:
- После чего создаем TV поле одноименное, с указанием типа MIGx и имени его конфигурации AccordionItems.
- Следующим этапом идет создание MIGx конфигурации AccordionSections тут все по аналогии, но только в поле inputTV мы уже указываем TV AccordionItems:
- После чего создаем TV поле одноименное, с указанием типа MIGx и имени его конфигурации AccordionSections.
- Ну а напоследок самое интересное, на мой взгляд создаем чанк который бы выводил аккордеоны с заголовками, причем нужно было чтобы редактировались данные в одном месте, в данном случае в одном ресурсе, а выводилось одни и те же секции везде где будет вставлен чанк.
Ниже код чанка и затем пояснение по некоторым моментам:
{if $_modx->resource.id == '832'?} <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> {foreach ($_modx->resource.AccordionSections | fromJSON) as $AccordionSection} {var $sectionIds = $AccordionSection.MIGX_id} <p class="accordion-section-title">{$AccordionSection.sectionTitle}</p> {foreach ($AccordionSection.sectionContent | fromJSON) as $AccordionItem} <div class="panel panel-default"> {var $accordionIds = $AccordionItem.MIGX_id} <div class="panel-heading" role="tab" id="h{$sectionIds}-{$accordionIds}"> <h4 class="panel-title"> <a role="button" data-toggle="collapse" data-parent="#accordion" href="#c{$sectionIds}-{$accordionIds}" aria-expanded="true" aria-controls="c{$sectionIds}-{$accordionIds}"> <i class="more-less glyphicon glyphicon-plus"></i> <span class="accordion-section-header">{$AccordionItem.title}</span> </a> </h4> </div> <div id="c{$sectionIds}-{$accordionIds}" class="panel-collapse collapse" role="tabpane{$sectionIds}-{$accordionIds}" aria-labelledby="h{$sectionIds}-{$accordionIds}"> <div class="panel-body"> {$AccordionItem.description} </div> </div> </div> {/foreach} {/foreach} </div><!-- panel-group --> {else} <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> {var $otherAccSections = 832 | resource : 'AccordionSections'} {foreach ($otherAccSections | fromJSON) as $AccordionSection} {var $sectionIds = $AccordionSection.MIGX_id} <p class="accordion-section-title">{$AccordionSection.sectionTitle}</p> {foreach ($AccordionSection.sectionContent | fromJSON) as $AccordionItem} <div class="panel panel-default"> {var $accordionIds = $AccordionItem.MIGX_id} <div class="panel-heading" role="tab" id="h{$sectionIds}-{$accordionIds}"> <h4 class="panel-title"> <a role="button" data-toggle="collapse" data-parent="#accordion" href="#c{$sectionIds}-{$accordionIds}" aria-expanded="true" aria-controls="c{$sectionIds}-{$accordionIds}"> <i class="more-less glyphicon glyphicon-plus"></i> <span class="accordion-section-header">{$AccordionItem.title}</span> </a> </h4> </div> <div id="c{$sectionIds}-{$accordionIds}" class="panel-collapse collapse" role="tabpane{$sectionIds}-{$accordionIds}" aria-labelledby="h{$sectionIds}-{$accordionIds}"> <div class="panel-body"> {$AccordionItem.description} </div> </div> </div> {/foreach} {/foreach} </div> {/if}
- Для вывода данных используется простой разбор полей с помощью foreach
- Для того чтобы секции аккордеона имели уникальные уникальные css классы и айди использовались поля MIGx конфигураций MIGX_id и создавались переменные для того чтобы не запутаться в коде.
- В чанке условие, если айди ресурса тот для которого изначально создавалось TV поле с аккордеоном, то код имеет вид наподобие
, если ресурс имеет любой другой айди то в коде указывается айди и поля ресурса которые нужно разобрать{$_modx->resource.AccordionSections}
{832 | resource : 'AccordionSections'}
- При разборе полей TV уровня, то есть AccordionSections когда доходим до поля sectionContent, производим еще один разбор этого поля как TV типа MIGx ведь оно в себе как раз и содержит вложенный TV второго уровня, то есть AccordionItems
Комментарии: 8
Замудрил конечно) Все делается намного проще если сразу код migx указывать в tv поле.
id получить тоже можно гораздо проще.
id получить тоже можно гораздо проще.
{foreach ($AccordionSection.sectionContent | fromJSON) as $idx => $AccordionItem}
в $idx будет id нужный
Я на счёт этого промолчал, хотя и вот это тоже мне не понятно, думал, что еще кого-то обижу (много людей сейчас обижаются):
Зачем засовывать в переменную что-то, если в этом нет необходимости, разве что для удобство…
{var $accordionIds = $AccordionItem.MIGX_id}
Зачем засовывать в переменную что-то, если в этом нет необходимости, разве что для удобство…
мне так удобнее было, не знаю какие обиды.
Да я то не про вас лично :), тем более я так и написал:
разве что для удобствА…
Сразу извиняюсь, просто если раньше нужно было так делать, то сейчас можно и попроще и без лишних TV
1)
TV создавать бессмысленно, так как есть Input TV type в котором нужно указывать тип поля, т.е. достаточно указать richtext и всё. Результат: Тот же, зато нет лишнего TV.
2)
Это из той же оперы, зачем создавать TV, если есть Input TV type и Configs которому в json формате можно передать все параметры, т.е. можно например так:
Input TV type указать number и передать ему что-то типа:
В вашем же случае нужно так:
Фотография кликабельна
Спасибо за внимание!
1)
Далее настроил форму, причем в поле description в качестве inputTV можно было ничего не указывать, я указал созданный заранее простой TV с визуальным редактором TinyMCE чтобы было удобно наполнять текстом. Если бы не указал, то было бы простое текстовое поле:
TV создавать бессмысленно, так как есть Input TV type в котором нужно указывать тип поля, т.е. достаточно указать richtext и всё. Результат: Тот же, зато нет лишнего TV.
2)
После чего создаем TV поле одноименное, с указанием типа MIGx и имени его конфигурации AccordionItems.
Это из той же оперы, зачем создавать TV, если есть Input TV type и Configs которому в json формате можно передать все параметры, т.е. можно например так:
Input TV type указать number и передать ему что-то типа:
{
"allowDecimals":"No",
"allowNegative":"No"
}
т.е. здесь я вместо того чтобы создавать лишний TV с типом ввода «Число», где «Разрешить десятичные» и «Разрешить минус» поставил бы «Нет» и данный TV у меня просто бы висел в админке и в БД так и не пригодившись, я указываю MIGX-у.В вашем же случае нужно так:
Фотография кликабельна
Спасибо за внимание!
в данном случае в конфиге не нужен json — достаточно просто указать AccordionItems. JSON нужен только для полей, отличных от migx
Спасибо за конструктивную критику и разъяснения. Решение сам искал, не знал что можно было сделать иначе)
А если бы статью не написал, то и не узнал бы) и другие тоже почитают комменты и что-то для себя вынесут (я, например, тоже новое прочитал).
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.