Наверх

Как избавиться от большого количества шаблонов в MODX

Обычно сайт состоит из нескольких разделов, у которых одинаковая шапка и футер, но различается контентная часть. Причём различия эти могут быть существенными — например, в блоге нужно выводить дочерние ресурсы в виде заголовка и аннотации, а в портфолио — в виде большых превьюшек:



Мне никогда не нравилось создавать несколько шаблонов для того, чтобы настроить такое отображение. Хотя, конечно, это логичное решение. Но в MODX выбор шаблона остаётся на откуп контент-менеджера. Поэтому возникает путаница. Кроме того клиенты начинают спрашивать «Я создал новый ресурс, а вместо текста отображается что-то другое». Чтобы такого избежать приходится настраивать, например, автоматический выбор шаблона (при создании статей или проектов в портфолио).

Одним из решений этой проблемы может быть вот такой чанк контентной части шаблона:
{var $default_content = true}

<!-- Проверяем ID ресурса -->
{switch $_modx->resource.id}
    {case 1}
        {include 'content_main'}
        {var $default_content = false}
    {case 10}
        {include 'content_about'}
        {var $default_content = false}
    {case 28}
        {include 'content_portfolio'}
        {var $default_content = false}
    {case 30}
        {include 'content_blog'}
        {var $default_content = false}
{/switch}

<!-- Проверяем родителя ресурса -->
{switch $_modx->resource.parent}
    {case 30}
        {include 'content_blog_item'}
        {var $default_content = false}
{/switch}

<!-- Если ни одно из условий не сработало,
     выводим обычную текстовую страницу -->
{if $default_content}
    {include 'content_default'}
{/if}

Здесь используется синтаксис Fenom, так что у вас должен быть установлен pdoTools, и включена соответствующая настройка.

В этом чанке мы сами определяем, какой раздел и каким образом показывать. Клиент или контент-менеджер ничего не сломают — ведь если ни одно условие не выполняется (когда, например, создаётся новый раздел), будет выведен стандартный чанк, например, текстовой страницы.

Таким образом шаблонов у нас, всё-таки, несколько. Только шаблонами тут являются чанки, отвечающие за контент определённых страниц, а объект «Шаблон» у нас один для всех страниц.


