Есть зло, которое уже давно живет в WordPress, и сегодня мы попробуем его побороть! Это зло – дубли. Наш любимый движок, может доставить массу проблем, плодя бесполезные страницы. Лечиться этот недуг просто добавлением нескольких строк кода, которые избавят владельцев сайтов от лишней головной боли в дальнейшем.
Когда мы только установили WordPress или пришли к выводу, что у нас есть страницы, которые не хотелось бы видеть в выдаче, то мы можем решить эту задачу несколькими способами. Первый - это воспользоваться файликом robots.txt – это удалит страницы из индекса, но они останутся доступны для наших посетителей. Мало кому взбредёт сослаться на закрытые страницы, то нам от этого пользы будет мало, поэтому есть второй способ – это воспользоваться WordPress API, при помощи, которого мы можем закрыть страницы и установить необходимые редиректы.
Основные дубли в WordPress, с которыми мы можем столкнуться это:
- Страницы вложений – под каждый загруженный файл или изображение генерируется полноценная страница с формой. Мало того, что в большинстве случаев она сама лишний груз, так ещё через форму комментирования мы можем получить нескончаемый поток спама;
- Архивы дат – с одной стороны полезная штука, но мы получаем три страницы с одним и тем же контентом (/год/, /год/месяц/, /год/месяц/день/) - это большой минус, который надо обязательно устранять;
- Пагинация у статей – как по мне, бесполезный функционал, который только размазывает контент;
- ?replytocom – в комментариях к ссылке ответить добавляется эта часть, раньше это было страшной бедой, так как если статья была обсуждаема, то мы получали на неё десяток и более дублей.
Для того, чтобы избавиться от этих дублей в WordPress, нам потребуется открыть файл functions.php в активной теме и добавить туда код. Давайте будем работать поочередно и сперва разберемся со страницами вложений, для этого добавим следующие строчки:
add_action('template_redirect', 'remove_attachment_pages', 1);
function remove_attachment_pages(){
global $post;
$post_parent = $post->post_parent;
if(!isset($post_parent) || !is_numeric($post_parent)){
return false;
}
if(is_attachment() && $post_parent != 0){
$page_url = get_permalink($post_parent);
$status = 301;
}else if(is_attachment() && $post_parent < 1){
$page_url = get_home_url();
$status = 302;
}else{
return false;
}
wp_safe_redirect(
esc_url_raw(
apply_filters(
'sitecare_redirect_unattached_images',
$page_url
)
),
$status
);
exit();
}
Мы прикрепляем к событию template_redirect свою функцию, в которой устанавливаем редирект при открытии страницы с файлом или изображением. Так же, если вложение не прикреплено к контентной странице, перенаправляем пользователя на главную.
Двигаемся дальше и разберемся с архивами. Принцип тот же, только мы прикрепляем свою функцию к событию wp:
add_action('wp', 'remove_archives_date');
function remove_archives_date(){
if(is_date() && !is_admin()){
wp_redirect(
get_home_url(),
301
);
exit();
}
return false;
}
Для того, чтобы избавиться от пагинации у постов нам потребуется добавить следующий код:
add_action('template_redirect', 'remove_post_pagination');
function remove_post_pagination(){
if(is_singular() && !is_front_page()){
global $post, $page;
$num_pages = substr_count($post->post_content, '<!--nextpage-->') + 1;
if($page > $num_pages || $page == 1){
wp_redirect(
get_permalink($post->ID)
);
exit();
}
}
return false;
}
Чтобы решить проблему с дублями ?replytocom, нам потребуется установить редирект и, дополнительно, убрать параметр у самих ссылок:
Добавляем перенаправление на саму же статью:
add_action('template_redirect', 'remove_replytocom', 1);
function remove_replytocom(){
if(isset($_GET['replytocom']) && is_singular()){
$post_url = get_permalink($GLOBALS['post']->ID);
$comment_id = sanitize_text_field($_GET['replytocom']);
$query_string = remove_query_arg(
'replytocom',
sanitize_text_field(
$_SERVER['QUERY_STRING']
)
);
if(!empty($query_string)){
$post_url .= '?'.$query_string;
}
$post_url .= '#comment-'.$comment_id;
wp_redirect($post_url, 301);
exit();
}
return false;
}
И вырезаем сомнительный параметр из ссылки:
add_filter('comment_reply_link', 'link_remove_replytocom');
function link_remove_replytocom($link){
return preg_replace(
'`href=(["\'])(?:.*(?:\?|&|&)replytocom=(\d+)#respond)`',
'href=$1#comment-$2',
$link
);
}
Вот и всё, мы получили нормальную ссылку на форму с ответом.
Как вы могли заметить мы смогли довольно легко залатать дыры в нашем движке и для этого нам потребовалось немного расширить наш functions.php, но это не самый лучший вариант! Третий способ – это установить соответствующий плагин. Так как если нам потребуется создать новый проект, то весь код придётся копипастить и добавлять заново, а его только для удаления дублей получилось строк 100. Для решения это задачи, а также чистки кода и оптимизации WordPress я написал собственный плагин Bicycles by falbar, где более 30+ объединённых в одном месте велосипедов.