Метка: wordpress

noindex, nofollow — хак для плагина Yoast SEO

Иногда необходимо закрыть страницы таксономий на сайте WordPress от индексации поисковыми системами. Если вы используете плагин Yoast SEO, он по умолчанию проставляет метатег noindex, follow. Однако, если вы хотите, чтобы на определенных таксономиях использовалось значение noindex, nofollow, можно добавить следующий код в файл functions.php вашей темы:

Пример кода для установки noindex, nofollow:

// добавляем для нужных таксономий noindex
add_filter('wpseo_robots', 'artit_wpseo_robots', 10, 2);
function artit_wpseo_robots($robots_str, $index) {
    if (is_tax()) { // Проверяем, что это таксономическая страница
        $current_taxonomy = get_queried_object(); // Получаем текущий объект таксономии
        
        // Если текущая таксономия относится к temp_taxonomy или another_temp_taxonomy
        if (in_array($current_taxonomy->taxonomy, ['temp_taxonomy', 'another_temp_taxonomy'])) {
            return 'noindex, nofollow'; // Устанавливаем noindex, nofollow
        }
    }
    // Возвращаем значение по умолчанию для всех остальных случаев
    return $robots_str;
}
// добавляем для нужных таксономий noindex

Объяснение кода:

  1. Добавление фильтра wpseo_robots:
    • Функция add_filter('wpseo_robots', 'artit_wpseo_robots', 10, 2); добавляет фильтр для изменения значений robots в мета-тегах Yoast SEO. Этот фильтр будет вызывать функцию artit_wpseo_robots с двумя аргументами: текущей строкой robots и индексом.
  2. Функция artit_wpseo_robots:
    • Функция artit_wpseo_robots($robots_str, $index) обрабатывает значения для мета-тегов robots.
  3. Проверка, является ли текущая страница таксономией:
    • if (is_tax()) проверяет, что текущая страница является страницей таксономии.
  4. Получение текущего объекта таксономии:
    • $current_taxonomy = get_queried_object(); получает информацию об объекте текущей таксономии.
  5. Проверка конкретной таксономии:
    • if (in_array($current_taxonomy->taxonomy, ['temp_taxonomy', 'another_temp_taxonomy'])) проверяет, является ли текущая таксономия одной из указанных (temp_taxonomy или another_temp_taxonomy).
  6. Применение noindex, nofollow:
    • Если текущая таксономия совпадает с указанными, строка robots изменяется на noindex, nofollow, что запрещает индексацию и следование по ссылкам на странице.
  7. Возврат значения по умолчанию:
    • Если условие не выполнено, функция возвращает исходное значение robots, предоставленное Yoast SEO.

Таким образом, с помощью данного кода мы добавляем гибкое управление индексацией и атрибутами robots для конкретных таксономий.

Как отключить автоматическое обновление в WordPress

Чтобы отключить автоматические обновления в WordPress, можно воспользоваться несколькими способами. Я расскажу о каждом из них с пояснениями.

Способ 1: Использование файла wp-config.php

  1. Откройте файл wp-config.php: Этот файл находится в корневой папке вашего сайта WordPress.
  2. Добавьте следующие строки:
    • Чтобы полностью отключить автоматические обновления, добавьте следующую строку в wp-config.php:
define('AUTOMATIC_UPDATER_DISABLED', true);

Это отключит все типы автоматических обновлений: для ядра WordPress, плагинов и тем.

Чтобы отключить автоматические обновления только для ядра WordPress, добавьте эту строку:

define('WP_AUTO_UPDATE_CORE', false);

Таким образом, ядро WordPress не будет обновляться автоматически, но это не повлияет на обновления плагинов и тем.

Способ 2: Использование фильтров в файле functions.php

Откройте файл functions.php вашей темы: Этот файл находится в папке текущей активной темы (wp-content/themes/your-theme/).

Добавьте код для отключения обновлений:

  • Отключение всех автоматических обновлений:
add_filter('automatic_updater_disabled', '__return_true');

Отключение автоматических обновлений ядра WordPress:

add_filter('auto_update_core', '__return_false');

Отключение автоматических обновлений плагинов и тем:

add_filter('auto_update_plugin', '__return_false'); add_filter('auto_update_theme', '__return_false');

Способ 3: Использование плагинов

Если вы не хотите редактировать код вручную, можно воспользоваться плагинами для управления автоматическими обновлениями. Например:

  • Easy Updates Manager: Этот плагин предоставляет интерфейс для настройки автоматических обновлений для ядра, плагинов, тем и даже переводов.

