• Skip to main content
  • Skip to primary sidebar
  • Skip to footer

nSiteful Web Builders

Building a Better Web - One Site at a Time.

  • Home
  • About
    • Testimonials
    • Resources
    • Partner With Me
    • Frequently Asked Questions
  • Web Sites
  • Online Marketing
  • WordPress Support
    • Customized WordPress Training
    • 60-for-60 Sessions
  • Web Applications
  • Blog
    • At-A-Glance
    • Blog Articles Grouped by Category
    • Case Studies
    • General
    • Portfolio
    • Reviews
    • Snippets
    • Techniques
    • Projects
  • Contact
    • Purchase Retainer Consulting Hours
    • About Retainer Consulting Hours
    • Book a Meeting with Jeff
    • Tell Me About Your Web Project
    • nSiteful Newsletter Archives
    • nSiteful Rewards
Protecting

By Jeff - 1/7/2025
Cats: Techniques · Tags: Custom Fields, Custom Post Types, MemberPress, Membership Sites, WordPress

techniques

How To Use MemberPress to Protect Posts that Contain Custom Fields

On this page...

Toggle
  • Why won’t MemberPress rules alone work?
  • Enter Custom Post Types
  • Two Primary Approaches:
    • Drawbacks to Unauthorized Redirection
  • Background/Use Case
    • Desired Outcomes:
      • If the user is not logged in:
      • If the user is logged in but hasn’t purchased the membership:
      • If the user is logged in and has purchased the membership:
    • Custom Post Type
    • Custom Fields, using ACF Pro
    • Custom Taxonomy
    • MEPR Rule
      • Custom Unauthorized Message:
    • Archive & Single Templates
    • single-sdodv.php — Where the magic happens
  • Extra Stuff
    • Code for registering the CPT
    • Code for registering taxonomy

If you’re trying to use MemberPress to protect posts that contain custom fields, relying on MemberPress rules alone will not work.

Jump down here to see the desired outcomes in screen shots.
Jump down here to skip everything else and see how I created the single template file.

Why won’t MemberPress rules alone work?

As explained in this knowledge base (“KB”) article on the MemberPress website, this is because MemberPress rules only protect content that is outputted through the WordPress the_content() function.

(Note that the MemberPress knowledge base article misleadingly references “ACF fields”, suggesting that the solution pertains only to custom fields created with the Advanced Custom Fields plugin. Not true. The solution pertains to any custom fields created in any way.)

Enter Custom Post Types

Although any post type can contain custom fields, the most common use cases for custom fields are custom post types. So, if you’re trying to use MemberPress to protect custom post types, you’ll want to read on.

Two Primary Approaches:

As the above-referenced article points out, there are two primary approaches for using MemberPress to protect posts that contain custom fields:

  1. using Unauthorized Redirection
  2. protecting individual custom fields

Drawbacks to Unauthorized Redirection

As the KB article points out, there are potential drawbacks to using Unauthorized Redirection:

  • It applies globally to all protected content.
  • This means that rule-specific unauthorized messages aren’t possible: Unless you write custom code, unauthorized users will see the same (necessarily generic) message, regardless of what content they’re attempting to access.
  • If you want to display excerpts for some protected content but not for others — or login forms for one but not for others, or registration links for some and not for others — you’re out of luck (unless you write a whole bunch of custom code).

