WooCommerce Memberships: Restricting Content
Shortcode [wcm_restrict]
The easiest way to restrict content is with the help of WooCommerce Memberships shortcodes. The advantage of this method is that you can use it in your content editor in WordPress admin and directly in the code as well. In the post editor it will look like this:
We begin with the public content.
[wcm_restrict]
This text or HTML is available for members with any active plan.
[/wcm_restrict]
This content is availale for everyone again.
How to implement the same in the code? Easily-breezy — with the standard WordPress do_shortcode()
function.
echo do_shortcode( 'We begin with the public content. [wcm_restrict]This text or HTML is available for members with any active plan.[/wcm_restrict] This content is availale for everyone.');
The shortcode has some useful parameters as well, I will describe them in a second.
Allow to view the content for users with specific active plans
We begin with the public content.
[wcm_restrict plans="premium_silver, premium_gold"]
This piece of content is only visible to premium members with premium_silver or premium_gold active plans
[/wcm_restrict]
This content is availale for everyone again.
plans
parameter accepts plan IDs, plan slugs (multiple comma-separated plans are allowed).
Delayed access
[wcm_restrict delay="5 week"]
This piece of content will be available for any active plan users after 5 weeks they've registered.
[/wcm_restrict]
You can also pass to this parameter such time values as 20 days, 3 weeks, 1 month, 2 years.
But it also can accept the exact date parameter. In fact it understands several date formats but my recommendation is the ISO (yyyy-mm-dd), like in the example below:
[wcm_restrict delay="2017-05-25"]
This piece of content will be available for any active plan users at May 25, 2017
[/wcm_restrict]
Start after trial
I think everything should be clear with start_after_trial
shortcode parameter:
[wcm_restrict start_after_trial="yes"]
This piece of content will be available to any plan members when their membership moves from "Free Trial" to "Active" status.
[/wcm_restrict]
The only thing that needs proper understanding is using both delay
and start_after_trial
parameters in the same shortcode:
[wcm_restrict delay="5 days" start_after_trial="yes"]
This piece of the content will be available for all members 5 days after their trial period ends
[/wcm_restrict]
wc_memberships_restrict()
wc_memberships_restrict( $content, $membership_plans = null, $delay = null, $exclude_trial = false )
- $content
- (string) Piece of text or HTML code you would like to restrict.
- $membership_plans
- (int|string|array) Membership plan ID, slug or an array of ID or slugs for multiple plans.
- $delay
- (string) Time delay in content access after the user membership plan becomes active. Accepts time values like 2 months, 5 days, 1 year or the exact date like 2017-05-02 (yyyy-mm-dd — recommended) or May 2, 2017.
- $exclude_trial
- (bool) If
true
— the content is restricted for trial members.
Let’s look at the example with all the parameters in one place:
$content = 'This is the piece of content, we would like to restrict.';
wc_memberships_restrict( $content, array( 5101, 'premium_gold' ), '1 week', true );
Now let me explain: in the above example we have a piece of content, and only non-trial users with the membership plan with id 5101 or with the plan premium_gold
can access it after 1 week their membership become active.
If user doesn’t have this membership, function returns nothing. If a user membership is in the trial period (or one week has not passed yet), the function prints the message that the content is the part of user’s membership but not yet — and this message can be customized with the wc_memberships_get_content_delayed_message
filter.
Conditional Functions
wc_memberships_is_user_active_member()
This is a very simple conditional function and it is similar to wc_memberships_is_user_member()
, the only difference is that it returns true
for active memberships only (trial users are also included).
wc_memberships_is_user_active_member( $user_id = null, $plan )
- $user_id
- (int) By default — current user.
- $plan
- (int|string|object) Membership Plan slug, post object or its post ID
if( wc_memberships_is_user_active_member( null, 'premium_gold' ) ) {
// do stuff for the current user with active "premium_gold" plan (even in trial period)
}
wc_memberships_user_can()
This is the only standard WooCommerce Memberships function that allows you to check easily if user can view a specific post, page, product or another custom post type element. This function can be used to check if the user can buy a specific product as well.
wc_memberships_user_can( $user_id, $action, $target, $when = '' )
- $user_id
- (int) User ID is required, you can pass the current user ID by the
get_current_user_id()
function. - $action
- (int|string) Only one of the following values
view
orpurchase
(products only). - $target
- (array) Currently this parameter supports only a simple array like
array( 'post' => id )
— for any custom post types except product orarray( 'product' => id )
— for products only (do not forget to replace ‘id’ with the actual value of the post/product ID). - $when
- (int|string) UTC timestamp to compare for content access (defaults to now)
And the example:
if( wc_memberships_user_can( get_current_user_id(), 'view' , array( 'post' => 32 ) ) ) {
echo 'Yes'; // Yes - the current user can view the post/page/product with ID 32
} else {
echo 'No';
}
current_user_can() / user_can()
wc_memberships_user_can()
function is great, but you can do completely the same with already familiar (I hope ?) functions like current_user_can()
and user_can()
.
Let me show you an example – let’s check if the current user can view a post with a certain ID.
if( current_user_can( 'wc_memberships_view_restricted_post_content', $post_id ) ) {
// show content
}
But you can also do this check for any user, just pass a user ID as a first function parameter.
if( user_can( $user_id, 'wc_memberships_view_restricted_post_content', $post_id ) ) {
// show content
}
Restricted Taxonomy Access
Currently I know only one working way to check if a user can view restricted taxonomy term content or not.
if( current_user_can( 'wc_memberships_view_restricted_taxonomy_term', 'category', $term_id ) ) {
// show something
}
Do not forget to replace the second parameter category
with you custom taxonomy name if you are going to use it for taxonomy terms. You can also use user_can()
function to restrict content for a certain user.
Previously I used the function below to check this, but it has stopped working in the latest WooCommerce Memberships version. I just leave it here in case you need it.
/**
@param int $user_id Default: Current User
@param string $taxonomy Taxonomy name
@param int $term_id
@return bool true if user can view the specific taxonomy term, false - otherwise
*/
if( function_exists( 'wc_memberships' ) ) {
function rudr_if_user_can_view_term( $user_id = null, $taxonomy, $term_id ) {
if ( ! $user_id ) {
$user_id = get_current_user_id();
}
if ( ! $user_id ) {
return null;
}
$r = wc_memberships()->get_rules_instance()->get_taxonomy_term_content_restriction_rules( $taxonomy, $term_id );
return wc_memberships()->get_rules_instance()->user_has_content_access_from_rules( $user_id, $r, $term_id );
}
}
And this is how to use it:
if( rudr_if_user_can_view_term( null, 'category', 30 ) ) {
// do stuff if current user can view category with ID 30
}
If you have any question or recommendation to this post, I will be glad to have a conversation with you in comments below.

