Мета-тег «canonical» для любых типов страниц WP, а не только для «singular»

Есть такой мета-тег:

<link rel="canonical" href="http://example.site/page" />

Который сообщает поисковому роботу, что постоянный адрес запрошенной страницы: /page, и если вдруг страница запрошена по другому адресу (например, /?p=123), то её можно изучить, но не следует добавлять в индекс. Это позволяет избежать дубликатов контента.

WordPress может автоматически добавлять мета-тег link rel="canonical" к страницам типа «singular» (это посты, WP-страницы и страницы вложений). А вы, например, хотите раскручивать (в плане SEO) метку или рубрику. Сделали к ним уникальное описание, но раскрутка не идёт, потому что контент дублируется на страницах пагинации метки.

В идеале у каждой продвигаемой страницы должен быть мета-тег link rel="canonical", а у вспомогательных страниц (например, пагинация) должен быть другой мета-тег:

<meta name="robots" content="noindex, follow" />

Который сообщает индексатору, что эту страницу не надо вносить в индекс, но надо проверить ссылки на ней — вдруг какой-то новый контент найдётся при переходе по ссылке.

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

Я решил отказаться от плагинов для решения такой тривиальной (вроде бы) задачи, как указания канонического URL-а или «noindex, follow» вместо него. Написал скрипт для себя. Публикую, вдруг ещё кому-то будет нужен. Т.к. скрипт написан для себя и под свои нужды, он не вмещает в себя всю вселенную возможных вариантов. Я не хотел раздувать код на сотни строк, описывая тот функционал, который мне не нужен. Потому вот ряд ограничений для использования:

  • работает без пермалинков и с пермалинк-структурой только «/%postname%»;
  • и с произвольными (пользовательскми) таксономиями только без иерархии (типа меток, а не рубрик). Но с самими рубриками, конечно, работает без проблем;
  • возвращает канонический URL страниц home, singular, category, tag, tax;
  • для прочих типов или страниц пагинации (исключение ниже) возвращает пустую строку;
  • если для страницы пагинации (is_paged) хотите в качестве канонического указать адрес 1-й страницы, функцию нужно вызвать с ненулевым параметром, например, pavluha_canonical_url( 1 ).

Пример использования (php-код):

if ( $url = pavluha_canonical_url() )
	echo '<link rel="canonical" href="', $url, '" />', "\n";
else if ( is_paged() and is_archive() )
	echo '<meta name="robots" content="noindex, follow" />';

В этом случае робот-индексатор будет проинструктирован не включать в индекс, но следовать по ссылкам любых страниц пагинации архивов (например, архивов за день, месяц, год или «архив постов Васи Пупкина»).

Код публикуется в целях ознакомления. Если используете, то на свой страх и риск. Замечания по сути приветствуются. Негодования автоматически считаются причиной криворукости или глупости негодующего.

###
## Работает без пермалинков
## и с пермалинк-структурой /%postname% (ТОЛЬКО!),
## и с произвольными таксономиями ТОЛЬКО БЕЗ иерархии
## Возвращает канонический урл страниц home, singular, category, tag, tax
## для прочих типов или для пагинации (исключение ниже) возвращает пустую строку
## для пагинации если передан $first_page (не false), возвращает URL 1-й страницы
## v. 7 июля 2014
#
function pavluha_canonical_url( $first_page = false ) {
	global $wp_query, $wp_rewrite, $wpdb;
	if ( $wp_query->is_404 or $wp_query->is_paged and ! $first_page ) return '';
	$url = get_option( 'siteurl' ) .'/';
	if ( $wp_query->is_home ) return $url;
	$q = $wp_query->queried_object;
	if( ! $wp_rewrite->permalink_structure ) {
		$s = array(
			'post' => 'p',
			'page' => 'page_id',
			'attachment' => 'attachment_id',
			'category' => 'cat',
			'post_tag' => 'tag'
		);
		if ( $wp_query->is_singular ) {
			if( ! isset( $s[$q->post_type] ) ) return '';
			return $url .'?'. $s[$q->post_type] .'='. $q->ID;
		}
		if ( $wp_query->is_archive ) {
			if ( ! $q or ! $q->taxonomy ) return '';
			if( ! isset( $s[$q->taxonomy] ) )
				return $url .'?'. $q->taxonomy .'='. $q->slug;
			$url .= '?'. $s[$q->taxonomy] .'=';
			if ( 'category' == $q->taxonomy ) return $url . $q->term_id;
			return $url . $q->slug;
		}
		return '';
	}
	if ( $wp_query->is_singular ) {
		$name = $q->post_name;
		$parent_id = $q->post_parent;
		$sq = "SELECT `post_name`, `post_parent` FROM `$wpdb->posts` WHERE `ID` = ";
 		while ( $parent_id ) {
			if ( $rq = $wpdb->get_row( $s . $parent_id ) ) {
				$name = $rq->post_name .'/'. $name;
				$parent_id = $rq->post_parent;
			} else $parent_id = false;
		}
		return $url . $name;
	}
	if ( $wp_query->is_category ) {
		$struct = $wp_rewrite->extra_permastructs['category']['struct'];
		if ( '/' == $struct[0] ) $struct = substr( $struct, 1 );
		$name = $q->category_nicename;
		$parent_id = $q->category_parent;
		$sq = "SELECT t.slug slug, tt.parent category_parent FROM `$wpdb->terms` t "
			. "LEFT JOIN `$wpdb->term_taxonomy` tt ON tt.term_id = t.term_id "
			. "WHERE t.term_id = ";
 		while ( $parent_id ) {
			if ( $rq = $wpdb->get_row( $sq . $parent_id ) ) {
				$name = $rq->slug .'/'. $name;
				$parent_id = $rq->category_parent;
			} else $parent_id = false;
		}
		return $url . str_replace( '%category%', $name, $struct );
	}
	if ( $wp_query->is_archive ) {
		if ( ! $q->slug or ! $s = $wp_rewrite->extra_permastructs[$q->taxonomy]['struct'] ) return '';
		if ( '/' == $s[0] ) $s = substr( $s, 1 );
		$name = str_replace( '%'.$q->taxonomy.'%', $q->slug, $s );
		if ( $name == $s ) return '';
		return $url . $name;
	}
	return '';
}

Рабочий пример: на сайте супов есть рубрика «Куриные супы» 3-го уровня вложенности. Смотреть исходный код страницы по ссылке. Также на этом сайте каноническми являются страницы меток и ингредиентов (произвольная таксономия).

Кстати, для генерации всех мета-данных (включая title, description, keywords) я тоже использую свою функцию. Но пока индивидуально настраиваю её для каждого сайта. Возможно, опубликую позже.

Запись опубликована в рубрике SEO, Web-мастеринг с метками , . Короткая ссылка для добавления в закладки: Мета-тег «canonical» для любых типов страниц WP, а не только для «singular».

2 Responses

  1. sweatego говорит:

    Здравия. Подскажите пожалуйста, а то не совсем понял, как можно добавить для страниц вида site.ru/page2/ и меток в wordpress?

    • Павлуха говорит:

      Очень просто. Копируете оба блока кода (что под фразой «Пример использования»). И вставляете между тегами <head> и </head>. Если чудо не произошло, то вы либо не дунули (© Амаяк Акопян), либо программирование не ваша стезя.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Иногда ваш комментарий может не отобразиться сразу после публикации - будто пропал. Не волнуйтесь, он не пропадёт и появится потом, после моего одобрения.