Exclude articles from a category tree on your WordPress homepage
A nice way to manage articles visible only to registered users on your WordPress based site is to create one parent category exclusively for those posts and then create sub categories if needed.
Once you have the top, subscriber-only category, you will most likely not change it anytime soon, and therefore you can use its category ID as an argument to construct your query, for instance query_posts(cat=-3)
.
In this example all posts from the category with ID 3 are excluded from the listing. However, this doesn’t exclude posts in child categories, and if we knew all the IDs, we’d expand the call to function like so query_posts(cat=-3,-4,-5)
.
In the real life, there are two possible issues. First, it’s a bad practice to rely on IDs for child categories, and the second one is that the default argument syntax cat=-3
won’t always work, due to plugins incompatibilities.
How to get the child categories IDs?
We can use get_categories
to get the sub categories. In the following example we will first create a string, which we’d use with query_posts(cat=' . $subcat_string)
, but aforementioned issues with plugins could require a different argument construction.
<?php // In this example, the parent category ID is 3 $subcategories = get_categories('child_of=3'); $subcat_string = ''; foreach ($subcategories as $subcat) { $subcat_string .= '-' . $subcat->cat_ID . ','; } // we also include parent category ID in the list $subcat_string .= '-3'; // and then call query_posts query_posts(cat=' . $subcat_string); ?>
A slightly more advanced (for designers at least) query_posts()
call is to use an array for arguments. Quite often where cat=-n
doesn’t work this should fix the problem. I believe this is due to plugins incompatibility, but it could be also due to WordPress itself. Whatever the problem is, this is one way to handle it:
<?php // Subcategories IDs as an array // In this example, the parent category ID is 3 $subcategories = get_categories('child_of=3'); $subcat_array = array(); foreach ($subcategories as $subcat) { $subcat_array[] = '-' . $subcat->cat_ID; } // we also include parent category ID in the list $subcat_array[] = '-3'; // and then call query_posts query_posts(array('category__not_in' => $subcat_array)); ?>
Hide posts from the members-only categories
To check if a visitor is logged-in or not, you’d test $user_ID
variable. If the visitor wasn’t a member, we would display latest articles sans members-only category. For signed-in users we would display the default query results, i.e. all articles from all categories.
<?php if (!$user_ID) { // we created an array of categories to exclude: $subcategories = get_categories('child_of=3'); $subcat_array = array(); foreach ($subcategories as $subcat) { $subcat_array[] = '-' . $subcat->cat_ID; } $subcat_array[] = '-3'; // Here, we set $limit for showposts (so it can be redefined via admin if needed) $limit = get_option('posts_per_page'); // ... and $paged (to tell WP which page in the Loop is current) $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; // then populate arguments $args = array( 'category__not_in' => $subcat_array, 'paged' => $paged, 'showposts' => $limit ); // and call the function query_posts($args); // the general loop code goes here } ?>
Got something to add? Speak up!