Разъяснение:

  • Ядро WordPress — это основная система WordPress, которая время от времени получает обновления для исправления багов, повышения безопасности и добавления новых функций. Отключая автоматические обновления, вы берете на себя ответственность за своевременное обновление системы.
  • Плагины и темы также получают обновления. Отключая их автоматическое обновление, важно следить за обновлениями вручную, чтобы избежать уязвимостей.

Рекомендуется не отключать автоматические обновления безопасности, если нет крайней необходимости, поскольку это может сделать ваш сайт уязвимым для атак.

Как убрать слеш ‘/’ в конце строки

Очень часто возникает задача, в которой необхлодимо убрать слеш в конце строки. Это может быть как адрес сайта, домена, ссылка или еще вообще что угодно.

Чтобы решить эту задачу очень простая функция есть rtrim. В которую нужно передать текущую строку, которую нужно обработать и очистить и параметры.

Выглядит это так:

$str = rtrim($str, '/\\');

Функция возвращает уже очищенную строку.

Вот например, у себя в проекте мы используем так ее:

<link rel="amphtml" href="<?=str_replace(site_url(), $static_amp_domain_name, home_url($wp->request)); ?>">

Кстати home_url($wp->request) — используется в WordPress для того, чтобы получить URL текущей страницы.

Как отправить email в формате html с помощью WordPress правильно

Вы можете отправлять электронные письма с помощью WordPress и PHP-скриптов. Вот пример простого PHP-скрипта, который можно использовать для отправки электронной почты через WordPress:

// Устанавлием возможность отправки письма в виде html
add_filter('wp_mail_content_type', function( $content_type ) {
            return 'text/html';
});
// Отправляем письмо
$mail_sent = wp_mail($to, $subject, $body, $headers);

// Проверяем результат отправки письма
if ($mail_sent) {
    echo 'Письмо успешно отправлено!';
} else {
    echo 'Ошибка при отправке письма.';
}

Можно отправить и просто php функцией mail(). Однако, для этого в WordPress ест своя функция — wp_mail();

Вот ее параметры:

wp_mail( string|string[] $to, string $subject, string $message, string|string[] $headers = ”, string|string[] $attachments = array() ): bool

Sends an email, similar to PHP’s mail function. — перевод Отправляет электронное письмо, аналогично функции почты PHP.

Возвращаемое значение true не означает автоматически, что пользователь получил электронное письмо успешно. Это всего лишь означает, что используемый метод смог обработать запрос без каких-либо ошибок.

Тип контента по умолчанию — text/plain, что не позволяет использовать HTML.
Однако вы можете установить тип контента электронного письма, используя фильтр «wp_mail_content_type».

Кодировка по умолчанию основана на кодировке, используемой в блоге. Кодировку можно установить с помощью фильтра wp_mail_charset.

Передаваемые параметры

$to string|string[] required
Массив или список адресов электронной почты, разделенных запятыми, для отправки сообщения.
$subject string required
Тема письма.
$message string required
Содержание сообщения.
$headers string|string[] optional
Дополнительные заголовки. По умолчанию: »
$attachments string|string[] optional
Пути к файлам для прикрепления. По умолчанию: array[]

Возвращаться
bool Указывает, было ли письмо отправлено успешно.

Обратите внимание, что вам также потребуется обработка данных формы, чтобы избежать уязвимостей, таких как атаки по инъекции.

Вывод тегов для категории (включая подкатегории)

Добавляем в файл functions.php следующую функцию (код):

