MODX - Облако тегов

На этом уроке рассмотрим, как с помощью компонентов Tagger и pdoTools организовать на сайте теги к статьям, поиск по этим тегам и облако тегов.

Установка Tagger и pdoTools

Для создания тегов к статьям, облака тегов и страницы, которая будет выводить ресурсы в соответствии с переданным ей тегом, будем использовать компоненты Tagger и pdoTools.

Установку необходимых компонентов произведём на странице "Управление пакетами" (Приложения -> Установщик):

  • Tagger - компонент, который добавляет в MODX теги, категории и многое другое.
  • pdoTools - компонент, представляющий собой набор сниппетов, позволяющих решить очень большое количество задач. На этом уроке будем использовать сниппеты pdoResources и pdoPage.

Компонент Tagger

Работу с Tagger начнём с создания группы и тегов в ней. Для этого в верхнем меню нажмем на пункт Приложения и выберем подпункт Tagger. На открывшейся странице перейдём на вкладку Group и создадим новую группу с помощью кнопки "Create a new Group".

MODX (компонент Tagger) - Создание группы
MODX - Создание группы для тегов

Основные поля:

  • name - название группы (tags).
  • description - описание группы (теги к статьям).
  • place - место отображение тегов (in tab - во вкладке).
  • show for templates - для каких шаблонов отображать группу (2 - id шаблона статей).
  • allow blank - определяет, можно ли не указывать теги.
Внимание: Работа с Tagger всегда начинается с создания группы, т.к. теги не могут сами по себе существовать, они должны принадлежать к той или иной группе.

Перейдём на вкладку Tags и создадим теги в группе tags.

MODX (компонент Tagger) - Создание нового тега
MODX - Создание нового тега

Основные поля:

  • name - имя тега (например, HTML)
  • alias - псевдоним тега (например, html)
  • group - группа (выбираем ранее созданную группу tags)

После этого создадим ещё несколько тегов.

MODX (компонент Tagger) - Список тегов
MODX - Список тегов

Добавим к статьям, имеющим шаблон Пост (id=2), теги. Добавление тегов осуществляется во вкладке Tagger.

MODX (компонент Tagger) - Добавление тегов к тикету
MODX - Добавление тегов к тикету

Создание ресурса "Вывод статей по тегу"

Создадим ресурс "Вывод статей по тегу" и шаблон, который свяжем с ним. Результат данного действия показан на рисунке. Во вкладке "Настройки" укажем данному ресурсу URI - show-posts. Запомним идентификатор (id) данного ресурса (например, 20).

MODX - Создание ресурса, который будет использоваться для вывода статей по тегу
MODX - Вывод статей в соответсвии с некоторым тегом

Вывод тегов, прикреплённых к статье

Для вывода тегов, добавленных к статье необходимо открыть шаблон (Пост) и вставить в него вызов сниппета TaggerGetTags:

[[TaggerGetTags?
  &resources=`[[*id]]`
  &rowTpl=`@INLINE <div class="btn-group"><span class="btn btn-primary btn-sm">#</span><a class="btn btn-info btn-sm" href="[[~20]]?tag=[[+alias]]">[[+tag]]</a></div>`
]]

Параметр:

&rowTpl - чанк, который используется для вывода каждого тега.

Плейсхолдеры:

  • [[+alias]] - псевдоним тега.
  • [[+tag]] - имя тега.

Вывод тегов организуем с помощью ссылок, каждая из которых будет иметь следующее значение атрибута href:

[[~20]]?tag=[[+alias]]

где:

  • [[~20]] - URL ресурса "Вывод статей по тегу". Данный ресурс будем использовать для вывода статей, имеющих указанный тег.
  • [[+alias]] - значение передаваемого GET-параметра tag. Данное значение будем использовать в ресурсе [[~20]] для создания запроса к базе данных, выбирающих из неё только записи, имеющие этот тег.
MODX (компонент Tagger) - Вывод тегов на странице тикета
MODX - Вывод тегов на странице ресурса

Создание облака тегов

Для создания облака тегов воспользуемся сниппетом pdoResources. Но перед тем как переходить к выборке, рассмотрим MySQL схему компонента Tagger. Данная схема отображает связь между таблицами (классами) компонента Tagger и modResource.

MODX - Схема Tagger (+таблица modResource)
MODX - Схема Tagger (+таблица modResource)

Из схемы видно, что компонент Tagger состоит из 3 таблиц (классов):

  • TaggerTag - список тегов.
  • TaggerTagResource - связывает modResource и TaggerTag. Т.е. каждая строчка содержит id тега и id ресурса.
  • TaggerGroup - список групп.

Класс modResource приведён для наглядности.

Для создания облака тегов необходимо воспользуемся сниппетом pdoResources:

[[!pdoResources?
  &loadModels=`tagger`
  &class=`TaggerTag`
  &leftJoin=`{
    "TaggerTagResources": {
	  "class": "TaggerTagResource",
	  "on": "TaggerTag.id = TaggerTagResources.tag"
    }
  }`
  &select=`{
    "TaggerTag": "*",
	  "TaggerTagResources": "COUNT(TaggerTagResources.tag) as countTags"
	}`
  &groupby=`TaggerTag.id`
  &sortby=`TaggerTag.tag`
  &sortdir=`ASC`  
  &tplWrapper=`@INLINE <div class="panel panel-primary"><div class="panel-heading"><span class="glyphicon glyphicon-tags"></span> Теги</div><div class="panel-body">[[+output]]</div></div>`
  &tpl=`@INLINE <a href="[[~20]]?tag=[[+alias]]" class="btn btn-primary">[[+tag]] <span class="badge">[[+countTags]]</span></a>`
]]

Вставим вышепредставленный код, например, в правую колонку шаблона Пост.

MODX (компонент Tagger) - Облако тегов
MODX - Облако тегов

Реализация страницы "Вывод статей по тегу"

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

Рассмотрим этот момент более подробно. На страницах каждый тег оформлен в виде ссылки, которая имеет в своём составе параметр tag.

Например, тег bootstrap имеет следующий URL:

http://site.ru/show-posts?tag=bootstrap

Следовательно, для того чтобы вывести соответствующие ресурсы необходимо:

  1. Получить значение параметра tag из массива GET.
  2. Создать запрос для выборки необходимых данных.
  3. Указать данному запросу условие (where). Т.е. ограничить выборку только теми записями, которые имеют указанный тег.
  4. Создать чанк для оформления результатов.

Вставим в шаблон "Статьи по тегу" базовый каркас страницы и вызов сниппета pdoPage:

[[!pdoPage?
  &element = `pdoResources`
  &limit=`2`
  &loadModels=`tagger`
  &class=`TaggerTagResource`
  &leftJoin=`{
    "NameTag": {
      "class": "TaggerTag",
      "on": "TaggerTagResource.tag = NameTag.id"
    },
    "Posts": {
      "class": "modResource",
      "on": "TaggerTagResource.resource = Posts.id"
    }
  }`
  &select=`{
    "TaggerTagResource": "*",
    "NameTag": "NameTag.tag, NameTag.alias",
    "Posts": "Posts.id, Posts.pagetitle, Posts.description"
  }`
  &where=`{
    "NameTag.alias": "[[!#GET.tag]]"
  }`
  &sortby=`TaggerTagResource.resource`
  &sortdir=`ASC`  
  &tplWrapper =`@INLINE <h2 class="h3">Всего результатов: [[+page.total]]</h2>[[+output]]`
  &tpl= `chunkTagRow`
]]
[[!+page.nav]]

Чанк chunkTagRow:

<div class="panel panel-default">
  <div class="panel-body">
    <h3 class="h4">[[+pagetitle]]</h3><p>[[+description]]</p>
    <p class="text-right"><a href="[[~[[+id]]]]" class="btn btn-primary" role="button">Читать далее...	</a></p>
  </div>
