Assign Categories to Pages in WordPress

by Amit Verma on February 17, 2010

in Blogging,tools

WordPress has different options for organizing posts. One of them is Categories. The categories can only be assigned to posts, not to pages in WordPress. But sometime you might want to categorize the pages as well. Here are a few cases.

  1. To display related posts on a page.
  2. To display pages and categories in navigation menu in mixed order. WordPress provides the two different functions to display a list of Pages and Categories. But it doesn’t give the option to setup a navigation menu mixed with pages and categories, like the example given below. In such a case you can map pages to categories and use them as category pages. Obviously it will need some changes in the template.
    • Page 1
    • Page 2
    • Category 1
    • Page 3
    • Category 2
  3. To display pages on the category pages with the posts.

How to map Categories to pages

Add following lines of code in the function.php of your theme directory. If you don’t have a function.php in the theme directory then you can add it using any text editor. You can also download the plugin which I have made from http://wordpress.org/extend/plugins/map-categories-to-pages/.

function add_category_box_on_page(){
//add meta box
add_meta_box('categorydiv', __('Categories'), 'post_categories_meta_box', 'page', 'side', 'low');
}

add_action('admin_menu', 'add_category_box_on_page');

It will show the category selection box on the right side on “Edit Page” page.

Template changes

You will also have to edit the page template to use categories. You can use standard category code on your page template. Take a look at http://codex.wordpress.org/Function_Reference/get_the_category and http://codex.wordpress.org/Template_Tags/the_category.

Here is a small piece of code to build a page of posts. This example uses the styles from WordPress default theme.

<?php
global $post;
$cats=array();
foreach(get_the_category() as $category) {
	$cats[]=$category->cat_ID;
}
$showposts = -1; // -1 shows all posts
$do_not_show_stickies = 1; // 0 to show stickies
$args=array(
   'category__in' => $cats,
   'showposts' => $showposts,
   'caller_get_posts' => $do_not_show_stickies
   );
$my_query = new WP_Query($args);

