Intereting Posts
Внутренняя ошибка 500, доступ к теме> Настроить Показать аватар с формой комментариев? Параметр wp_nav_menu $ theme_location игнорируется Проблема с комментариями WordPress query_posts не упорядочивает по названию Сообщения из пользовательского типа сообщений, не отображаемые в архиве категории Нужно ли использовать вместе wp_reset_postdata и wp_reset_query вместе? Иерархический пользовательский тип Post Walker? Как получить термин до последнего из пользовательской таксономии? Wrap posts p tags в div Комментарии не отображаются в пользовательском типе сообщений – WordPress Предварительный просмотр / обновление некоторых страниц приводит к тому, что «Запрошенный URL был отклонен» Ошибка База категорий для URL в пользовательском типе / таксономии Как отобразить биографию пользователя (а не автора или зарегистрированного пользователя) Невозможно удалить теги из пользовательской таксономии WordPress 4.7+

Похожие сообщения по нескольким тегам?

Мне было любопытно, можно ли отображать связанные сообщения несколькими тегами.

На сайте, на котором я работаю, есть около 5 тегов за сообщение. В большинстве сообщений есть 1 или 2 тега. Связанные должности, которые я хотел бы показать, имеют 3-5 общих тегов.

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

Предположим, что я показываю 3 связанные должности: relatedpost1 будет иметь 4 тега, связанный с post2 будет иметь 3 общего, а связанный с ним post3 – 1 общий.

Возможно ли это сделать?

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

Первый метод ( код ) показывает только сообщения с ЛЮБЫМИ тегами.