</div>
MODX - Вывод статей, имеющих соответствующий тег
MODX - Вывод статей, имеющих соответствующий тег


   MODX Revo 0    4071 +1

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

  1. Алексей # 0
    Шеф, лучи добра тебе за очередной полезные материал!
    Только надо в параметры вывода тегов добавить
    &resources=`[[*id]]`
    А то так он выводит ко всем статьям одинаковые теги, добавленные в разные статьи.
    Пол дня голову ломал из-за чего так) Уже хотел у тебя тут снова помощи просить, но рад, что сам догадался)
    И ещё
    allow tag — определяет, можно ли не указывать теги.
    Allow blank же)
    1. сергей # 0
      Спасибо за подробную статью.
      Подскажите пожалуйста, теги на кириллице поддерживаются? и возможно ли формировать красивый урл к тегам для поисковой индексации?
      Спасибо!
      1. Алексей # 0
        Конечно поддерживаются. Что мешает попробовать?)
        В статье же всё написано
        Например, тег bootstrap имеет следующий URL:
        http://site.ru/show-posts?tag=bootstrap
        Или это некрасивый урл?)
        1. Сергей # 0
          Да, я уже опробовал кириллицу. У меня просто до этого было проблема с похожим компонентом, поэтому и спросил.
          Красивый урл это вот так: site.ru/tags/name_tag/ — можно такой сделать?
          1. Алексей # 0
            Вывод тегов организуем с помощью ссылок, каждая из которых будет иметь следующее значение атрибута href:
            [[~20]]?tag=[[+alias]]
            где:
            [[~20]] — URL ресурса «Вывод статей по тегу». Данный ресурс будем использовать для вывода статей, имеющих указанный тег.
            [[+alias]] — значение передаваемого GET-параметра tag. Данное значение будем использовать в ресурсе [[~20]] для создания запроса к базе данных, выбирающих из неё только записи, имеющие этот тег.
            Следовательно:
            <a href="[[~20]]/[[+alias]]">
            Либо
            <a href="[[~20]]/[[+tag]]">
            если алиас отличается от имени. При этом псевдоним страницы должен быть tags.
            1. Сергей # 0
              У вас нет параметра. Такая конструкция буде 404

              Данная страница будет выводить список статей, которые имеют указанный тег. Как Вы уже наверно догадались, получать тег эта страница будет из URL (из GET параметра tag).
              1. Александр Мальцев # 0
                Добавьте в .htaccess правило:
                RewriteRule ^show-posts/(.*)$ /show-posts?tag=$1 [L]
                1. Сергей # 0
                  К сожалению не работает.
                  1. Александр Мальцев # 0
                    Чтобы это работало необходимо очистить кэш сайта.
                    В итоге будет: _http://mysite.ru/show-posts/modx == _http://mysite.ru/show-posts?tag=modx
                    1. Сергей # 0
                      Я чистил кэш. Не работает, и к тому же перестают выводиться тегированые записи.
                      1. Алексей # 0
                        С делал как Александр ниже написал. У меня всё работает. Ты бы хоть код свой привёл)
                2. Алексей # 0
                  Действительно. Я что-то подумал, что можно самому урл сформировать.
                  1. Александр Мальцев # 0
                    URL тоже надо формировать:
                    &tpl=`@INLINE <a href="[[~20]]/[[+alias]]" class="btn btn-primary">[[+tag]] <span class="badge">[[+countTags]]</span></a>`
                    
                    В итоге получается следующая картина:
                    _http://mysite.ru/show-posts/modx
                    _http://mysite.ru/show-posts/bootstrap
                    и т.д.
                    Но, у нас то этих страниц нет. А есть только одна страница:
                    _http://mysite.ru/show-posts
                    Которая может принимать GET-параметр tag:
                    _http://mysite.ru/show-posts?tag=modx
                    _http://mysite.ru/show-posts?tag=bootstrap
                    и т.д.
                    И чтобы всё это работало необходимо дополнительно написать правило в .htaccess, которое делало бы следующее
                    _http://mysite.ru/show-posts/modx => _http://mysite.ru/show-posts?tag=modx
                    _http://mysite.ru/show-posts/bootstrap => _http://mysite.ru/show-posts?tag=bootstrap
                    и т.д.
                    Т.е. RewriteRule ^show-posts/(.*)$ /show-posts?tag=$1 [L] или какое-то другое в зависимости от сервера.
                    1. Алексей # 0
                      Очередная порция лучей добра тебе) У меня всё работает)
                      1. Сергей # 0
                        Александр, большое спасибо вам! Все работает!
          2. Александр Мальцев # 0
            Спасибо, Алексей.
          3. Читатель # 0
            Спасибо за статью! Подскажите, пожалуйста, как на странице вывода списка статей по тегу получить его название.
            1. Александр Мальцев # 0
              Здравствуйте, тег и его alias находится в таблице (классе) TaggerTag.
              Получить его можно следующим образом:
              [[!pdoResources?
                &loadModels=`tagger`
                &class=`TaggerTag`
              	&where=`{
              	"TaggerTag.alias": "modx"
                }`
                &select=`{
                  "TaggerTag": "[[!#GET.tag]]"
              	}`
                &sortby=`TaggerTag.tag`
                &tpl=`@INLINE <h3>Тег: [[+tag]]</h3>`
                &fastMode=`1`
              ]]
              
              1. Алексей # 0
                Шеф, не пойму куда этот код затусовать, чтобы в шаблоне вывода статей по тегу можно было бы добавить его имя.
                Например,
                &tplWrapper =`@INLINE <h2 class="h3">Всего результатов по тегу [[+tagName]]: [[+page.total]]</h2>[[+output]]`
                Или как нибудь ещё.
                1. Александр Мальцев # 0
                  Плейсхолдер tagName можно использовать только в чанке, указанном в качестве значения параметра tpl.
                  1. Алексей # 0
                    Шеф, вот тут-то мне, видимо, нужен развёрнутый ответ) Я не пойму куда и как правильно вставить этот код, чтобы на странице «Статьи по тегу» можно было вывести его название. А то получается Всего результатов: и дальше пошёл список статей. Не совсем понятно по какому тегу они выведены. Пробовал ради эксперимента вставить этот код перед и после вызова сниппета pdoPage, ничего не происходит.
                    Догадался только изменить код в вызове сниппета pdoPage
                    "NameTag": "NameTag.tag as tagName, NameTag.alias as tagAlias",
                    и добавить
                    <h1>Всего результатов по тегу <i class="fa fa-hashtag"></i>[[+tagName]]: [[+page.total]]</h1>
                    в чанк, указанном в качестве значения параметра tpl.
                    Но тогда получается Всего результатов по тегу Разное: 4 перед каждой статьёй.
                    Как быть то?)
                    1. Александр Мальцев # 0
                      В шаблоне:
                      [[!pdoPage?
                        &element = `pdoResources`
                        &limit=`2`
                        &loadModels=`tagger`
                        &class=`TaggerTagResource`
                        &leftJoin=`{
                          "NameTag": {
                            "class": "TaggerTag",
                            "on": "TaggerTagResource.tag = NameTag.id"
                          },
                          "Posts": {
                            "class": "modResource",
                            "on": "TaggerTagResource.resource = Posts.id"
                          }
                        }`
                        &select=`{
                          "TaggerTagResource": "*",
                          "NameTag": "NameTag.tag, NameTag.alias",
                          "Posts": "Posts.id, Posts.pagetitle, Posts.description"
                        }`
                        &where=`{
                          "NameTag.alias": "[[!#GET.tag]]"
                        }`
                        &tplWrapper =
                          `@INLINE <h2 class="h3">Всего результатов ([[+page.total]]) по тегу  
                          [[!pdoResources?
                            &loadModels=`tagger`
                            &class=`TaggerTag`
                            &where=`{
                      	"TaggerTag.alias": "[[!#GET.tag]]"
                            }`
                            &select=`{
                              "TaggerTag": "TaggerTag.tag as tagPage"
                            }`
                            &sortby=`TaggerTag.tag`
                            &tpl=`@INLINE [[!+tagPage]]`
                          ]]
                          </h2>[[+output]]`
                        &tpl= `chunkTagRow`
                        &sortby=`TaggerTagResource.resource`
                        &sortdir=`ASC`
                      ]]
                      [[!+page.nav]]
                      
                      1. Алексей # 0
                        Огромная благодарность тебе! Я даже и не думал, что так можно. Буду рад очередным новым и полезным урокам.
            2. Сергей # 0
              Пробовал через .htaccess сделать красивый урл, но ничего не выходит.
              RewriteRule ^tag/([^/]+)$ /tag?tag=$1 [L]
              1. Алексей # 0
                Зачем такой огород, когда можно сразу сделать нужную ссылку?)
              2. Алексей # 0
                Шеф, возникло два вопроса)
                1. На странице с одной статьёй облако тегов, которое в правой колонке, выводится без проблем. Но на главной странице блога и на всех таких страницах (т.е. разделы с тикетами которые) вместо облака тегов подгружаются статьи в виде блога, как на самой странице. Я так понимаю это из-за плейсхолдера [[+output]], который, по ходу, тоже Тикетсом используется. Может надо какие-то манипуляции сделать как здесь со сниппетом mSearch?

                2. Как сделать, чтобы сами теги ещё отображались в статьях на главной странице блога? С параметром
                &resources=`[[*id]]`
                ничего не выводит, видимо, не может id подцепить. А без этого параметра выводятся все используемые теги.
                1. Александр Мальцев # 0
                  Но, не используй output.
                  Сделай следующим образом:
                  <div class="panel panel-primary">
                    <div class="panel-heading">
                      <span class="glyphicon glyphicon-tags"></span> Теги
                    </div>
                    <div class="panel-body">
                      [[!pdoResources?
                        &loadModels=`tagger`
                        &class=`TaggerTag`
                        &leftJoin=`{
                          "TaggerTagResources": {
                  	  "class": "TaggerTagResource",
                  	  "on": "TaggerTag.id = TaggerTagResources.tag"
                          }
                        }`
                        &select=`{
                          "TaggerTag": "*",
                  	"TaggerTagResources": "COUNT(TaggerTagResources.tag) as countTags"
                        }`
                        &groupby=`TaggerTag.id`
                        &sortby=`TaggerTag.tag`
                        &sortdir=`ASC`  
                        &tpl=`@INLINE <a href="[[~20]]?tag=[[+alias]]" class="btn btn-primary">[[+tag]] <span class="badge">[[+countTags]]</span></a>`
                      ]]
                    </div>
                  </div>
                  
                  Если вывод статей осуществляешь с помощью getTicket, то необходимо сделать следующее:
                  1. Сделать копию чанка tpl.Tickets.list.row, например, с именем tpl.Tickets.list.row2.
                  2. Открыть чанк и добавить в него вызов TagerGetTags, например, под названием статьи:
                  <div class="tickets-row">
                    <h3 class="title"><a href="[[~[[+id]]]]">[[+pagetitle]]</a></h3>
                    [[TaggerGetTags?
                      &resources=`[[+id]]`
                      &rowTpl=`@INLINE <div class="btn-group"><span class="btn btn-primary btn-sm">#</span><a class="btn btn-info btn-sm" href="[[~20]]?tag=[[+alias]]">[[+tag]]</a></div>`
                    ]]
                  
                  3. Указать данный чанк в качестве параметра &tpl:
                  [[!pdoPage? &element=`getTickets` &tpl=`tpl.Tickets.list.row2` &limit=`5`]]
                  [[!+page.nav]]
                  
                  1. Алексей # 0
                    Александр, очередной раз огромная благодарность тебе! Всё работает. Думал, что без output не будут теги выводится)
                    По п.п. 1,2,3 у меня и так все было сделано) Надо только было
                    &resources=`[[*id]]`
                    заменить на
                    &resources=`[[+id]]`
                    Но появился такой косячок:
                    Ссылка вида
                    &rowTpl=`@INLINE <a href="[[~44]]?tag=[[+alias]]"><i class="fa fa-hashtag"></i>[[+tag]]</a>`
                    в статьях и облаке ведёт как и надо на _http://site.ru/show-posts?tag=алиас тега
                    А в разделах с тикетами, то бишь на главной станице блога на _http://site.ru/show-posts?tag=алиас статьи
                    Я так понимаю [[+alias]] перехватывается Тикетсом) Как тут-то быть?)
                    1. Александр Мальцев # 0
                      Дать другие имена:
                      &select=`{
                        "TaggerTag": "TaggerTag.tag as tagName, TaggerTag.alias as tagAlias",
                        "TaggerTagResources": "COUNT(TaggerTagResources.tag) as countTags"
                      }`
                      
                      Ну и соответственно использовать их при выводе:
                      &tpl=`@INLINE <a href="[[~20]]?tag=[[+tagAlias]]" class="btn btn-primary">[[+tagName]] <span class="badge">[[+countTags]]</span></a>`
                      
                      1. Алексей # 0
                        В облаке тегов работает как положено. А вот в самих статьях и на странице блога не подхватывает новые имена. По аналогии даже не пойму, что туда добавить нужно) Пробовал добавить select такой же. Не работает.
                        Я только не могу понять, как самому в этом начать соображать) Учить php и sql?
                        1. Александр Мальцев # 0
                          Это можно сделать с помощью pdoResources:
                          [[!pdoResources?
                            &loadModels=`tagger`
                            &class=`TaggerTagResource`
                            &leftJoin=`{
                              "ListTag": {
                                "class": "TaggerTag",
                                "on": "TaggerTagResource.tag = ListTag.id"
                              },
                              "Article": {
                                "class": "modResource",
                                "on": "TaggerTagResource.resource = Article.id"
                              }
                            }`
                            &select=`{
                              "ListTag": "ListTag.tag as tagName, ListTag.alias as tagAlias"
                            }`
                            &where=`{
                              "Article.id": "[[*id]]"
                            }`
                            &sortby=`ListTag.alias`
                            &sortdir=`ASC`  
                            &tpl= `@INLINE <div class="btn-group"><span class="btn btn-primary btn-sm">#</span><a class="btn btn-info btn-sm" href="[[~20]]?tag=[[+tagAlias]]">[[+tagName]]</a></div>`
                          ]]
                          
                          1. Алексей # 0
                            От души!
                            1. Андрей # 0
                              Александр, а как сделать вывод тегов только определенной группы при этом решении?
                  2. Андрей # 0
                    Александр, Вы можете прокомментировать, чем Ваше решение отличается от _http://realadmin.ru/saytostroy/key-word-in-modx.html? Вроде тоже самое можно сделать, только проще. Спасибо
                    1. Александр Мальцев # 0
                      Решение в представленной ссылке базируется на TV-поле. Для выборки данных используется tagLister и getResources. Здесь приведено решение на базе компонента Tagger. Функционал Tagger намного больше, чем у одного TV-поля. Вот основное отличие. Чтобы что-то дальше сравнивать необходимо проводить анализ быстродействия. Если функционал особо не нужен, то какое решение будет быстрее, то лучше. Жалко, что в указанном ресурсе нет картинок, чтобы посмотреть, что хоть там получилось…
                      1. Андрей # 0
                        Я правильно понимаю, что с помощью групп Tagger-а можно выводить теги разных категорий публикаций и разделять их? Т.е. у меня есть новости и есть раздел с нормативной базой и их можно независимо теггировать и выводить.
                        1. Александр Мальцев # 0
                          Tagger позволяет создавать группы, а уже к группам привязывать теги. Т.е. теги, например, у одной группы будут одни, а у другой — будут другие. Группы тоже можно привязывать к различным ресурсам (а точнее шаблонам).Т.е. новости могут иметь один набор тегов, а нормативная база — другие.
                    2. Алексей # 0
                      Шеф, может пригодится кому)
                      Сделал себе такие настройки и стало просто сказка)

                      Расположил под контентом, чтобы можно было всё сразу на одной странице делать) Теги можно создавать прямо при создании/редактировании материала. Не надо заранее заморачиваться. Неиспользуемые удаляются. И теги сами выводятся под списком, остаётся только мышкой нажать на нужные.
                      1. Саша # 0
                        Приветствую, Александр)
                        Я только начинаю свое знакомство с Modx и пока дается трудновато. Поэтому прошу помочь заставить работать countTags в постах, если выводим их через pdoResources. Как?
                        [[!pdoResources?
                          &loadModels=`tagger`
                          &class=`TaggerTagResource`
                          &leftJoin=`{
                            "ListTag": {
                              "class": "TaggerTag",
                              "on": "TaggerTagResource.tag = ListTag.id"
                            },
                            "Article": {
                              "class": "modResource",
                              "on": "TaggerTagResource.resource = Article.id"
                            }
                          }`
                          &select=`{
                            "ListTag": "ListTag.tag as tagName, ListTag.alias as tagAlias"
                          }`
                          &where=`{
                            "Article.id": "[[*id]]"
                          }`
                          &sortby=`ListTag.alias`
                          &sortdir=`ASC`  
                          &tpl= `@INLINE <a href="[[~23]]?tag=[[+tagAlias]]">#[[+tagName]] ([[+countTags]])</a>`
                        ]]
                        Большое спасибо за itchief.ru/lessons/modx-revo/modx-tag-cloud#comment-1392

                        Также нашел здесь же в комментариях способ привести ЧПУ к виду /tag/…
                        Так вот у меня 23 ресурс выводит статьи по тегу и ссылки имеют вид "/articles/tag?tag=jquery". Ссылку формировал как указано здесь itchief.ru/lessons/modx-revo/modx-tag-cloud#comment-1361 и .htaccess правил соответственно, но выводится белая страница при переходе /articles/tag/… что я сделал не так?
                        1. Александр Мальцев # 0
                          Здравствуйте.
                          Первый вопрос не совсем понял. Что Вы хотите сделать?
                          Во втором — необходимо проверить правильность URL (URI) в .htaccess, ресурсах и в параметрах сниппетов.
                          1. Саша # 0
                            [[+countTags]] — не выводится счетчик с общим количеством статей по тегу. Идет выборка через pdoResources, но не в облако тегов в сайдбар, а в каждой статье. Соответственно не понимаю, что дописать в данный код, чтобы начали выводится [[+countTags]] к каждому тегу из ListTag.

                            Касаемо URL меня стоит Translit и ссылки выводятся без .html на конце(Создал новый Тип содержимого HTML-NO). Формируя ссылки на теги [[+tag]] и добавив в .htaccess RewriteRule ^articles/(.*)$ /articles?tag=$1 [L] пустая страница при переходе по тегу
                            1. Александр Мальцев # 0
                              Тут необходимо выбрать в 2 этапа (например, с помощью pdoResources).
                              1 Этап. Создаём сниппет (например, mySnippet). Он будет выбирать теги текущего ресурса и выдавать на выходе некоторую строку (условие).
                              <?php
                              $pdo = $modx->getService('pdoTools');
                              $data = $modx->runSnippet('pdoResources', array(
                                'loadModels'=>'tagger',
                                'class'=>'TaggerTagResource',
                                'select' => array(
                                  'TaggerTagResource' => 'TaggerTagResource.tag'
                                ),
                                'where' => array(
                                  'TaggerTagResource.resource' => $resource 
                                ),
                                'sortby'=> 'TaggerTagResource.tag',
                                'sortdir' =>'asc',
                                'showLog' => '0',
                                'outputSeparator' => ',',
                                'tpl' => '@INLINE [[+tag]]'
                              ));
                              $data = '{"tag:IN":['.$data.']}';
                              return $data;
                              
                              На выходе получим что-то такое (где 2,4 — это id тегов текущего ресурса):
                              {"tag:IN":[2,4]}
                              2. Выбрать теги с количеством и оставить только те из них, которые соответствуют текущему ресурсу (т.е., например, 2 и 4):
                              [[!pdoResources?
                                &loadModels=`tagger`
                                &class=`TaggerTagResource`
                                &select=`{
                                  "TaggerTagResource": "TaggerTagResource.tag as tag, COUNT(TaggerTagResource.resource) as countTags",
                                  "TaggerTag" : "TaggerTag.alias"
                                }`
                                &leftJoin=`{
                                  "TaggerTag": {
                                    "class": "TaggerTag",
                                    "on": "TaggerTag.id = TaggerTagResource.tag"
                                  }
                                }`
                                &where=`[[!mySnippet? &resource=`[[*id]]`]]`	
                                &groupby=`TaggerTagResource.tag`
                                &sortby=`TaggerTagResource.tag`
                                &sortdir=`ASC`  
                                &tpl=`@INLINE <a href="[[~23]]?tag=[[+tag]]" class="btn btn-primary">[[+alias]] <span class="badge">[[+countTags]]</span></a>`
                              ]]
                              
                        2. Саша # 0
                          И ещё вопрос. В чанке «news_blog_item»(который отвечает за вывод отдельного поста в категории), если я вставляю
                          [[!TaggerGetTags?
                            &resources=`[[+id]]` 
                            &rowTpl=`@INLINE <a href="[[~29]]?tag=[[+alias]]">#[[+tag]]</a>`
                          ]]
                          теги выводятся нормально, но в ссылке вместо "[[+alias]]" выводится псевдоним поста "[[*alias]]". Почему может не срабатывать вывод алиаса тега?
                          Посты вывожу на странице коллекции так:
                          [[!pdoPage? &element=`pdoResources` &showHidden=`1` &tpl=`news_blog_item` &limit=`1` &includeTVs=`image` &parents=`[[*id]]` &hideContainers=`1` &pageNavVar=`page.nav`]] Страница [[+page]] из [[+pageCount]] [[!+page.nav]]
                          1. Алексей # 0
                            Выводи так. Тогда будет алиас тега.
                            У меня в .haccess прописано так
                            RewriteRule ^tag/(.*)$ /tag?tag=$1 [L]
                            и работает.
                            Не надо создавать новый тип содержимого. Достаточно в текущем удалить расширение. У меня тоже ссылки без html.
                            1. Александр Мальцев # 0
                              Попробуй вместо @INLINE использовать чанк.
                            2. Саша # 0
                              Александр, поможете сделать выборку в два этапа?
                              А со вторым вопросом?
                              1. Александр Мальцев # 0
                                Саша, не надо дублировать вопросы.
                                Ответ на 1 вопрос:
                                itchief.ru/lessons/modx-revo/modx-tag-cloud#comment-1821
                                Чтобы разобраться со вторым вопросом (пустая страница). Для начала посмотри, какая ошибка возникает.
                              2. Серый # 0
                                Спасибо за туториал!
                                Я пытаюсь настроить небольшой магазинчик на базе Shopkeeper`a, с tagManager`ом не срастается никак, поэтому я решил воспользоваться компонентом Tagger и без вашего урока сам бы ни за что!
                                Вобщем, всё хорошо, всё как надо, но на странице вывода связанных с тегом товаров не выводится цена товара, указанная в TV-поле. Причем, картинка, добавляемая также через TV отображается нормально, а цену не выводит((
                                Может быть как-то можно организовать вывод товаров по тегу через getProducts? Ну или просто что б цену выводил…
                                1. Серый # 0
                                  И еще у меня проблемка — для вывода getProducts я настроил для getPages параметры пагинатора внутри выражения:
                                  [[!getPage?
                                      &elementClass=`modSnippet`
                                      &element=`getProducts`
                                      &tpl=`device-card`
                                      &sortby=`pagetitle`
                                      &includeTVs=`1`
                                      &includeTVList=`price1,image`
                                      &limit=`10`
                                      &pageFirstTpl=` <li> <a [[+classes]] href="[[+href]]">Первая</a> </li> `
                                      &pageLastTpl=` <li> <a [[+classes]] href="[[+href]]">Последняя</a> </li> `
                                      &pageNextTpl=` <li> <a style="font-size:21px;line-height:17px;"[[+classes]] href="[[+href]]">→</a> </li> `
                                      &pagePrevTpl=` <li> <a style="font-size:21px;line-height:17px;"[[+classes]] href="[[+href]]">←</a> </li> `
                                      &pageActiveTpl=` <li class="active"> <a [[+classes]]">[[+pageNo]]</a> </li> `
                                  ]]
                                  <p style="display: inline-block;width: 100%;">
                                  	<ul class="pagination">
                                  		[[!+page.nav]]
                                  	</ul>
                                  </p>
                                  А когда помещаю все эти &page...Tpl в приведенное у вас выражение вставлял, почему-то не работает((
                                  1. Александр Мальцев # 0
                                    Сниппету getPage нельзя таким образом задавать шаблоны (tpl). Изменение стандартных шаблонов в getPage осуществляется через набор свойств.
                                  2. Александр # 0
                                    Здравствуйте, большое спасибо за урок.
                                    У меня возникла не большая проблема как у комментария выше. Не выводятся tv параметры на странице «вывод стайте по тегу» уж не знаю что и делать, всю голову сломал. Подскажите пожалуйста как можно наладить вывод tv параметров.
                                    Вот такая ошибка в логах.
                                    [2016-04-14 02:34:48] (ERROR @ /index.php) [pdoTools] Instantiated a derived class "TaggerTagResource" that is not a subclass of the "modResource", so tvs not joining.
                                    1. Александр Мальцев # 0
                                      Здравствуйте.
                                      В этой статье работа с тегами осуществляется с помощью компонента Tagger. TV поля не используются.
                                      1. Александр # 0
                                        А возможно подключить при выводе статей по тегу дополнительно к статье tv поле? Просто у меня через tv поле выводиться изображение к статье, а tagger выводит теги и он работает корректно.
                                    2. Андрей # 0
                                      Сделал такую выборку вместе с ms2Gallery:
                                      [[!pdoPage?
                                      	&element=`getTickets`
                                      	&tpl=`tpl.begin.blog` 
                                      	&includeContent=`1`
                                      	&ajaxMode=`default`
                                      	&limit=`6`
                                      	&hideContainers=`1`
                                              &class=`TaggerTagResource`
                                      	&loadModels=`ms2gallery,tagger` 
                                      	&tplPageWrapper=`@INLINE <nav class="pagination-wrapper"><ul class="pagination">[[+prev]][[+pages]][[+next]]</ul></nav>`
                                      	&leftJoin=`{
                                      	"600x400": {"class":"msResourceFile","alias":"600x400", "on": "600x400.resource_id = Ticket.id AND 600x400.path LIKE '%/600x400/' AND 600x400.rank=0"},
                                      	"NameTag": {"class": "TaggerTag","on": "TaggerTagResource.tag = NameTag.id"},
                                          "Posts": {"class": "modResource","on": "TaggerTagResource.resource = Posts.id"}
                                      	}`
                                      	&select=`{
                                      	"Ticket":"*",
                                      	"600x400":"600x400.url as 600x400",
                                      	"TaggerTagResource": "*",
                                          "NameTag": "NameTag.tag, NameTag.alias",
                                          "Posts": "Posts.id, Posts.pagetitle, Posts.description"
                                      	}`
                                      	&where=`{
                                          "NameTag.alias": "[[!#GET.tag]]"
                                      	}`
                                      	&sortby=`TaggerTagResource.resource`
                                      	&sortdir=`ASC`
                                      	&showLog=`1`
                                      	]]
                                      Пишет что у него поля выборки нет
                                      0.0000272: Loaded model "ms2gallery" from "//home/admin/web/10lic.ru/private/core/components/ms2gallery/model/"
                                      0.0000100: Loaded model "tagger" from "//home/admin/web/10lic.ru/private/core/components/tagger/model/"
                                      0.0000472: Query parameters are prepared.
                                      0.0000439: xPDO query object created
                                      0.0002000: leftJoined TicketsSection as Section
                                      0.0001440: leftJoined modUser as User
                                      0.0001509: leftJoined modUserProfile as Profile
                                      0.0001478: leftJoined msResourceFile as 600x400
                                      0.0006709: leftJoined TaggerTag as NameTag
                                      0.0001569: leftJoined modResource as Posts
                                      0.0000041: Grouped by Ticket.id
                                      0.0001259: Added selection of TicketsSection: SQL_CALC_FOUND_ROWS `id` AS `section.id`, `type` AS `section.type`, `contentType` AS `section.contentType`, `pagetitle` AS `section.pagetitle`, `longtitle` AS `section.longtitle`, `description` AS `section.description`, `alias` AS `section.alias`, `link_attributes` AS `section.link_attributes`, `published` AS `section.published`, `pub_date` AS `section.pub_date`, `unpub_date` AS `section.unpub_date`, `parent` AS `section.parent`, `isfolder` AS `section.isfolder`, `introtext` AS `section.introtext`, `richtext` AS `section.richtext`, `template` AS `section.template`, `menuindex` AS `section.menuindex`, `searchable` AS `section.searchable`, `cacheable` AS `section.cacheable`, `createdby` AS `section.createdby`, `createdon` AS `section.createdon`, `editedby` AS `section.editedby`, `editedon` AS `section.editedon`, `deleted` AS `section.deleted`, `deletedon` AS `section.deletedon`, `deletedby` AS `section.deletedby`, `publishedon` AS `section.publishedon`, `publishedby` AS `section.publishedby`, `menutitle` AS `section.menutitle`, `donthit` AS `section.donthit`, `privateweb` AS `section.privateweb`, `privatemgr` AS `section.privatemgr`, `content_dispo` AS `section.content_dispo`, `hidemenu` AS `section.hidemenu`, `class_key` AS `section.class_key`, `context_key` AS `section.context_key`, `content_type` AS `section.content_type`, `uri` AS `section.uri`, `uri_override` AS `section.uri_override`, `hide_children_in_tree` AS `section.hide_children_in_tree`, `show_in_tree` AS `section.show_in_tree`, `properties` AS `section.properties`
                                      0.0000241: Added selection of modUser: `username`
                                      0.0000470: Added selection of modUserProfile: `internalKey`, `fullname`, `email`, `phone`, `mobilephone`, `blocked`, `blockeduntil`, `blockedafter`, `logincount`, `lastlogin`, `thislogin`, `failedlogincount`, `sessionid`, `dob`, `gender`, `address`, `country`, `city`, `state`, `zip`, `fax`, `photo`, `comment`, `website`, `extended`
                                      0.0002232: Added selection of Ticket: `id`, `type`, `contentType`, `pagetitle`, `longtitle`, `description`, `alias`, `link_attributes`, `published`, `pub_date`, `unpub_date`, `parent`, `isfolder`, `introtext`, `content`, `richtext`, `template`, `menuindex`, `searchable`, `cacheable`, `createdby`, `createdon`, `editedby`, `editedon`, `deleted`, `deletedon`, `deletedby`, `publishedon`, `publishedby`, `menutitle`, `donthit`, `privateweb`, `privatemgr`, `content_dispo`, `hidemenu`, `class_key`, `context_key`, `content_type`, `uri`, `uri_override`, `hide_children_in_tree`, `show_in_tree`, `properties`
                                      0.0000331: Added selection of msResourceFile: 600x400.url as 600x400
                                      0.0000858: Added selection of TaggerTagResource: `tag`, `resource`
                                      0.0000339: Added selection of TaggerTag: NameTag.tag, NameTag.alias
                                      0.0000319: Added selection of modResource: Posts.id, Posts.pagetitle, Posts.description
                                      0.0002210: Added where condition: class_key=Ticket, NameTag.alias=esn
                                      0.0000720: Sorted by TaggerTagResource.resource, ASC
                                      0.0000060: Limited to 6, offset 0
                                      0.0007141: SQL prepared "SELECT SQL_CALC_FOUND_ROWS `Section`.`id` AS `section.id`, `Section`.`type` AS `section.type`, `Section`.`contentType` AS `section.contentType`, `Section`.`pagetitle` AS `section.pagetitle`, `Section`.`longtitle` AS `section.longtitle`, `Section`.`description` AS `section.description`, `Section`.`alias` AS `section.alias`, `Section`.`link_attributes` AS `section.link_attributes`, `Section`.`published` AS `section.published`, `Section`.`pub_date` AS `section.pub_date`, `Section`.`unpub_date` AS `section.unpub_date`, `Section`.`parent` AS `section.parent`, `Section`.`isfolder` AS `section.isfolder`, `Section`.`introtext` AS `section.introtext`, `Section`.`richtext` AS `section.richtext`, `Section`.`template` AS `section.template`, `Section`.`menuindex` AS `section.menuindex`, `Section`.`searchable` AS `section.searchable`, `Section`.`cacheable` AS `section.cacheable`, `Section`.`createdby` AS `section.createdby`, `Section`.`createdon` AS `section.createdon`, `Section`.`editedby` AS `section.editedby`, `Section`.`editedon` AS `section.editedon`, `Section`.`deleted` AS `section.deleted`, `Section`.`deletedon` AS `section.deletedon`, `Section`.`deletedby` AS `section.deletedby`, `Section`.`publishedon` AS `section.publishedon`, `Section`.`publishedby` AS `section.publishedby`, `Section`.`menutitle` AS `section.menutitle`, `Section`.`donthit` AS `section.donthit`, `Section`.`privateweb` AS `section.privateweb`, `Section`.`privatemgr` AS `section.privatemgr`, `Section`.`content_dispo` AS `section.content_dispo`, `Section`.`hidemenu` AS `section.hidemenu`, `Section`.`class_key` AS `section.class_key`, `Section`.`context_key` AS `section.context_key`, `Section`.`content_type` AS `section.content_type`, `Section`.`uri` AS `section.uri`, `Section`.`uri_override` AS `section.uri_override`, `Section`.`hide_children_in_tree` AS `section.hide_children_in_tree`, `Section`.`show_in_tree` AS `section.show_in_tree`, `Section`.`properties` AS `section.properties`, `User`.`username`, `Profile`.`internalKey`, `Profile`.`fullname`, `Profile`.`email`, `Profile`.`phone`, `Profile`.`mobilephone`, `Profile`.`blocked`, `Profile`.`blockeduntil`, `Profile`.`blockedafter`, `Profile`.`logincount`, `Profile`.`lastlogin`, `Profile`.`thislogin`, `Profile`.`failedlogincount`, `Profile`.`sessionid`, `Profile`.`dob`, `Profile`.`gender`, `Profile`.`address`, `Profile`.`country`, `Profile`.`city`, `Profile`.`state`, `Profile`.`zip`, `Profile`.`fax`, `Profile`.`photo`, `Profile`.`comment`, `Profile`.`website`, `Profile`.`extended`, `Ticket`.`id`, `Ticket`.`type`, `Ticket`.`contentType`, `Ticket`.`pagetitle`, `Ticket`.`longtitle`, `Ticket`.`description`, `Ticket`.`alias`, `Ticket`.`link_attributes`, `Ticket`.`published`, `Ticket`.`pub_date`, `Ticket`.`unpub_date`, `Ticket`.`parent`, `Ticket`.`isfolder`, `Ticket`.`introtext`, `Ticket`.`content`, `Ticket`.`richtext`, `Ticket`.`template`, `Ticket`.`menuindex`, `Ticket`.`searchable`, `Ticket`.`cacheable`, `Ticket`.`createdby`, `Ticket`.`createdon`, `Ticket`.`editedby`, `Ticket`.`editedon`, `Ticket`.`deleted`, `Ticket`.`deletedon`, `Ticket`.`deletedby`, `Ticket`.`publishedon`, `Ticket`.`publishedby`, `Ticket`.`menutitle`, `Ticket`.`donthit`, `Ticket`.`privateweb`, `Ticket`.`privatemgr`, `Ticket`.`content_dispo`, `Ticket`.`hidemenu`, `Ticket`.`class_key`, `Ticket`.`context_key`, `Ticket`.`content_type`, `Ticket`.`uri`, `Ticket`.`uri_override`, `Ticket`.`hide_children_in_tree`, `Ticket`.`show_in_tree`, `Ticket`.`properties`, 600x400.url as 600x400, `TaggerTagResource`.`tag`, `TaggerTagResource`.`resource`, NameTag.tag, NameTag.alias, Posts.id, Posts.pagetitle, Posts.description FROM `lic10_tagger_tag_resources` AS `TaggerTagResource` LEFT JOIN `lic10_site_content` `Section` ON `Section`.`id` = `Ticket`.`parent` LEFT JOIN `lic10_users` `User` ON `User`.`id` = `Ticket`.`createdby` LEFT JOIN `lic10_user_attributes` `Profile` ON `Profile`.`internalKey` = `User`.`id` LEFT JOIN `lic10_ms2_resource_files` `600x400` ON 600x400.resource_id = Ticket.id AND 600x400.path LIKE '%/600x400/' AND 600x400.rank=0 LEFT JOIN `lic10_tagger_tags` `NameTag` ON TaggerTagResource.tag = NameTag.id LEFT JOIN `lic10_site_content` `Posts` ON TaggerTagResource.resource = Posts.id WHERE  ( `TaggerTagResource`.`class_key` = 'Ticket' AND `NameTag`.`alias` = 'esn' )  GROUP BY Ticket.id ORDER BY TaggerTagResource.resource ASC LIMIT 6 "
                                      0.0009739: Could not process query, error #1054: Unknown column 'Ticket.id' in 'field list'
                                      0.0000122: Returning processed chunks
                                      0.3597610: Total time
                                      13 893 632: Memory usage
                                      Помогите пожалуйста
                                      1. Александр Мальцев # 0
                                        У Вас ошибка в первом leftJoin, т.к. она, не как ни связана с TaggerTagResource.
                                        1. Андрей # 0
                                          Такой вывод нужен из-за использования 1-го изображения галереи ms2gallery, чтобы потом не заполнять отдельно фото анонса. Как же быть в этой ситуации, сможете подсказать? Спасибо
                                          1. Александр Мальцев # 0
                                            Попробуйте в первом leftJoin поменять Ticket.id на TaggerTagResource.resource.
                                            1. Андрей # 0
                                              Я в отчаянии
                                              &leftJoin=`{
                                              	"600x400": {"class":"msResourceFile","alias":"600x400", "on": "600x400.resource_id = TaggerTagResource.resource AND 600x400.path LIKE '%/600x400/' AND 600x400.rank=0"},
                                              	"NameTag": {"class": "TaggerTag","on": "TaggerTagResource.tag = NameTag.id"},
                                                  "Posts": {"class": "modResource","on": "TaggerTagResource.resource = Posts.id"}
                                              	}`
                                              0.0008740: Could not process query, error #1054: Unknown column 'Ticket.id' in 'field list'
                                              1. Андрей # 0
                                                Заработало только с &element=`pdoResources` вместо &element=`getTickets` только теперь [[+fullname]] не работает и другие плюшки тикета
                                                1. Дмитрий # 0
                                                  Здравствуйте! У меня такая же проблема, вы разобрались как подружить Tickets и Tagger?
                                                  1. Александр Мальцев # 0
                                                    Используйте вместо modResource его расширенную версию Ticket
                                                    "Posts": { "class": "Ticket", "on": "TaggerTagResources.resource = Posts.id"}
                                                    
                                      2. Владимир # 0
                                        Привет всем.
                                        show for templates без доп. условия (например связи с родительским ресурсом) расстроил. В трех контекстах у меня одинаковые шаблоны для трех разных языков, а вот теги надо разные. Соответственно, в админке сейчас выводятся все три варианта (три группы), боюсь менеджеры будут путаться.
                                        Может у кого то есть мысли, простой костыль, что бы показывать в админке строго в связи с родительским ресурсом?
                                        1. Данил # 0
                                          Была страница на которой с помощью pdoresources выводились дочерние. После установки tagger и прикрепления группы к шаблону дочерних элементов, перестало заходить на страницу где выводились дочерние, 404. Тэгов даже создать не успел. Что я сделал не так?
                                          1. Александр Мальцев # 0
                                            Смотрите журнал ошибок MODX, может он что подскажет.
                                          2. Шведов Дмитрий # 0
                                            Здравствуйте, у меня такая проблема!
                                            Начал тестировать сайт и вот что заметил.

                                            1) Главный вопрос! После удаления нескольких статей, у которых были теги, в облаке тегов они продолжали висеть. Сейчас в итоге есть одна статья с двумя тегами, остальные удалил, почистил кэш. В облаке тегов остались все теги активными и количество статей осталось прежним, как будто он запомнил id статей и продолжает их выводить, не смотря на то что они удалены.

                                            Облако вставлено на самой странице «Статьи» и «Поиск по тегам».
                                            Теги выводятся в «Статьи», «Поиск по тегам», «Статья»
                                            Код облака:
                                            [[!pdoResources?
                                                &loadModels=`tagger`
                                                &class=`TaggerTag`
                                                &leftJoin=`{
                                                    "TaggerTagResources": {
                                                        "class": "TaggerTagResource",
                                                        "on": "TaggerTag.id = TaggerTagResources.tag"
                                                    }
                                                }`
                                                &select=`{
                                                    "TaggerTag": "*",
                                                    "TaggerTagResources": "COUNT(TaggerTagResources.tag) as countTags"
                                                }`
                                                &groupby=`TaggerTag.id`
                                                &sortby=`TaggerTag.tag`
                                                &sortdir=`ASC`  
                                                &tpl=`@INLINE <a href="[[~70]]?tag=[[+alias]]">[[+tag]] <span class="badge">[[+countTags]]</span></a>`
                                            ]]
                                            
                                            2) Так же в настройках пакета обнаружил, что настройки не работают вообще. Какие бы я галочки не убирал или ставил, они не на что не влияют.
                                            a) Создать тег в настройках статьи я не могу, не смотря на то что галочка стоит (Разрешать создание новых).
                                            b) Удалять не используемые теги — не удаляет
                                            c) При попытке ввести новый тег, выпадает список из уже имеющихся, хотя в настройках стоит показывать «Поле тегов». Но показывает и поле и список.
                                            Может что у меня не так, не знаю.
                                            Заранее спасибо :)
                                            1. Шведов Дмитрий # 0
                                              Второй пункт исправил, пришлось все переустановить. Но вот с удаление все так же. Причем на странице «Поиск по тегам» выводит пустые чанки удаленных статей. Я думаю это не сложно делается, но понятия не имею как это исправить.
                                              1. Александр Мальцев # 0
                                                Добавьте условие, чтобы он не выбирал удалённые:
                                                [[!pdoResources?
                                                    &loadModels=`tagger`
                                                    &class=`TaggerTag`
                                                    &leftJoin=`{
                                                        "TaggerTagResources": {
                                                            "class": "TaggerTagResource",
                                                            "on": "TaggerTag.id = TaggerTagResources.tag"
                                                        },
                                                        "Posts": {
                                                          "class": "modResource",
                                                          "on": "TaggerTagResources.resource = Posts.id"
                                                        }
                                                    }`
                                                    &where=`{
                                                      "Posts.deleted": "0"
                                                    }`
                                                    &select=`{
                                                        "TaggerTag": "*",
                                                        "TaggerTagResources": "COUNT(TaggerTagResources.tag) as countTags"
                                                    }`
                                                    &groupby=`TaggerTag.id`
                                                    &sortby=`TaggerTag.tag`
                                                    &sortdir=`ASC`  
                                                    &tpl=`@INLINE <a href="[[~70]]?tag=[[+alias]]">[[+tag]] <span class="badge">[[+countTags]]</span></a>`
                                                ]]
                                                
                                                1. Шведов Дмитрий # 0
                                                  Вот еще проблема, я думаю это связанно как то с привязкой к id. Если запись не опубликована, то в «Поиск по тегам она отображается» :(
                                                  1. Александр Мальцев # 0
                                                    Да, по связям в таблицах.
                                                    Добавьте условие, чтобы вызов сниппета выбирал только опубликовынные:
                                                    [[!pdoPage?
                                                      &element = `pdoResources`
                                                      &limit=`5`
                                                      &loadModels=`tagger`
                                                      &class=`TaggerTagResource`
                                                      &leftJoin=`{
                                                        "NameTag": {
                                                          "class": "TaggerTag",
                                                          "on": "TaggerTagResource.tag = NameTag.id"
                                                        },
                                                        "Posts": {
                                                          "class": "modResource",
                                                          "on": "TaggerTagResource.resource = Posts.id"
                                                        }
                                                      }`
                                                      &select=`{
                                                        "TaggerTagResource": "*",
                                                        "NameTag": "NameTag.tag, NameTag.alias",
                                                        "Posts": "Posts.id, Posts.pagetitle, Posts.description, Posts.published"
                                                      }`
                                                      &where=`{
                                                        "NameTag.alias": "[[!#GET.tag]]",
                                                        "Posts.published": "1"
                                                      }`
                                                      &sortby=`TaggerTagResource.resource`
                                                      &sortdir=`ASC`
                                                      &tplWrapper =`@INLINE <h2 class="h3">Всего результатов: [[+page.total]]</h2>[[+output]]`
                                                      &tpl= `chunkTagRow`
                                                    ]]
                                                    [[!+page.nav]]
                                                    
                                                    Тогда и выше в коде замени
                                                    "Posts.deleted": "0"
                                                    
                                                    на
                                                    "Posts.published": "1"
                                                    
                                                  2. Александр Мальцев # 0
                                                    Для создания новых — одной галочки «Разрешать создание новых» недостаточно. Ещё необходимо установить галочку «Разрешённые типы», иначе Вы не сможете вводить значение в это поле.

                                                    Удалять не используемые теги работает только если этих тегов нет в базе данных.

                                                    Там всё просто достаточно разобраться, что означает каждая из галочек.
                                                    1. Шведов Дмитрий # 0
                                                      Все работает, огромное спасибо. Отдельное спасибо за оперативность!
                                                  3. Алексей # 0
                                                    Добрый день, Александр.
                                                    Нашел ваш сайт, при попытке настроить Tagger для работы с магазином Minishop2 и mfilter2.
                                                    Я понимаю, что вполне может быть вы не сталкивались с этими дополнениями, но решил попытать удачу.
                                                    Если сможете, подскажите пожалуйста, как можно заставить товары фильтроваться по тегам Taggera.
                                                    Насколько я знаю для вывода в minishop используется тот же pdopage и pdoresources.
                                                    Я нашел заметку, все сделал вроде как нужно modx.pro/news/6318-minishop2-tagger/
                                                    Осталось лишь написать правильный вызов сниппета, а с этим беда(
                                                    Заранее огромная благодарнасть за любую помощь, даже за намек куда копать.
                                                    1. Александр Мальцев # 0
                                                      Добрый. В minishop 2 есть же своя система тегов.
                                                      1. Алексей # 0
                                                        Беда в том, что эти теги не совсем полноценные в части построения урл, если использовать их, то будут например такие ссылки:
                                                        sitename.ru/catalog/odezhda/?tag=Для детей
                                                        А требовались нормальные с транслитом и без get запросов, поэтому пришлось воспользоваться сторонним плагином, с отдельной таблицей, в которой есть поле alias.
                                                        В любом случае спасибо, что откликнулись. Два дня мучений и я справился с этим, расширив класс mfiter2.
                                                    2. Валерий # 0
                                                      Александр, добрый день.
                                                      В комментариях не нашел ответа, может быть так подскажите.

                                                      Я использую вывод материалов через pdoPage с TV-полями (4 поля). У меня так и не вышло заставить систему видеть эти поля на страничке вывода тегов. Большее, что вышло — это вывести одно из полей. Такой записью (лишнее удалил):

                                                      &leftJoin=`{
                                                      "Tv": {
                                                          "class": "modTemplateVarResource",
                                                          "on": "TaggerTagResource.resource = Tv.contentid AND Tv.tmplvarid = 28"
                                                      }
                                                      }`
                                                      &select=`{
                                                          "Tv": "Tv.value as switch_style"
                                                      }`
                                                      Если добавлять в строку «Tv.value as switch_style» через запятую «Tv.value as preview_300_img», то выводится все равно одно поле, последнее. Это и понятно. А как сформировать конструкцию так, чтобы подключить 4 TV?

                                                      Спасибо.
                                                      1. Валерий # 0
                                                        На данный момент сделал при помощи FastField — [[#[[+id]].switch_style]], но эта конструкция выполняется почти в 12 раз медленней (Total time: ~ 0.01 без нее против ~ 0.12 с ней). Что ужасно, с учетом, что всего 4 записи выводится…
                                                        1. Александр Мальцев # 0
                                                          Здравствуйте, Валерий.
                                                          Для этого необходимо подключить несколько TV-полей (а не одно):
                                                          &leftJoin=`{
                                                            ...,  
                                                            "TV1": {
                                                              "class": "modTemplateVarResource",
                                                              "on": "TaggerTagResource.resource = TV1.contentid and TV1.tmplvarid=2"
                                                            },
                                                            "TV2": {
                                                              "class": "modTemplateVarResource",
                                                              "on": "TaggerTagResource.resource = TV2.contentid and TV2.tmplvarid=3"
                                                            },
                                                            ...
                                                          }`
                                                          &select=`{
                                                            ...,
                                                            "TV1": "TV1.value as tv1",
                                                            "TV2": "TV2.value as tv2",
                                                            ...
                                                          }`
                                                          
                                                          1. Валерий # 0
                                                            Все-таки наращивать таким образом… Спасибо за пример! :) Так заработало. Но забавный момент — эта запись оказалось занимает больше времени, чем моя версия с FastField… При этом, первый раз FastField отнимает почти столько же секунд (около 0.28) и чуть больше оперативной памяти (если я правильно читаю логи — 11 010 048), но во второй и последующие уже почти на 1 секунды быстрее и памяти столько же, сколько запись через LeftJoin.
                                                            1. Александр Мальцев # 0
                                                              Тогда можно написать свой собственный сниппет.
                                                        2. Тим # 0
                                                          Приветствую, никак не получается связать вывод статей по тегам c Tickets.
                                                          [[!pdoPage?
                                                            &element = `getTickets`
                                                            &limit=`2`
                                                            &loadModels=`tagger`
                                                            &class=`TaggerTagResource`
                                                            &leftJoin=`{
                                                              "NameTag": {
                                                                "class": "TaggerTag",
                                                                "on": "TaggerTagResource.tag = NameTag.id"
                                                              },
                                                              "Posts": {
                                                                "class": "Ticket",
                                                                "on": "TaggerTagResource.resource = Posts.id"
                                                              }
                                                            }`
                                                            &select=`{
                                                              "TaggerTagResource": "*",
                                                              "NameTag": "NameTag.tag, NameTag.alias",
                                                              "Posts": "Posts.id, Posts.pagetitle, Posts.description"
                                                            }`
                                                            &where=`{
                                                              "NameTag.alias": "[[!#GET.tag]]"
                                                            }`
                                                            &sortby=`TaggerTagResource.resource`
                                                            &sortdir=`ASC`  
                                                            &tplWrapper =`@INLINE <h2 class="h3">Всего результатов: [[+page.total]]</h2>[[+output]]`
                                                            &tpl= `tpl.main-block-list`
                                                            &showLog=`1`
                                                          ]]
                                                          [[!+page.nav]]
                                                          Лог:
                                                          0.0000319: Loaded model "tagger" from "/core/components/tagger/model/"
                                                          0.0000560: Query parameters are prepared.
                                                          0.0000660: xPDO query object created
                                                          0.0002029: leftJoined TicketsSection as Section
                                                          0.0001142: leftJoined modUser as User
                                                          0.0001090: leftJoined modUserProfile as Profile
                                                          0.0008969: leftJoined TicketTotal as Total
                                                          0.0006142: leftJoined TaggerTag as NameTag
                                                          0.0001180: leftJoined Ticket as Posts
                                                          0.0000050: Grouped by Ticket.id
                                                          0.0001419: Added selection of TicketsSection: SQL_CALC_FOUND_ROWS `id` AS `section.id`, `type` AS `section.type`, `contentType` AS `section.contentType`, `pagetitle` AS `section.pagetitle`, `longtitle` AS `section.longtitle`, `description` AS `section.description`, `alias` AS `section.alias`, `link_attributes` AS `section.link_attributes`, `published` AS `section.published`, `pub_date` AS `section.pub_date`, `unpub_date` AS `section.unpub_date`, `parent` AS `section.parent`, `isfolder` AS `section.isfolder`, `introtext` AS `section.introtext`, `richtext` AS `section.richtext`, `template` AS `section.template`, `menuindex` AS `section.menuindex`, `searchable` AS `section.searchable`, `cacheable` AS `section.cacheable`, `createdby` AS `section.createdby`, `createdon` AS `section.createdon`, `editedby` AS `section.editedby`, `editedon` AS `section.editedon`, `deleted` AS `section.deleted`, `deletedon` AS `section.deletedon`, `deletedby` AS `section.deletedby`, `publishedon` AS `section.publishedon`, `publishedby` AS `section.publishedby`, `menutitle` AS `section.menutitle`, `donthit` AS `section.donthit`, `privateweb` AS `section.privateweb`, `privatemgr` AS `section.privatemgr`, `content_dispo` AS `section.content_dispo`, `hidemenu` AS `section.hidemenu`, `class_key` AS `section.class_key`, `context_key` AS `section.context_key`, `content_type` AS `section.content_type`, `uri` AS `section.uri`, `uri_override` AS `section.uri_override`, `hide_children_in_tree` AS `section.hide_children_in_tree`, `show_in_tree` AS `section.show_in_tree`, `properties` AS `section.properties`
                                                          0.0000222: Added selection of modUser: `username`
                                                          0.0000350: Added selection of modUserProfile: `internalKey`, `fullname`, `email`, `phone`, `mobilephone`, `blocked`, `blockeduntil`, `blockedafter`, `logincount`, `lastlogin`, `thislogin`, `failedlogincount`, `sessionid`, `dob`, `gender`, `address`, `country`, `city`, `state`, `zip`, `fax`, `photo`, `comment`, `website`, `extended`
                                                          0.0000460: Added selection of Ticket: `id`, `type`, `contentType`, `pagetitle`, `longtitle`, `description`, `alias`, `link_attributes`, `published`, `pub_date`, `unpub_date`, `parent`, `isfolder`, `introtext`, `richtext`, `template`, `menuindex`, `searchable`, `cacheable`, `createdby`, `createdon`, `editedby`, `editedon`, `deleted`, `deletedon`, `deletedby`, `publishedon`, `publishedby`, `menutitle`, `donthit`, `privateweb`, `privatemgr`, `content_dispo`, `hidemenu`, `class_key`, `context_key`, `content_type`, `uri`, `uri_override`, `hide_children_in_tree`, `show_in_tree`, `properties`
                                                          0.0001130: Added selection of TicketTotal: `comments`, `views`, `stars`, `rating`, `rating_plus`, `rating_minus`
                                                          0.0000679: Added selection of TaggerTagResource: `tag`, `resource`
                                                          0.0000339: Added selection of TaggerTag: NameTag.tag, NameTag.alias
                                                          0.0000231: Added selection of Ticket: Posts.id, Posts.pagetitle, Posts.description
                                                          0.0001919: Added where condition: class_key=Ticket, NameTag.alias=test
                                                          0.0000770: Sorted by TaggerTagResource.resource, ASC
                                                          0.0000069: Limited to 2, offset 0
                                                          0.0006270: SQL prepared "SELECT SQL_CALC_FOUND_ROWS `Section`.`id` AS `section.id`, `Section`.`type` AS `section.type`, `Section`.`contentType` AS `section.contentType`, `Section`.`pagetitle` AS `section.pagetitle`, `Section`.`longtitle` AS `section.longtitle`, `Section`.`description` AS `section.description`, `Section`.`alias` AS `section.alias`, `Section`.`link_attributes` AS `section.link_attributes`, `Section`.`published` AS `section.published`, `Section`.`pub_date` AS `section.pub_date`, `Section`.`unpub_date` AS `section.unpub_date`, `Section`.`parent` AS `section.parent`, `Section`.`isfolder` AS `section.isfolder`, `Section`.`introtext` AS `section.introtext`, `Section`.`richtext` AS `section.richtext`, `Section`.`template` AS `section.template`, `Section`.`menuindex` AS `section.menuindex`, `Section`.`searchable` AS `section.searchable`, `Section`.`cacheable` AS `section.cacheable`, `Section`.`createdby` AS `section.createdby`, `Section`.`createdon` AS `section.createdon`, `Section`.`editedby` AS `section.editedby`, `Section`.`editedon` AS `section.editedon`, `Section`.`deleted` AS `section.deleted`, `Section`.`deletedon` AS `section.deletedon`, `Section`.`deletedby` AS `section.deletedby`, `Section`.`publishedon` AS `section.publishedon`, `Section`.`publishedby` AS `section.publishedby`, `Section`.`menutitle` AS `section.menutitle`, `Section`.`donthit` AS `section.donthit`, `Section`.`privateweb` AS `section.privateweb`, `Section`.`privatemgr` AS `section.privatemgr`, `Section`.`content_dispo` AS `section.content_dispo`, `Section`.`hidemenu` AS `section.hidemenu`, `Section`.`class_key` AS `section.class_key`, `Section`.`context_key` AS `section.context_key`, `Section`.`content_type` AS `section.content_type`, `Section`.`uri` AS `section.uri`, `Section`.`uri_override` AS `section.uri_override`, `Section`.`hide_children_in_tree` AS `section.hide_children_in_tree`, `Section`.`show_in_tree` AS `section.show_in_tree`, `Section`.`properties` AS `section.properties`, `User`.`username`, `Profile`.`internalKey`, `Profile`.`fullname`, `Profile`.`email`, `Profile`.`phone`, `Profile`.`mobilephone`, `Profile`.`blocked`, `Profile`.`blockeduntil`, `Profile`.`blockedafter`, `Profile`.`logincount`, `Profile`.`lastlogin`, `Profile`.`thislogin`, `Profile`.`failedlogincount`, `Profile`.`sessionid`, `Profile`.`dob`, `Profile`.`gender`, `Profile`.`address`, `Profile`.`country`, `Profile`.`city`, `Profile`.`state`, `Profile`.`zip`, `Profile`.`fax`, `Profile`.`photo`, `Profile`.`comment`, `Profile`.`website`, `Profile`.`extended`, `Ticket`.`id`, `Ticket`.`type`, `Ticket`.`contentType`, `Ticket`.`pagetitle`, `Ticket`.`longtitle`, `Ticket`.`description`, `Ticket`.`alias`, `Ticket`.`link_attributes`, `Ticket`.`published`, `Ticket`.`pub_date`, `Ticket`.`unpub_date`, `Ticket`.`parent`, `Ticket`.`isfolder`, `Ticket`.`introtext`, `Ticket`.`richtext`, `Ticket`.`template`, `Ticket`.`menuindex`, `Ticket`.`searchable`, `Ticket`.`cacheable`, `Ticket`.`createdby`, `Ticket`.`createdon`, `Ticket`.`editedby`, `Ticket`.`editedon`, `Ticket`.`deleted`, `Ticket`.`deletedon`, `Ticket`.`deletedby`, `Ticket`.`publishedon`, `Ticket`.`publishedby`, `Ticket`.`menutitle`, `Ticket`.`donthit`, `Ticket`.`privateweb`, `Ticket`.`privatemgr`, `Ticket`.`content_dispo`, `Ticket`.`hidemenu`, `Ticket`.`class_key`, `Ticket`.`context_key`, `Ticket`.`content_type`, `Ticket`.`uri`, `Ticket`.`uri_override`, `Ticket`.`hide_children_in_tree`, `Ticket`.`show_in_tree`, `Ticket`.`properties`, `Total`.`comments`, `Total`.`views`, `Total`.`stars`, `Total`.`rating`, `Total`.`rating_plus`, `Total`.`rating_minus`, `TaggerTagResource`.`tag`, `TaggerTagResource`.`resource`, NameTag.tag, NameTag.alias, Posts.id, Posts.pagetitle, Posts.description FROM `modx_tagger_tag_resources` AS `TaggerTagResource` LEFT JOIN `modx_site_content` `Section` ON `Section`.`id` = `Ticket`.`parent` LEFT JOIN `modx_users` `User` ON `User`.`id` = `Ticket`.`createdby` LEFT JOIN `modx_user_attributes` `Profile` ON `Profile`.`internalKey` = `User`.`id` LEFT JOIN `modx_tickets_totals` `Total` ON  LEFT JOIN `modx_tagger_tags` `NameTag` ON TaggerTagResource.tag = NameTag.id LEFT JOIN `modx_site_content` `Posts` ON TaggerTagResource.resource = Posts.id WHERE  ( `TaggerTagResource`.`class_key` = 'Ticket' AND `NameTag`.`alias` = 'test' )  GROUP BY Ticket.id ORDER BY TaggerTagResource.resource ASC LIMIT 2 "
                                                          0.0003991: Could not process query, error #1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'JOIN `modx_tagger_tags` `NameTag` ON TaggerTagResource.tag = NameTag.id LEFT JOI' at line 1
                                                          0.0000250: Returning processed chunks
                                                          0.0156150: Total time
                                                          13 631 488: Memory usage
                                                          Пробовал использовать стандартный &where=`[[!TaggerGetResourcesWhere? &tags=`tag` &where=`{«isfolder»: 0}`]]` тоже не получилось.
                                                          Посмотрите, пожалуйста, что может быть не так.
                                                          1. Александр Мальцев # 0
                                                            Не используйте getTickets. Вместо него применяйте pdoResources. Это связано с тем, что сниппет getTicket не может выполнить то же самое, что и pdoResources, хоть и базируется на его основе.
                                                            1. Тим # 0
                                                              Спасибо за ответ! Пробовал такой вариант, не получилось с помощью pdoResources получить переменные getTickets.
                                                              1. Александр Мальцев # 0
                                                                Для этого необходимо настроить параметр &select и при необходимости, если нужны данные из других таблиц (объектов), присоединить их с помощью &leftJoin.
                                                          2. Александр # 0
                                                            Добрый день!
                                                            Возможно ли вывести облако тегов не на странице материала, а только на странице родительского каталога материалов, к которому относится этот материал?
                                                            Спасибо!
                                                            1. Тим # 0
                                                              [[*isfolder:is=`1`:then=`[[чанк_облака_тегов]]`:else=`[[чанк_материала]]`]]
                                                              Выведет чанк тегов только в документах-контейнерах.
                                                              1. Александр # 0
                                                                Так не работает. Мне нужно что бы соответствующее облако выводилось только в том контейнере, в котором материал имеет тег. Сейчас же во всех контейнерах выводится группа тегов, которая к контейнеру не имеет отношение.

                                                                Пример: контейнер1. В нем материал1 с тегом «тест1». И контейнер2. В нем материал2 с тегом «тест2».
                                                                Нужно вывести в контейнере1 тег «тест1», а в контейнере2- «тест2».
                                                                Может есть возможность присвоить группу тегов к определенному контейнеру?
                                                                1. Александр Мальцев # 0
                                                                  Запрос будет сложный. Здесь либо писать свой сниппет, ли использовать группы. Группу можно назначить к шаблонам.

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