{"id":1072,"date":"2020-09-25T19:31:57","date_gmt":"2020-09-25T23:31:57","guid":{"rendered":"https:\/\/www.blindemanwebsites.com\/today-i-learned\/?p=1072"},"modified":"2020-09-25T19:32:00","modified_gmt":"2020-09-25T23:32:00","slug":"restricting-access-to-content-in-wp","status":"publish","type":"post","link":"https:\/\/www.blindemanwebsites.com\/today-i-learned\/2020\/restricting-access-to-content-in-wp\/","title":{"rendered":"Restricting Access to Content in WP"},"content":{"rendered":"\n<p>A few notes on how to restrict access to content in WordPress, both for anonymous visitors and logged-in visitors with a specific user role, by using <code>wp_safe_redirect()<\/code>.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h3 class=\"wp-block-heading\">What<\/h3>\n\n\n\n<p>When you want to hide some of your content, for example posts in a certain category, a page, a particular Custom Post Type, you can use the <code>wp_safe_redirect()<\/code> function. This does not allow for showing a teaser on the page, since visitors will never see the page, and I don&#8217;t think the following is a good solution for a full-fledged membership site. <\/p>\n\n\n\n<p>This solution might be good though for a temporary lockdown of a site, or very simple membership sites.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How<\/h3>\n\n\n\n<p>Basically, it&#8217;s this: check which page is being called, check if the user is logged in, redirect if necessary.<\/p>\n\n\n\n<pre title=\"Hide some content from visitors\" class=\"wp-block-code\"><code lang=\"php\" class=\"language-php line-numbers\">add_action( 'template_redirect', 'bw_restrict_content');\nfunction bw_restrict_content(){\n\tif( ( is_singular( array( 'my-cpt-1', 'my-cpt-2' ) ) || is_page('my-page') ) &amp;&amp; !is_user_logged_in() ) {\n\t\tnocache_headers();\n\t\twp_safe_redirect( home_url() );\n\t\texit;\n\t}\n}<\/code><\/pre>\n\n\n\n<p>I&#8217;m redirecting within the site, so I&#8217;m using <code>wp_safe_redirect()<\/code> instead of <code>wp_redirect()<\/code>, but choose the later if you want to redirect to a different site altogether. And I&#8217;m redirecting them to home in this case, because the site I&#8217;m using this on does not have an open registration, but you can redirect to any old URL.<\/p>\n\n\n\n<p>The <code>nocache_header()<\/code> function is called, as kZeni mentions on the WP reference page for <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_safe_redirect\/\" target=\"_blank\">this function<\/a>, so that the redirect isn&#8217;t cached and users will actually see the restricted content once they log in, instead of still being automatically redirected.<\/p>\n\n\n\n<p>You can use this with any number of <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.wordpress.org\/themes\/basics\/conditional-tags\/\" target=\"_blank\">conditional tags<\/a>, such as is_category(), is_feed() and I&#8217;ve used it with is_author() and is_search() for example.<\/p>\n\n\n\n<p>If you want to check for a specific user role, you can check for <a rel=\"noreferrer noopener\" href=\"https:\/\/wordpress.org\/support\/article\/roles-and-capabilities\/\" target=\"_blank\">capabilities<\/a>. For example, want to hide posts with the category &#8220;premium&#8221; from not-logged-in visitors and logged-in subscribers?<\/p>\n\n\n\n<pre title=\"Hide posts in a certain category from visitors &amp; subscribers\" class=\"wp-block-code\"><code lang=\"php\" class=\"language-php line-numbers\">add_action( 'template_redirect', 'bw_hide_premium' );\nfunction bw_hide_premium(){\n    if( (!is_user_logged_in() || !current_user_can( 'edit_posts' ) ) &amp;&amp; ( is_category( 'premium' ) || in_category( 'premium' ) ) ){\n        nocache_header();\n        wp_safe_redirect( home_url() );\n        exit;\n    }\n}<\/code><\/pre>\n\n\n\n<p>Snippets like this should not be the functions.php file, in my opinion, because they remain true, regardless of the theme I&#8217;m using. A site-specific plugin would make more sense, but I usually end up tweaking snippets like this regularly, so I like something a bit more accessible: the <a rel=\"noreferrer noopener\" href=\"https:\/\/wordpress.org\/plugins\/code-snippets\/\" target=\"_blank\">Code Snippets<\/a> plugin.<\/p>\n\n\n\n<p>I am also using a plugin to control which items are visible in the site navigation: <a rel=\"noreferrer noopener\" href=\"https:\/\/wordpress.org\/plugins\/user-menus\/\" target=\"_blank\">User Menus<\/a>. Once you&#8217;ve activated it, all necessary options can be found in the standard WordPress menus and menu items.<\/p>\n\n\n\n<p>For any posts, pages, CPT that should only be visible to Administrators en Editors, I just set them to Private. If it&#8217;s something I want to add to site navigation (usually a page), I will publish first, then add to a menu, then set to Private, and then I hide the menu item from everyone with the User Menus plugin settings.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Where<\/h3>\n\n\n\n<p>An answer on WordPress StackExchange by <a rel=\"noreferrer noopener\" href=\"https:\/\/wordpress.stackexchange.com\/questions\/257767\/is-it-possible-to-restrict-viewing-of-category-page-to-logged-in-users-only#answer-257769\" target=\"_blank\">bynicolas<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Thoughts<\/h3>\n\n\n\n<p>I used to use a plugin for this: <a rel=\"noreferrer noopener\" href=\"https:\/\/wordpress.org\/plugins\/restrict-user-access\/\" target=\"_blank\">Restrict User Access<\/a>. I still might on occasion, I like it, it does enough and not too much. But on my last project, just turning the plugin on removed the CPT from the author archive pages and, well, it was too much hassle to fix that.<\/p>\n\n\n\n<p>I tried another plugin that showed promise: <a rel=\"noreferrer noopener\" href=\"https:\/\/wordpress.org\/plugins\/content-control\/\" target=\"_blank\">Control Content<\/a>. Sadly, it didn&#8217;t work at all, though it seemed sympathetically lightweight and unobtrusive. One of the nice options it has is that you can very easily hide widgets as well, something Restrict User Access lacks, and which was the one thing that actually worked for me. Control Content also led me to the User Menus plugin, since it&#8217;s from the same plugin authors, but this one actually works and is really easy to use. Beautiful plugin.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few notes on how to restrict access to content in WordPress, both for anonymous visitors and logged-in visitors with a specific user role, by using wp_safe_redirect().<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[197,200,194,100,193,199,196,198,195,41],"class_list":["post-1072","post","type-post","status-publish","format-standard","hentry","category-new-things","tag-code-snippets","tag-control-content","tag-private-content","tag-redirection","tag-restrict-access","tag-restrict-user-access","tag-stack-exchange","tag-user-menus","tag-user-roles","tag-wordpress","infinite-scroll-item"],"_links":{"self":[{"href":"https:\/\/www.blindemanwebsites.com\/today-i-learned\/wp-json\/wp\/v2\/posts\/1072","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blindemanwebsites.com\/today-i-learned\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blindemanwebsites.com\/today-i-learned\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blindemanwebsites.com\/today-i-learned\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blindemanwebsites.com\/today-i-learned\/wp-json\/wp\/v2\/comments?post=1072"}],"version-history":[{"count":3,"href":"https:\/\/www.blindemanwebsites.com\/today-i-learned\/wp-json\/wp\/v2\/posts\/1072\/revisions"}],"predecessor-version":[{"id":1075,"href":"https:\/\/www.blindemanwebsites.com\/today-i-learned\/wp-json\/wp\/v2\/posts\/1072\/revisions\/1075"}],"wp:attachment":[{"href":"https:\/\/www.blindemanwebsites.com\/today-i-learned\/wp-json\/wp\/v2\/media?parent=1072"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blindemanwebsites.com\/today-i-learned\/wp-json\/wp\/v2\/categories?post=1072"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blindemanwebsites.com\/today-i-learned\/wp-json\/wp\/v2\/tags?post=1072"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}