ADBLOCK_MSG
Единая фильтрация вывода модуля mod_jcomments_latestОпубликовано: 23.06.2016, 10:48 Автор: Ogri Просмотров: 39294
Внутренние ссылки Joomla и примеры их применения :: ОГЛАВЛЕНИЕ
Структура внутренних ссылок сайта на Joomla
Фильтруем контент по материалам, категориям и компонентам
Единая фильтрация вывода модуля mod_jcomments_latest
end faq
Во вступлении к статье о фильтрации контента по материалам, категориям и компонентам я упомянул, что для избирательной привязки модуля последних комментариев требуется создавать некоторое количество его копий. На сайте, достаточно разветвленном по структуре и тематике, а особенно - в случае многоязычности, это количество может исчисляться десятками. Каждая копия имеет свои настройки, устанавливаемые в менеджере модулей. Если нужно изменить какие-либо параметры во всех или даже нескольких копиях модуля, предстоит кропотливая и нудная работа в админке сайта - открывать страницу каждой копии и вручную вносить изменения. Можно, конечно, объединять комментарии к нескольким смежным темам в один общий модуль, но не лучше ли найти гибкое решение, позволяющее и рыбку съесть - четко отфильтровать комменты к каждой теме или даже подтеме, и манту не замочить - свести количество копий модуля к минимуму, а то и к одной-единственной. Я, как мне кажется, таковое решение нашел, и помогло мне в этом знание структуры внутренних ссылок страниц приложений, формируемых движком Джумлы.
Как известно, модули Joomla привязываются к пунктам меню. В случае mod_jcomments_latest введена также привязка к компонентам. Есть еще и дополнительная фильтрация по категориям, но лишь для случая, когда в списке компонентов выбран ТОЛЬКО com_content. Соответственно, нужны отдельные копии модуля для каждой категории основного компонента Joomla, а также для каждого дополнительного приложения. В пределах копии можно объединять категории com_content или несколько компонентов. Нет возможности объединить, например, комментарии к категориям и комментарии к приложениям, отличным от com_content, в один блок. Мой метод позволяет в пределах блока фильтровать комментарии к категориям и отдельным материалам приложения com_content и одновременно - к другим компонентам и их структурным элементам. Подробно и с примерами объясню принцип такой гибкой фильтрации.
Кастомизация кода модуля mod_jcomments_latest
Изменения требуется внести в код класса помощника данного модуля, который стандартно расположен в файле [корень_сайта]\modules\mod_jcomments_latest\helper.php. Рассматривается билд 3.0.4 - новейший на время написания статьи. (Кстати, на русскоязычной части сайта производителя пакета JComments на странице закачки модулей - http://www.joomlatune.ru/jcomments-modules.html - почему-то последний билд - 3.0.3, тогда как на англоязычной - http://www.joomlatune.com/jcomments-modules.html - 3.0.4. Имейте это в виду и не удивляйтесь.)
Все кастомизации вносятся в код ключевого и самого первого метода класса modJCommentsLatestHelper. Метод этот - getList. Вы можете скачать архив, содержащий две версии файла помощника - оригинальную и мною отредактированную, - и сравнить содержимое каким-нибудь инструментом (например, WinMerge):
Original & Customised helper.php of mod_jcomments_latest | |
2016-06-23 Windows 7.5 KB 493 | Скачать |
Здесь же в коде класса, расположенном чуть ниже под катом, я укажу только сами измененные части (блоки) кода. Каждый из двух блоков я сопроводил в комментариях номерами строк, соответствующих началу и концу заменяемого блока кода в изначальном файле. Для наглядности присутствуют и кликабельные скриншоты результатов сравнения в WinMerge с подсветкой изменений (справа - оригинальный код, слева - кастомизированный).
Измененный код функции getList
public static function getList(&$params) { /* cut 1 */ //Customization #1 ==BEGIN== (lines 27 - 36 in original file) switch ($params->get('ordering', '')) { case 'vote': $orderBy = '(isgood-ispoor) DESC'; break; case 'date': default: $orderBy = 'date DESC'; break; } //Customization #1 --END-- /* cut 2 */ //Customization #2 ==BEGIN== (lines 100 - 134 in original file) $categories = ''; $components = array(); getCommentsFilter($categories, $components); $query = ''; $union = false; for ($i = 0; $i <= 1; $i++) { //1st for com_content, 2nd for other components $joins = array(); $where_i = $where; //resets $where_i for each iteration if ($i == 0 && !empty($categories)) { //1st iteration $joins[] = 'JOIN #__content AS cc ON cc.id = o.object_id'; if ($categories != 'all') $joins[] = 'LEFT JOIN #__categories AS ct ON ct.id = cc.catid'; $where_i[] = "(cc.publish_up = '0000-00-00 00:00:00' OR cc.publish_up <= '$now')"; $where_i[] = "(cc.publish_down = '0000-00-00 00:00:00' OR cc.publish_down >= '$now')"; $where_i[] = "(c.object_group = " . $db->Quote('com_content') . ($categories != 'all' ? " AND cc.catid IN (" . $categories . ")" : "") . ")"; } elseif ($i == 1 && !empty($components)) { //2nd iteration $where_cmp = array(); for ($j = 0, $nj = sizeof($components); $j < $nj; $j++) $where_cmp[] = '(c.object_group LIKE ' . $db->Quote($components[$j] . '%') . ')'; $where_i[] = '(' . implode(' OR ', $where_cmp) . ')'; } else continue; $union = $i == 1 && !empty($query); //2nd iteration, 1st query filtering by categories was built if ($union) $query = '(' . $query . ') UNION ('; $query .= "SELECT c.id, c.userid, c.comment, c.title, c.name, c.username, c.email, c.date, c.object_id, c.object_group, '' as avatar" . ", o.title AS object_title, o.link AS object_link, o.access AS object_access, o.userid AS object_owner" . " FROM #__jcomments AS c" . " JOIN #__jcomments_objects AS o ON c.object_id = o.object_id AND c.object_group = o.object_group AND c.lang = o.lang" . (count($joins) ? ' ' . implode(' ', $joins) : '') . (count($where_i) ? ' WHERE ' . implode(' AND ', $where_i) : ''); } $list = array(); if (!empty($query)) { $query .= ($union ? ")" : "") . " ORDER BY " . $orderBy; //adds common ordering for both queries in union (if any) of just for one quey $db->setQuery($query, 0, $params->get('count')); $list = $db->loadObjectList(); if (!is_array($list)) { $list = array(); } } //Customization #2 --END-- /* cut 3 */ }
end faq
Изменение 1:
Как видим, здесь просто убраны все вхождения префикса алиаса таблицы для предложения сортировки ORDER BY sql-запроса (query). Зачем - будет ясно далее.
Изменение 2 - глобальное:
Не буду подробно разбирать код строка за строкой; кому интересно - может разобраться сам, в чем помогут комментарии внутри кода. Я же изложу идею и реализацию.
В коде формируется запрос к таблицам комментариев, долженствующий выдавать список комментариев по условиям привязки. Условия - строковая переменная $categories и массив $components, заполняемые в функции getCommentsFilter, о которой ниже. В оригинале результат фильтрует альтернативно либо комменты к статьям и категориям компонента com_content, либо ко всем страницам отличных от него приложений. В моем варианте эти два результата могут быть скомбинированы в единый общий, а до комплекту - для ВСЕХ, в том числе сторонних, приложений становится возможной привязка к отдельным страницам этих компонентов по более избирательному фильтру.
Для этого реализованы два прохода (итерации): первая - для com_content, вторая - для прочих компонентов. Результаты запросов затем объединены с помощью оператора UNION, после чего уже совокупный результат сортируется через ORDER BY. И вот тут и становится ясен смысл первой кастомизации: при наличии псевдонимов (алиасов) таблиц MySQL выдает ошибку, поскольку они определены только внутри каждого из объединяемых запросов и недоступны для объединенного запроса.
Также предусмотрен вариант отсутствия в условии привязки либо по com_content, либо по прочим компонентам. В этом случае соответствующая итерация пропускается и объединение не производится.
Функция getCommentsFilter
Ее каждый создает по своим конкретным условиям привязки. Для этого используются принципы, описанные в обеих предыдущих статьях цикла. Вначале задются и инициализируются глобальные переменные, соответствующие параметрам выводимой страницы. В моем случае таких переменных 5:
- $cf_option - имя компонента (с префиксом com_);
- $cf_view - вид (представление) конкретной страницы компонента;
- $cf_art_cat_id - идентификатор материала или категории в зависимости от текущего представления (см. здесь);
- $cf_cat_id - идентификатор категории, в которую входит выводимый материал (в случае, когда
cf_view==article);
- $cf_lang - язык страницы (для мультиязычного сайта).
Как описано здесь, код функции можно разместить в одной из существующих библиотек, лучше всего - в файле functions.php активного шаблона. Код инициализации глобальных переменных лучше всего поместить в файл индекса шаблона templates\[active_template]\index.php ниже строки подключения библиотеки. Начало кода в моем файле index.php выглядит следующим образом:
defined('_JEXEC') or die; require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'functions.php'; $app = JFactory::getApplication(); $jinput = $app->input; global $cf_option, $cf_view, $cf_art_cat_id, $cf_cat_id, $cf_lang; $cf_option = $jinput->getCmd('option'); $cf_view = $jinput->getCmd('view'); $temp = explode(':', $jinput->getCmd('id')); $cf_art_cat_id = $temp[0] + 0; $temp = explode(':', $jinput->getCmd('catid')); $cf_cat_id = $temp[0] + 0; $cf_lang = substr(JFactory::getLanguage()->getTag(),0,2);
Определение функции getCommentsFilter имеет следующий вид:
function getCommentsFilter(&$categories, &$components)
Аргументами функции являются две вышеупомянутые переменные - строковая $categories и массив $components, передаваемые из кастомизированного нами метода getList класса помощника модуля mod_jcomments_latest по ссылке, о чем свидетельствуют знаки амперсанд (&) перед их именами. В функции они заполняются значениями: первый - списком идентификаторов категорий, разделенных запятой, второй - списком имен компонентов; затем передаются обратно в метод getList и используются как условия выборки в предложении WHERE соответствующего sql-запроса.
Ниже под катом - код функции getCommentsFilter, используемый на момент написания статьи на этом сайте:
Код функции getCommentsFilter
function getCommentsFilter(&$categories, &$components) { global $cf_option, $cf_view, $cf_art_cat_id, $cf_cat_id, $cf_lang; if ($cf_lang == 'ru') { $hebro_cats = array(69, 71, 72, 73, 75, 76, 77, 83, 84, 85); $reg_cats = array(25, 26, 27, 48, 86); $tech_cats_str = '26,27'; if ($cf_option == 'com_content') { if ($cf_view == 'article') { if (in_array($cf_art_cat_id, array(783, 307))) // Glavnaya, obratnaya-svyaz $categories = 'all'; elseif (in_array($cf_cat_id, $reg_cats)) // Blog, chinim-kompy, stroim-sajty, trudoustrojstvo-zapiski-posvyashchennogo, sovety-doktora-aleny $categories = $cf_cat_id; elseif ($cf_cat_id == 28) // guitar $categories = 'guitar'; elseif (in_array($cf_art_cat_id, array(614, 454, 603, 694)) || in_array($cf_cat_id, $hebro_cats)) // Hebroman $categories = 'hebroman'; elseif (in_array($cf_art_cat_id, array(433, 434, 724, 957))) //video $categories = 'all'; } elseif ($cf_view == 'category') { if (in_array($cf_art_cat_id, $reg_cats)) // Blog, chinim-kompy, stroim-sajty, trudoustrojstvo-zapiski-posvyashchennogo, sovety-doktora-aleny $categories = $cf_art_cat_id; elseif ($cf_art_cat_id == 28) // guitar $categories = 'guitar'; elseif (in_array($cf_art_cat_id, $hebro_cats)) // Hebroman $categories = 'hebroman'; } } elseif ($cf_option == 'com_muscol') // TiALP $categories = 'guitar'; elseif ($cf_option == 'com_bt_portfolio') { // portfolio $categories = $tech_cats_str; // fixing-comps, building-sites $components[] = 'com_bt_portfolio'; } elseif ($cf_option == 'com_joomgallery') // fotogalereya $components[] = 'com_joomgallery'; elseif ($cf_option == 'com_jdownloads') { if (in_array($cf_cat_id, array(8, 9, 11))) // Hebroman $categories = 'hebroman'; elseif ($cf_cat_id == 3) // Attachments $categories = $tech_cats_str; // chinim-kompy, stroim-sajty elseif ($cf_cat_id == 4) // Comp $categories = '26'; // chinim-kompy elseif ($cf_cat_id == 5) // Joomla $categories = '27'; // stroim-sajty } elseif ($cf_option == 'com_xmap') { if ($cf_art_cat_id == 1) // karta-sajta $categories = 'all'; elseif ($cf_art_cat_id == 4) // karta-hebroman $categories = 'hebroman'; } if ($categories == 'guitar') { $categories = '28'; $components[] = 'com_muscol'; } elseif ($categories == 'hebroman') $categories = implode(',', $hebro_cats); } elseif ($cf_lang == 'en') { $reg_cats = array(42, 43, 54); $tech_cats_str = '42,43'; if ($cf_option == 'com_content') { if ($cf_view == 'article') { if (in_array($cf_art_cat_id, array(784, 306))) // home, feedback $categories = 'all'; elseif (in_array($cf_cat_id, $reg_cats)) // fixing-comps, building-sites, employment-notes-of-the-initiate $categories = $cf_cat_id; } elseif ($cf_view == 'category') { if (in_array($cf_art_cat_id, $reg_cats)) // fixing-comps, building-sites, employment-notes-of-the-initiate $categories = $cf_art_cat_id; } } elseif ($cf_option == 'com_muscol') // TiALP $components[] = 'com_muscol'; elseif ($cf_option == 'com_bt_portfolio') { // portfolio $categories = $tech_cats_str; // fixing-comps, building-sites $components[] = 'com_bt_portfolio'; } elseif ($cf_option == 'com_joomgallery') // photogallery $components[] = 'com_joomgallery'; elseif ($cf_option == 'com_jdownloads') { if ($cf_cat_id == 3) // Attachments $categories = $tech_cats_str; // fixing-comps, building-sites elseif ($cf_cat_id == 4) // Comp $categories = '42'; // fixing-comps elseif ($cf_cat_id == 5) // Joomla $categories = '43'; // building-sites } elseif ($cf_option == 'com_xmap') { if ($cf_art_cat_id == 2) // site-map $categories = 'all'; } } }
end faq
Как из него видно, первым делом идет привязка к языкам. Для каждого языка фильтруются комменты к статьям и категориям компонента com_content, а затем - к остальным компонентам. Некоторые из этих компонентов (в частности, com_jdownloads и com_xmap) также имеют категории, и привязка осуществляется отдельно к каждой из них в соответствии с ее тематикой. В случае многоуровневой (древовидной) структуры категорий комментарии дочерних категорий объединяются для привязки к категории-родителю. Пример - обработка страниц категорий компонента com_jdownloads. В случае гитарной директории объединяются комментарии к страницам самой директории (компонент com_muscol) и категории 'Гитара' (id==28) компонента com_content - в представлениях как блога категории, так и каждого материала, к ней относящегося.
Для случая, когда выводятся последние комменты ко всем страницам компонента com_content, функция передает в вызывающий ее код значение 'all' переменной $categories. В моем случае, например - для Главной страницы, формы обратной связи, страниц категории 'Видео' в обоих представлениях, а также всех карт сайта. Когда же нет необходимости в фильтрации комментариев к страницам прочих приложений, массив $components остается пустым.
Таким образом, в моем случае обработаны все разделы сайта для каждого языка:
- Отдельные страницы - Главная, Обратная связь.
- 8 разделов в русской и 3 в английской частях сайта. Каждый раздел включает страницы в представлении материалов и блогов одной или нескольких категорий.
- По 5 прочих приложений для каждого языка:
- Гитарная директория com_muscol - комменты к ней объединены с таковыми к категории 'Гитара' компонента com_content;
- Компонент портфолио com_bt_portfolio - объединены комменты к страницам самого приложения и к страницам двух технических категорий;
- Компонент для скачивания файлов com_jdownloads - обработаны 4 категории в русской части, 3 - в английской;
- Карта сайта com_xmap - обработаны 2 карты в русской, 1 - в английской;
- Галерея изображений com_joomgallery - обычная привязка ко всем страницам приложения.
Итого: для привязки последних комментариев до кастомизации я использовал около 20 (двадцати!) копий модуля mod_jcomments_latest. При этом отсутствовала возможность объединять комменты к страницам компонента com_content и других приложений. Теперь же я могу объединить комменты к ЛЮБЫМ страницам ЛЮБЫХ приложений. На данный момент у меня всего две копии модуля - для каждого из языков сайта, привязанные в админке по умолчанию - реальная привязка осуществляется в измененном коде.
Какой минус? При изменении структуры и условий привязки требуется вносить изменения в код модуля. Лично для меня это давно не является проблемой, как не является ею и сохранение кастомизаций при обновлении расширений разработчиками. Можно, конечно, усовершенствовать административную часть модуля, добавив функционал для подобной гибкой привязки и получая на фронт-энде условия фильтрации из параметров модуля. Но вот это уже - целый проект, игра не стоит свеч. А вот разобраться в структуре внутренних ссылок Joomla и утилизировать приобретенные знания для повышения гибкости привязки кода к избранным страницам сайта - дело весьма полезное. Эта статья, как и предыдущие (и, надеюсь, последующие) статьи цикла "Внутренние ссылки Joomla и примеры их применения", призвана помочь вам в этом.
Новые
-
20.07.2020, 00:53
Joomla 3: Перенаправление на ту же страницу после авторизации -
13.02.2017, 14:09
Joomla: как добавить свои языковые константы или переопределить существующие -
13.02.2017, 13:23
Joomla: Интегрируем reCAPTCHA v2 (NO CAPTCHA) в JComments -
23.06.2016, 10:48
Единая фильтрация вывода модуля mod_jcomments_latest -
13.09.2015, 13:06
Постим иллюстрированные статьи Joomla-сайта на Facebook, используя OG-теги
Популярные
-
118184
Миграция с Joomla 1.5 на Joomla 2.5. Ч.2-1. Перенос jDownloads и jComments -
87344
Joomla: Интегрируем reCAPTCHA v2 (NO CAPTCHA) в JComments -
63783
Редактирование анимированных GIF-имиджей в Photoshop CS3 -
60850
Joomla: как добавить свои языковые константы или переопределить существующие -
44741
Цифровые коды WEB (веб) цветов для сайта
Авторизация
Гитара
Гостевая колонка
Последние комментарии
-
Joomla: Интегрируем reCAPTCHA v2 (NO CAPTCHA) в JComments
- Тест 25.08.2020 11:37
-
Николай3333
05.08.2020 07:55
Неужели работает?
-
Дарья Смирнова
29.07.2020 06:02
Здравствуйте, все вроде сделала по инструкции, но точно так же никаких изменений. Разве что теперь ...
-
ТвойБро
24.03.2020 03:42
Огромное спасибо, помогло. Странно, что по дефолту в jcomments предлагает в настройках выбрать ...
-
Валерий
21.02.2020 03:25
Проверка
-
Денис
02.01.2020 21:21
УРАААА! Заработало после очистки кэша сайта! Спасибо!
-
Денис
02.01.2020 20:56
Забыл сказать, что этот вариант установился на сайт, но по-прежнему при использовании reCAPTCHA ...
-
Вованя
25.12.2019 18:31
12345
-
Вованя
25.12.2019 18:31
Проверка, просто проверяю. раз раз раз)
-
Миграция с Joomla 1.5 на Joomla 2.5. Ч.2-1. Перенос jDownloads и jComments
-
Андрей67
11.08.2020 16:54
У меня такая же картина, нет кнопки Импорт. как быть?
-
Андрей67
11.08.2020 16:54
Подробнее...