Компонент Tagger для создания в MODx тегов

Tagger - это достаточно удобный компонент, который добавляет в MODX теги и категории. Позволяет создать облако тегов и страницу с выводом тематических материалов по тегам

1. Установка Tagger

Скачиваем пакет tagger из репозитория. Кроме tagger вам понадобится pdoTools (скорее всего он у вас уже установлен). Установку необходимых компонентов произведём на странице "Управление пакетами" (Приложения -> Установщик)

После установки tagger будет доступен из верхнего меню.

2. Создание группы тегов

На первом этапе необходимо создать новую группу (теги не могут сами по себе существовать, они должны принадлежать к той или иной группе, поэтому работа с tagger всегда начинается с создания группы). Панель управления компонентом имеет две закладки: теги и группы. Переходим во вкладку группы и нажимаем "Создать новую группу"

Компонент Tagger

Основные поля для заполнения:

  • Название: Теги для статей (здесь лучше задать конкретное понятное название, оно понадобится при создании новых тегов)
  • Описание: (в моем случае оставил незаполненным, поскольку используется лишь одна группа, ее суть понятна из названия)
  • Псевдоним: tags (это значение будет отображаться в URL, поэтому маленькими латинскими буквами, с понятным смыслом)
  • Место: в отдельной вкладке (это то, каким образом и в какой вкладке будет отображаться управление тегами, для вкладки доп. параметры еще можно указать расположение: выше или ниже)
  • Показывать для шаблонов: номера id шаблонов, для которых необходимо выводить теги
  • Разрешать пустые: ставим галочку (чтобы можно было использовать страницы без тегов)

Остальные параметры я оставил по умолчанию (их назначение подробно описано во всплывающих подсказках)

Нажимаем сохранить - теперь у нас есть группа "Теги для статей".

3. Создание тегов

Переходим к созданию тегов. Кликаем на вкладку Tags и создадим теги в группе "Теги для статей".

Компонент Tagger

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

  • Название - имя тега (например: интересные факты)
  • Label - описание тега (его можно сделать таким же как и название)
  • Псевдоним - псевдоним тега (отображается в URL, поэтому делаем строчными латинскими буквами, например: this-is-interesting)
  • Группа - группа тега (выбираем ранее созданную группу "Теги для статей")

Создадим ещё необходимые теги:

Компонент Tagger

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

Компонент Tagger
4. Создание ресурса "вывод статей по тегу"

На этой странице будет выводиться поиск по тегам. В моем случае она называется: Тематические материалы AMY.RU, псевдоним tags (id = 9).

Компонент Tagger

Эту страницу необходимо создать в первую очередь, поскольу ее id будет использовано во всех последующих модулях.

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

Далее необходимо открыть шаблон, в котором вы хотите выводить теги и вставить в него вызов сниппета 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="[[~9]]?tag=[[+alias]]">[[+tag]]</a></div>`
]]

Описание параметров:

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

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

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

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

  • [[~9]]?tag=[[+alias]]

где:

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

Немного о внешнем виде. В моем случае классы css (btn-group, btn, btn-primary, btn-sm, btn-info) используют стандартые настойки bootstrap 4. Вы можете использовать собственный css для придания необходимого внешнего вида.

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

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

В моем случае это выглядит так:


[[!pdoMenu?
  &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`
  &rowClass=`nav-tags-widget-row`  
  &tplWrapper=`@INLINE 
    [[+output]]`
  &tpl=`@INLINE <li[[+classes]]><a href="[[~9]]?tag=[[+alias]]">[[+tag]] <span class="badge">[[+countTags]]</span></a></li>`
]]

Описание параметров и плейхолдеров те же, что и для вывода тегов, прикрепленных к статье. Дополнительно используется [[+countTags]] - для подсчета количества тегов.

В результате вывода получаем:

Компонент Tagger
7. Страница "вывод статей по тегу"

Ранее мы создали ресурс "вывод статей по тегу". Теперь его необходимо оформить, чтобы на данной странице выводились статьи по заданноми тегу. Получать тег эта страница будет из URL (из GET параметра tag).

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

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


https://amy.ru/tags?tag=bootstrap

Для вывода соответствующих ресурсов необходимо:

  • получить значение параметра tag из массива GET.
  • создать запрос для выборки необходимых данных.
  • указать данному запросу условие where (ограничить выборку записями, которые имеют указанный тег).
  • создать чанк для оформления вывода

Для решения задачи воспользоваться сниппетом pdoPage

В моем случае это выглядит так:


[[!pdoPage?
  &element = `pdoResources`
  &limit=`100`
  &loadModels=`tagger`
  &class=`TaggerTagResource`
  &leftJoin=`{
    "NameTag": {
      "class": "TaggerTag",
      "on": "TaggerTagResource.tag = NameTag.id"
    },
    "Posts": {
      "class": "modResource",
      "on": "TaggerTagResource.resource = Posts.id"
    },
    "ImagePage": {
	  "class": "modTemplateVarResource",
	  "on": "Posts.id = ImagePage.contentid and ImagePage.tmplvarid = 1"
		   }
  }`
  &select=`{
    "TaggerTagResource": "*",
    "NameTag": "NameTag.tag, NameTag.alias",
    "Posts": "Posts.id, Posts.pagetitle, Posts.description",
    "ImagePage": "ImagePage.value as ImagePage"
  }`
  &where=`{
    "NameTag.alias": "[[!#GET.tag]]"
  }`
  &sortby=`TaggerTagResource.resource`
  &sortdir=`DESC`
  &tplWrapper =`@INLINE <h5><b>[[!GetParentsTag]]</b> найдено результатов: [[+page.total]]</h5>[[+output]]`
  &tpl= `TagsRow`
]]
[[!+page.nav]]

На что обратить внимание:

  • ImagePage - имя доп. поля TV для вывода картинки
  • TagsRow - чанк вывода списка результатов поиска по тегам
  • GetParentsTag - дополнительный сниппет для вывода текущего названия тега
  • [[+page.total]] - количество материалов с заданным тегом
  • tmplvarid - id доп. поля, откуда вызывается картинка (в моем случае это 1)
Чанк TagsRow (вывод списка результатов):


<div class="tag-list">
  <ul>
    <li>
      <a href="[[~[[+id]]]]">[[+pagetitle]]</a>
      <a href="[[~[[+id]]]]"><img src="[[+ImagePage]]"></a><span>[[+description]]<a class="float-right" href="[[~[[+id]]]]"><small> [читать дальше...]</small></a></span>
    </li><hr>
  </ul>
</div>

Где:

  • [[~[[+id]]]] - ссылка на материал с заданным тегом
  • [[+ImagePage]] - картинка материала
  • [[+pagetitle]] - заголовок материала с заданным тегом
  • [[+description]] - описание материала с заданным тегом

При желании картинку можно обрезать (чтобы не грузить лишние килобайты), например с помощью phpThumbOf. Либо выводить в адаптивном режиме.

Для вывода текущего названия тега я использую дополнительный сниппет (GetParentsTag):


<?php
$modx->getService('tagger','Tagger',$modx->getOption('tagger.core_path',null,$modx->getOption('core_path').'components/tagger/').'model/tagger/', array());
if(!$res = $modx->getObject('TaggerTag', array('alias' => $_GET['tag']))) return;
return $res->get('tag');

Результат вывода с пояснениями:

Компонент Tagger