In this article I’ll share how I used the second approach — protecting individual custom fields — using the current_user_can('mepr-active', rules:xxx') conditional.

Background/Use Case

I’m offering a one-time membership that allows members to watch on-demand videos.

Desired Outcomes:

If the user is not logged in:

User sees notice about not being logged in and is presented login form.

Not logged in
User not logged in

If the user is logged in but hasn’t purchased the membership:

User sees notice about being logged in, but s/he hasn’t purchased the needed membership. A link to the registration page is included.

Logged-in user
User logged in but has not purchased membership

If the user is logged in and has purchased the membership:

User gets to watch the video.

Authorized
Authorized user

Custom Post Type

sdodv (Sahara Dance On-Demand Video, actual name = “SD On-Demand Video”)
The CPT supports title, thumbnail, and page-attributes. I’m not currently utilizing the thumbnail, and the page-attributes feature is enabled so that the posts can be ordered.

Code below for registering CPT

There are currently two posts:
3pm Show – Sahara Dance Fall Caravan 2024
6pm Show – Sahara Dance Fall Caravan 2024

Custom Fields, using ACF Pro

The custom fields are:

  1. description (odv_description)
  2. video embed code (odv_embed_code_iframe)

Custom Taxonomy

There is a custom taxonomy, ‘access-category’.
Both CPT posts have the “fall-2024-caravan-access” access-category term assigned to them.

Code below for registering custom taxonomy

MEPR Rule

I have a MemberPress rule ID 186): “SD On-Demand Video with Access Category: Fall 2024 Caravan Access”. The rule restricts the content to people who have a particular membership.

Custom Unauthorized Message:

The custom unauthorized message uses several MemberPress shortcodes.

  • Lines 2, 5, 7, 11: Opening and closing of mepr-show. Line 2 begins the section for logged-in users; line 7 begins the section for logged-out users.
  • Line 9: The mepr-membership-link shortcode displays the registration form for the membership that allows viewing these videos.
  • Line 10: Display the login form.
  • Lines 3 and 8: Just for display purposes. The “callout”-related classes allow the messages to be displayed distinctively.
(Only logged-in users who purchased the "Fall 2024 Caravan" videos can watch this video.)
[mepr-show if="loggedin"]
<div class="callout callout-warning">You are logged in, but you have not purchased these videos.</div>
[mepr-membership-link id="93"]Purchase these videos[/mepr-membership-link]
[/mepr-show]

[mepr-show if="loggedout"]
<div class="callout callout-caution">You are not logged in. If you <strong>have</strong> an account, log in using the form below.</div>
If you <strong>do not</strong> have an account, [mepr-membership-link id="93"]create an account and purchase these videos now[/mepr-membership-link].
[mepr-login-form use_redirect="true"]
[/mepr-show]

Archive & Single Templates

I created 2 very simple pages for the archive and single. For the purposes of this article, I’ll only show and explain the single template.

single-sdodv.php — Where the magic happens

<?php
get_header();
?>
<?php if ( have_posts() ) : ?>
		<div class="wrapper">
			<?php while ( have_posts() ) : the_post(); ?>
				<?php
					// Put custom field values in simple variables:
					$description 		= get_post_meta($post->ID, 'odv_description', true);
					$video 				= get_post_meta($post->ID, 'odv_embed_code_iframe', true);
					// Set variable for access:
					$current_user_can 	= current_user_can('mepr-active','rules:186'); 
					// Dim the dessciption for unauthorized, via CSS class and rule:
					$about_class 		= ( $current_user_can ) ? 'auth' : 'no-auth';
				?>
				<div class="item">
					<h2><?php the_title();?></h2>
					<?php if( $current_user_can ) : ?>
						<div class="video"><?php echo $video;?></div>
						<div class="description <?php echo $about_class;?>"><?php echo wpautop($description);?></div>
					<?php else: ?>
						<div class="description <?php echo $about_class;?>"><?php echo wpautop($description);?></div>
						<div><?php echo do_shortcode('[mepr-unauthorized-message]'); ?></div>
					<?php endif; ?>
				</div>
			<?php endwhile; ?>
		</div>
<?php endif; ?>
<?php get_footer(); ?>

Notes on highlighted lines:

  • Line 12: Setting the variable for access, using current_user_can() function with the mepr-active capability
  • Lines 19-20: If the user is authorized, show the video above the description.
  • Line 22: If the user is not authorized, show the desciption only.
  • Line 23: Use the do_shortcode() function to display the unauthorzed message assigned to the rule.

Extra Stuff

