Как скрыть часть контента от незарегистрированных пользователей в WordPress при помощи шорткодов

Очень часто на форумах можно встретить уведомления «Ссылки могут видеть только зарегистрированные пользователи» или «Скачивание файлов доступно только для зарегистрированных».

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

Рассмотренные в этой статье примеры закрывают контент не только от неавторизованных посетителей сайта, но и от поисковиков.

Отображение контента только для зарегистрированных пользователей

Сначала создаем шорткод, вставив этот код в functions.php текущей темы:

function true_logged_in_user_content( $atts, $content = null ) {
	if ( is_user_logged_in() && !is_null( $content ) && !is_feed() ) {
		return $content;
	}
	return ''; // тут в кавычках можете написать сообщение об ошибке, отображающееся для пользователей, у которых нет доступа, можно использовать HTML.
}
 
add_shortcode( 'member', 'true_logged_in_user_content' );

Теперь второй шаг, при написании поста, когда вы захотите скрыть какую-то часть текста, просто поместите его между [member] и [/member], например:

[member]
 
Этот текст увидят только зарегистрированные пользователи.
 
[/member]

Сюда можно засунуть не только текст, но также ссылки (например ограничить доступ к скачиванию файлов), картинки и прочий HTML.

Отображение контента в зависимости от роли пользователя

Тут действует тот же самый принцип, но только с некоторыми усовершенствованиями. Опять начинаем с создания шорткода через functions.php:

function true_content_by_user_cap( $attr, $content = null ) {
	// массив со значениями по умолчанию, которые будут применяться, если в шорткоде не был указан параметр
	$defaults = array(
		'capability' => 'read'
	);
	extract( shortcode_atts( $defaults, $attr ) );
	if ( current_user_can( $capability ) && !is_null( $content ) && !is_feed() ) {
		return $content;
	}
	return ''; // указываем сообщение об ошибке если нужно
}
 
add_shortcode( 'access', 'true_content_by_user_cap' );

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

[access capability="edit_posts"]
 
Эта часть контента видна пользователям, которые могут редактировать записи.
 
[/access]

А в этом случае будут применяться значения по умолчанию из массива $defaults:

[access]
 
Это сообщение увидят все зарегистрированные пользователи.
 
[/access]

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

Подпишитесь, чтобы раз в неделю получать свежие статьи с блога по email.

Смотрите также

Комментарии 56

  • adarka22 апреля 2013 в 12:04 #

    спасибо! то , что надо! перекопала кучу плагинов, а тут такой простой и изящный метод!

  • Алексей16 мая 2013 в 17:05 #

    Почему то после вставки кода а functions.php и вывода шорткода в посте-ничего не происходит.только код не активный какой то-весь черный без подсветки.И этот код всплывает сверху в админке.Помогите разобраться в чем проблема...

  • Алексей20 мая 2013 в 14:05 #

    Миша спасибо я уже разобрался) Действительно в этом проблема была...

    • Миша21 мая 2013 в 06:05 #

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

  • Алексей22 июня 2013 в 10:06 #

    Миша подскажи пожалуйста...
    А вот то же самое можно реализовать на Joomla ???
    Очень хотелось бы...

    • Миша23 июня 2013 в 15:06 #

      я джумлой не занимаюсь, но по идее должна быть такая возможность (или плагин какой-нибудь)

  • Виктор7 сентября 2013 в 20:09 #

    Добрый день! У меня противоположная проблема, после работы со страничкой вдруг стала активна эта функция входа на страничку через пароль. ПОдскажите как убрать это и сделать как прежде свободный вход

  • Программист7 октября 2013 в 12:10 #

    НЕ РАБОТАЕТ! Не в коем случае не пробуйте так сделать!

  • Алексей7 октября 2013 в 12:10 #

    Все работает,чего ты гонишь... Я на трех блогах проверял и никаких проблем...

  • Роман7 октября 2013 в 14:10 #

    Подскажите, как сделать так, чтобы скрыть один пункт в меню в шапке? На сайте есть меню: Главная Документы Контакты. Нужно сделать так, чтобы пункт "документы" становился видным после авторизации, а для гостей был скрыт.

  • Павел7 января 2014 в 04:01 #

    Здравствуйте, Михаил!

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

    Скажите, как сделать этот скрытый блок недоступным поиску?

    • Миша7 января 2014 в 08:01 #

      Добрый день!

      чтобы сказать точно, нужно смотреть и тестировать, а так мне кажется вам следует в шаблоне поиска заменить get_the_content() на the_content(). Теоретически.

  • Олег16 мая 2014 в 11:05 #

    Михаил, добрый день.

    У меня почему то не работает Ваш вариант.

    Вставил код в Functions.php в конец файла.

    До и после поставил < ? php

    На странице своей обрамил текст [member] Text [/member]
    но хоть регистрированный, хоть нет пользователь все равно видно текст.
    И кстати видно и тег [member] вокруг текста.

    В чем может быть проблема?

  • hardcore28 декабря 2014 в 23:12 #

    Михаил, добрый день.
    А для полного сайта(контента) можете показать пример? Типа гости только видели одну статическую страницу. Спасибо!

    • Миша29 декабря 2014 в 07:12 #

      Добрый день!
      Вот универсальное условие для администраторов / редакторов:

      if ( current_user_can( 'edit_posts' ) ) {
       
      }

      А вот для авторизованных пользователей:

      if ( is_user_logged_in() ) {
       
      }
  • Ильяс16 февраля 2015 в 00:02 #

    Спасибо большое,все просто и все работает :)

  • FROLOff31 марта 2015 в 16:03 #

    Все перепробовал. Инструмент отнюдь не универсальный.

    • orion83300031 марта 2015 в 16:03 #

      А что тебе нужно универсального? Миша дал рабочий вариант с помощью него я не 1 тысячу рубликов зарабатывал... нужен универсальный - купи Wish List Member и танцуй с бубном.

      • FROLOff1 апреля 2015 в 09:04 #

        А что тебе нужно от меня? Считаешь нужной мне ту информацию, которую выдал под комментарием?:)

  • FROLOff1 апреля 2015 в 09:04 #

    Михаил, может, подскажете, почему у меня все-таки не получается:

    Установил шорткод, и он отлично работает на страницах. Вот код из файла functions.php:

    add_shortcode( 'member', 'true_logged_in_user_content' );
    function true_logged_in_user_content( $atts, $content = null ) {
        if ( is_user_logged_in() && !is_null( $content ) && !is_feed() ) {
            return $content;
        }
        return 'Требуется регистрация';
    }

    Однако на странице редактирования шаблона (page.php) обычный шорткод не работает. Использую следующий вариант: Текст, который нужно скрыть, и получается вот такое: Требуется регистрацияТекст, который нужно скрыть. Естественно, фраза "Текст, который нужно скрыть" и должна скрываться фразой "Требуется регистрация".

    Обычный вариант [member]Текст[/member] не работает, естественно. Как же "зажать" текст в эти теги на php-странице?

    • Миша1 апреля 2015 в 12:04 #

      он отлично работает на страницах

      Однако на странице редактирования шаблона (page.php) обычный шорткод не работает

      Так где он в итоге у вас работает, а где нет?

      • FROLOff1 апреля 2015 в 12:04 #

        Работал в записях, не работал на страницах. Разобрался. Спасибо за пост.
        Чтобы добавить "универсальности", советую отредактировать статью. Добавьте прямой пример рабочего кода для страниц .php:

        <?php echo do_shortcode('[member]Текст[/member]');?>
        • Миша1 апреля 2015 в 13:04 #

          Рад, что вы разобрались. Рекомендую ознакомиться с теорией, как работают шорткоды truemisha.ru/blog/wordpress/shortcodes.html.

          • Людмила19 апреля 2015 в 07:04 #

            Ну спасибо, пошла Вордпресс переустанавливать. Все слетело - пустая страница.

            • Миша19 апреля 2015 в 10:04 #

              Уверяю вас, переустанавливать WP совсем ни к чему. Во-первых, можете вставить код именно после <?php (почему-то мне кажется, что проблема в этом), во-вторых, вы можете просто удалить мой код, в третьих, вы можете зайти в wp-config.php, включить WP_DEBUG и посмотреть, где именно возникла ошибка :P

              • Алексей Фатькин19 апреля 2015 в 13:04 #

                Миша в точку сказал... зачем WP то переустанавливать?

              • Людмила19 апреля 2015 в 13:04 #

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

  • SuperSanek15 июля 2015 в 01:07 #

    все работает на 100% , скрывает кнопки например, подскажите, как сделать ссылку на страницу регистрации прямо с надписи которая закрывает контент "зарегистрируйтесь бла бла..."

  • Алексей3 сентября 2015 в 16:09 #

    Проблема в отображении текста ошибки, обвожу тегами, текст пропадает, но уведомления нет на месте скрытого текста

  • Павел8 ноября 2015 в 22:11 #

    Михаил, здравствуйте!

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

    function private_content( $content ) {
    	if ( is_user_logged_in() && !is_null( $content ) && !is_feed() ) {
    		return '<div class="private">' . $content . '</div>';
    		} else {
    		return '';
    	}
    }
     
    add_filter ('the_content',  'private_content');

    Но он прячет не содержимое контейнера .private, а вообще всё содержимое записи...

    • Павел8 ноября 2015 в 23:11 #

      Ну, чтобы не отвлекать маэстро глупостями, пишу ответ:

      function private_content( $content ) {
       
      	if ( is_user_logged_in() && !is_null( $content ) && !is_feed() ) {
      		return $content;
      		} else {
      		return preg_replace('/(<div class="private">.*?<\/div>)/uis', '', $content);
      	}
       
      }
       
      add_filter ('the_content',  'private_content');

      Кто-нибудь знает, как выбросит содержимое этого контейнера и из поиска тоже?

  • Musicman6 декабря 2015 в 01:12 #

    Здравствуйте, Михаил. Код работает хорошо, но возникла ситуация.
    Я обернул в данные теги контент, где содержатся другие теги с прямыми скобками, в частности, я спрятал таблицу, в ячейках которой вставлены аудиозаписи в теге [audio]Музон[/audio]
    В итоге незарегенные все правильно - не видят ничего, а вот зареганные видят исходный код контента, ни плееров, ни ссылок. Что можно придумать?

  • Дима26 января 2016 в 00:01 #

    Подскажите пожалуйста, возможно ли сделать этот метод для мультиязычного сайта? Установлен WP Multisite, русский и английский, файл functions.php один для всех. Т. е. или на английском сайте будет отображаться русское оповещение о регистрации, или на русском английское. Ну и ссылку соответственно не вставить о регистрации. Была идея написать уведомление через слеш, мол: "Регистрируйся/Register", но всё же.

    • Миша26 января 2016 в 08:01 #

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

      • Дима26 января 2016 в 12:01 #

        Благодарю за быстрый ответ. Вышел из положения дублированием функции, добавил: "true_logged_in_user_content_en".

      • Дима26 января 2016 в 13:01 #

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

        • Миша27 января 2016 в 09:01 #

          Так через CSS :)

          • Дима31 января 2016 в 09:01 #

            Style.css? Открываем и... Как сослаться на функцию может подскажете? Методом тыка пытался менять стили, но меняется весь текст(

            • Миша31 января 2016 в 10:01 #

              Там, где нужно указать сообщение об ошибке — оберните его например в

              <span id="errorm">Сообщение об ошибке.</span>

              А потом в стилях:

              #errorm{
               
              }
              • Дима31 января 2016 в 14:01 #

                Огромная благодарность! Всё работает как часы швейцарские! Всего Вам наилучшего!

  • Иван27 августа 2016 в 16:08 #

    Миш, объясни, что ты делаешь этой строчкой:

    extract( shortcode_atts( $defaults, $attr ) );

    Я давно читал об этой функции, но что то не могу понять, что она здесь делает

    • Миша28 августа 2016 в 08:08 #

      Привет,

      функция shortcode_atts() заменяет элементы массива $defaults на элементы из $atts, но только в том случае и только на те, которые указаны.

      Функция extract() "распечатывает" массив в переменные, то есть $attr['hello'] превратится в $hello и т.д.

Оставить комментарий / вопрос

phpjsHTMLCSSSQLПросто код
  Для того, чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или авторизуйтесь на сайте.
  • Миша: Привет ещё раз, не поверишь, реально не сталкивался с этим вопросом. По теории можно сказать следующее: во-первых,...

  • Миша: Привет, вообще без проблем, делаешь всё через require(), require_once() - выбирай любую, какая больше нравится.

  • Виталий Моргунов: Привет! Не могу разобаться, как я могу контролировать порядок подключения стилей. В моем случае мне нужно чтобы стили...

  • Миша: Спасибо!

  • w0rmak: Это было просто. Нашел код в интернете. Добавьте и себе ymaps.load(function () { var input = document.getElem...