
Если ваш сайт на Joomla имеет большое количество материалов, то отличной идеей может стать их дополнительная перелинковка путем добавления блока похожих статей после основного текста. С одной стороны, такой подход позволит увеличить количество просмотров страниц пользователями сайта (это хорошо, в том числе, и для продвижения), с другой стороны, поисковые системы будут лучше индексировать сайт.
В данном уроке я расскажу о том, как вы можете быстро, самостоятельно, и абсолютно бесплатно сделать блок с похожими статьями под основным материалом, выведя в нем практически любую информацию. Для создания блока не используются сторонние расширения, только функционал Joomla «из коробки».
Содержание
Как угодить всем?
Я долго думал, как подобрать материалы Joomla в блоке похожих статей таким образом, чтобы угодить и поисковым системам и пользователям. Мой опыт показывает, что если подбор материалов автоматизировать, то, как ни старайся, они все равно не будут подходить идеально. Мне кажется, что лучший способ показать именно подходящие материалы – выбрать их вручную.
Если вы автор всех материалов на сайте, или, по крайней мере, хорошо разбираетесь в тематике, то легко сможете подобрать статьи, которые могли бы дополнительно заинтересовать пользователя и при этом были бы релевантными по тематике. Давайте реализуем эту задумку.
Блок похожих статей Joomla. Шаг 1. Создаем дополнительное поле
Начиная с версии 3.7, в Joomla появились настраиваемые поля (Custom Fields). Используя их, мы можем добавлять к материалам отдельные блоки информации. К сожалению, среди доступных типов полей, нет поля «Похожие материалы Joomla», но зато есть поле SQL, которое мы и будем использовать.
На первом этапе наша задача сводится к тому, чтобы создать для материала дополнительное поле, позволяющее привязывать к нему любые другие материалы. Для этого нам нужен множественный SELECT, опциями которого будут являться все материалы Joomla. Создать его очень легко.
1) Переходим в «Материалы –> Поля» и нажимаем кнопку «Создать»:
Перед вами откроется форма создания нового дополнительного поля. Заполняем ее следующим образом:
На вкладке «Основные» задаем:
- Тип: SQL
- Категория: Все
- Имя: see-more
- Название: на ваш выбор
- Обязательно: Нет
- Мультивыбор: Да
- Запрос: SELECT id as value, title as text FROM #__content WHERE state = 1
На вкладке «Параметры» задаем:
- Показать в: Оба
- Автоматическое отображение: Не показывать автоматически
После этого сохраняем поле, и видим его в списке:
Если всё сделано правильно, то при создании новой статьи или при изменении существующей, вы увидите вкладку «Поля» на которой будет наше созданное поле с возможностью выбора любой опубликованной статьи с сайта.
В настройках поля мы использовали самый простой SQL-запрос, который выбирает все опубликованные материалы из базы данных. Если вы хотите каким-либо образом ограничить этот список, то подправьте запрос под себя, добавив, например, категории или даты публикации для фильтрации выбора. Хотя в Joomla удобно работать с полем SELECT даже с большим списком опций.
Если после создания дополнительного поля вы не видите его в форме редактирования материала, убедитесь, что:
1) У вас активирована опция: «Общие настройки –> Материалы –> Вкладка «Интеграция» –> Включить настраиваемые поля»
2) Плагины дополнительных полей активированы в менеджере плагинов.
3) Вы используете Joomla 3.7 или выше.
На этом первый шаг закончен. Поле выбора похожих материалов создано.
Блок похожих статей Joomla. Шаг 2. Вносим правки в макет материала
Теперь, когда у нас есть возможность выбора похожих материалов, нужно вывести их под текстом текущей статьи. Для этого нам нужно внести некоторые исправления в макет материала Joomla. Хаков не будет, т.к. этот макет переопределяется в шаблон Joomla.
Для переопределения макета материала, копируем файл:
/components/com_content/views/article/tmpl/default.php
в папку:
/templates/ВАШ_ШАБЛОН/html/com_content/article/
и вносим все дальнейшие изменения уже там.
В скопированном файле нам нужно внести следующие изменения:
1) Найдите строчку (~24):
JHtml::_('behavior.caption');
и вставьте после нее:
//------------------------------------------------------------------------------
//Получаем данные настраиваемых полей в удобном виде
foreach($this->item->jcfields as $jcfield)
{
$this->item->jcFields[$jcfield->name] = $jcfield;
}
//------------------------------------------------------------------------------
В принципе, эту строчку можно вставить в любом месте в начале файле после:
defined('_JEXEC') or die;
2) Найдите код:
<div itemprop="articleBody">
<?php echo $this->item->text; ?>
</div>
и вставьте после него:
<?php //------------------------------------------------------------------------
if ($this->item->jcFields['see-more']->rawvalue) {
$model = JModelLegacy::getInstance('Articles', 'ContentModel', array('ignore_request' => true));
$appParams = JFactory::getApplication()->getParams();
$model->setState('params', $appParams);
//Оставьте в следующей строке только те поля, которые нужны вам для отображения похожих статей
$model->setState('list.select', 'a.fulltext, a.id, a.title, a.alias, a.introtext, a.state, a.catid, a.created, a.created_by, a.created_by_alias, a.modified, a.modified_by, a.publish_up, a.publish_down, a.images, a.urls, a.attribs, a.metadata, a.metakey, a.metadesc, a.access, a.hits, a.featured');
$access = !JComponentHelper::getParams('com_content')->get('show_noauth');
$authorised = JAccess::getAuthorisedViewLevels(JFactory::getUser()->get('id'));
$model->setState('filter.access', $authorised);
//Подставляем ID материалов из дополнительного поля
$model->setState('filter.article_id', $this->item->jcFields['see-more']->rawvalue);
$seemore_items = $model->getItems();
?>
<div class="related-articles">
<h3>Смотрите также</h3>
<ul>
<?php foreach ($seemore_items as $seemore_item) { ?>
<li>
<a href="/<?php echo JRoute::_(ContentHelperRoute::getArticleRoute($seemore_item->id, $seemore_item->catid)); ?>"><?php echo $seemore_item->title ?></a>
</li>
<?php } ?>
</ul>
</div>
<?php } //--------------------------------------------------------------------?>
Этот код получает материалы Joomla по их ID, которые, в свою очередь, мы берем из дополнительного поля, созданного на первом шаге. Далее материалы выводятся списком в блок похожих статей. Если вам сложно разобраться с кодом, начните, например, с видеоуроков html.
Статьи выводятся простым списком:
На самом деле, в $seemore_item доступно очень много дополнительных данных по статьям, которые вы также можете вывести при желании. Вы можете оформить вывод похожих статей в виде таблице или блоков с картинками, добавить к ним даты, краткое описание, рейтинг и многие другие параметры.
Есть еще один вариант использования, аналогичный старому доброму плагину Extranews – показывать краткое описание похожих материалов, при наведении курсора на ссылку. Если хотите такой вариант, используйте код:
<?php //------------------------------------------------------------------------
if ($this->item->jcFields['see-more']->rawvalue) {
$model = JModelLegacy::getInstance('Articles', 'ContentModel', array('ignore_request' => true));
$appParams = JFactory::getApplication()->getParams();
$model->setState('params', $appParams);
//Оставьте в следующей строке только те поля, которые нужны вам для отображения похожих статей
$model->setState('list.select', 'a.fulltext, a.id, a.title, a.alias, a.introtext, a.state, a.catid, a.created, a.created_by, a.created_by_alias, a.modified, a.modified_by, a.publish_up, a.publish_down, a.images, a.urls, a.attribs, a.metadata, a.metakey, a.metadesc, a.access, a.hits, a.featured');
$access = !JComponentHelper::getParams('com_content')->get('show_noauth');
$authorised = JAccess::getAuthorisedViewLevels(JFactory::getUser()->get('id'));
$model->setState('filter.access', $authorised);
//Подставляем ID материалов из дополнительного поля
$model->setState('filter.article_id', $this->item->jcFields['see-more']->rawvalue);
$seemore_items = $model->getItems();
JHTML::_('behavior.tooltip');
?>
<div class="related-articles">
<h3>Смотрите также</h3>
<ul>
<?php foreach ($seemore_items as $seemore_item) { ?>
<li>
<a class="hasTip" title="<?php echo htmlentities($seemore_item->title); ?>::<?php echo htmlentities($seemore_item->introtext); ?>" href="/<?php echo JRoute::_(ContentHelperRoute::getArticleRoute($seemore_item->id, $seemore_item->catid)); ?>"><?php echo $seemore_item->title ?></a>
</li>
<?php } ?>
</ul>
</div>
<?php } //--------------------------------------------------------------------?>
Результат, в этом случае, будет выглядеть так:
Дальнейшее оформление блока зависит только от вашей фантазии.
Блок похожих статей Joomla. Шаг 3. Добавляем похожие материалы и проверяем
Блок похожих материалов Joomla готов. Осталось только наполнить дополнительное поле релевантными статьями для разных материалов Joomla и они автоматически появятся на сайте в нашем блоке.
Поле выбора в Joomla сделано очень удобно и содержит в себе форму поиска по названию, позволяющую быстро ориентироваться даже в большом списке опций:
Вот и всё. Таким нехитрым способом мы реализовали дополнительный, очень полезный функционал, обойдясь встроенными инструментами Joomla, и не используя сторонних расширений.
Даже если ваши заметки не являются необходимыми именно сейчас, они позволяют чувствовать ритм.
Спасибо!
Вопрос по теме: "как реализовать вывод такого поля для похожих статей, но не в под текстом текущей статьи, а например, после 5 абзаца?"
Но вообще, это сомнительный вариант, как раз потому, что не всегда в тексте есть абзацы, оформленные тегом "p" и не всегда их 5 и больше. Вы можете также использовать маркер разбиения статьи на 2 части, который будете вставлять в материал самостоятельно, что-то вроде: {divide}. Далее делаете примерно так, как я писал в этом кейсе: https://wedal.ru/virtuemart-cases/kak-razdelit-opisanie-v-kategorii-virtuemart-2-3-na-do-i-posle-tovarov-kejs-6.html
Делаю так , но выводит массив
Автомеханик{"image_intro":"images\/1.jpg","float_intro":"","image_intro_alt":"","image_intro_caption":"","image_fulltext":"images\/1.jpg","float_fulltext":"","image_fulltext_alt":"","image_fulltext_caption":""}
пробовал отсюда брать переменные, типа
ничего не выводит по ним. Подскажите, как нужно. Спасибо
Посмотрите эту статью. В ней описан пример добавления изображений как раз из JSON:
https://wedal.ru/uroki-joomla/dobavlenie-izobrazhenij-v-standartnyj-modul-novostej-joomla.html
Добавил
После
Добавил
но результата нет, ничего не выводится, что не так?
Добавьте в html-секции:
Там всё увидите.
{"image_intro":"images\/1.jpg","float_intro":"","image_intro_alt":"","image_intro_caption":"","image_fulltext":"images\/1.jpg","float_fulltext":"","image_fulltext_alt":"","image_fulltext_caption":""}
Спасибо большое!
Первым делом нужно проверить, а не загрузились ли уже данные настраиваемых полей в $seemore_items. Для этого поместите его в print_r
и посмотрите выведенные данные.
Если полей нет, то самым простым способом был бы SQL-запрос на их выбор из базы данных по ID материала. Но это не наш метод.
Правильный способ описан в этой из этих статей:
https://docs.joomla.org/J3.x:Adding_custom_fields/Implement_into_your_component
https://docs.joomla.org/J3.x:Adding_custom_fields/Overrides
Подробнее, к сожалению, не напишу - нужно тестировать.
Смотрите также
В цикл foreach нужно добавить
Добавьте перед:
две строчки:
Astroid Framework . Благодарю.
Виталий, спасибо за ответ, буду искать. сейчас узнал, что в шаблоне было много изменений и переопределений и работают такие плагины как nodouble и тд. возможно причина где то рядом. Благодарю за полезную статью и ответ!
1) Переменная $access вроде не используется в коде и зачем нужны эти две строчки, если без них все работает?
2) Как эти поля вывести в модуле? Просто вставить в модуль HTML-кода не получается.
1) Да, вы правы. Эти две строчки, которые вы привели, должны выполняться внутри проверки на $authorised. Примерно вот так:
2) В общем случае это некорректно. Поля относятся к материалам, а не к модулю. Теоретически, вы можете сделать модуль, в котором по ID будет определяться текущий открытый материал, а дальше для него будут загружаться поля. Но зачем такие сложности?
2) Чтобы выводить их в боковой колонке, а не в статье. Есть способ сделать это без модуля?
1) Может быть сейчас так. Много времени прошло с момента публикации. Смотрите по результатам. Если вас устраивает результат без этой проверки, то ок.
2) В общем случае - нет. Все способы будут до некоторой степени велосипедами. Наверное, самым правильным способом будет написание своего специального модуля. Но это и самый сложный способ.
В каждой статье у меня имя автора и аватар со ссылкой на его блог. Плюс еще нужна возможность присваивать пункт меню для каждого блога. В к2 это все организовано из коробки. Но почему то в joomla этого нет. Может подскажете решение?
Спасибо!
Не забудьте переопределить макет, в котором будете добавлять картинку, в шаблон Joomla. Переопределение макетов работает и для шаблонов админки.
А есть описание как это сделать в Joomla 4.
Спасибо.
JHtml::_('behavior.caption');
а при вставке в любое место кода:
//------------------------------------------------------------------------------
//Получаем данные настраиваемых полей в удобном виде
foreach($this->item->jcfields as $jcfield)
{
$this->item->jcFields[$jcfield->name] = $jcfield;
}
//------------------------------------------------------------------------------
страница не работает
JHtml::_('behavior.caption'); - в этой версии быть не должно.
Следующий код - включите в настройках Joomla отображение ошибок и посмотрите, какая ошибка появляется.