The stuff in this section doesn’t impact the protection issues that are the main topic of this article. But if you’ve read this far, you might be interested in the code I used to register the custom post type and the custom taxonomy. So here’s that…

Code for registering the CPT

function register_sdodv() {
	$labels = array(
		'name'                  => _x( 'SD On-Demand Video', 'Post Type General Name', 'text_domain' ),
		'singular_name'         => _x( 'SD On-Demand Video', 'Post Type Singular Name', 'text_domain' ),
		'menu_name'             => __( 'SD On-Demand Videos', 'text_domain' ),
		'name_admin_bar'        => __( 'SD On-Demand Video', 'text_domain' ),
		'archives'              => __( 'SD On-Demand Videos Archives', 'text_domain' ),
		'attributes'            => __( 'SD On-Demand Video Attributes', 'text_domain' ),
		'parent_item_colon'     => __( 'Parent SD On-Demand Video:', 'text_domain' ),
		'all_items'             => __( 'All SD On-Demand Videos', 'text_domain' ),
		'add_new_item'          => __( 'Add New SD On-Demand Video', 'text_domain' ),
		'add_new'               => __( 'Add New', 'text_domain' ),
		'new_item'              => __( 'New SD On-Demand Video', 'text_domain' ),
		'edit_item'             => __( 'Edit SD On-Demand Video', 'text_domain' ),
		'update_item'           => __( 'Update SD On-Demand Video', 'text_domain' ),
		'view_item'             => __( 'View SD On-Demand Video', 'text_domain' ),
		'view_items'            => __( 'View SD On-Demand Videos', 'text_domain' ),
		'search_items'          => __( 'Search SD On-Demand Video', 'text_domain' ),
		'not_found'             => __( 'Not found', 'text_domain' ),
		'not_found_in_trash'    => __( 'Not found in Trash', 'text_domain' ),
		'featured_image'        => __( 'Featured Image', 'text_domain' ),
		'set_featured_image'    => __( 'Set featured image', 'text_domain' ),
		'remove_featured_image' => __( 'Remove featured image', 'text_domain' ),
		'use_featured_image'    => __( 'Use as featured image', 'text_domain' ),
		'insert_into_item'      => __( 'Insert into item', 'text_domain' ),
		'uploaded_to_this_item' => __( 'Uploaded to this item', 'text_domain' ),
		'items_list'            => __( 'Items list', 'text_domain' ),
		'items_list_navigation' => __( 'Items list navigation', 'text_domain' ),
		'filter_items_list'     => __( 'Filter items list', 'text_domain' ),
	);
	$args = array(
		'label'                 => __( 'SD On-Demand Video', 'text_domain' ),
		'description'           => sdodv_blurb(),
		'labels'                => $labels,
		'supports'              => array( 'title', 'thumbnail', 'page-attributes' ),
		'taxonomies' 			=> array( 'access-category' ),
		'hierarchical'          => true,
		'public'                => true,
		'show_ui'               => true,
		'show_in_menu'          => true,
		'menu_position'         => 5,
		'show_in_admin_bar'     => true,
		'show_in_nav_menus'     => true,
		'can_export'            => true,
		'has_archive'           => 'sdodv',
		'exclude_from_search'   => false,
		'publicly_queryable'    => true,
		'capability_type'       => 'page',
		'show_in_rest'			=> true,
	);
	register_post_type( 'sdodv', $args );
}
add_action( 'init', 'register_sdodv', 0 );

Code for registering taxonomy