<?php $orig_post = $post; global $post; $tags = wp_get_post_tags($post->ID); if ($tags) { $tag_ids = array(); foreach($tags as $individual_tag) $tag_ids[] = $individual_tag->term_id; $args=array( 'tag__in' => $tag_ids, 'post__not_in' => array($post->ID), 'posts_per_page'=>3, // Number of related posts that will be shown. 'caller_get_posts'=>1 ); $my_query = new wp_query( $args ); if( $my_query->have_posts() ) { echo '<div id="relatedposts"><h3>Related Posts</h3><div class="relatedbreak"></div><ul id="relatedul">'; while( $my_query->have_posts() ) { $my_query->the_post(); ?> <li><div class="relatedthumb"><a href="<? the_permalink()?>" rel="bookmark" title="<?php the_title(); ?>"><?php the_post_thumbnail(array(185, 185)); ?></a></div> <div class="relatedcontent"> <center><a href="<? the_permalink()?>" rel="bookmark" title="<?php the_title(); ?>"><div class="comments_text"><?php the_title(); ?></div></center></a> </div> </li> <? } echo '</ul></div>'; } } $post = $orig_post; wp_reset_query(); ?>` 

Второй метод ( код ) просто показывает сообщения с первым общим тегом.

 <?php //for use in the loop, list 5 post titles related to first tag on current post $tags = wp_get_post_tags($post->ID); if ($tags) { echo '<div id="relatedposts"><h3>Related Posts</h3></div><div class="relatedbreak"></div>'; $first_tag = $tags[0]->term_id; $args=array( 'tag__in' => array($first_tag), 'post__not_in' => array($post->ID), 'posts_per_page'=>3, 'caller_get_posts'=>1 ); $my_query = new WP_Query($args); if( $my_query->have_posts() ) { while ($my_query->have_posts()) : $my_query->the_post(); ?> <ul id="relatedul"> <li><div class="relatedthumb"><a href="<? the_permalink()?>" rel="bookmark" title="<?php the_title(); ?>"><?php the_post_thumbnail(array(185, 185)); ?></a></div> <a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><div class="comments_text"><?php the_title(); ?></div></a></li> </ul> <?php endwhile; } wp_reset_query(); } ?> 

Оба вида сосать; Я либо получаю довольно случайные сообщения (поскольку большинство моих сообщений имеют по крайней мере 1 общий тег) или (для некоторых сообщений) не получают связанных сообщений (так как их общие теги – тег 4 или 5).

Любая помощь будет принята с благодарностью.

Solutions Collecting From Web of "Похожие сообщения по нескольким тегам?"

У меня была такая же идея, и я написал небольшой плагин, чтобы помочь мне сделать это.

 function get_pew_related_data($args, $post_id, $related_id) { global $post, $wpdb; $post_id = intval( $post_id ); if( !$post_id && $post->ID ) { $post_id = $post->ID; } if( !$post_id ) { return false; } $defaults = array( 'taxonomy' => 'topics', 'post_type' => array('post'), 'max' => 5 ); $options = wp_parse_args( $args, $defaults ); $transient_name = 'pew-related-' . $options['taxonomy'] . '-' . $post_id; if( isset($_GET['flush-related-links']) && is_user_logged_in() ) { echo '<p>Related links flushed! (' . $transient_name . ')</p>'; delete_transient( $transient_name ); } $output = get_transient( $transient_name ); if( $output !== false && !is_preview() ) { //echo $transient_name . ' read!'; return $output; } $args = array( 'fields' => 'ids', 'orderby' => 'count', 'order' => 'ASC' ); $orig_terms_set = wp_get_object_terms( $post_id, $options['taxonomy'], $args ); //Make sure each returned term id to be an integer. $orig_terms_set = array_map('intval', $orig_terms_set); //Store a copy that we'll be reducing by one item for each iteration. $terms_to_iterate = $orig_terms_set; $post_args = array( 'fields' => 'ids', 'post_type' => $options['post_type'], 'post__not_in' => array($post_id), 'posts_per_page' => 50 ); $output = array(); while( count( $terms_to_iterate ) > 1 ) { $post_args['tax_query'] = array( array( 'taxonomy' => $options['taxonomy'], 'field' => 'id', 'terms' => $terms_to_iterate, 'operator' => 'AND' ) ); $posts = get_posts( $post_args ); /* echo '<br>'; echo '<br>'; echo $wpdb->last_query; echo '<br>'; echo 'Terms: ' . implode(', ', $terms_to_iterate); echo '<br>'; echo 'Posts: '; echo '<br>'; print_r( $posts ); echo '<br>'; echo '<br>'; echo '<br>'; */ foreach( $posts as $id ) { $id = intval( $id ); if( !in_array( $id, $output) ) { $output[] = $id; } } array_pop( $terms_to_iterate ); } $post_args['posts_per_page'] = 10; $post_args['tax_query'] = array( array( 'taxonomy' => $options['taxonomy'], 'field' => 'id', 'terms' => $orig_terms_set ) ); $posts = get_posts( $post_args ); foreach( $posts as $count => $id ) { $id = intval( $id ); if( !in_array( $id, $output) ) { $output[] = $id; } if( count($output) > $options['max'] ) { //We have enough related post IDs now, stop the loop. break; } } if( !is_preview() ) { //echo $transient_name . ' set!'; set_transient( $transient_name, $output, 24 * HOUR_IN_SECONDS ); } return $output; } function pew_related( $args = array(), $post_id = '', $related_id = '' ) { $post_ids = get_pew_related_data( $args, $post_id, $related_id ); if( !$post_ids ) { return false; } $defaults = array( 'post__in' => $post_ids, 'orderby' => 'post__in', 'post_type' => array('post'), 'posts_per_page' => min( array(count($post_ids), 10)), 'related_title' => 'Related Posts' ); $options = wp_parse_args( $args, $defaults ); $related_posts = new WP_Query( $options ); if( $related_posts->have_posts() ): ?> <h5><?=$options['related_title']?></h5> <div id="related-material" class="promo"> <?php while ( $related_posts->have_posts() ): $related_posts->the_post(); ?> <a class="post" href="<?=the_permalink();?>"> <div class="meta"> <?php $post_project = wp_get_object_terms($related_posts->post->ID, 'projects'); $project = 'Pew Research Center'; $project_slug = ''; if( isset($post_project[0]) ) { $project = $post_project[0]->name; $project_slug = $post_project[0]->slug; } elseif( $related_posts->post->post_type == 'fact-tank' ) { $project = 'Fact Tank'; $project_slug = 'fact-tank'; } ?> <span class="project <?=$project_slug;?> right-seperator"><?=$project;?></span> <span class="date"><?php the_time('M j, Y'); ?></span> </div> <h2><?=the_title();?></h2> </a> <?php endwhile; wp_reset_postdata(); ?> </ol> </div> <?php endif; } 

Он ищет должности, которые имеют общие термины, и термины сортируются по частоте, поэтому наименее используемые термины становятся первыми, чем более популярные термины. Первая функция извлекает данные и сохраняет их в переходном режиме, поэтому результаты не повторяются и снова и снова неоправданно. Вторая функция просто выводит результат. Это то, что заставляет наши связанные должности на одном из наших сайтов работать http://www.pewresearch.org/fact-tank/2013/08/02/both-parties-underwater-heading-into-2014-elections/

Алгоритм работает следующим образом:

  1. Получите все условия от поста, упорядоченного по счету в порядке возрастания (наименее популярным для более популярных)
  2. Прокрутите этот набор терминов и найдите сообщения, содержащие Term1 AND Term2 AND Term3
  3. С каждой итерацией удалите наименее популярный термин из списка, расширяя наши результаты, пока мы не получим желаемое количество сообщений, или у нас останется только один срок для проверки.
  4. Если у нас по-прежнему недостаточно должностей для удовлетворения наших потребностей, тогда найдите сообщения, содержащие Term1 OR Term2 OR Term3
  5. Сохраните результат в переходный период, поэтому нам не нужно запускать эти запросы еще некоторое время.

Надеюсь, что это помогает вам.

Я не думаю, что query_posts() или new WP_Query() будут здесь полезны. Вам нужно напрямую запросить базу данных. Здесь идет метод, который я написал для достижения того, что вам кажется нужным:

 /* * Returns related posts to a given post based on a specific taxonomy * By default, this method returns list of posts with the highest number of common tags * * var $post_id - the reference post for which we want to get the list of similar posts * var $number_posts - max how many related posts to return, 0 for unlimited * var $taxonomy - which taxonomy to use to determine related posts ( 'post_tag' or 'category' are the basic examples ) * var $post_type - change to a custom post_type if you want to get related posts of another post type */ function exe_get_related_posts_by_common_terms( $post_id, $number_posts = 0, $taxonomy = 'post_tag', $post_type = 'post' ) { global $wpdb; $post_id = (int) $post_id; $number_posts = (int) $number_posts; $limit = $number_posts > 0 ? ' LIMIT ' . $number_posts : ''; $related_posts_records = $wpdb->get_results( $wpdb->prepare( "SELECT tr.object_id, count( tr.term_taxonomy_id ) AS common_tax_count FROM wp_term_relationships AS tr INNER JOIN wp_term_relationships AS tr2 ON tr.term_taxonomy_id = tr2.term_taxonomy_id INNER JOIN wp_term_taxonomy as tt ON tt.term_taxonomy_id = tr2.term_taxonomy_id INNER JOIN wp_posts as p ON p.ID = tr.object_id WHERE tr2.object_id = %d AND tt.taxonomy = %s AND p.post_type = %s GROUP BY tr.object_id HAVING tr.object_id != %d ORDER BY common_tax_count DESC" . $limit, $post_id, $taxonomy, $post_type, $post_id ) ); if ( count( $related_posts_records ) === 0 ) return false; $related_posts = array(); foreach( $related_posts_records as $record ) $related_posts[] = array( get_post( (int) $record->object_id ), 'common_tax_count' => $record->common_tax_count ); return $related_posts; } 

Мехтод предназначен для получения связанных сообщений, основанных на единой таксономии, по умолчанию в таксономии «post_tag». Сообщения сортируются по числу общих терминов от наивысшего до самого низкого . Чтобы получать связанные сообщения для нескольких общих таксономий одновременно, вам нужно настроить AND tt.taxonomy = %s на что-то вроде AND ( tt.taxonomy = 'post_tag' OR tt.taxonomy = 'category' ) . То же самое применяется, если вы хотите получать сообщения из разных типов сообщений.