?>

	<?php if( $my_query->have_posts() ) : ?>

		<?php while ($my_query->have_posts()) : $my_query->the_post(); ?>
			<?php
			//necessary to show the tags
			global $wp_query;
			$wp_query->in_the_loop = true;
			?>
			<div <?php post_class() ?> id="post-<?php the_ID(); ?>">
				<h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
				<small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --></small>

				<div class="entry">
					<?php the_content('Read the rest of this entry »'); ?>
				</div>

				<p class="postmetadata"><?php the_tags('Tags: ', ', ', '
'); ?> Posted in <?php the_category(', ') ?> | <?php edit_post_link('Edit', '', ' | '); ?>  <?php comments_popup_link('No Comments »', '1 Comment »', '% Comments »'); ?></p>
			</div>

		<?php endwhile; ?>

	<?php else : ?>

		<h2 class="center">Not Found</h2>
		<p class="center">Sorry, but you are looking for something that isn't here.</p>

	<?php endif; ?>

Displaying pages on Category pages

When WordPress fetches the posts from database, the default post type is ‘post’. So even when you have mapped a page to a category, it won’t display the page on that category page. The post type needs to be changed explicitly on the category page. To change the post type, add following code in function.php.

//call a function just before the query runs to fetch posts
add_action('pre_get_posts','change_post_type');

function change_post_type($var) {
	if(is_category()) {
    	    	$var->query_vars['post_type'] = 'any';
            	//it will change the value to 'any' from the default value of ;post';
            	//can be any, attachment,  page, post, or revision.
            	//'any' retrieves any type except revisions.
	}
}
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • email
  • FriendFeed
  • LinkedIn
  • Live
  • Technorati
  • Twitter

{ 17 comments }

dandy March 1, 2010 at 12:01 pm

Very nice effort indeed. This would be really useful. But this isnt working for Wordpress 2.8.6

i get this error when i activate plugin. This error is shown on edit page below categories box.

Warning: call_user_func(post_categories_meta_box) [function.call-user-func]: First argument is expected to be a valid callback in /home2/artefact/public_html/wp-admin/includes/template.php on line 2936

Can you please check?

Thanks.

Amit March 1, 2010 at 3:27 pm

@dandy I have tested the current version with WP 2.8.6 and there was no problem in activating the plugin but there was some problem in the Category box on “edit page” page. So I have updated the plugin and you can download it from here. I have tested it on WP 2.8.6. Hope it will help. If still it doesn’t work, feel free to contact me. Let me know how it goes.

I will update it on wordpress plugin directory soon with a option to display Pages on Category pages.

dandy March 1, 2010 at 3:46 pm

Thanks Amit for your prompt reply and help. I really appreciate. And thanks for fixing up the issue. It works great now and i can assign category to my pages now.

But i think this isnt what i wanted. I wanted to assign pages to categories and then display specific category pages using wp_query.
Like, i wanted to make a category “Header Navigation Pages” and then put all pages in this category that are to appear in header top navigation and then do something like this

<a href="">

But as i assign pages to category and go to “manage category” menu, i see “0″ as a post count in that category.

Still thanks anyway, this is a great plugin indeed.

dandy March 1, 2010 at 3:47 pm

Thanks Amit for your prompt reply and help. I really appreciate. And thanks for fixing up the issue. It works great now and i can assign category to my pages now.

But i think this isnt what i wanted. I wanted to assign pages to categories and then display specific category pages using wp_query.
Like, i wanted to make a category “Header Navigation Pages” and then put all pages in this category that are to appear in header top navigation and then do something like this

<a href="”>

But as i assign pages to category and go to “manage category” menu, i see “0″ as a post count in that category.

Still thanks anyway, this is a great plugin indeed.

dandy March 1, 2010 at 3:47 pm

Thanks Amit for your prompt reply and help. I really appreciate. And thanks for fixing up the issue. It works great now and i can assign category to my pages now.

But i think this isnt what i wanted. I wanted to assign pages to categories and then display specific category pages using wp_query.
Like, i wanted to make a category “Header Navigation Pages” and then put all pages in this category that are to appear in header top navigation and then do something like this

<a href="”>

But as i assign pages to category and go to “manage category” menu, i see “0″ as a post count in that category.

Still thanks anyway, this is a great plugin indeed.

dandy March 1, 2010 at 3:49 pm

Thanks Amit for your prompt reply and help. I really appreciate. And thanks for fixing up the issue. It works great now and i can assign category to my pages now.

But i think this isnt what i wanted. I wanted to assign pages to categories and then display specific category pages using wp_query.
Like, i wanted to make a category “Header Navigation Pages” and then put all pages in this category that are to appear in header top navigation and then do something like this

wp_reset_query();$postlist = get_posts(‘category_name=header_navigation_pages&numberposts=4′);

foreach ($postlist as $post){ setup_postdata($post); ?> <a href="”>

But as i assign pages to category and go to “manage category” menu, i see “0″ as a post count in that category.

Still thanks anyway, this is a great plugin indeed.

Amit March 6, 2010 at 4:55 pm

@dandy, The default post type in wp_query is ‘post’. So you will have to change it. Try the code below. I haven’t tested the code but it should work.
[sourcecode language="php"]
<?php
$showposts = 4; // to retrive 4 posts only, -1 to shows all posts
$do_not_show_stickies = 1; // 0 to show stickies
$post_type=’any’; //’post_type’ => ‘page’ – returns Pages; defaults to value of post; can be any, attachment, page, post, or revision. any retrieves any type except revisions.

$args=array(
‘category_name’ => ‘header_navigation_pages’,
‘showposts’ => $showposts,
‘caller_get_posts’ => $do_not_show_stickies,
‘post_type’ => $post_type
);
$my_query = new WP_Query($args);
?>

<?php if( $my_query->have_posts() ) : ?>

<?php while ($my_query->have_posts()) : $my_query->the_post(); ?>

<!–Enter your stuff here–>

<?php endwhile; ?>
<?php endif; ?>
[/sourcecode]

David March 29, 2010 at 12:38 pm

Hi Amit,
Your plugin has been saving my life on a project! Thanks so much. Using your documentation I am able to get my pages to appear in category archives. But I’m still having trouble getting them to activate a category nav I’m working with below. Do I need to insert some code to look for categories in pages first? Currently the category nav is only showing the categories which have posts associated with them… when I really also want pages. My code is below. My site is here: sod2010.info. Thanks for any help.

<a href="”>

category_parent == ’0′ ) { ?>
<a href="cat_ID); ?>”>cat_name; ?>
category_description; ?>
cat_ID) ) { ?>

cat_ID ); ?>

