Плагин WordPress. Исключаем ненужные категории.

6 мая, 2010
wordpress plugin exclude categories

На сегодняшний день, не смотря на всю критику в его адрес, движок WordPress остаётся наиболее популярным среди блоггеров. И одна из основных причин такой популярности – огромное количество плагинов и готовых тем оформления.

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

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

Для чего это может понадобиться.

1) Вы ведёте тематический блог, но иногда любите писать просто о жизни. По-умолчанию, на главной страницы блога отображаются последние записи. Посетитель, попав на ваш ресурс, в первую очередь, будет смотреть именно на них, и если они ему не понравятся, то вряд ли он станет листать ваши архивы, надеясь найти тематическую статью.

2) Вы занимаетесь размещением платных статей. Тут вообще всё просто. Постоянные читатели вряд ли оценят seo'шную статью о преимуществах очередного интернет магазина :) В тоже время, монетизировать блог как-то нужно.

Возвращаемся к реализации.

Сразу даю ссылку на архив

архив с исходным кодом

UPD. Плагин обновлен для использования с WP 3.1.

Вообще-то, я нашел несколько готовых плагинов с похожим функционалом. Но по разным причинам они меня не устроили. Возможности некоторых были явно избыточны (для меня), другие работали не совсем так, как мне хотелось. Поэтом я решил сделать свой вариант.

Установка и подключение точно такие же, как и у большинства плагинов. Архив нужно распаковать в папку wp-content\plugins и активировать в панели у правления. После этого в разделе Settings появится страница с настройками плагина.

wp plugin exclude categories admin

Отмечаете нужные категории, и решаете где их не нужно показывать.

Теперь разберем реализацию плагина.

Начало стандартное.

/*
Plugin Name: Exclude Category Plugin
Plugin URI: http://www.simplecoding.org/plagin-wordpress-isklyuchaem-nenuzhnye-kategorii.html
Description: Позволяет убрать посты указанных категорий с главной страницы и из RSS ленты.
Version: 1.0
Author: Statsenko Vladimir
Author URI: http://www.simplecoding.org
*/

Этот комментарий содержит данные, которые отображаются на панели управления плагинами.

Создание страницы в панели управления.

Нам нужно выполнить два действия: создать новый пункт в меню Settings и создать форму с настройками плагина.

Начнём с создания формы.

  1. <?php
  2. function ec_settings_page() {
  3.   //получаем список категорий
  4.   $categories = get_categories(array('hide_empty' => false));
  5. ?>
  6. <div class="wrap">
  7.   <h2>Exclude Category Plugin Settings</h2>
  8.   <form method="post" action="options.php">
  9.     <?php
  10.       //Необходимо для автоматической обработки формы
  11.       settings_fields( 'ec-settings-group' );
  12.     ?>
  13.     <table class="form-table">
  14.       <tbody>
  15.         <tr valign="top">
  16.           <th scope="row">Выберите категории, которые нужно исключить</th>
  17.           <td>
  18.             <fieldset>
  19.               <legend class="screen-reader-text"><span>Выберите категории, которые нужно исключить</span></legend>
  20.             <?php
  21.               //читаем значение текущее опции
  22.               $curCL = get_option('cats_list');
  23.               foreach ($categories as $category) {
  24.                 $checked = '';
  25.                 if (is_array($curCL) && in_array($category->cat_ID, $curCL)) {
  26.                   $checked = 'checked="checked"';
  27.                 }
  28.                 echo '<label><input '.$checked.' type="checkbox" name="cats_list[]" value="'.$category->cat_ID.'" /> '.$category->name.'</label><br />';
  29.               }
  30.             ?>
  31.             </fieldset>
  32.           </td>
  33.         </tr>
  34.         <tr valign="top">
  35.           <th scope="row">Не выводить выбранные категории</th>
  36.           <td>
  37.             <fieldset>
  38.               <legend class="screen-reader-text"><span>Не выводить выбранные категории</span></legend>
  39.               <?php
  40.                 $curCH = get_option('cats_home');
  41.                 $cH = $cF = '';
  42.                 if (is_array($curCH)) {
  43.                   $cH = in_array('home', $curCH) ? 'checked="checked"' : '';
  44.                   $cF = in_array('feed', $curCH) ? 'checked="checked"' : '';
  45.                 }
  46.               ?>
  47.               <label><input type="checkbox" <?php echo $cH; ?> name="cats_home[]" value="home" /> на главной</label><br />
  48.               <label><input type="checkbox" <?php echo $cF; ?> name="cats_home[]" value="feed" /> в RSS ленте</label>
  49.             </fieldset>
  50.           </td>
  51.         </tr>
  52.       </tbody>
  53.     </table>
  54.     <p class="submit"><input type="submit" class="button-primary" value="Сохранить" /></p>
  55.   </form>
  56. </div>
  57.  
  58. <?php
  59. }
  60. ?>

* This source code was highlighted with Source Code Highlighter.

Получилась она довольно объёмной, но в основном из-за разметки. Кода совсем немного.

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

Перед отображением формы мы получаем список всех постов с помощью функции get_categories. Внутри формы создаём группу чекбоксов для них. Атрибут name у этой группы имеет значение cats_list[].

Вторая группа чекбоксов позволяет указать, откуда нужно исключить записи. У неё атрибут name равен cats_home[].

Теперь обратите внимание на функцию settings_fields('ec-settings-group'), которую мы вызываем сразу после открытия формы. Она создаёт несколько скрытых полей, с помощью которых автоматически выполняется сохранение данных, введённых в форму.

Но для того, чтобы эта возможность заработала необходимо зарегистрировать оба наших набора чекбоксов.

function register_ec_settings() {
	register_setting( 'ec-settings-group', 'cats_list' );
	register_setting( 'ec-settings-group', 'cats_home' );
}

В первом параметре функции register_setting передаём имя группы (оно должно совпадать с параметром, переданным settings_fields). Во втором параметре указываем атрибут name группы чекбоксов.

Теперь, при сохранении формы данные автоматически будут записаны в таблицу wp_options (при этом выполняется их сериализация).

Получить сохранённые данные можно с помощью функции settings_fields. Что мы и делаем перед формированием списка чекбоксов в форме. Проверку, есть ли текущая категория среди выбранных ранее, выполняем с помощью функции is_array.

Добавляем новый пункт в меню Settings

  1. //создаём подменю Settings->Exclude Category Plugin и соответствующую форму
  2.  
  3. //регистрируем функцию создания меню
  4. add_action('admin_menu', 'ec_create_menu');
  5.  
  6. //функция создания меню
  7. function ec_create_menu() {
  8.   add_submenu_page('options-general.php'
  9.            ,'Exclude Category Plugin Settings'
  10.            , 'Exclude Category'
  11.            , 'edit_plugins'
  12.            , __FILE__
  13.            , 'ec_settings_page');
  14.   
  15.   //Регистрируем функцию register_ec_settings. Она нужна для автоматической
  16.   //обработки формы с настройками
  17.   add_action( 'admin_init', 'register_ec_settings' );
  18. }

* This source code was highlighted with Source Code Highlighter.

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

Для того, чтобы WP создал меню, нужно добавить действие (add_action). В её первом параметре мы указываем название действия в котором мы хотим выполнить наш код (в данном случае это admin_menu), во втором параметре – имя функции, которую нужно выполнить, именно в ней должен быть вызов add_submenu_page. Кроме того, в этой функции мы добавляем еще одно действие – admin_init, и в нём регистрируем обработчик register_ec_settings.

На данном этапе у нас есть рабочая форма в админке с двумя наборами чекбоксов. Все отмеченные чекбоксы сохраняются в базе данных (таблица wp_options) и доступ к ним можно получить с помощью get_option('cats_home') и get_option('cats_list').