// get tags for category (with children)
function get_category_tags($args) {
	global $wpdb;
	
	$tags = $wpdb->get_results
	("
		SELECT DISTINCT terms2.term_id as tag_id, terms2.name as tag_name, null as tag_link
		FROM
			".$wpdb->prefix."posts as p1
			LEFT JOIN ".$wpdb->prefix."term_relationships as r1 ON p1.ID = r1.object_ID
			LEFT JOIN ".$wpdb->prefix."term_taxonomy as t1 ON r1.term_taxonomy_id = t1.term_taxonomy_id
			LEFT JOIN ".$wpdb->prefix."terms as terms1 ON t1.term_id = terms1.term_id,

			".$wpdb->prefix."posts as p2
			LEFT JOIN ".$wpdb->prefix."term_relationships as r2 ON p2.ID = r2.object_ID
			LEFT JOIN ".$wpdb->prefix."term_taxonomy as t2 ON r2.term_taxonomy_id = t2.term_taxonomy_id
			LEFT JOIN ".$wpdb->prefix."terms as terms2 ON t2.term_id = terms2.term_id
		WHERE
			t1.taxonomy = 'category' AND p1.post_status = 'publish' AND terms1.term_id IN (".$args['categories'].") AND
			t2.taxonomy = 'post_tag' AND p2.post_status = 'publish'
			AND p1.ID = p2.ID
		ORDER by tag_name
	");
	$count = 0;
	foreach ($tags as $tag) {
		$tags[$count]->tag_link = get_tag_link($tag->tag_id);
		$count++;
	}
	return $tags;
}
// get tags for category (with children)

Вызываем эту функцию после в нужном шаблоне и нужном месте следующим образом:

$args = array(
        'categories'                => '12,13,14'
    );

$tags = get_category_tags($args);

12, 13, 14 — меняете на свои IDшники категорий, которые нужно вам показать.

Также в нашем случае необходимо было сделать вывод именно кастомных постов, по этому текущий код мы еще доработали:

// get tags for category (with children)
function get_category_tags($args) {
	global $wpdb;
	if(array_key_exists('post_type', $args)===false)
	{
		$args['post_type'] = "'post'";
	}
	
	$tags = $wpdb->get_results
	("
		SELECT DISTINCT terms2.term_id as tag_id, terms2.name as tag_name, null as tag_link
		FROM
			".$wpdb->prefix."posts as p1
			LEFT JOIN ".$wpdb->prefix."term_relationships as r1 ON p1.ID = r1.object_ID
			LEFT JOIN ".$wpdb->prefix."term_taxonomy as t1 ON r1.term_taxonomy_id = t1.term_taxonomy_id
			LEFT JOIN ".$wpdb->prefix."terms as terms1 ON t1.term_id = terms1.term_id,

			".$wpdb->prefix."posts as p2
			LEFT JOIN ".$wpdb->prefix."term_relationships as r2 ON p2.ID = r2.object_ID
			LEFT JOIN ".$wpdb->prefix."term_taxonomy as t2 ON r2.term_taxonomy_id = t2.term_taxonomy_id
			LEFT JOIN ".$wpdb->prefix."terms as terms2 ON t2.term_id = terms2.term_id
		WHERE
			t1.taxonomy = 'category' AND p1.post_status = 'publish' AND p1.post_type IN (".$args['post_type'].") AND terms1.term_id IN (".$args['categories'].") AND
			t2.taxonomy = 'post_tag' AND p2.post_status = 'publish' AND p2.post_type IN (".$args['post_type'].")
			AND p1.ID = p2.ID
		ORDER by tag_name
	");
	$count = 0;
	foreach ($tags as $tag) {
		$tags[$count]->tag_link = get_tag_link($tag->tag_id);
		$count++;
	}
	return $tags;
}
// get tags for category (with children)

Вызов функции теперь будет следующий для вывод тегой для кастомных постов:

<?$providers = get_category_tags(['categories' => $category_id, 'post_type' => '"game"']);?>

Использовать все это в теме можно следующим образом:

<?$providers = get_category_tags(['categories' => $category_id, 'post_type' => '"game"']);?>
		<?if(count($providers)):?>
		<nav class="providers">
			<?foreach($providers as $provider):?>
			<a href="<?=$provider->tag_link;?>"><?=$provider->tag_name;?></a>
			<?endforeach;?>
		</nav>
		<?endif;?>

Вывод тегов (tags) для кастомных постов (custom post type)

Всем привет.

У нас на проекте появилась задача сделать страницу в WordPress, где будут отображаться дополнительные параметры для кастомных типов записей. Грубо говоря — вывести все сущности одного типа, по которым фильтруются кастомные типы записей.

К примеру: у вас есть типа записей games. Условно говоря — это запись с игрой. Для каждой игры, помимо категории своей, есть также такой параметр, как «Провайдер» (Provider). Вот его мы решили хранить в базе, как тег для нашего custom_post_type => ‘game’.

И наша задача состоит в том, что нужно вывести на странице все провайдеры, у которых есть хоть одна запись типа «game». Получился код у нас следующий:

function get_terms_by_custom_post_type( $post_type, $taxonomy ){
	$args = array( 'post_type' => $post_type);
	$loop = new WP_Query( $args );
	$postids = array();
	// build an array of post IDs
	while ( $loop->have_posts() ) : $loop->the_post();
		array_push($postids, get_the_ID());
	endwhile;
	// get taxonomy values based on array of IDs
	$taxonomies = wp_get_object_terms( $postids,  $taxonomy );
	return $taxonomies;
}

Этот код работает. Все хорошо. Однако те, кто хорошо знает WordPress, заметит, что если эту функцию использовать, то сбиваются настройки для обьекта $post.

Для того, чтобы все работало как должно, нужно добавить еще одну строку:

	wp_reset_postdata();
В итоге у нас получился следующий код, который нужно добавить в файл functions.php для вашей темы:
function get_terms_by_custom_post_type( $post_type, $taxonomy ){
	$args = array( 'post_type' => $post_type);
	$loop = new WP_Query( $args );
	$postids = array();
	// build an array of post IDs
	while ( $loop->have_posts() ) : $loop->the_post();
		array_push($postids, get_the_ID());
	endwhile;
	// get taxonomy values based on array of IDs
	$taxonomies = wp_get_object_terms( $postids,  $taxonomy );
	wp_reset_postdata();
	return $taxonomies;
}

Использовать эту функцию необходимо следующим образом:

<?$providers = get_terms_by_custom_post_type('game', 'post_tag');?>

Наш код в итоге для вывода провайдеров получился следующим:

<?$providers = get_terms_by_custom_post_type('game', 'post_tag');?>
	
	<?if(count($providers)):?>
	<div class="games__body">
		<h1 class="entry-title text-center"><?=the_title();?></h1>
		<div class="games-providers__grid">
			<?foreach($providers as $provider):?>
			<a href="<?=get_term_link($provider, 'post_tag');?>" class="games-providers__item" id="<?=$provider->name;?>">
			</a>
			<?endforeach;?>
		</div>
	</div>
	<?endif;?>

Всем спасибо. Надеюсь будет полезна эта функция.

Скрываем админпанель для пользователей

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

Для своих сайтов и сайтов своих клиентов я всегда скрываю эту панель.

В этой статье расскажу как это делается.

Открываем файл functions.php в корне своей темы.

Далее вставляем следующий код:

add_filter('show_admin_bar', '__return_false');

Все. Теперь ваши авторизованные пользователи сайта WordPress не будут видеть админпанель вверху сайта.

Что мы сделали в итоге: мы добавили фильтр, который возвращает false для параметра show_admin_bar.

Если же вы хотите отключить ее только для определенного пользователя, то необходимо зайти во вкладку «Пользователи» в админпанели /wp-admin/users.php. Выбираем необходимого пользователя и у него снимаем флаг напротив Show Toolbar when viewing site.

Нажимаем синюю кнопку обновить. Готово!

Замена вариаций продукта с Select на Radio buttons для WooCommerce (вариант 2)

В одном из статей был описан метод, как можно заменить стандарный вывод выбора вариаций с помощью select на radio. Эта статья находится тут.

Сегодня же будет показан еще один, альтернативный, вариант решения данной проблемы.

Открываем файл /ваша_тема/woocommerce/single-product/add-to-cart/variable.php (если такого файла нет, то нужно создать его.

В папке /ваша_тема/woocommerce/ находятся шаблоны woocommerce, которые изменяются для темы. Исходники их находятся в папке с плагином woocommerce в папке /templates.

В этом файле мы перед функцией вывода select выбора вариаций товара добавляем

<?foreach($options as $index => $item):?>
<label for="<?=sanitize_title( $attribute_name );?>_<?=$item;?>" <?if($index===0):?>class="active"<?endif;?>><?=$item;?></label>
<?endforeach;?>

и оборачиваем все это (вместе с выводом select) в обертку

<div class="radio-input-container"></div>

В итоге у нас получится следующая конструкция:

<div class="radio-input-container">
<?foreach($options as $index => $item):?>
<label for="<?=sanitize_title( $attribute_name );?>_<?=$item;?>" <?if($index===0):?>class="active"<?endif;?>><?=$item;?></label>
<?endforeach;?>
<?php
wc_dropdown_variation_attribute_options(
array(
'options'   => $options,
'attribute' => $attribute_name,
'product'   => $product,
)
);
?>
</div>

в js файл со скриптами добавляем:

$('.radio-input-container label').on('click', function(){
var Value = $(this).text();
var Label = $(this);
$('.radio-input-container label').removeClass('active');
Label.addClass('active');
Label.parent().find('select').val(Value).change();
});

Я также добавил очистку наших «лейблов» по клику на ссылку «Очистить»:

$('.reset_variations').on('click', function(){
$('.radio-input-container label').removeClass('active');
});

и следующие стили получились:

.radio-input-container {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 15px;
label {
width: 20%;
text-align: center;
border: 1px solid @colorGrey;
border-radius: 5px;
padding: 6px 15px 5px 15px;
cursor: pointer;
font-weight: 500;
&:hover, &.active {
border-color: @colorRed;
background: @colorWhite;
}
}
select {
display: none;
}
}

Select я спрятал намеренно, что не портило дизайн и не путало пользователя.

В итоге получилась такая вот красота: