Excludeposts — плагин WP для скрытия постов с «главной» и из RSS по рубрикам, меткам и индивидуально

Задача скрытия постов с «главной» и из RSS в блогах на WordPress уже многократно решена. Но я не знаю ни одного решения, которое бы обладало функционалом плагина Pavluha.net Excludeposts, а именно:

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

Я сам — человек весьма скрытный, потому, естественно, плагин Excludeposts буду использовать на всех сайтах, где по разным причинам потребуется скрывать какие-то посты с «главной» и из RSS.

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

А это значит, что плагин будет поддерживаться в актуальном 100% рабочем состоянии, даже если разработчики WP что-то очень изменят в своём движке. К слову, работоспособность плагина не гарантируется на WP древнее версии 3.1. Потому что я использовал современные технологии. :)

Внимание, смертельный номер! Сейчас я активирую плагин на этом блоге и продемонстрирую его работоспособность.

Установка

Стандартная и знакомая многим процедура. Добавляю новый плагин путём его загрузки со своего компьютера. Для этого выбираю архив pavluha.net-excludeposts.zip, после получения сообщения об удачной установке не забываю активировать плагин.

Редактор рубрик

Теперь админка моего блога изменилась до неузнаваемости. :) Конкретно, в редакторе рубрик при выборе любой рубрики можно лицезреть новую опцию: Исключить посты. Она имеет 4 значения:

  • Не исключать
  • Только из RSS
  • Только с «главной»
  • С «главной» и RSS

Там же есть небольшая подсказка. Под «главной» подразумевается ваша основная лента постов, которая обычно выводится на главной странице блога. А под RSS подразумевается основная RSS-лента постов, которая обычно доступна по адресу /feed или /?feed=rss. Кроме неё есть свои ленты у каждой рубрики, метки, и даже своя лента комментариев у каждого поста — из них плагин ничего не исключает.

Кстати, новое меню «Исключить посты» добавилось также и в редактор меток. Принцип действия прост и понятен: выбираете, откуда исключать посты данной рубрики или метки, нажимаете «Обновить». Теперь посмотрим список рубрик:

Список рубрик

Здесь появился новый столбец «Exclude?», в котором отображается информация для каждой рубрики, исключены ли её посты с «главной» и RSS. Вы можете нажать на заголовок любой рубрики, добавить для неё правило исключения постов или отменить исключение выбором пункта «Не исключать». То же самое относится и к меткам:

Редактор меток

Виджет в редакторе записи

Изменения произошли и в редакторе постов. В правой колонке в самом низу появился виджет, позволяющий выборочно исключить любую запись с «главной», RSS или из обоих этих лент. Вы можете виджет перетащить в любое удобное вам место (даже в левую колонку). А можете отключить. Для этого в самом верху страницы есть «Настройки экрана» — снимите галочку «Pavluha.net Excludeposts». Так вы просто уберёте с экрана виджет, но посты по-прежнему будут исключаться.

Скачать плагин Excludeposts

Важные замечания!

Если вы уже пользуетесь другим плагином или кодом исключения, то при активации плагина Excludeposts ваши скрытые посты могут на какое-то время попасть в RSS и на главную, пока вы не настроите плагин Excludeposts. Для предотвращения такого поведения найдите в файле плагина строчку:

add_filter( 'pre_get_posts', 'excludeposts__main' );

И модифицируйте её следующим образом:

add_filter( 'pre_get_posts', 'excludeposts__main', 1 );

Т.е. теперь функция плагина Excludeposts сработает раньше функции вашего плагина и не уничтожит результат его работы. Затем настройте плагин Excludeposts и установите ему самое позднее срабатывание:

add_filter( 'pre_get_posts', 'excludeposts__main', 99999 );

Информация для чистюль. После деинсталляции плагина Excludeposts все посты будут отображаться как обычно, а в базе данных останется немножко «мусора»: это 2 записи в таблице «options», которые начинаются на «pavluha_net_excludeposts__». И записи в таблице «postmeta»: «_pavluha_net_excludeposts__single» (искать в поле meta_key) — их будет ровно столько, сколько постов вы исключили индивидуально в редакторе постов.

А вот и код плагина:

<?
/*
Plugin Name: Pavluha.net Excludeposts
Plugin URI: http://pavluha.net/excludeposts-wordpress-plugin.html
Description: Плагин помогает опционально исключить с "главной" и из RSS посты определённых категорий, с определёнными метками и просто отдельных записей.
Version: 1.0
Author: Pavluha
Author URI: http://pavluha.net/
*/

/*  Copyright 2013  Pavluha.net ( feedback: http://pavluha.net/feedback.htm )

    This program is free software and bla, bla, bla...
*/

/* Внесение изменений в административную часть */
add_action( 'admin_init', 'excludeposts__actions' );
function excludeposts__actions() {
	add_action( 'category_edit_form_fields', 'excludeposts__fields_form' );
	add_action( 'category_edit_form_fields', 'excludeposts__fields_form' );
	add_action( 'post_tag_edit_form_fields', 'excludeposts__fields_form' );
	add_action( 'edited_post_tag', 'excludeposts__save' );
	add_action( 'edited_category', 'excludeposts__save' );
	add_meta_box( 'excludeposts__post_fields', 'Pavluha.net Excludeposts', 'excludeposts__post_func', 'post', 'side' );
	add_action( 'save_post', 'excludeposts__save_post' );
	add_filter( 'manage_edit-category_columns', 'excludeposts__add_column' );
	add_filter( 'manage_edit-post_tag_columns', 'excludeposts__add_column' );
	add_filter( 'manage_category_custom_column', 'excludeposts__fill_column', 10, 3 );
	add_filter( 'manage_post_tag_custom_column', 'excludeposts__fill_column', 10, 3 );
}

/* Фильтрация постов перед получением */
add_filter( 'pre_get_posts', 'excludeposts__main' );

/* Добавляем опцию исключения постов в редактор рубрик, меток */
function excludeposts__fields_form( $t ) {
	$option_name = 'pavluha_net_excludeposts__' . $t->taxonomy;
	$o = get_option( $option_name );
	if ( isset( $o[$t->term_id] ) ) $o = $o[$t->term_id];
	else $o = 0;
?>
	<tr class="form-field">
	<th scope="row" valign="top"><label for="exclude">Исключить посты:</label></th><td>
		<? excludeposts__select( $o ); ?>
		<p class="description">Вы можете исключить попадание постов рубрики (метки) <strong><?= $t->name ?></strong> на "главную" (т.е. посты не будут попадать в основную общую ленту постов), в RSS (имеется ввиду основная общая RSS) или оба варианта (последний пункт в списке).</p>
	</td></tr>
<?
}

/* Сохраняем значение опции исключения постов в редакторе рубрик, меток */
function excludeposts__save() {
	if ( ! $_POST['tag_ID'] or ! $_POST['taxonomy'] or ! isset( $_POST['exclude'] ) ) return;
	$option_name = 'pavluha_net_excludeposts__' . $_POST['taxonomy'];
	if ( ! $option = get_option( $option_name ) ) $option = array();
	$option[$_POST['tag_ID']] = (int) $_POST['exclude'];
	update_option( $option_name, $option );
}

/* Интерфейс для исключения записей в на странице редактирования записи */
function excludeposts__post_func( $post ) {
	$o = (int) get_post_meta( $post->ID, '_pavluha_net_excludeposts__single', true );
?>
	<p class="description">Вы можете исключить попадание этого поста на "главную" (т.е. пост будет исключён из общей ленты постов), в RSS (имеется ввиду основная общая RSS) или оба варианта (последний пункт в списке).</p>
	<? excludeposts__select( $o ) ?>
	<p class="description">Изменения сохранятся при <strong>публикации, обновлении или сохранении записи!</strong></p>
<?
}

/* Добавляем метаданные поста при сохранении записи */
function excludeposts__save_post( $post_id ) {
	if ( ! current_user_can( 'edit_post', $post_id ) ) return false;
	if ( isset( $_POST['exclude'] ) ) {
		$new = (int) $_POST['exclude'];
		$old = (int) get_post_meta( $post_id, '_pavluha_net_excludeposts__single', true );
		if ( ! $new and $old ) delete_post_meta( $post_id, '_pavluha_net_excludeposts__single' );
		else if ( $new and $old != $new ) update_post_meta( $post_id, '_pavluha_net_excludeposts__single', $new );
	}
}

/* Добавляем столбец исключения постов в списки рубрик, меток */
function excludeposts__add_column( $columns ) { $columns['exclude'] = 'Exclude?'; return $columns; }

/* Заполняем столбец исключения постов в списках рубрик, меток */
function excludeposts__fill_column( $out, $column_name, $id ) {
	if ( 'exclude' != $column_name ) return $out;
	$screen = get_current_screen();
	$option_name = 'pavluha_net_excludeposts__' . $screen->taxonomy;
	$option = get_option( $option_name );
	$options_texts = array( '-', 'RSS', 'Главная', 'RSS & Главная' );
	if ( ! isset( $option[$id] ) ) $option[$id] = 0;
	if ( ! isset( $options_texts[$option[$id]] ) ) return '?';
	else return $options_texts[$option[$id]];
}

