Логотип

Блок "Похожие статьи"

Несмотря на размах Битрикса в его функционале нет готового решения для вывода похожих статей. Но ниже представлен простой способ генерации этого блока. Причём создавать его мы будем автоматически; собирать список вручную же легче всего через свойство привязки элементов, но это уже совсем просто.

Итак, какая идея?

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

Сам метод

Считаю, что зачастую этот функционал нужен на странице детального просмотра статьи. Как вы можете знать, в Битриксе news.detail отвечает за детальный просмотр элемента, а news.list за вывод списка элементов. Не вижу причин нарушать эту логику, поэтому сам блок мы вставим в конец шаблона детальной страницы, а блоком будет являться второй компонент. Как вы могли догадаться, самым сложным здесь является генерация массива для фильтрации.

Фильтр

Код отвечающий за массив для фильтрации статей.

<?
// похожие статьи
// удаляем лишние знаки
echo $tmpName = str_replace(array(".", ",", "?", "!", "-"), " ", trim($arResult["NAME"]." ".$arResult["TAGS"]));

// если есть с чем работать
if (strlen($tmpName) > 0){
	$arLooksLike = array(
		"INCLUDE_SUBSECTIONS" => "Y",
		"!ID"                 => intval($arResult["ID"]) // не данный элемент
	);

	$stuffWords = Array("в", "на", "по", "из"); // эти слова не несут смысла
	// массив, который будет использоваться для поиска в имени или тегах
	$NameItems = explode(" ", $tmpName);
	$itemsArray = array();
	foreach ($NameItems as $item){
		if (in_array($item, $stuffWords)){ // убираем предлоги
			continue;
		}
		if (strlen($item) > 1){ // редко бывают значимые слова в одну букву
			$itemsArray[] = array("NAME" => "%".$item."%");  // ищем элементы, у которых выбранное свойство есть в названии
			$itemsArray[] = array("TAGS" => "%".$item."%");  // ищем элементы, у которых выбранное свойство есть в поисковых тегах
		}
	}
	$addFArray = array(
		array(array_merge(array("LOGIC" => "OR"), $itemsArray)),
	);

	// массив для фильтра
	$GLOBALS["similarArticles"] = array_merge($arLooksLike, $addFArray);
}
?>

Не думаю, что здесь нужны какие-то пояснения: я привёл комментарии, а откуда $arResult вы и сами должны знать; отмечу лишь, что сам массив должен быть глобальным, такова логика системы.

Подключение компонента

Это может быть слишком очевидно, но приведу здесь код для вызова news.list для вывода статей. Вещи, на которые стоит обратить внимание, я прокомментировал. Подробнее про все поля можете прочитать здесь.

<? $APPLICATION->IncludeComponent(
	"bitrix:news.list",
	"similar-articles",
	Array(
		"AJAX_MODE"                       => "N",
		"IBLOCK_TYPE"                     => $arResult["IBLOCK_TYPE"], // Тот же тип инфоблока
		"IBLOCK_ID"                       => $arResult["IBLOCK_ID"], // Тот же инфоблок
		"NEWS_COUNT"                      => "5",
		"SORT_BY1"                        => "SORT",
		"SORT_ORDER1"                     => "ASC",
		"SORT_BY2"                        => "ACTIVE_FROM",
		"SORT_ORDER2"                     => "DESC",
		"FILTER_NAME"                     => "similarArticles", // Тот самый фильтр, что мы сгенерировали
		"FIELD_CODE"                      => "PREVIEW_TEXT",
		"PROPERTY_CODE"                   => "",
		"CHECK_DATES"                     => "Y",
		"DETAIL_URL"                      => "",
		"PREVIEW_TRUNCATE_LEN"            => "",
		"ACTIVE_DATE_FORMAT"              => "j F Y",
		"SET_TITLE"                       => "N", // Стараемся ни на что не влиять
		"SET_BROWSER_TITLE"               => "N", // Стараемся ни на что не влиять
		"SET_META_KEYWORDS"               => "N", // Стараемся ни на что не влиять
		"SET_META_DESCRIPTION"            => "N", // Стараемся ни на что не влиять
		"SET_LAST_MODIFIED"               => "N", // Стараемся ни на что не влиять
		"INCLUDE_IBLOCK_INTO_CHAIN"       => "N", // Стараемся ни на что не влиять
		"ADD_SECTIONS_CHAIN"              => "N", // Стараемся ни на что не влиять
		"HIDE_LINK_WHEN_NO_DETAIL"        => "N",
		"PARENT_SECTION"                  => "", // Все разделы
		"PARENT_SECTION_CODE"             => "", // Все разделы
		"INCLUDE_SUBSECTIONS"             => "Y", // Все разделы
		"CACHE_TYPE"                      => "A",
		"CACHE_TIME"                      => "36000000",
		"CACHE_FILTER"                    => "Y",
		"CACHE_GROUPS"                    => "N",
		"PAGER_TEMPLATE"                  => ".default",
		"DISPLAY_TOP_PAGER"               => "N",
		"DISPLAY_BOTTOM_PAGER"            => "N",
		"PAGER_TITLE"                     => "Новости",
		"PAGER_SHOW_ALWAYS"               => "N",
		"PAGER_DESC_NUMBERING"            => "N",
		"PAGER_DESC_NUMBERING_CACHE_TIME" => "36000",
		"PAGER_SHOW_ALL"                  => "N",
		"PAGER_BASE_LINK_ENABLE"          => "N",
		"SET_STATUS_404"                  => "N",
		"SHOW_404"                        => "N",
		"MESSAGE_404"                     => "",
		"AJAX_OPTION_JUMP"                => "N",
		"AJAX_OPTION_STYLE"               => "Y",
		"AJAX_OPTION_HISTORY"             => "N",
	),
	$component // Потому что подключаем внутри шаблона
); ?>

Итог

Как видите, всё действительно просто. Но есть некоторые проблемы, например, не учтена релевантность в сортировке и предлоги забиваются вручную.

Если у вас есть идеи для доработки решения, вопросы по расширению функционала и просто свои мысли, пишите их в комментариях.

Комментарии

Максим

Максим 31.08.2016 09:19

Отличный пример, сразу взял в реализацию :)
Юрий

Юрий 16.07.2017 09:48

Отличный вариант, чтоб не писать каркас самому, в поисках значений всех этих массивов! Далее уже настройки.

Написать комментарий

Внимание!

Этот сайт использует технологию "cookies" и интернет-сервисы для сбора технических данных!

Условия использования и другие юридические моменты можно найти в пользовательском соглашении и в политике конфиденциальности.

Цель - получение статистической информации и возможность работы множества сервисов на страницах сайта и самого сайта.

Если Вы не согласны на обработку данных на указанных выше условиях, покиньте сайт.