function register_sd_access_catetory() {
	$labels = array(
		'name'                       => 'Access Categories',
		'singular_name'              => 'Access Category',
		'menu_name'                  => 'Access Categories',
		'all_items'                  => 'All Access Categories',
		'new_item_name'              => 'New Access Category',
		'add_new_item'               => 'Add New Access Category',
		'edit_item'                  => 'Edit Access Category',
		'update_item'                => 'Update Access Category',
		'view_item'                  => 'View Access Category',
		'separate_items_with_commas' => 'Separate items with commas',
		'add_or_remove_items'        => 'Add or remove Access Categories',
		'choose_from_most_used'      => 'Choose from the most used',
		'popular_items'              => 'Popular Access Categories',
		'search_items'               => 'Search Access Category',
		'not_found'                  => 'Not Found',
		'no_terms'                   => 'No items',
		'items_list'                 => 'Access Categories list',
		'items_list_navigation'      => 'Access Categories list navigation',
	);
	$args = array(
		'labels'                     => $labels,
		'hierarchical'               => true,
		'public'                     => true,
		'show_ui'                    => true,
		'show_admin_column'          => true,
		'show_in_nav_menus'          => true,
		'show_tagcloud'              => true,
	);
	register_taxonomy( 'access-category', array( 'sdodv' ), $args );
}
add_action( 'init', 'register_sd_access_catetory', 0 );

Like what you see? Share with others and join my mailing list. No long-term commitment, unsubscribe any time.

Related Posts

  1. Customize User Roles & Capabilities in WordPress: How (and Why)
  2. Offer Live Chat for Enhanced Customer Engagement and Sales
  3. Custom Front-End Member Listing for MemberPress Website
  4. MemberPress: Create a Custom Shortcode to Display a MemberPress Membership Price ANYWHERE on Your Website
  5. MemberPress: How to Create a Custom MemberPress Course Progress Page

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

mailchimp signup

Subscribe to get notified when new articles are published. Unsubscribe any time. No spam. I promise. Check out my newsletter archives.

social

Twitter Facebook LinkedIn

Recent Articles

  • Post-Specific CSS for WordPress October 5, 2026
  • You built an online course, but they haven’t come. September 16, 2026
  • Custom MemberPress Pricing Pages December 19, 2025
  • CSS Data Attribute Override December 11, 2025
  • MemberPress Rules Using Custom Taxonomies and Custom Roles December 10, 2025

Filter By Category/Tag

Categories

  • Case Studies (8)
  • For Staff (1)
  • General (73)
  • Portfolio (7)
  • Reviews (14)
  • Snippets (24)
  • Techniques (52)

Popular Tags

Advanced Custom Fields Blogging Child Themes Content Marketing CSS Customer Service Custom Fields Custom Post Types Diagnostics Domain Names Facebook FooGallery Genesis Hosting HTML Images iPhone Libra Live Chat Marketing Media MemberPress MemberPress Courses Membership Sites Mobile-Friendly MySQL Photo Gallery php Pinterest Plugins Post Formats Pricing Project Management SEBA SEO Seth Godin Shortcodes Social Networking Surveys Taxonomies Twitter Video Web design Web forms WordPress

Footer

Background

Web Sites | WordPress Support | Web Applications.

Formally trained in liberal arts and education (I have a B.A. in Government from Harvard and studied Secondary Education at Rutgers Graduate School), I have honed my skills in the communication arts and sciences as a teacher, trainer, instructional designer, writer, photographer, calligrapher, helpdesk manager, database programmer, and multimedia developer.

(I've also been a group counselor, waiter, bartender, bicycle messenger boy, computer salesman, carpenter's helper, financial analyst, and school board president.)

Tech

Systems since 1983.
Web sites since 1994.
PHP since 2001.
WordPress since 2007.

Contact

Book Meeting
770-772-5134
Email Jeff
Send Money
All Ways

Copyright 2026, nSiteful Web Builders, Inc.

Cookies Consent
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
  • Manage options
  • Manage services
  • Manage {vendor_count} vendors
  • Read more about these purposes
View preferences
  • {title}
  • {title}
  • {title}
https://iframe.mediadelivery.net/embed/392008/42d18bc1-2adc-4741-b733-053d08d09c32
https://vz-000c5976-3ab.b-cdn.net/42d18bc1-2adc-4741-b733-053d08d09c32/play_720p.mp4

Receive occasional emails from Jeff