Рассмотрим принцип удаления постов.

Список постов движок WP получает из базы данных с помощью обычного запроса. Т.е. нам нужно добавить к этому запросу условия, которые исключат ненужные нам категории.

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

add_filter('pre_get_posts','ec_exclude');

Событие pre_get_posts возникает как раз перед отправкой запроса, а ec_exclude – название нашей функции, причем в первом её параметре WP передаст объект с запросом. Рассмотрим её подробнее.

  1. function ec_exclude($query) {
  2.   //читаем массивы с опциями
  3.   if (is_array($target = get_option('cats_home'))) {
  4.     if (is_array($categories = get_option('cats_list'))) {
  5.       //добавляем к id категорий знак "-"
  6.       foreach ($categories as $i => $category) {
  7.         $categories[$i] = '-'.$categories[$i];
  8.       }
  9.       //формируем строку с перечнем категорий
  10.       $cat_string = implode(',', $categories);
  11.       //удаляем посты указанных категорий из RSS ленты
  12.       if (in_array('feed', $target) && $query->is_feed) {
  13.         $query->set('cat',$cat_string);
  14.       }
  15.       //удаляем посты указанных категорий с главной страницы
  16.       if (in_array('home', $target) && $query->is_home) {
  17.         $query->set('cat',$cat_string);
  18.       }
  19.     }
  20.   }
  21.   return $query;
  22. }

* This source code was highlighted with Source Code Highlighter.

Исключить ненужные категории можно с помощью метода set.
Например:

$query->set('cat', '-1,-2,-5');

Здесь 1, 2, 5 – id категорий в БД, знак минус означает, что категории нужно исключить.

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

$query->set('category__not_in',$categories);

В самой функции ec_exclude мы проверяем, указаны ли страницы, с которых нужно убрать посты и список ненужных категорий (с помощью get_option('cats_home') и get_option('cats_list')).

Если эти опции установлены, то формируем строку с id категорий $cat_string и передаём её методу set. При этом с $query->is_home и помощью $query->is_feed проверяем, какая страница в данный момент формируется.

Не зависимо от того, вносили мы изменения в запрос или нет, функция ec_exclude обязательно должна вернуть объект $query, иначе сформировать страницу не получится.

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

Все замечания, вопросы и предложения пишите в комментариях. Постараюсь ответить ;)

Понравилась статья? Подписывайтесь на продолжение rss link !

Или на мой твиттер twitter link

]]>

Добавьте эту страницу в google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

]]>

Опубликовано в HTML, PHP, Web разработка, WordPress Комментарии (52) »

]]>