Misha Rudrastyh
Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me
Thanks for the very helpful tutorial.
Is it possible to add multiple plans in a statement like this?
if( wc_memberships_is_user_member( null, 'premium_gold' ) )
I’ve tried adding multiple plans but can’t get it to work.
Thanks
Hi Jimmy,
I think you can make it something like this:
if( wc_memberships_is_user_member( null, 'premium_gold' ) || wc_memberships_is_user_member( null, 'premium_silver' ) ) {
Thanks so much Misha, that worked!
Thank you, thank you, thank you, Misha! This is SO helpful.
super helpful! thank you!
Misha,
Great post here! Any suggestions of how to use this membership ID restriction function to allow access to Buddypress user tabs or wildcard URL slugs in general? I am building a membership site designed to allow access to various parts of a buddypress platform based upon WC membership level.
Hi Leland,
Sorry, I never had a chance to work with BuddyPress.
I am using the restrict shortcode for members that are logged in…
[wcm_restrict delay=”2 weeks”]
This content will be available to members of any plan once they’ve been a member for two weeks.
[/wcm_restrict]
It works fine and exactly as I need, but now the issue I’m having is that there is this message right in the middle of many content pages (“This content is part of your membership, but not yet! You will gain access on…”). I’ve been able to hide this message with CSS but now there’s a real big gap right in the middle of the pages and looks real ugly. I’ve been searching Google for code where I can remove this completely until it’s time to reveal the restricted content. So far I can’t find anything on this. I can’t imagine that I’m the only one that’s ever needed this. Any help would be greatly appreciated.
Hey Ken,
wc_memberships_get_content_delayed_message
filter hook should help you.Example if you do not want to display anything:
Please let me know if it works for you.
Misha,
It worked perfectly!
Thank you so much.
This is exaclty what I was looking for.
Have A Blessed Day :)
I’m glad to help! 🙃
Have a great day too!
Hi Misha. Great post thanks.
I want to show a coming soon button for 7 days then show a link to the content. I can successfully use the restrict, plan and delay shortcodes to show the button and content after 7 days but am hoping there is a way to show a coming soon message or button until then and then make it disappear when the 7 days comes around.
Hi Jonathan,
Not sure if I understand you correctly. Dod you try
wc_memberships_get_content_delayed_message
fiter hook?Hi Misha – Thanks for the reply. The site is essentially a group of online courses with 7 weeks of content.
I have created an account page where only those course that have been purchased show up using the [wcm_restrict plans=”membership”] and the [wcm_nonmember] codes.
I also have course pages where the courses are released on a weekly basis. Each week uses a variation of [wcm_restrict plans=“membership” delay=”1 week”] to only show the content as it becomes available.
However, with the code above the content is invisible until the 1 week is up. I want to put a “coming soon” message until the week and then make that disappear and the content come up.
Maybe I just didn’t understand you correctly, sorry, but for me it seems like the code below should help you:
Hi Misha
Great tutorial.
Conditional Checks: Taxonomy Terms
user_has_content_access_from_rules
is no longer availableHi,
Ok, how to replace it?
Hi Misha, Nice article thanks for the tips
Do you know if its possible To Hook in and add content after the restriction message box?
We need a more elaborate restriction message / landing but still want to use the lead in text if done automatically.
wc_memberships_the_restricted_content
would we be able to use that to add html under the message box you think?Hi Tarik,
Sure, try this hook
wc_memberships_content_restricted_message
. Example:Hi Misha,
Thanks for your reply!
I understand this will replace the message in the box. Can we replace the box itself or put something after the div that contains the message ?
Thanks
T
In my example the box won’t be replaced, just a custom message will be added after it.
Hi Misha,
Any idea how we could exclude plans in [wcm_restrict] shortcode?
Example: [wcm_restrict not_plans=”premium_silver”]
That making this content available for all plans except the Silver one. When having more than 30 plans it’s sometimes easier to exclude than include
Thanks
Hi Ex,
That would be great, but nope,
wcm_restrict
shortcode supports onlyplan
,plans
,delay
andstart_after_trial
parameters, at least in WooCommerce Memberships 1.12.4I sent a request to SkyVerge, maybe it will be included in a future release :)
Maybe, who knows 🙃
Hi @Ex I’m looking for exactly the same option, and they said they’ll add it to the roadmap but didn’t say for next release. I also don’t know the date of your comment so maybe you have the answer? :D
please share if you do, thanks!
Hi Carolina, Misha,
Just FYI, you can use
[wcm_nonmember]
shortcode and specify a plan in it. It will show this to all members that are not part of the specific plan.Example:
[wcm_nonmember plans="silver"]Visible for everyone except Silver Plan[/wcm_nonmember]
This wasn’t exactly what I was looking for but if you combine this with the wcm_restrict shortcode you can start conditionally show content.
Best regards
Hi Misha,
Me again :)
In the following example how is it possible to show the
wc_memberships_content_restricted_message
instead of “No”?Hey,
Found something like this in the plugin source code:
\WC_Memberships_User_Messages::get_message_html( 'content_restricted', array( 'post' => $post ) );
Let me know please if it works for you 🙃
hi misha
you are my wp hero! :)
is there any chance or possibility that restrict a list of post types that relevant one to one with woocommerce product?based on purchase
no membership, no subscription. no membership plan and level, just based on (woocommerce purchase)
by the way I want to sell streaming tutorial video on post types per master
I google whole galaxy but couldn’t find something usful :(
Hi Milad,
Thank you 😊
Sorry but I am not sure that I understand your question. If you want to restrict certain post types depending on a memberships, it can be simply done in /wp-admin/
thanks Misha for your respond
I want to correspond various post types peer to peer with woocommerce product , in other words restricting the content of each post types (video) based on Woocommerce purchase and not base on membership.
In addition I want these post type to be accessible on (my account) page instead of woocommerce products
I found this link but it seems not to work:
https://www.youtube.com/watch?v=Ury5dF3mJ9U
I’m going to use this ability as means for creating a personal LMS to stream my videos
and thats my kind of brief description :)
Hello, thanks for the tutorial ! Great help. One question remains though: Can you restrict only divs to be only visible by non members ?
I would like to add on my product page a call to action to become member (to get discounts) only for people that is not yet subscribed to a membership plan. (I work with Divi by the way). I think I would need to give a specific ID to the call to action block and then restrict its visibility to non-members only, but I don’t know how to.
Thanks !