A few weeks ago, AJ Clarke of WP Explorer released a really slick photography theme called Fotos. Aside from just being a great theme, it also has a great feature that allows users to password protect their photo foto galleries. While developing the theme, AJ, who is a good friend of mine, asked me for help on writing the functions that would allow him to give his users this password protection feature. Over a couple of days, with lots of tweaking, we came up with a pretty solid system that worked really well. It uses the taxonomy meta system built into WordPress, which I showed you how to use with Adding Custom Meta Fields to Taxonomies, and allows you to password protect every post inside of particular taxonomy terms by setting one single password on the taxonomy term page. Now, I’d like to show you how it works so you can build your own password protected taxonomies.

Due to the nature of how this system works, I’m going to show you how to password protect the regular Post Category taxonomy, but you could very easily adapt it to any custom taxonomy. AJ’s theme uses a custom taxonomy called “album_cats”.

Unlike many of my other tutorials, there will not be a simple plug-and-play plugin to use at the end, but rather a selection of snippets and functions that you will use in your theme’s template files. It would be possible to extend the results I give you here to a complete plugin that works out of the box, but it’s beyond the scope of this tutorial.

You must be logged in and have an active premium membership to view the rest of this content. Register or login from the sidebar.

Join now to gain access to this tutorial and more.

Join Now
  1. chrispian

    I’m logged in but still can’t see the rest of the content, fyi.

    • Pippin

      This tutorial is restricted to paid subscribers. You will need to add a subscription to your account if you want to view the rest of this post.

  2. chrispian

    Gotcha. Thanks!

  3. smartmediaas

    Hi Pippin..

    Will the ‘enter password’ display when going to archive/taxonomy/term? So you can’t see the list of posts in term without password..


    • Pippin

      No, the functions are designed for individual posts. It could be modified pretty easily, however, to hide all posts in a term.

  4. up84

    I think it might be better to use something like this: add_filter(‘the_content’, ‘check_the_post’);
    We can use conditional statements then, such as: is_single() and is_index(). What do you think?

    • Pippin

      That is better for one scenario: when you only care about hiding the post content. When I built this, AJ really wanted to hide everything, including titles, dates, and post thumbnails. In order to do that, an extra function had to be added to the loop, as in my example.

    • up84

      I see. Thanks for reply.

  5. scimon

    This is a very spiffy plug-in, but it blocks viewing of the preview when drafting a new post once a protected category checkbox is ticked. What would be the best way to allow previews, other than to remember to not check the box until you need to remember to check the box before posting? thanks in advance!

  6. scimon

    Here’s a little something I whipped up to easily list all passwords that are set. It could be more robust (check blog_id in wp_options, specify the taxonomic type in the table and URL) but it works for our purposes and could be a good starting point for someone.

    add_action('admin_menu', 'my_pass_list_enable');
    function my_pass_list_enable(){
    #Place in Posts menu
    add_posts_page('Taxonomy Passwords', 'Taxa Passwords', 'publish_posts', 'my-taxa-pass', 'my_pass_list');
    function my_pass_list(){
    global $wpdb;

    $taxametas = $wpdb->get_results('SELECT option_name, option_value FROM wp_options WHERE option_value LIKE "%term_pass%"');

    foreach ($taxametas as $taxameta) {
    preg_match('/(\d+)$/', $taxameta->option_name, $taxid);
    $opts = unserialize($taxameta->option_value);
    $cat = get_category($taxid[0]);
    $taxainfo[$cat->name] = array('slug'=>$cat->slug,

    echo 'TermPassword';
    while( list($key, $val) = each($taxainfo) ){
    printf('%s%s', $val['slug'], $key, $val['pass']);
    echo '';

    • scimon

      Insert the following before return true on line 79 (no valid password yet) to allow the post author to preview drafts/pending posts.

              #punt if draft/preview & am author
              $chk = get_post($post_id);
              if( ($chk->post_status == 'draft' || $chk->post_status == 'pending') &&
                  $chk->post_author == wp_get_current_user()->ID
                return false;
    • Pippin

      Yep, that should work.

    • scimon

      #Generalize get_category above to allow use on tags or custom taxa
      $cat = get_term($taxid[0], 'category');

  7. scimon

    Doh, your site seems to process the accepted HTML tags other than code before code (and escaping the contents thereof) :-/

    • Pippin

      You need to paste the code inside of PRE tags. Like this:

      <pre lang=”php” line=”1″>
      // code here

  8. Danice

    Awesome you should think of smotehing like that

  9. scimon

    Note that the session initiation in part two needs to have action set a lower level e.g; 16; for compatibility with the User Switching plugin; otherwise you can only switch to a given user once per twenty-four hours.

    • scimon

      I have also found that it is necessary to add another condition to the test to determine whether or not to initiate a session:

      && !defined(‘DOING_CRON’)

      This eliminates the following message from showing up in your error log whenever cron is invoked

      Cannot send session cache limiter – headers already sent in …/wp-includes/plugin.php on line 406

  10. Dan Jørgensen

    I was stupid enough to think that it would work so many years after. What do I need to change to get it to work in version 4.1 ?

    • Pippin

      It should still work. It’s possible, however, that your server does not support PHP sessions.

      What happens when you try?

Error: Please enter a valid email address

Error: Invalid email