MODX - Создание шаблона для постов

На этом уроке мы создадим, а точнее напишем код для шаблона "Пост", который определяет структуру и внешний вид веб-страницы, содержащей пост.

В шаблоне «Пост» будем использовать следующие сниппеты:

  • pdoCrumbs - для вывода «хлебных крошек»: (параметры сниппета: tpl - чанк для оформления ресурса в навигационной цепочке; tplWrapper – чанк-обёртка для навигационной цепочки; tplHome – чанк, для оформления ссылки на главную страницу; outputSeparator – строка, которая выступает в качестве разделителя между элементами в навигационной цепочке; showCurrent – булевский параметр, который определяет выводить текущий ресурс в хлебных крошках или нет; showHome – булевский параметр, который определяет выводить ссылку на главную страницу в начале навигации или нет).

    Результат работы сниппета pdoCrumbs

    [[pdoCrumbs? 
      &tpl=`@INLINE <li><a href="[[+link]]">[[+menutitle]]</a></li>` 
      &tplWrapper=`@INLINE <ol class="breadcrumb">[[+output]]</ol>`
      &tplHome=`@INLINE <li><a href="/"><i class="glyphicon glyphicon-home"></i></a></li>`
      &outputSeparator=``
      &showCurrent=`0`
      &showHome=`1`
    ]]
    
  • TicketMeta – для вывода информации о текущем посте.

    Результат работы сниппета TicketMeta

    [[TicketMeta]]
    
  • pdoNeighbors – для вывода ссылок на предыдущий и следующий посты от текущего (параметры сниппета: tplPrev – чанк, содержащий ссылку на предыдущий пост; tplNext - чанк, содержащий ссылку на следующий пост; tplWrapper – чанк, который является обёрткой для вывода ссылок на "соседние" посты).

    Результат работы сниппета pdoNeighbors

    [[pdoNeighbors? 
      &tplPrev=`@INLINE <span class="link-prev"><li class="previous"><a href="[[+link]]"><span class="glyphicon glyphicon-chevron-left"></span> [[+menutitle]]</a></li></span>` 
      &tplNext=`@INLINE <span class="link-next"><li class="next"><a href="[[+link]]">[[+menutitle]] <span class="glyphicon glyphicon-chevron-right"></span></a></li></span>`
      &tplWrapper=`@INLINE <div class="neighbors"><ul class="pager">[[+prev]][[+next]]</ul></div>`
    ]]
    

    CSS код:

    .neighbors {
    margin-bottom:10px;
    }
    
  • TicketComments – для вывода комментариев и формы для комментирования поста (параметр поста: allowGuest – булевский параметр, который позволять включить возможность комментирования для неавторизованных пользователей).

    Результат работы сниппета TicketComments

    [[!TicketComments? &allowGuest=`1`]]
    

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

  1. Открываем шаблон "Пост".
  2. Вводим следующий код:

    Создание кода (html) для шаблона Пост

    <!DOCTYPE html>
    <html lang="ru">
    [[$chunk.head]]
    <body>
      <div class="container"> 
        <div class="row">
          [[$chunk.header]]
          [[$chunk.navbar]]
          <div class="main-block col-md-8">
            [[pdoCrumbs? &tpl=`@INLINE <li><a href="[[+link]]">[[+menutitle]]</a></li>` 
                         &tplWrapper=`@INLINE <ol class="breadcrumb">[[+output]]</ol>`
                         &tplHome=`@INLINE <li><a href="/"><i class="glyphicon glyphicon-home"></i></a></li>`
                         &outputSeparator=``
                         &showCurrent=`0`
                         &showHome=`1`]]
            <h1 class="h2 page-header">[[*pagetitle]]</h1>
            [[*content]]
            [[TicketMeta]]
            [[pdoNeighbors? 
              &tplPrev=`@INLINE <span class="link-prev"><li class="previous"><a href="[[+link]]"><span class="glyphicon glyphicon-chevron-left"></span> [[+menutitle]]</a></li></span>` 
              &tplNext=`@INLINE <span class="link-next"><li class="next"><a href="[[+link]]">[[+menutitle]] <span class="glyphicon glyphicon-chevron-right"></span></a></li></span>`
              &tplWrapper=`@INLINE <div class="neighbors"><ul class="pager">[[+prev]][[+next]]</ul></div>`]]
            [[!TicketComments? &allowGuest=`1`]]
          </div>
          <div class="col-md-4">
          </div>
        </div>
      </div>
      [[$chunk.footer]]
    </body>
    </html>
    
