Setting up scheduled posts with Member Mouse

On a recent membership site we built, we had a few specific criteria for how members would be able to access content:

  1. New content is published every week on the same day of the week
  2. Each week, all members get access to the same new piece of content (as opposed to a drip schedule)
  3. Members should only be able to access content that has been published since they signed up (as opposed to all old content)

Member Mouse has support built in for protecting content on a drip schedule. With that setup, what content a member sees each week (or day, or month, etc.) depends on how long they’ve been a member. For instance, they might immediately get access to post 1 when they join, then post 2 a week later, post 3 a week after that, etc.

One benefit of a drip setup is that if you only have a set amount of content that you’ll ever publish, once you prepare it all, you’re done. The downside to that approach is that once a someone has been a member long enough to access all of the content, there’s no reason for them to continue paying. As a result, the lifetime value of a member is capped. Another drawback is that because each member isn’t seeing the same new content each week, you can’t discuss that specific piece of content when promoting the site (for instance “this week, members get XYZ – join now!”).

With all that in mind, this site needed some customizations to make the content protection work as desired. We can use Member Mouse’s built in content protection settings and grant access on day 0, but that’s not enough.

Member Mouse content protection


With that in place, when a new member joins, they’d be able to access all previously published content, which isn’t what was needed for this site. To prevent that, I simply ran a quick check to compare a member’s “days as member” value in Member Mouse to the number of days a piece of content had been published, and if it had published more than seven days prior to a member joining (well, not really – more on that in a minute), the member is redirected to an error page. Here’s the code to do that:

Remember how I mentioned that I’m not really comparing to a member’s join date above? Take a look at the “days as member” calculation. I’m not actually checking the member’s join date. Instead, I’m referencing the Member Mouse “days as member” number. The important difference there is that once a member joins, that join date can never be changed (at least not from within the Member Mouse UI). By contrast, the “days as member” number can be manually changed later on:

Member Mouse days as memberWhy does that matter? Well, the truth is, it probably doesn’t. However, I believe it’s always good to design a solution with edge cases in mind. Perhaps someone will join the site at some point, then want to pay extra to be given access to all old content. It doesn’t take any extra work to write the code in such a way that that kind of scenario is easily accommodated, and it’s one less issue that might crop up in the future.

Actually, all of the above is really just extra protection. The way we set up the site, a member shouldn’t ever actually see a link to a piece of content they aren’t allowed to access. To ensure that this is the case, we alter the query on the meal plan (the custom post type we’re protecting) archive page with the following code:

Here, we again check for the “days as member” value, then add seven days, and get only content published after that date. Why the seven days in both of these functions? Because content is published weekly (on Fridays, in this case), and we want to avoid a situation where someone signs up and has nothing available to them. This way, as long as content is published every week, a new member will immediately have access to a piece of content.

Additionally, on that meal plan archive view, we filter the message that’s displayed if no posts are found and replace it with our own message. If the user is logged in, then we apologize (because they should be able to see something), and request that they contact us. If they’re not logged in, we tell them, and provide a login form (helpfully provided by Member Mouse) in case they’re already members but just happen to not be logged in.

We also encourage them to view the plans available if they’re not a member yet, and link to the relevant page on the site. Non-members shouldn’t ever get to that page, but again, we’re trying to anticipate the edge cases and design for them, rather than ignore them. I’m sure our client would rather a visitor be encouraged to browse membership options if they happen to land on that page, rather than being rudely turned away!

Got any questions about Member Mouse customization? I’d love to help out if I can. Also, if you see any issues with the code I shared, please let me know!

12 Replies to “Setting up scheduled posts with Member Mouse”

  1. Interesting! I’ve been wanting to do this.

    Will the future or past posts that people don’t have access to be shown? We organize our content categorically, so I’d imagine that those posts would still show up.

    Also, can this same thing be done with bundles?

    1. I’m not 100% sure I understand your first question, but with this setup, the (past) posts that a member doesn’t have access to should not be visible in any way. If you’re dealing with a category archive view, you might need to also alter the query/queries for those archives to be sure the old posts that a member doesn’t have access to aren’t shown. However, you should be able to re-purpose that same code for use on other archive views, with an adjustment to the if statement that kicks off gfmp_show_allowed_meal_plans(). I also just realized I neglected to show where that function is added (pre_get_posts) – check that gist now for an updated version (line 34).

      Unfortunately, this project hasn’t involved bundles in any way yet, so I can’t speak to whether or not this same technique would work there. If you try it, though, let me know!

    2. As of the next release of MemberMouse (ver. 2.1.1) you’ll be able to do this for bundles as well. Pretty much everything that Travis has done for membership level will apply directly, the only difference is that instead of using the ‘daysAsMember’ attribute of the MM_Member_Data SmartTag, you’ll use ‘daysWithBundle_#’ where # is the ID of the bundle you want to get the number of days for.

      $days_with_bundle = mm_member_data( array( ‘name’ => ‘daysWithBundle_2’ ) );

  2. We are looking for a similar solution for a client.

    They want to have a Monthly and Annual membership levels to content. The content (products in MemberMouse) will be essentially the same, however the challenging requirement is to have Monthly Members access only future dated posts, (like Sports Illustrated, you only get future issues) while the Annual membership would have the additional benefit of access to all the archives of content.

    Any thoughts of that ?

    1. Roy,

      You should be able to use the mm_member_decision() function to accomplish that. For example, in both of the functions I included above, you could use that function to check the membership ID, and if the current membership ID matches the annual membership, then do nothing.

      For more info on that function, look over these two support pages: Using the PHP Interface and MM_Member_Decision SmartTag.

      Let me know if you have any other questions about that!

    2. Another useful tool for adding custom content protection requirements are our WordPress filters. You can use our content protection filters to bypass MemberMouse’s internal content protection rules which gives you a clean way to implement any custom requirements. Here’s a full list of our WordPress filters:

      function customContentProtection($data)
      $registration_date = mm_member_data( array( ‘name’ => ‘registrationDate’ ) );

      // check if date of post requesting access to is less than the registration date and if so, return true
      // by returning true you’re instructing MemberMouse to block access to the requested content
      add_filter(‘mm_block_access’, ‘customContentProtection’);

  3. Great job on this Travis! Just wanted to give a little more info on the ‘days as member’ calculation. It was definitely a good idea to use this as opposed to just going by the join date. As you mentioned, the ‘days as member’ calculation can be modified through the UI and as you guessed, manually changing this is useful when needed but doesn’t happen too often. However, we programatically modify this value based on a member’s account status changing which happens pretty regularly. For example, if a member pauses their account, the ‘days as member’ calculation will be set to ‘Fixed’ for the number of days they are currently a member. This allows them to maintain access to content they already had access to but won’t give them access to future dripped content. If a member cancels their account and then reactivates their account at a later date, the ‘days as member’ calculation will be set such that the drip content sequence starts from where they left off. The same applies to bundles as well.

  4. Hi Travis, I need to implement this on my site. Are you able to assist with implementation at all? ~Sandy

  5. Thank you Travis. Exactly what I needed and combined with Eric’s comment about the “daysWithBundle” then I managed to get it to work. Really appreciate you helping out in the WP community.

  6. I have created member level and products in membermouse but when i create paid members, they are inserted into default free membership rather than status change.

Leave a Reply

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