В базовом комплекте MaxSite CMS список похожих страниц для блока "Еще записи по теме" формируется на основе их принадлежности к категориям. Более достоверный список похожих страниц можно получить, используя в качестве меры похожести число общих меток.
Этим и займется наш плагин similar_post_tag.
Способ определения похожести.
Все страницы сравниваются с текущей страницей и для каждой страницы формируется мера похожести на текущую - сколько у страниц общих меток и категорий.
foreach ($all_pages as $cur_page) // сравниваем все страницы с текущей { if ($cur_page['page_id'] == $page['page_id']) continue; // похожесть страниц - это сколько у них одинаковых меток и категорий $tag_similarity = count(array_intersect($cur_page['page_tags'] , $page['page_tags'])); $cat_similarity = count(array_intersect($cur_page['page_categories'] , $page['page_categories'])); $k = 1; // коэффициент $similarity = $tag_similarity*$k + $cat_similarity; if ($similarity) // похожесть > 0 - есть общие метки и категории { $cur_page['similarity'] = $similarity; $bl_pages[] = $cur_page; } }
Отсортированный по мере похожести массив номеров и используется в дальнейшем для получения похожих страниц.
Способ вывода.
В предыдущей версии плагина использовался вывод похожих страниц по хуку content_end.
В последних версиях MaxSite CMS есть стандартный блок вывода похожих страниц "Еще записи по теме", который можно использовать.
При формировании страниц в блоке "Еще записи по теме" есть возможность добавить в вызов mso_get_pages свои строчки SQL-запроса.
Вот как выглядит функция mso_page_other_pages в фале common\page.php:
# блок "Еще записи этой рубрики" function mso_page_other_pages($page_id = 0, $page_categories = array()) { if ($bl_title = mso_get_option('page_other_pages', 'templates', tf('Еще записи по теме'))) { // алгоритм получения записей $algoritm = mso_get_option('page_other_pages_algoritm', 'templates', 'all'); $type_page = mso_get_option('page_other_pages_type_page', 'templates', ''); if (!$type_page) $type_page = false; $custom_type = 'category'; if ($algoritm == 'lowlewel') // только из подрубрик { $all_cat = mso_cat_array_single(); // все рубрики $bl_page_categories = array(); // обработаный массив id-level foreach ($page_categories as $cat_id) { $bl_page_categories[$cat_id] = $all_cat[$cat_id]['level']; } arsort($bl_page_categories); // сортируем в обратном порядке $bl_page_categories = array_keys($bl_page_categories); // оставляем только ключи (id) // если что-то есть, то оставляем только первую рубрику, иначе $page_categories if (isset($bl_page_categories[0])) $bl_page_categories = array($bl_page_categories[0]); else $bl_page_categories = $page_categories; } elseif ($algoritm == 'no-cat') // не учитывать рубрики { $bl_page_categories = array(); $custom_type = 'home'; } else { // обычный вывод по всем рубрикам $bl_page_categories = $page_categories; } // своя функция sql-запроса для function_add_custom_sql // задается через mso_set_val() $fasc = mso_get_val('page_other_pages_function_add_custom_sql', false); $bl_pages = mso_get_pages( array( 'type'=> $type_page, 'content'=> false, 'pagination'=>false, 'custom_type'=> $custom_type, 'categories'=>$bl_page_categories, 'exclude_page_id'=>array($page_id), 'limit'=> mso_get_option('page_other_pages_limit', 'templates', 7), 'order'=>mso_get_option('page_other_pages_order', 'templates', 'page_date_publish'), 'order_asc'=>mso_get_option('page_other_pages_order_asc', 'templates', 'random'), 'function_add_custom_sql' => $fasc, ), $_temp); if ($bl_pages) { if ($f = mso_page_foreach('page-other-pages-out')) // свой вывод { require($f); } else { echo '<div class="mso-page-other-pages">' . mso_get_val('page_other_pages_start', '<h4>') . $bl_title . mso_get_val('page_other_pages_end', '</h4>') . '<ul>'; foreach ($bl_pages as $bl_page) { mso_page_title($bl_page['page_slug'], $bl_page['page_title'], '<li>', '</li>', true); } echo '</ul></div>'; } } } }
Необходимо только добавив в запрос получения записей для этого блока всего одну строчку:
$CI->db->where_in('page.page_id', $array_id);
Для этого нам необходимо определить функцию, добавляющую эту строчку, при построении запроса получения записей по теме.
// функция - добавка, получаемая в mso_get_val('page_other_pages_function_add_custom_sql', false); // добавляем условие получения только похожих страниц function sql_add_similar_posts_tags() { global $page; // не страница if (!isset($page['page_id']) or !$page['page_id']) return array(); $CI = & get_instance(); // добавим в запрос id похожих страниц $field_of_numbers = 'similar_post_tags_id'; // метаполе, где находится список похожих страниц // на всякий случай проверка, хотя поле должно быть обязательно if ( isset($page['page_meta'][$field_of_numbers][0]) and $page['page_meta'][$field_of_numbers][0]) { $array_id = mso_explode($page['page_meta'][$field_of_numbers][0]); if ($array_id) $CI->db->where_in('page.page_id', $array_id); } }
Имя этой функции занесем в специальную переменную при помощи mso_set_val.
Кроме того, нам нужно между моментом, когда текущая запись уже получена, и моментом получения записей для блока "Еще записи по теме" получить массив номеров записей, похожих на текущую запись и записать этот массив в искусственное метаполе. Это удобно сделать по хуку content_end.
Искусственность метаполя состоит в том, что оно не хранится в базе данных и используется только для передачи массива из функции в функцию.
# функция автоподключения плагина function similar_posts_tags_autoload($args = array()) { if ( is_type('page') ) { // зададим функцию - добавку к запросу получения страниц mso_set_val('page_other_pages_function_add_custom_sql', 'sql_add_similar_posts_tags'); // определим функцию - добавку к запросу получения страниц require(getinfo('plugins_dir').'similar_posts_tags/functions.php'); // после получения страницы нам нужно в результат добавить метаполе с похожими страницами mso_hook_add('content_end', 'similar_posts_tags_get_id'); } }
Скачать плагин похожих статей для MaxSite CMS.
Ноябрь 2019.
Версия 2.1.
Добавлена возможность указать коэффициент для категорий и меток.
Целочисленное число, позволяющее придать приоритет вычислениях.
Например:
Вес категорий=0 => категории не учитываются.
Вес меток=2 => метки в два раза важнее категорий.
Алгоритм очень простой.
foreach ($all_pages as $cur_page) // сравниваем все страницы с текущей { if ($cur_page['page_id'] == $page['page_id']) continue; // похожесть страниц - это сколько у них одинаковых меток и категорий $tag_similarity = count(array_intersect($cur_page['page_tags'] , $page['page_tags'])); $cat_similarity = count(array_intersect($cur_page['page_categories'] , $page['page_categories'])); $similarity = $tag_similarity*$k_tag + $cat_similarity*$k_cat; if ($similarity) // если похожесть больше 0, тоесть есть общие метки и категории { $cur_page['similarity'] = $similarity; $bl_pages[] = $cur_page; } }