/* Список вариантов исключения */
function excludeposts__select( $o ) {
?>
	<select class="postform" id="exclude" name="exclude">
		<option value="0"<?= 0 == $o ? 'selected' : '' ?>>Не исключать</option>
		<option value="1"<?= 1 == $o ? 'selected' : '' ?>>Только из RSS</option>
		<option value="2"<?= 2 == $o ? 'selected' : '' ?>>Только с "главной"</option>
		<option value="3"<?= 3 == $o ? 'selected' : '' ?>>С "главной" и RSS</option>
	</select>
<? # Номера option value используются в строках скрипта с меткой #thesenum
}

/* Основная функция исключения постов */
function excludeposts__main ( $query ) {
# 1 - RSS; 2 - Главная; 3 - RSS & Главная.
# Меткой #thesenum обозначены строки, где используются эти цифры
	$n_ex = array();
    if ( $query->is_home )
		$n_ex = array( 2, 3 ); #thesenum;
	else if ( $query->is_feed and ! $query->is_single and ! $query->is_archive )
        $n_ex = array( 1, 3 ); #thesenum;
	if ( $n_ex ) {
		$ex = excludeposts__get_ex_array( 'category', $n_ex );
		if ( $ex ) $query->set( 'category__not_in', $ex );
		$ex = excludeposts__get_ex_array( 'post_tag', $n_ex );
		if ( $ex ) $query->set( 'tag__not_in', $ex );
		$ex = excludeposts__get_ex_array( 'post', $n_ex );
		if ( $ex ) $query->set( 'post__not_in', $ex );
	}
    return $query;
}

/* Ф-я возвращает массив номеров исключённых объектов.
   $taxonomy - суффикс опции WP, $n_ex - массив исключаемых значений: см. #thesenum */
function excludeposts__get_ex_array ( $taxonomy, $n_ex ) {
	if ( 'post' == $taxonomy ) {
		global $wpdb;
		return $wpdb->get_col( "SELECT `post_id` FROM $wpdb->postmeta " .
			"WHERE `meta_key` = '_pavluha_net_excludeposts__single' " .
			"AND `meta_value` IN ( " . join( ',', $n_ex ) . " )" );
	}
	if ( ! $option = get_option( "pavluha_net_excludeposts__$taxonomy" ) ) return false;
	$ex = array(); foreach( $option as $k=>$v ) if ( in_array( $v, $n_ex ) ) $ex[] = $k;
	return $ex;
}
?>
Запись опубликована в рубрике Web-мастеринг с метками , , . Короткая ссылка для добавления в закладки: Excludeposts — плагин WP для скрытия постов с «главной» и из RSS по рубрикам, меткам и индивидуально.

9 Responses

  1. Уведомление: WordPress 3.1 - исключённые посты на главной и в RSS (решение) / блог Hyper SEO

  2. Насколько он увеличивает нагрузку на сервер... хотя бы в количестве запросов БД?

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

      При запросе главной и RSS появляются 3 дополнительных запроса. Рост потребления памяти на 0.05 Мб. Время выполнения на тестовом блоге как было в диапазоне 0.41 — 0.42 секунды, так и осталось в этих пределах — ввиду погрешности изменение заметить невозможно. При запросе других страниц (кроме главной и RSS) плагин бездействует.

      3 запроса — это 1) информация о скрытых метках, 2) информация о скрытых рубриках, 3) информация о скрытых постах. В общем-то можно сократить до 2-х запросов, объединив инфо рубрик и меток в одну опцию.

      В любом случае, если вы переживаете за нагрузку, наверняка используете плагин кэширования, и эти 3 запроса исполняются пару раз в сутки.

  3. Агент 00x говорит:

    а я Advanced Category Excluder использую, тоже хорошая штука

  4. Федор говорит:

    Павлуха зайди забери свои деньги Ты выиграл в конкурсе

    Я так понимаю случайно. но все равно забирай.

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

      Правильно понимаешь, Фёдор — случайно. Я даже не знал о конкурсе. :) Кошелёк на почту отправил.

  5. Тимофей говорит:

    Спасибо за плагин. Искал именно такой чтобы с главной страницы исключать отдельные посты написанные копирайтерами. Многие плагины выключают целыми категориями. Для меня это роскошь)) А плагин Simply Excluder не заработал. А твой прекрасно справился и проверен на вордпресс 4.2.2

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

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

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