Вы можете оставить комментарий. Трекбеки закрыты.

  • http://www.blogmastera.com/ Sergey

    интересно, возьму себе на вооружение!

  • http://www.blogmastera.com Sergey

    интересно, возьму себе на вооружение!

  • http://ostrovrusskij.ru/ iNet Domovoi

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

    • http://www.simplecoding.org/ Владимир

      У меня нормальное к этому отношение.
      Реклама на блогах присутствует практически всегда, даже если это реклама услуг самого автора или способ заработать авторитет.
      Поэтому не вижу ничего плохого в том, что кто-то размещает статьи за деньги.
      Если автор пишет интересные для меня статьи, то я их читаю. Если среди них будет реклама, то я ее пропущу. Если рекламы будет очень много, то, возможно, отпишусь от блога (хотя такого еще не было :) )

  • http://ostrovrusskij.ru/ iNet Domovoi

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

    • http://www.simplecoding.org/ Владимир

      У меня нормальное к этому отношение.
      Реклама на блогах присутствует практически всегда, даже если это реклама услуг самого автора или способ заработать авторитет.
      Поэтому не вижу ничего плохого в том, что кто-то размещает статьи за деньги.
      Если автор пишет интересные для меня статьи, то я их читаю. Если среди них будет реклама, то я ее пропущу. Если рекламы будет очень много, то, возможно, отпишусь от блога (хотя такого еще не было :) )

  • http://profitgid.ru/ Eduard

    Хороший плагин, думаю он мне пригодится! Спасибо! А к рекламе я тоже отношусь нормально, главное чтобы блоги не были ней перегружены!

  • http://profitgid.ru/ Eduard

    Хороший плагин, думаю он мне пригодится! Спасибо! А к рекламе я тоже отношусь нормально, главное чтобы блоги не были ней перегружены!

  • http://s-movie.ru/ Серёга

    Хороший плагин, но вот реклама иногода сильно напрягает!

  • http://s-movie.ru Серёга

    Хороший плагин, но вот реклама иногода сильно напрягает!

  • http://twilight3.biz/ Антон

    Да плагин действительно хорош!

  • http://twilight3.biz Антон

    Да плагин действительно хорош!

  • Игорь

    Если бы без рекламы, было бы замечательно!

  • http://okulich.ru zzmenchik

    Спасибо за помощь – это то что я искал и не знал как сделать. Ещё раз спасибо.

  • http://zoomexe.net Denis

    Спасибо, отличный плагин, искал что-то подобное!

  • http://www.microwebnet.com/ Алекс

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

  • http://imuno.maniya.org imunomanka

    Интересно, можно ли с помощью этого плагина убрать категорию Архив на блоге? У вас я вижу нет архивной рубрики. Мне она на нервы давит…

  • http://imuno.maniya.org imunomanka

    Скачала, установлю на свой страх и риск. Спасибо потом скажу…

  • http://www.simplecoding.org Владимир

    Убрать можно любую категорию. Но, мне кажется, вы имеете ввиду не категорию, а блок с перечнем месяцев и количеством записей в них. Он создается либо с помощью виджета (т.е. его можно убрать из админке на странице управления виджетами), либо с помощью php кода в файле sidebar.php (этот файл находится в папке с вашей темой).

  • http://www.air-jordan-18.com air jordan 18

    Very vivid appearance, perfect plot, challenging game. Many of us put this game as a very important part of life. Surprise,when I browse the web ,I found these website Pretty good. adidas arenas Signature

  • Pingback: Вопросы и ответы по Wordpress - выпуск 7

  • Pingback: Как скрыть некоторые категории с главной страницы и из RSS | Exclude categories | n-wp.ru | темный Незнайка светлый Wordpress

  • Pingback: Создание сайта. Разработка сайта. Киев, Оболонь » Post Topic » Плагин Exclude categories исключаем категории с главной и RSS

  • http://www.my-zozh.ru/ Irina

    Спасибо, лёгкий и понятный плагин – решила-таки не мудрить на этот раз с кодами, а использовать то, что уже есть!

  • Dasha

    подскажите, а как убрать ссылку на категорию еще и из Виджета "Категории" ?

    • http://www.simplecoding.org Владимир

      Я не советую изменять стандартные виджеты WP, т.к. это придется делать после каждого обновления движка.

      Лучше используете AVH Extended Categories Widgets

  • http://twitter.com/newlookmedia_ru newlookmedia_ru

    Отличный плагин, но он и как варианты с function.php ^
    function myFeedExcluder($query) {
    if ($query->is_feed || $query->is_search) {
    $query->set('cat', '-29');
    }
    return $query;
    }
    add_filter('pre_get_posts','myFeedExcluder');

    Удаляет возможность подписки на RSS отдельных рубрик.

    • http://www.simplecoding.org Владимир

      Согласен.
      Плагин работает примерно таким же образом.
      Только предоставляет интерфейс для удобного выбора категории, которую
      нужно исключить.

      • http://twitter.com/newlookmedia_ru newlookmedia_ru

        Я вижу, что так) Вопрос в том можно ли сохранить ОТДЕЛЬНЫЕ ленты для разных категорий? Что-то вроде http://САЙТ.ru/?feed=rss2&cat=5
        Теперь же все ленты подменяются на одну единственную, общую.
        Хочется решения….
        Спасибо

  • http://life-trip.ru Life-trip.ru

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

    Ставил Advanced Category Excluder, так он слишком навороченный, да еще к тому-же делает не то что надо (его секций недостаточно), плюс рушит блог на локалхосте.

  • http://twitter.com/Ginom_Home Ginom

    Доброй ночи на версии вордпресс 3.1 плагин не работает.

    • Global

      Да, сегодня я тоже обнаружил, что все "продажные" посты вылезли в ленту, твиттер и,тд

    • Shishlena

      Да, и у меня тоже самое :( (((((((((

    • http://www.simplecoding.org Владимир

      Большое спасибо за то, что сообщили о проблеме. И прошу прощения за задержку.

      Я выложил исправленную версию плагина.

      • Global

        А подскажите еще пожалуйста, как обновить РСС? точнее удалить от туда некоторые посты которых больше нет или я не хочу чтоб они там были

        • http://www.simplecoding.org Владимир

          Удалить посты можно используя их id или какой-нибудь другой параметр, например, в этом плагине используется категория.

          Дальше все просто.
          1) используете фильтр pre_get_posts.
          2) модифицируете запрос так, как вам нужно ($query)

  • http://404-found.ru Virturum

    Товарищ, спасибо большое. Все по-русски, все понятно. Единственный вариант, который мне помог)))
    Спасибо за плагин!

  • http://tods-blog.com.ua/ Tod

    Жаль, что там не было "напоминания" о новой версии, а то как-то не обратил на это внимания и обновил вп, а там бац вылезли сообщения, которые не должны были появляться)

    • http://www.simplecoding.org Владимир

      Честно говоря, я не думал, что этот плагин приобретет какую-то популярность. Существуют аналоги с гораздо более широкими возможностями.

      Поэтому я не стал размещать этот плагин на официальном сайте. Из-за этого уведомления об обновлениях плагина не работают.

      Думаете, имеет смысл перенести этот плагин на оф. сайт?

  • Даша

    А у меня что-то все-равно не работает:((
    Старый удалила, новый поставила, а не работает! В чем может быть дело

    • http://www.simplecoding.org Владимир

      Напишите, пожалуйста, какую версию WP вы используете. И, желательно, версию PHP и список установленных плагинов.

  • http://sheko.ru Даша

    WordPress 3.1.
    Плагины вот – http://sheko.ru/wp-content/uploads/2011/03/4.jpg

    • http://www.simplecoding.org Владимир

      У меня не получается воспроизвести ошибку. Попробуйте отключить плагины (по одному). С версией 3.1 я проверял, плагин работает.

  • Lunalin

    спасибо! это именно то, что мне сейчас надо!:)

  • http://lex111.ru/ lex111

    Спасибо! Отличный плагин и не надо ничего вставлять в функции темы

  • Pingback: Плагин для Wordpress: Exclude Categories. Убрать категорию постов с главной страницы | LAAcrus's блог

  • http://dzyo-san.ru/ seo-самурай

    Скачал плагин. Буду использовать для работы с гогетлинкс, т.к. там не нужно чтобы комментировали. Остаётся открытым вопрос, а при подписке на почтовый ящик, также посты будут исключаться?

    • http://www.simplecoding.org Владимир

      Каким образом реализована подписка? Через feedburner? Если да, то feedburner возмет содержимое RSS. Т.е. уберете посты из RSS и их не будет в рассылке.

      • http://dzyo-san.ru/ seo-самурай

        Да, через feedburner. Плагин протестировал. Работает.

        • http://dzyo-san.ru/ seo-самурай

          Ещё плагин One click close comments скачал, чтобы отключать комментарии у отдельных постов, тоже работает.

  • 7wander7

    Спасибо за плагин! Очень пригодился)

  • http://ясчастливый.рф/ Иван Шипилов

    Спасибо за плагин!

]]>
Tweet