11 октября 2016

Как убрать циклическую ссылку в свежих публикациях WordPress

Приветствую вас, уважаемый читатель!

В современных реалиях SEO, да и с точки зрения логичности, было бы правильно убирать из свежих публикаций, выводимых стандартным виджетом WordPress циклические ссылки.

Если на странице есть ссылка на себя саму, то она называется циклической.

Циклическая ссылка в виджете WP

Рис. 1. Я нахожусь в публикации «Тестовая запись», при этом в сайдбаре присутствует ссылка на эту же самую публикацию.

Для решения задачи я предлагаю вставить нижепредставленный код в файл function.php (например, в конец файла) активной темы. В результате список виджетов пополнится морковными свежими записями.

Код для function.php

/**
 * RecentPosts_Morkovin_Widget widget.
 */
class RecentPosts_Morkovin_Widget extends WP_Widget {

	/**
	 * Register widget with WordPress.
	 */
	function __construct() {
		parent::__construct(
			'recentpost_morkovin_widget', // Base ID
			__( 'Морковные свежие записи', 'text_domain' ), // Name
			array('description' => __( 'Свежие публикации без цилических ссылок от Морковина.', 'text_domain' ), ) // Args
		);
	}

	/**
	 * Front-end display of widget.
	 *
	 * @see WP_Widget::widget()
	 *
	 * @param array $args     Widget arguments.
	 * @param array $instance Saved values from database.
	 */
	public function widget( $args, $instance ) {

		$show_not_home = esc_attr($instance['show_not_home']);

		$not_show = false;
		if(is_front_page() and $show_not_home) $not_show = true;
		
		if(!$not_show){
			$number_morkovin_rec_posts = esc_attr($instance['number_morkovin_rec_posts']);

			if(is_single()){
				wp_reset_postdata();
				$page_id = get_the_ID();

				$args_morkovin = array(
					'posts_per_page' => $number_morkovin_rec_posts,
					'post__not_in' => array($page_id),
				);
			}
			else{
				$args_morkovin = array(
					'posts_per_page' => $number_morkovin_rec_posts,
				);	
			}

			$loop = new WP_Query($args_morkovin);

	     	$rec_morkovin_posts = "";
	     	
	     	if ($loop->have_posts()) {
				while ($loop->have_posts()) {
		       		$loop->the_post();
		       		$permalink = get_permalink();
		       		$post_title= get_the_title();
		            $rec_morkovin_posts .= "<li><a href=\"$permalink\">$post_title</a></li>";
		       	}
	    	}

	    	wp_reset_postdata();

	    	$rec_morkovin_posts = "$number<ul>".$rec_morkovin_posts."</ul>";

	    	echo $args['before_widget'];
			
			if ( ! empty( $instance['title'] )) {
				echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ). $args['after_title'];
			}
			echo __( $rec_morkovin_posts, 'text_domain' );
			echo $args['after_widget'];
		}
	}

	/**
	 * Back-end widget form.
	 *
	 * @see WP_Widget::form()
	 *
	 * @param array $instance Previously saved values from database.
	 */
	public function form( $instance ) {
		$title = ! empty( $instance['title'] ) ? $instance['title'] : __( 'Свежие публикации', 'text_domain' );
		$number_morkovin_rec_posts = ! empty( $instance['number_morkovin_rec_posts'] ) ? $instance['number_morkovin_rec_posts'] : __( '6', 'text_domain' );
		$show_not_home = isset( $instance['show_not_home'] ) ? (bool) $instance['show_not_home'] : false;
		?>
		<p>
		<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label> 
		<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
		</p>
		<p>
		<label for="<?php echo $this->get_field_id( 'number_morkovin_rec_posts' ); ?>">Количество записей:</label> 
		<input id="<?php echo $this->get_field_id( 'number_morkovin_rec_posts' ); ?>" name="<?php echo $this->get_field_name( 'number_morkovin_rec_posts' ); ?>" type="text" size="3" value="<?php echo esc_attr( $number_morkovin_rec_posts ); ?>">
		</p>
		<p>
		<input class="checkbox" type="checkbox" <?php checked( $show_not_home ); ?> id="<?php echo $this->get_field_id( 'show_not_home' ); ?>" name="<?php echo $this->get_field_name( 'show_not_home' ); ?>" />
		<label for="<?php echo $this->get_field_id( 'show_not_home' ); ?>">Не показывать на главной</label>
		</p>
		<?php 
	}

	/**
	 * Sanitize widget form values as they are saved.
	 *
	 * @see WP_Widget::update()
	 *
	 * @param array $new_instance Values just sent to be saved.
	 * @param array $old_instance Previously saved values from database.
	 *
	 * @return array Updated safe values to be saved.
	 */
	public function update( $new_instance, $old_instance ) {
		$instance = array();
		$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
		$instance['number_morkovin_rec_posts'] = ( ! empty( $new_instance['number_morkovin_rec_posts'] ) ) ? strip_tags( $new_instance['number_morkovin_rec_posts'] ) : '';
		$instance['show_not_home'] = isset( $new_instance['show_not_home'] ) ? (bool) $new_instance['show_not_home'] : false;

		return $instance;
	}

} // class RecentPosts_Morkovin_Widget

// register RecentPosts_Morkovin_Widget widget
function register_morkovin_widget() {
    register_widget( 'RecentPosts_Morkovin_Widget' );
}
add_action( 'widgets_init', 'register_morkovin_widget' );

Морковные свежие записи

Рис. 2. В результате появился новый виджет, который не будет содержать циклических ссылок.

Теперь циклической ссылки в виджете не будет, а вместо нее список дополнится более ранней публикацией.

Как видно из рис. 2, морковные свежие записи имеют опцию, отключающую их отображение на главной странице. Это сделано исходя из следующих соображений. Часто на главной странице в центральной части выводится список свежих публикаций, тогда нет никакого смысла дублировать этих ссылки в виджете сайдбара.

P.S. Не пользуйтесь дебильным плагином «Remove Redundant Links», который удаляет атрибут href у ссылки, т.к. получается полный маразм. У тега ссылки обязательно должен быть атрибут href или name.

ОБНОВЛЕНИЕ

Теперь скрипт умеет выводить дату публикации, если установить соответствующую галочку в настройках виджета. Вот ссылка на свежую версию скрипта: https://yadi.sk/d/uDdvuPb53HYWXS