More Intuitive Membership Workflow using Template Files

Submitted by Leighton Whiting on Fri, 01/27/2012 - 10:34

In most of my tutorials, I advocate using an Access Control module such as Content Access to restrict access to content to certain roles. This works great and gets the job done, but there are a few disadvantages to it.

Access Control in Drupal is an 'all-or-nothing' process. Either the user can view the content, teaser, and menu links, or the user can view nothing.

Sometimes you want to set it up so that users can still go to the node pages, but won't be able to view the full content unless they have the membership. This makes it easier for the users to see just what it is they will be getting access to when they pay. You could even provide a 'signup' link on the node page so that users can go to purchase the membership.

There are two ways to do this, and they are essentially the same in terms of how they work.

Module Solution

One way is to use a module such as Drupal's Premium module (6.x only) or MoneyScripts' Pay Per View module which allows you to set up nodes to only show the teasers unless the user has permission to view the whole node.

Pay Per View has many more features you can use such as tokens to show different information and the ability to add custom text to the protected message (such as a purchase link). It also allows you to simply sell access to individual nodes and fields, but that functionality wouldn't apply in this use case, since we are using Membership Suite.

Code Solution

Using either of those two modules would work, but if you are feeling adventurous and don't mind writing a little code into your theme .tpl files, then continue reading! Don't worry, I'll walk you through what you need to write.

This is the method I use personally on most of my sites, simply because it allows for greater control and flexibility to get it 'just how you want it'.

Set Up the Permission

In order for this to work, you still need to have a Premium Role of some sort that the Membership Plan grants to the user, just like the solutions above.

The idea is to have a check in the .tpl file to see if the user has access, and if they do, then they show the full content, but if they don't, then it shows a teaser with a purchase link.

Lots of people check if the user has a role or not to see if the user has access. I myself used to do this. You can find out more about this method here. This method works but is a little hard to maintain if anything changes, like the role name. So we are going to do a couple extra steps to make our code cleaner and easier to maintain.

Instead of checking if the user has a role, we are going to check if the user has a 'permission'. Permissions are found on the People->Permissions page. I usually add a permission such as 'view premium content for free' using a custom module by implementing hook_perm(). This works just fine, but I realize that many of you might not have a custom module or know how to write one. Well, there is another solution: the Config Perms module. This module lets you set up as many custom permissions as you need. So, install that module and create the permission 'view premium content for free' (or call it whatever you want, just remember it because we will use it later in our code). Or just add the permission using a custom module like I mentioned.

Next we need to make sure that our Premium Member role has that new permission, so go to the People->Permissions page and check the permission for that role.

Set up the TPL file

Now that the permission is set up, we need to add the code into our theme template files. Anyone using Drupal should know at least a little bit about how the theme tpl files work. It is an extremely useful tool. I'll explain it here.

Basically, when Drupal wants to display a node, it uses the .tpl files. It searches for these files in a specific order. The order is roughly as follows (skipping some steps that aren't relevant to this tutorial):

  1. Theme node--CONTENTTYPE.tpl.php
  2. Theme node.tpl.php
  3. Module node--CONTENTTYPE.tpl.php
  4. Module node.tpl.php

So it searches for the first tpl file it can find in that order, and uses it to display the node.

Your theme should already have a node.tpl.php file (every theme I've seen does). But we don't want to use that file because it matches EVERY node, no matter which content type. We want to only protect our Premium content type. So we are going to make a new file in the theme, called 'node--premium.tpl.php', where 'premium' is the content type (rename it to your content type). Note that this is the machine name of the content type, not the user friendly title.

Note that in Drupal 6, there is only 1 dash instead of 2, so it would be node-premium.tpl.php.

Once you have created the new file, simply copy and paste the contents of the node.tpl.php file into it, so that  it is an exact copy of the node.tpl.php file. Then add some text into your new theme file that will let you see if it is working. For example before the title, add "TESTING123".

Let's test and see if the new template file is being used for the content type. Go to Site Configuration -> Performance and click Clear Cache. This is a very important step because the cache needs to be cleared before the new template file is used. Now navigate to a node of the premium content type and see if the TESTING123 is showing. If it is, you can move on to the next step. If not, try debugging it and see if you named the tpl something wrong.

Adding the Access Code

Now that the .tpl file is set up, we can add our access code to it to check if the user should be able to view the full content or the protected message. Find where the $content is being printed in the template and replace it with our access code. Here is an example of the code you need:

  1. <?php
  2. if (user_access('view premium content for free')) {
  3.   // The user has access to view the whole node
  4.   print render($content);
  5. }
  6. else {
  7.   // The user doesn't have access. Show a message informing them of this
  8.   print "You don't have access to view the full content. Here is the teaser:<br />";
  9.   print substr(render($content), 0, 255);
  10.   print "<br />To view the full content, click here to sign up: <a href='/membership/purchase/1'>Sign Up</a>";
  11. }

Small and simple. You can configure to be more specific in what it does and doesn't show. Be creative! The purchase link was just an example. Enter any link that works for you.

Now the users that have the permission to view the content will be able to without any problems, while the users who don't will be given a sneak peak of the content as well as a helpful link to the signup page. This makes for a much better workflow for the end user! I hope y'all enjoyed this tutorial! Post comments if you have questions or suggestions to share!

 

Twitter Feed