David March 29, 2010 at 12:42 pm

Oops my code did not past as I had wanted it to. Not totally sure how to do that. Let me try again.

<a href="”>

category_parent == ’0′ ) { ?>
<a href="cat_ID); ?>”>cat_name; ?>
category_description; ?>
cat_ID) ) { ?>

cat_ID ); ?>

David March 29, 2010 at 12:47 pm

OK Sorry can’t figure out a way to show my code so I put it here:
http://sod2010.info/code-for-amit/

Please disregard my other attempts.

David

Amit March 29, 2010 at 12:48 pm

Glad to know that it helped. I didn’t get your problem clearly. If you want to list the categories which have only pages not posts you can use following code.

wp_list_categories(‘hide_empty=0′);

David March 29, 2010 at 12:57 pm

Hi Amit,
Thanks. If I use “wp_list_categories(‘hide_empty=0′);” how would I incorporate it into the code here: http://sod2010.info/code-for-amit/ so that it creates the nav bar?

Thanks,
David

David March 29, 2010 at 9:06 pm

It took me a while but I got it! Thanks.

David

Amit Verma March 29, 2010 at 9:10 pm

It will be great if you can share the solution here. It will help others.

David March 30, 2010 at 12:00 am

So here is howI did it. I was working with a nav system that had the following 2 lines of code to get and display categories. Only the cats that had associated posts were showing up but I wanted all cats to show up because I was associating cats to pages.

Original code here:
[sourcecode language="php"]
<?php foreach ( (get_categories(‘exclude=’.get_option(‘woo_cat_ex’) ) ) as $category ) { if ( $category->category_parent == ’0′ ) { ?>
<?php wp_list_categories(‘title_li&child_of=’ . $category->cat_ID ); ?>
[/sourcecode]

New code to show all cats here (just added hide_empty=0 to each line)
[sourcecode language="php"]
<?php foreach ( (get_categories(‘hide_empty=0&exclude=’.get_option(‘woo_cat_ex’) ) ) as $category ) { if ( $category->category_parent == ’0′ ) { ?>
<?php wp_list_categories(‘hide_empty=0&title_li&child_of=’ . $category->cat_ID ); ?>
[/sourcecode]

Thanks again Amit!

Luc April 2, 2010 at 12:41 am

Hi there,

I’ve been working with this plugin for a while now and I almost have it doing what I need but I’m not quite sure what I’m doing wrong here.

What I have is a top nav bar that are all “Pages”, my website is going to have many categories and to make things easy for the user what I wanted to do is associate certain categories to those pages (which works with the new categories menu added to the “Edit Pages” page) so when I click one of the main nav item (a page), it displays the blog posts that are associated to the same categories that the page is associated with.

Basically, what I want to see is…clicking on a page, blog posts associated with the perticular categories that the page is also associated with will show up.

Right now it seems only the Uncategorised posts show up, if I set a page to have any other category I get a Not Found.

I used your code for the page template you posted above.

I hope I was clear with my question…

Thanks!! :D

Amit April 5, 2010 at 12:29 pm

@Luc, please make sure that the categories are correctly assigned to the pages.

By default all the pages belong to Uncategorise category so it shows the posts which belong to Uncategorise until you change to category of the post.

If it still doesn’t help, would you share the code?

{ 1 trackback }

Comments on this entry are closed.

Previous post:

Next post: