Add custom post types to wordpress main feed

June 21st, 2010

Background

I wanted my custom post types that I created in my last writeup (custom post types with archive page) to appear in my wordpress main feed. By default the custom post types do not get added to the main feed that wordpress creates. In my last write up I showed how I added the necessary rewrite rules in order to have the structure: www.domain.com/custom-p-type/feed. This will create a feed with all of those custom post types. Perfect. But what about my “main” wordpress feed?

What I wanted

What I wanted is for my www.domain.com/feed to include ALL of my sites content. Be it posts, or custom post types that I create. There are a couple of methods I found for doing this. I finally found the solution on the track in this ticket. http://core.trac.wordpress.org/ticket/12943

The solution

Here is what will add your custom post type content to your sites main feed, and leave your regular custom post type feeds specific for their respective content…

function myfeed_request($qv) {
	if (isset($qv['feed']) && !isset($qv['post_type']))
		$qv['post_type'] = get_post_types($args = array(
	  		'public'   => true,
	  		'_builtin' => false
		));
		array_push($qv['post_type'],'post');
		return $qv;
}
add_filter('request', 'myfeed_request');

The explanation

Thats it! Done. This code checks to see if the query var ‘feed’ exists, if it does it also checks to see if the ‘post_type’ query var IS NOT set. If the post_type query var is set, this means we are on one of our regular custom post type pages, and we don’t want to modify the way the feeds are genereated, as wordpress handles them out of the box.

So, if we are on a “feed” page, and we don’t have a post_type query var set, we must be on the home page feed (in my case). So we modify the default feed by querying for all custom post types that are not built in, and that are public using the get_post_types() function. We then append the “post” post type to the end with array_push, because I wanted my main feed to include all my custom post type content, as well as my regular post content.

Now I have the structure: mydomain.com/feed/ Which houses all of my sites published content, and each custom post type has its respective feed at mydomain.com/custom-p-type/feed/

Thingabeauty.

Custom Post Types Wordpress 3.0 with template archives

April 15th, 2010

I’ve been playing around with the latest nightly betas of wordpress 3.0, especially the custom post type feature.  It looks great for what I want to do, but doesn’t exactly seem “ready”.  I’ve read various blogs and posts about custom post types trying to get a grips on making this lovely little feature do what I want.  Namely http://kovshenin.com/archives/extending-custom-post-types-in-wordpress-3-0/ and Wordpress Codex, and this plugin http://wordpress.org/extend/plugins/cms-press/

I tried reading various tutorials on the web, and nothing really did what I wanted, so I’ve decided to make my own tutorial on how to create custom post types in wordpress 3.0 with archive pages.

The code within the plugin was finally what got me what I wanted.  So if your looking how to use custom post types in Wordpress 3.0 and want to have your own archive template file with each of your custom post types then this post is for you.  I really JUST started to look into themeing and code in Wordpress, so much of my work is borrowed from the sources listed about, and may not be the optimal way of doing things.  If you know of better/other ways to accomplish this, please pipe up in the comments, we’re all friends here.  I’ll try and explain the steps in detail so noobs like myself can follow along.

Here is what I wanted:

  1. A custom post type, we’ll say called “stories” that allows me to add stories in the wordpress backend.
  2. The URL of that custom post type to be an “archive” page of all the stories e.g. (www.domain.com/stories/)
  3. Each story to have its own structure like so (www.domain.com/stories/my-first-story/)

Wordpress does numbers 1 and 3 automatically for you after you register the custom post type in your themes “functions.php” file.  This is done like so:

1st – Register the new Custom Post Type with wordpress

register_post_type('stories', array(
	'label' => __('Stories'),
	'singular_label' => __('Story'),
	'public' => true, // Allows it to be publicly queryable
	'show_ui' => true, // Displays the post time in the Admin Interface
	'_builtin' => false,
	'_edit_link' => 'post.php?post=%d',
	'capability_type' => 'post',
	'hierarchical' => false,
	'rewrite' => array("slug" => "stories"), // the slug for permalinks
	'supports' => array('title','editor','author','custom-fields') // What can this post type do
));

The code above will create a new link in your admin area where you can add the custom post type. If you don’t believe it, go ahead and add it to your functions.php file and check it out!

Number 2 turned out to be a LOT more tricky than I initially believed.  Before I get to the solution that worked for me, I’ll give a bit of background.

When you register a new custom post type in wordpress 3.0 it automatically creates rewrite rules for that post type.  (Which is what makes domain.com/stories/my-cool-story/) possible.  It doesn’t create any rewrite rules which would allow for (domain.com/stories/) to show an archive page.  If you tried to type that in, you would get a 404 not found.

The default rewrite rules that wordpress creates for your custom post types is like so:

[stories/[^/]+/attachment/([^/]+)/?$] => index.php?attachment=$matches[1]
[stories/[^/]+/attachment/([^/]+)/trackback/?$] => index.php?attachment=$matches[1]&tb=1
[stories/[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?attachment=$matches[1]&feed=$matches[2]
[stories/[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?attachment=$matches[1]&feed=$matches[2]
[stories/[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$] => index.php?attachment=$matches[1]&cpage=$matches[2]
[stories/([^/]+)/trackback/?$] => index.php?stories=$matches[1]&tb=1
[stories/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?stories=$matches[1]&feed=$matches[2]
[stories/([^/]+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?stories=$matches[1]&feed=$matches[2]
[stories/([^/]+)/page/?([0-9]{1,})/?$] => index.php?stories=$matches[1]&paged=$matches[2]
[stories/([^/]+)(/[0-9]+)?/?$] => index.php?stories=$matches[1]&page=$matches[2]
[stories/[^/]+/([^/]+)/?$] => index.php?attachment=$matches[1]
[stories/[^/]+/([^/]+)/trackback/?$] => index.php?attachment=$matches[1]&tb=1
[stories/[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?attachment=$matches[1]&feed=$matches[2]
[stories/[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?attachment=$matches[1]&feed=$matches[2]
[stories/[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$] => index.php?attachment=$matches[1]&cpage=$matches[2]

The current Wordpress beta has the logic built into the templating system to look for a file called single-(custom-post-type).php for the custom post types “singular” pages.  So in my case the url (domain.com/stories/my-cool-story/) would be looking for a template file called “single-stories.php” in my themes folder.  If that file doesn’t exists it will use the regular single file, or eventually fall back on the “index.php” file.  Depends on how your theme is set up.

So the problem is that first, there are no rewrite rules for /stories/ to work.  Second, there is no logic to re-direct /stories/ to a template file which would show an “archive” of my stories.

The Solution.

2nd – Add new rewrite rules

After you’ve registered your custom post type, like I showed earlier in this post, we have to set up some re-write rules for our new shiny post type.  This is done like so.


add_new_rules();
function add_new_rules(){

	global $wp_rewrite;

	$rewrite_rules = $wp_rewrite->generate_rewrite_rules('test/');
	$rewrite_rules['test/?$'] = 'index.php?paged=1';

	foreach($rewrite_rules as $regex => $redirect)
	{
		if(strpos($redirect, 'attachment=') === false)
			{
				$redirect .= '&post_type=test';
			}
		if(0 < preg_match_all('@\$([0-9])@', $redirect, $matches))
			{
				for($i = 0; $i < count($matches[0]); $i++)
				{
					$redirect = str_replace($matches[0][$i], '$matches['.$matches[1][$i].']', $redirect);
				}
			}
		$wp_rewrite->add_rule($regex, $redirect, 'top');
	}

}

This bit of code I mostly took from the CMS Press plugin mentioned above. Check it out, it’s pretty sweet.

Which should produce the following NEW rewrite rules which are added to our already default rules that Wordpress supplies us.  For a total of 19 rules/ custom post type.  (Someone could possibly speak to how many rules would be “acceptable” for a medium sized website in production, as I’m not really sure what constitutes “to many” rewrite rules when it comes to performance in WP…)

[stories/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?&feed=$matches[1]&post_type=stories
[stories/(feed|rdf|rss|rss2|atom)/?$] => index.php?&feed=$matches[1]&post_type=stories
[stories/page/?([0-9]{1,})/?$] => index.php?&paged=$matches[1]&post_type=stories
[stories/?$] => index.php?paged=1&post_type=stories

Notice that we added  the variable “post_type=stories” to each of our url’s that we rewrote.  This will allow us to redirect to our custom template in the next step.

Note: I’m not sure really where to hook this function so that it doesn’t make rewrite rules on each page load.  Really we only need to write the rules each time the permastructure changes, or we add a new post type, but I’m not sure how/where to do that.. Any ideas?

If your having troubles getting that rewrite rule to work, go and re-update your permalinks settings page.

3rd – Redirect requests on our new rules to our custom template files

So now we are going to add a hook into the system to over-ride the default templating system, because as mentioned in the background info section, wordpress doesn’t have this built in.

We essentially are checking to see if the variable “post_type=stories” exists in our query vars.  If it does, then we set up the feeds and trackbacks stuff that wordpress does, and we redirect to one of two theme files.

If the “name” variable isn’t in our query vars, then obviously the query is for the archive page, as the name variable only appears when we are requesting a single post.  So we redirect to a template file called “single-stories.php” if the name file does exists, (which is what wordpress would have done normally) and we re-direct to a template file called “single.php” if the name variable doesn’t exist.

Here’s my code:


	add_action("template_redirect",'template_redirect');
	function template_redirect()
	{
		global $wp;

		$muley_custom_types = array("stories");

		if (in_array($wp->query_vars["post_type"], $muley_custom_types))
		{
			if ( is_robots() ) :
				do_action('do_robots');
				return;
			elseif ( is_feed() ) :
				do_feed();
				return;
			elseif ( is_trackback() ) :
				include( ABSPATH . 'wp-trackback.php' );
				return;
			elseif($wp->query_vars["name"]):
				include(TEMPLATEPATH . "/single-".$wp->query_vars["post_type"].".php");
				die();
			else:
				include(TEMPLATEPATH . "/".$wp->query_vars["post_type"].".php");
				die();
			endif;

		}
	}

That way I can have custom 2 separate custom template files (post-type.php, and post-type-single) for each of my custom post types.

You would need to do that code for each of your custom post types, or write a little function to loop through an array of your custom post types and set them up automatically.

It would be nice if I could query wordpress for my custom post types and have it all be dynamic, but I haven’t looked into seeing if wordpress stores the custom post types in the DB.??

Anyway, that should get you started on hacking around with Custom Post Types.  I think that this should be the DEFAULT way that wordpress handles custom post types.  It seems to me logically that almost everyone is trying to do this by default with their wordpress installations that are running more “CMS” style instead of “blog” style.  Previously most everyone did this same sort of structure with categories and such with the Posts, but this way is much more organized if you ask me.

You can also add custom taxonomies (categories) for each of your custom post types should you so be inclined.  i.e. stories could be divided into fishing stories, hunting stories, hiking stories, etc.  however, we are focusing solely on post types in this tutorial.

Things to note:

-The title tags for your custom post type archives page won’t work.  I haven’t looked into how to fix this yet, as I have no idea how wordpress does titles, let alone for custom post types and custom rewrite rules.??  Any insights would be helpful.

Top 5 Best Professional Digital Cameras

August 6th, 2007

So I’ve been getting into photography lately, and have just recently purchased a entry-level-pro camera. I did extensive research on multiple sites trying to figure out what camera would give me the best bang for the buck.

These 5 cameras here are obviously not the most expensive and feature packed, but excellent digital cameras for under a $1000 dollars.

My first choice is a camera that I bought from newegg for $799.00 a week ago. Now it’s $725!

1. Nikon D80 – info from dpreview.com

2. Canon 400d (Digital Rebel xti) – info

3. Pentax k10d info

4. Nikon d40x info

5. Canon eos30D info

Remember that it’s not the camera thats going to take the perfect photo, but the photographer. If your budget is tight, go with the nikon d40x, or the canon Digital Rebel, and spend the extra money you would have spent on a more expensive body on a more expensive lens.

Remember: A high quality lens and cheap body will take much better pictures than a cheap lens with a high quality body.

Google’s definition for “digg clone site” is netscape.com

January 26th, 2007

So I was rather curious on how some of the ajax programming was done on the popular digg.com. I did a simple “how to make a digg clone site” on google to find out if there was a related tutorial on how to make a voting system. The first result made me laugh.

beta.netscape.com

Just goes to show the power of keywords and how they relate to SERP’s. Go ahead, try it, it’s funny.

This anomily is knows as Google Bombing. A famous example is the search for “miserable failure,” which turned up George Bushes name.

How to create a vector portrait in Illustrator in 2 minutes!

December 8th, 2006

So after seeing several tutorials on “how to create a self vector portrait in illustrator,” (Here and a High Tech version)

adblock

I decided to do one for myself. The only difference is that I will show you how to do one in 2 minutes! I don’t know about you, but I don’t have 16 hours to trace each little piece with the pen tool!

Here’s a tutorial on how to create a Vector Potrait using Photoshop and Illustrator. Start to Finish time. 1 min. 24 seconds!

Step 1)

Get a picture of yourself. Here is mine I used.
(Click images to enlarge)

Self Portrait

I cropped it down to just include my face.

Step 2)

Open your picture in Adobe Photoshop. Go to the filter menu and select Filter->Artistic->Cutout. (You’ll need Adobe CS2 for the Illustrator part.)

You should see this screen.

Photoshop Cutout Thumb

Choose whichever settings you like. For my example here I used 8 Levels, 3 Edge Simplicity, and 2 Edge Fidelity. Once your satisfied with the look, run the filter.

Step 3)

Save this newly filtered image as a .jpg or something similar and open it in Adobe Illustrator.

Step 4)

Select the picture or Object by clicking on it. Head to the Object menu and select Object->Live Trace->Tracing Options. You should see the following options.

Tracing Options

Change the mode to “color”, increase the color count. I chose 100 colors. Leave the rest of the settings at default, unless you want to tinker.

Step 5)

Finally, click Trace! Let Illustrator do its magic, and WALLA! Done

Vector Lines

Step 6)

Go ahead and zoom in as far as you can. Your used-to-be-raster image is now all vectorized! Here is snapshot of my left eye on my vector self portrait.

Eye Zoom

Update – I really did actually spend several hours hand tracing my picture in Adobe Illustrator. It took forever, hence the reason I wanted a quick n’ dirty way to do it. Here is a snapshot of my hand drawn portrait compared to the “two minute” portrait.

Hand Drawn Vecotr Portrait FinalFinal Vector Thumb Portait

Go ahead, Digg it!