Веб-страницу, содержащую пост "Ex ea voluptate" продемонстрируем с помощью 2 скриншотов.

Верхняя часть веб-страницы, содержащей пост

Нижняя часть веб-страницы, содержащей пост



   MODX Revo 0    4419 +1

Комментарии (41)

  1. Аня # 0
    Александр, всё получилось. Но почему то хлебные крошки прижаты кверху тела статьи. Конечно получается сделать отступ с помощью margin-top в 20px в .breadcrumb, но в мобильной версии опять прижимаются кверху. Может что-то не так делаю. Ищу. Не могу найти причину. Вроде всё верно)
    1. Александр Мальцев # 0
      Аня, в конце данного урока должен получиться следующий CSS файл:
      .main-block {
      background-color: rgba(255, 255, 255, 0.6);
      padding:15px;
      }
      .header {
      height:75px;
      background: url('/assets/images/logo/logo.png') no-repeat;
      }
      footer {
      background-color: rgba(255, 255, 255, 0.6);
      margin-top:15px;
      padding-top:5px;
      }
      .neighbors {
      margin-bottom:10px;
      }
      img {
      display: block;
      max-width: 100%;
      height: auto;
      }
      
    2. Аня # 0
      Александр, а вот если я захочу вместо логотипа разместить просто картинку в хидер? Какой ширины делать непонятно, если ориентироваться на меню от и до? Я так понимаю сайт растягивается по ширине монитора. (То что под мобильники сделано тоже понятно) поскажете, как с этим быть
      1. Александр Мальцев # 0
        Аня, самый простой вариант подготовить изображения для различных устройств: xs, sm, md и lg. Потом с помощью медиа запросов установить различные картинки для различных устройств:
        /* стиль для заголовка с шириной экрана до 768px */ 
        .header {
          height:75px;
          background: url('/assets/images/logo/logo-xs.png') no-repeat;
        }
        
        /* стиль для заголовка с шириной экрана до 992px */ 
        @media(min-width:768px) {
          .header {
            height:90px;
            background: url('/assets/images/logo/logo-sm.png') no-repeat;
          }
        }
        
        /* стиль для заголовка с шириной экрана до 1200px */ 
        @media(min-width:992px) {
          .header {
            height:100px;
            background: url('/assets/images/logo/logo-md.png') no-repeat;
          }
        }
        
        /* стиль для заголовка с шириной экрана свыше 1200px */ 
        @media(min-width:1200px) {
          .header {
            height:110px;
            background: url('/assets/images/logo/logo-lg.png') no-repeat;
          }
        }
        
      2. Аня # 0
        А возможно ли поменять слово «комментарии» на «отзывы»
        1. Александр Мальцев # 0
          Аня, Добрый день!
          1 Способ:
          Значок «Шестерёнка» -> Управление словарями.
          В открывшейся странице «Управления словарями» устанавливаем следующее:
          • в раскрывающемся списке «Пространство имён» выбираем «tickets»;
          • в раскрывающемся списке «Язык» выбираем «ru».
          После этого в таблице ищем имя «comments» и изменяем его значение на «Отзывы».
          После этого незабываем «Очистить кэш сайта».

          2 способ:
          Для этого открываем чанк «tpl.Tickets.comment.wrapper».
          Ищем следующую строчку:
          <h3 class="title">[[%comments]] (<span id="comment-total">[[+total]]</span>)</h3>
          Изменяем её на следующую строчку:
          <h3 class="title">Отзывы (<span id="comment-total">[[+total]]</span>)</h3>
        2. Аня # 0
          Спасибо
          1. velllum # 0
            ШЕФ помоги разобрать!!! Вопрос по Tickets, как вывести количество комментария принадлежащей только той страници или *id к которым они относятся? В инете есть информация, тоько примеры у меня не получается реализовать!!! Описание ниже в коментариях! Зарание спасибо!!!
            1. Александр Мальцев # 0
              1. Создаёшь сниппет TicketCommentCount
              <?php
              //получаешь id текущего ресурса
              $id = $modx->resource->id;
              $q = $modx->newQuery('modResource', $id);
              $q->leftJoin('TicketThread','TicketThread', "`TicketThread`.`name` = 'resource-{$id}'");
              $q->leftJoin('TicketComment','TicketComment', "`TicketThread`.`id` = `TicketComment`.`thread`");
              $q->select('COUNT(`TicketComment`.`id`) as `comments`');
              $count = 0;
              if ($q->prepare() && $q->stmt->execute()) {
              	$count = (integer) $q->stmt->fetch(PDO::FETCH_COLUMN);
              }
              return $count;
              
              2. Открываешь шаблон и в нужно месте вызываешь сниппет TicketCommentCount, который будет выводить количество комментариев:
              [[!TicketCommentCount]]
              
              1. velllum # 0
                А как мне снипету объяснить с какой страницы брать и выводить комментарии? Допустим у меня 10 страниц и на всех коменты на разные темы, мне нужно в «N» месте показать количество комментарии с одной страницы? например вот так «КОММЕНТАРИИ — (15)», как мне это сделать объясните пожалуйста????
                1. Александр Мальцев # 0
                  Этот сниппет получает комментарии для текущей страницы. Если вам надо получить количество комментариев для какой-то другой страницы, то её необходимо передать в сниппет:
                  [[!TicketCommentCount? &id=`5`]]
                  
                  А первую строку кода сниппета изменить на:
                  $id = $modx->getOption('id', $scriptProperties,$modx->resource->id);
                  
            2. Анна # 0
              Александр, подскажите пожалуйста как настроить модерацию комментариев, чтоб сначала проверить комментарий перед публикацией. Не разберусь с документацией, непонятно. спасибо
              1. Александр Мальцев # 0
                Привет, Аня.
                Там всё просто.
                Необходимо просто добавить параметр(ы) &autoPublishGuest=`0` (публиковать комментарии анонимных пользователей после модерации) и (или) &autoPublish=`0` (публиковать комментарии авторизированных пользователей после модерации) к сниппету TicketComments:
                [[!TicketComments? &allowGuest=`1` &allowGuestEmails=`1` &autoPublishGuest=`0`]]
                
                Теперь, после оставления пользователем комментария, он не опубликуется. Вам необходимо будет его проверить. Для этого необходимо зайти в Панель Управления MODX и перейти на страницу Комментарии:
                Приложения -> Тикеты -> Вкладка «Комментарии»
                На этой странице Вы его просматриваете и решаете, что с ним делать (публиковать или нет).
                1. Аня # 0
                  Спасибо. Действительно всё просто. А я в параметрах чанка меняю меняю и никак. А что значит 0 и 1 в кавычках? это да — нет? Или другой вариант.
                  1. Александр Мальцев # 0
                    1 — автоматически публиковать комментарии, 0 — автоматически не публиковать, публикация комментария осуществляется администратором или модератором, после его проверки.
              2. Алексей # 0
                Добрый день, Александр!
                Извините, что вопрос не совсем по теме.
                У меня на сайте вывод товаров организован при помощи таблицы MIGX.
                А хлебные крошки реализованы с помощью pdoCrumbs таким образом:
                [[pdoCrumbs? 
                  &tpl=`@INLINE <li><a href="[[+link]]">[[+menutitle]]</a></li>` 
                  &tplWrapper=`@INLINE <ol class="breadcrumb">[[+output]]</ol>`
                  &tplHome=`@INLINE <li><a href=""><i class="glyphicon glyphicon-home"></i></a></li>`
                  &outputSeparator=`  /  `
                  &showCurrent=`1`
                  &showHome=`1`
                ]]
                
                Проблема в том, что на странице самого товара (карточке товара) выводятся только: Главная / (название последнего пункта в списке ресурсов, на котором вообще стоит галочка «не показывать в меню»). Вся цепочка отсутствует и соответственно текущая страница (карточка товара).
                Подскажите пожалуйста, что нужно исправить.
                Спасибо!
                1. Александр Мальцев # 0
                  Здравствуйте, Алексей.
                  pdoCrumbs выводят хлебные крошки на основании иерархии ресурсов в дереве.
                  А у Вас товары организованы в таблице MIGX. Тут Вам придётся самостоятельно написать сниппет, который будет брать данные из таблицы и выводить их на странице.
                2. Ника # 0
                  Здравствуйте, Александр! Подскажите, пожалуйста, куда копать? «Текст комментария» и «Автор комментария» после обновления страницы превращаются в "???????". Слетает только кириллица. Все комментарии от незарегистрированных пользователей, до регистрации и прав еще «руки не дошли» :(
                  1. Ника # 0
                    Уточнения: комментарии на кириллице корректно отправляются на почту и выкладываются на сайте, слетают после обновления страницы, т.е. при попадании в интерфейс модх и базу. Хостинг на reg.ru: php 5.3, кодировка utf8_general_ci. В htaccess есть AddDefaultCharset UTF-8.
                    Помогите, пожалуйста.
                  2. Демьян Золин # 0
                    Здравствуйте. Выполнял все по Вашей инструкции. Но проблема вылезла когда написали комментарий. Посмотрите, пожалуйста, здесь, может ошибка явная. Спасибо.
                    1. Александр Мальцев # +1
                      Здравствуйте. У Вас скорее всего в вызове TicketLatest неправильно указан параметр tpl. Т.е. указан чанк (tpl.Tickets.comment.latest.my), который Вы не создали. Проверьте этот момент.
                      [[!TicketLatest? &limit=`3` 
                                             &tpl=`tpl.Tickets.comment.latest.my`   
                                             &action=`comments` 
                                             &includeContent=`1`]]
                      
                      Второй момент — это проверьте разметку.
                      Блок с классом:
                      <div class="col-md-4">
                      
                      должен быть расположен в том же контейнере что и следующий класс:
                      <div itemscope="" itemtype="http://schema.org/Article" class="main-block col-md-8">
                      
                      1. Демьян Золин # 0
                        В «последних комментариях» ошибку нашел, благодаря Вашей наводке. Проверяю разметку. Поначалу, не вижу ошибки в коде шаблона «Пост»
                        <!DOCTYPE html>
                        <html lang="ru">
                        [[$chunk.head]]
                        <body>
                          <div class="container"> 
                            <div class="row">
                              [[$chunk.header]]
                              [[$chunk.navbar]]
                              <div itemscope itemtype="http://schema.org/Article" class="main-block col-md-8">
                                [[pdoCrumbs? &tpl=`@INLINE <li><a href="[[+link]]">[[+menutitle]]</a></li>` 
                                             &tplWrapper=`@INLINE <ol class="breadcrumb">[[+output]]</ol>`
                                             &tplHome=`@INLINE <li><a href="/"><i class="glyphicon glyphicon-home"></i></a></li>`
                                             &outputSeparator=``
                                             &showCurrent=`0`
                                             &showHome=`1`]]
                                <h1 itemprop="name" class="h2 page-header">[[*pagetitle]]</h1>
                                <div itemprop="description"><em>[[*description]]</em></div>
                                <div itemprop="articleBody">[[*content]]</div>
                                <div itemprop="image">[[*photo]]</div>
                                
                                [[$tpl.yandexshare]]
                        
                                [[TicketMeta]]
                                [[pdoNeighbors? 
                                  &tplPrev=`@INLINE <li class="previous"><a href="[[+link]]"><span class="glyphicon glyphicon-chevron-left"></span> [[+menutitle]]</a></li>` 
                                  &tplNext=`@INLINE <li class="next"><a href="[[+link]]">[[+menutitle]] <span class="glyphicon glyphicon-chevron-right"></span></a></li>`
                                  &tplWrapper=`@INLINE <div class="neighbors"><ul class="pager">[[+prev]][[+next]]</ul></div>`]]
                                [[!TicketComments? &fastMode=`0` &allowGuest=`1` &allowGuestEmails=`1` &maxCaptcha=`30`]]     
                              </div>
                              <div class="col-md-4">
                               [[$lastComment]]
                              </div>
                            </div>
                          </div>
                          [[$chunk.footer]]
                        </body>
                        </html>
                        1. Александр Мальцев # 0
                          Шаблон нормальный. Но где-то всё равно зарылся лишний закрывающий тег div. Скорее всего в чанке, которые использует сниппет TicketComments.
                    2. Питон # 0
                      Добрался до комментариев :) Как сделать так чтобы форма добавления комментов разворачивалась по нажатию кнопку. Как у вас…
                      — Извините — сам разобрался: надо в стили добавить —
                      #comment-form {display: none;}
                      1. Демьян Золин # 0
                        Здравствуйте.
                        Захожу ресурс раздел с тикетами. (Дневник — моё название)
                        Нажимаю кнопку "+Создать тикет".
                        Открывается следующий вид (см. картинку)
                        Отсутствуют кнопки «Сохранить» и т.д.
                        Соответственно не могу создать тикет.
                        Пару недель ничего на сайте не делал.(Tickets обновлено)

                        Второй вопрос как называется эта группа кнопок(обведено красным)
                        1. Александр Мальцев # 0
                          Попробуйте переустановить MODX (заменить все файлы с дистрибутива). А также проверить есть ли ошибки в журнале (Управление->Отчёты->Журнал ощибок) и в консоли браузера.
                          В этой группе находятся кнопки для выполнения основных действий над текущим ресурсом: «Сохранить», «Посмотреть», «Отменить» и «Помощь».
                          1. Демьян Золин # 0
                            Бэкап помог, но осадок остался.
                            Жумлу напомнило, когда у нее вход в админку пропадал, приходилось через пхпадмин с юзером колдовать (
                            Друпал ни разу подобных эмоций не вызывал )
                            1. Александр Мальцев # 0
                              Да это не зависит от системы. Если у Вас произошло повреждение файлов, то это может случится с любой системой. Для этого и нужны бэкапы.
                        2. Алексей # 0
                          Здравствуйте, Александр.
                          Помогите разобраться. Когда начал писать сайт подключил по вашему уроку, все работало, комментарии добавлялись. Написал главную страницу и вернулся к странице поста. К своему огорчению обнаружил, что комментарии перестали добавляться, хотя сам шаблон поста не трогал (все как у вас). Все элементы страницы выводятся даже те комментарии, что я добавлял в начале написания сайта (когда проверял работоспособность коментов). Нажимаешь кнопку «НАПИСАТЬ» страница перегружается((. Что делать?
                          Могу дать ссылку
                          1. Александр Мальцев # 0
                            Необходимо проверить правильно ли Вы подключили библиотеку jQuery.
                            1. Алексей # 0
                              Большое спасибо за ответ.
                              Ошибку, нашел — пробел в закрывающем теге body, убрал все работает.
                          2. Алексей # 0
                            Здравствуйте Александр.
                            Подскажите пожалуйста.
                            Хочу вывести в шаблоне поста список ресурсов из родительского ресурса (подкаталога) в котором находится ресурс поста. Если проще, — есть каталог: телевизоры, пылесосы, и тд., в папке пылесосы статья. Нужно в этой статье вывести список всех статей из раздела «пылесосы» (то есть родительского раздела для этой статьи).
                            Вывожу так:
                            [[!pdoPage?
                            				&element=`getTickets`
                            				&action=`tickets` 
                            				&parents=`??????`
                            				&limit=`9`
                            				&tpl=`post_list_hits`
                            				&offset=`0`
                            				&includeTVs=`carousel-post-image, carousel-post-videoURL, video, image, hidden, photo-to-day`  
                            				&sortbyTV=`HitsPage`
                            				&sortbyTVType=`integer`
                            				&sortdir=`DESC`
                            				]]
                            Но что ставить в &parents=`??????` не пойму. Родительский (id) ресурс должен определяться автоматически.
                            Спасибо.
                            1. Александр Мальцев # 0
                              Получить родительский id можно так:
                              [[*parent]]
                              
                              1. Алексей # 0
                                Большое спасибо.
                                Заработало.
                                Скажите, а где можно посмотреть список всех системных плейсхолдеров MODXrevo?
                                1. Александр Мальцев # 0
                                  Вот на этой странице:
                                  _https://rtfm.modx.com/revolution/2.x/making-sites-with-modx/commonly-used-template-tags
                            2. Алексей # 0
                              Большое спасибо. Но вот только не пойму как строятся констукции типа [[~[[+section.id]]]] (вызывает в чанке шаблона pdopage ссылку на родителя.) или эти плейсхолдеры относятся только к pdotools?
                              Спасибо.
                              1. Александр Мальцев # 0
                                Плейсхолдеры генерируется сниппетами. В данном случае pdoPage.
                              2. Алексей # 0
                                Здравствуйте.
                                Проблема с установкой Tiskets. Во время установке вылезает сообщение:
                                Could not create table `modx_tickets_views` SQL: CREATE TABLE `modx_tickets_views` (`parent` INT(10) unsigned NOT NULL DEFAULT '0', `uid` INT(10) unsigned NOT NULL DEFAULT '0', `guest_key` CHAR(32) NULL, `timestamp` DATETIME NOT NULL, PRIMARY KEY (`parent`,`uid`,`guest_key`)) ENGINE=MyISAM ERROR: Array ( [0] => 42000 [1] => 1171 [2] => All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead ).
                                Подскажите что делать?
                                1. Александр Мальцев # 0
                                  Может быть это связано с версией MySQL. А также попробуйте удалить таблицу modx_tickets_views если, конечно же, она есть в базе данных.
                                2. Алексей # 0
                                  Спасибо, что откликнулись на мой вопрос.
                                  Проблему решил следующим образом: экспортировал с другого сайта все таблицы относящиеся к tickets, потом импортировал в свою базу, после этого tickets установился. Все равно этот способ мне кажется костылем. Возможно ошибка связана с тем, что устанавливал пакет tckets на готовую сборку shopkeeper3, а там используется Migs и много других компонентов, предполагаю, один из них конфликтует.

                                  И еще один вопрос, не совсем по теме. Подскажите как вывести два сниппета COMPARE (сравнение товаров) на одной странице. Дело в том, количество добавленных к сравнению товаров обновляется (AJAX-ом) только в сниппете который стоит первым в коде. Во втором сниппете обновление значения происходит только после перезагрузки страницы.
                                  Спасибо.
                                  1. Александр Мальцев # 0
                                    По shopkeeper3 не подскажу. Может попробовать это реализовать через другие сниппеты getResources или pdoResources.

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