16 комментариев

  1. Алексей 08 июня 2017, 19:15 # 0
    У меня пока так:
    {if $docid == 4} 
            {$_modx->getChunk('delivery')}
        {/if}
        
        {if $docid == 9} 
            {$_modx->getChunk('contacts')}
        {/if}
    
    Как раз думал на switch поменять, т.к. такое представление удобнее, но оставил т.к. есть запуски сниппетов и т.п., с If читается лучше. В моём случае + имхо, конечно.
    Теперь снова задумался )
    Спасибо!
    1. Илья Уткин 08 июня 2017, 19:31 # 0
      Тут смысл в том, что мы проверяем сначала ID, потом parent, и только если ни одно из условий не сработало, выводим стандартный чанк контента.
      1. Алексей 08 июня 2017, 19:45 # 0
        Да, понял. Читал не внимательно, а блок проверки родителя зелёный (закомментирован как-бы) я его даже и не смотрел )
    2. Ilia Konditerov 08 июня 2017, 19:50 # 0
      Спасибо
      1. Den Efremov 09 июня 2017, 08:25 # -1
        PyroCMS поможет вам избавиться от шаблонов Modx.
        1. Руслан Алеев 10 июня 2017, 15:44 # 0
          Здравствуйте, а есть ли преимущества fenom над стандартными фильтрами ввода-вывода MODX?
          1. Илья Уткин 10 июня 2017, 16:34 # +1
            Да, конечно. Во-первых, гораздо удобнее делать вложенные условия, во-вторых, fenom чуточку быстрее, а в-третьих, у него гораздо шире функционал — взять хотя бы расширение шаблонов.
            1. Руслан Алеев 10 июня 2017, 19:15(Комментарий был изменён) # 0
              Спасибо, еще вопрос не в тему: на некоторых хостах (например, beget) с fenom вылетает ошибка 502 (при выборке ресурсов в minishop2 и при фильтрации), из-за чего это происходит и как это исключить? Заранее спасибо.
              1. Илья Уткин 10 июня 2017, 20:14 # 0
                Причин может быть множество. Проверяйте версию php. По моему опыту fenom на Beget работает замечательно.
          2. Василий Столейков 12 июня 2017, 08:23 # 0
            А я уже давно использую следующую универсальную конструкцию:
            {$_modx->getChunk('content.'~$_modx->resource.id)}
            
            И если есть чанк у данной страницы типа content.5, то он автоматом подставляется.
            Из проекта в проект схема незначительно меняется в зависимости от особенностей проекта, но суть остаётся прежней — минимум шаблонов и стандартизированные чанки контента.
            1. Михаил Електрика 31 августа 2017, 10:45 # 0
              Есть минусы в такой конструкции. Когда выглядит все
              content.1
              content.2
              content.3
              content.4
              content.5
              content.6
              
              то читабельность ужасная
              1. Василий Столейков 31 августа 2017, 12:35 # 0
                Но иногда приходится прибегать к такой «ужасной» конструкции, особенно на больших порталах.
                По сути если хорошо всё организовать, то ею тоже можно пользоваться:

                1. Чётко структурировать по папкам эти чанки
                2. В описании чанка вписывать название страницы, чтобы при наведении на чанк оно показывалось.
                3. На фронте написать маленький сниппет, который проверяет, есть ли у текущей страницы чанк с таким именем и выводить кнопку редактирования именно этого чанка.

                Уже давно пользуюсь таким образом на нескольких больших сайтов, где другая конструкция увела бы в никуда, и пока всё работает… =)
            2. Сергей Никандров 29 мая 2018, 22:51 # 0
              Илья доброго времени суток!
              А можно например, если имеется 3 уровня меню, сделать такую конструкцию?
              {set $a = [$id]}
                              
                              {if $_modx->resource.parent in list $a}
                   
                              {'!pdoMenu' | snippet : [
                                  'parents' => $_modx->resource.id,
                                  'level' => '1',
                                  'tplOuter' => '@INLINE  <div style="padding: 15px; text-align: center!Important;">{$wrapper}</div>',
                                  'tpl' => '@INLINE   <h2 style="padding: 15px; margin:0; display: inline-block; font-size:20px;" class="text_bold">
                                                          <a href="{$link}">{$menutitle}</a>
                                                      </h2>{$wrapper}'
                              ]}
                              
                              
                              {elseif $_modx->resource.parent in list $a}
                              
                              {'!pdoMenu' | snippet : [
                                  'parents' => $_modx->resource.parent,
                                  'level' => '1',
                                  'tplOuter' => '@INLINE  <div style="padding: 15px; text-align: center!Important;">{$wrapper}</div>',
                                  'tpl' => '@INLINE   <h2 style="padding: 15px; margin:0; display: inline-block; font-size:20px;" class="text_bold">
                                                          <a href="{$link}">{$menutitle}</a>
                                                      </h2>{$wrapper}'
                              ]}
                              
                              {else}
                               {'!pdoMenu' | snippet : [
                                  'parents' => 'продедушка',
                                  'level' => '1',
                                  'tplOuter' => '@INLINE  <div style="padding: 15px; text-align: center!Important;">{$wrapper}</div>',
                                  'tpl' => '@INLINE   <h2 style="padding: 15px; margin:0; display: inline-block; font-size:20px;" class="text_bold">
                                                          <a href="{$link}">{$menutitle}</a>
                                                      </h2>{$wrapper}'
                              ]}
                              {/if}
              
              Как можно получить про дедушку ресурса на котором находишься?
              1. Илья Уткин 30 мая 2018, 10:53 # 0
                У ресурса нет данных о его прадедушке. Попробуйте использовать, например, pdoField:

                ...
                {elseif ($_modx->resource.parent | resource : "parent") in list $a}
                ...
                1. Сергей Никандров 30 мая 2018, 11:00 # 0
                  Спасибо Илья, получилась такая конструкция:
                  {set $a = [$id]}
                                  
                                  {if $_modx->resource.parent in list $a}
                       
                                  {'!pdoMenu' | snippet : [
                                      'parents' => $_modx->resource.id,
                                      'level' => '1',
                                      'tplOuter' => '@INLINE  <div style="padding: 15px; text-align: center!Important;">{$wrapper}</div>',
                                      'tpl' => '@INLINE   <h2 style="padding: 15px; margin:0; display: inline-block; font-size:20px;" class="text_bold">
                                                              <a href="{$link}">{$menutitle}</a>
                                                          </h2>{$wrapper}'
                                  ]}
                                  
                                  
                                  {elseif $_modx->resource.parent in list $a}
                                  
                                  {'!pdoMenu' | snippet : [
                                      'parents' => $_modx->resource.parent,
                                      'level' => '1',
                                      'tplOuter' => '@INLINE  <div style="padding: 15px; text-align: center!Important;">{$wrapper}</div>',
                                      'tpl' => '@INLINE   <h2 style="padding: 15px; margin:0; display: inline-block; font-size:20px;" class="text_bold">
                                                              <a href="{$link}">{$menutitle}</a>
                                                          </h2>{$wrapper}'
                                  ]}
                                  
                                  {elseif ($_modx->resource.parent | resource : "parent") in list $a}
                                   {'!pdoMenu' | snippet : [
                                      'parents' => $_modx->resource.parent,
                                      'level' => '1',
                                      'tplOuter' => '@INLINE  <div style="padding: 15px; text-align: center!Important;">{$wrapper}</div>',
                                      'tpl' => '@INLINE   <h2 style="padding: 15px; margin:0; display: inline-block; font-size:20px;" class="text_bold">
                                                              <a href="{$link}">{$menutitle}</a>
                                                          </h2>{$wrapper}'
                                  ]}
                                  {else}
                                  {'!pdoMenu' | snippet : [
                                      'parents' => ($_modx->resource.parent | resource : "parent"),
                                      'level' => '1',
                                      'tplOuter' => '@INLINE  <div style="padding: 15px; text-align: center!Important;">{$wrapper}</div>',
                                      'tpl' => '@INLINE   <h2 style="padding: 15px; margin:0; display: inline-block; font-size:20px;" class="text_bold">
                                                              <a href="{$link}">{$menutitle}</a>
                                                          </h2>{$wrapper}'
                                  ]}
                                  {/if}
                  
                  3 уровня меню в одном шаблоне.
              2. Евгений Александров 17 июля 2018, 19:05 # 0
                Я правильно понял что эту конструкцию надо вставить в чанк где head и footer у меня сейчас вызов идет вот так [[$tpl.[[*template]]]], а остальные страницы идут как tpl.1, tpl.2 и.т.д. не подскажите как мой вызов переделать на fenom или приспособить Ваш способ я его попробовал у меня выходит только главная, а на остальных страницах только head и footer

                Авторизация

                через сервис Loginza:


                Шаблоны MODX

                1 2 Дальше »

                Объектная
                модель
                MODX