UPDATE: WordPress 3.1 now has support for index (archive) pages for custom post types, meaning that this code has outlived its usefulness. See Mark McWilliams’ post for the basic lowdown.
WordPress 3.0 finally gives us a ton of goodness out of the box for custom content types (post types in WP parlance). There’s a few extra things that I also wanted, and I keep adding new things. I have no intention to turn this into a plugin — only folks comfortable with a bit of code need apply.
Features
- Custom URLs for a landing page for your post type, with full pagination & feed support. (eg http://yourdomain.com/movies/, http://yourdomain.com/movies/page/2/, http://yourdomain.com/movies/feed/ )
- Custom landing page templates: if you registered “movie” as your post type, you can use
movie/index.php
ormovie.php
in your theme directory (falls back toindex.php
if they don’t exist) - Custom single page templates: WP already looks for
single-movie.php
(and falls back tosingle.php
). This function allows you to usemovie/single.php
— great alongsidemovie/index.php
for better theme organization. - Adds classes to
body_class()
andpost_class()
for that post type. - Auto-generates appropriate admin UI labels if you don’t supply any yourself (otherwise WP defaults to “post” or “page”).
Usage
After including the SD_Register_Post_Type
class and the helper function sd_register_post_type()
, all you need in your functions.php file (or wherever you choose to run this) is the following line:
sd_register_post_type( 'movie' );
That’s it. Call it again with a new argument for another post type. Repeat as many times as you need post types. I’ve set good default arguments to pass to register_post_type()
, but you can override them with your own. (Read more about the $args here, here and here.)
sd_register_post_type( 'movie', $args_array );
Also, grammar pedants know that adding an “s” suffix is not appropriate for all plurals. In the case of post type “movie”, our URL landing structure is http://yourdomain.com/movies, which works fine. But, for irregular plurals, the function accepts an optional third argument:
sd_register_post_type( 'person', $args_array, 'people' );
The above URL structure would then be http://yourdomain.com/people for the post_type “person”.
Important Note
One note that’s very, very important: your custom URLs won’t work until you go to Options → Permalink in wp-admin and re-save your current URL structure. This will flush WP’s current URL structure and add our new rewrite rules. This is computationally expensive and you don’t want it happening every time WP loads, which is why I’m leaving it as a manual operation. You’ll only need to do it once (or after changing the third plural argument).
Download
[Download not found]Changelog
- 1.0
- Initial release
- 1.1
- Added feed support in URL rewrites
- 1.2
- Removed redundant post_class code
- Removed redundant single post_type template code
- Introduced directory support for template files
- 1.3
- Use the newer, more robust labels array to set defaults
- Some code refactoring
109 Comments
Hey thanks for the class.
I have changed some stuff inside your class to suit my needs.
e.g if my custom type name is project
i want all my projects url to be /projects/urlofpage and not /project/urlofpage
It is a small change but i prefer this way
thanks again
Hello,
Congratulations for this great idea. Sorry for the question but even if I copy everything as you have here I get a page not found error if I type http://www.myblog/movie, even resaving the permalink structure.
I have created a movie.php file and a single-movie.php, but how I get a list of the movie-type-posts in movie.php and how it get recognized when typing the url /movie/?
@John did you use the third parameter? If not, your URL will be at http://myblog.com/movies — note the plural. This can be overridden with the third parameter.
Sorry Matt, you are correct. It works with movies! And how I get a list of the movies under /movies/ please? Sorry for the newbie question.….
I got it, sorry Matt. And congratulations again!
Hi, you should add this as a ticket to the wordpress trac.
This function should be at the core.
@Victor I might strike up a discussion over there once WP 3.0 is released. For now, I don’t want to distract anyone from that goal.
Also, Andrew Nacin, one of the core developers, left a couple of comments on the original post, so they’re already aware of the desire for something like this.
hi
is there any way i can get the link to the archive page for the current post’s post_type?
e.g. on single post pages and after each result on my search results page, i want to say ‘posted in: My Post Type’ with the words being a link to the archive page for that post_type.
i tried using:
$type = get_post_type_object( $post->post_type );
$slug = $type->rewrite[‘slug’];
but the problem is i have used a custom plural, so it seems there is no way to retrieve this?
many thanks
simon
@simon Any reason why you can’t just hardcode it like
<?php echo home_url() . '/my-custom-plural'; ?>
? Or you could store it as a variable before passing it into thesd_register_post_type()
function and retrieve it in your template.i can’t hardcode it because each search result could be of a different post_type.
storing as variables sound like my best option — i will write a short function that returns the custom plural name when the post_type name is passed into it.
cheers!
simon
Hi, I got everything working OK.
Only problem is viewing a single custom post gives me the 404, I’ve visited the permalinks page, saved etc
(http://testing/2010/06/07/sample-post/ )
but still getting 404 not found, any tips would be greatly appreciated.
PS: http://testing/chairs works fine (the custom post listing)
Is there built in functionality for registering taxonomies?
I want to enable the post tag box for custom post types, but don’t know where to put this line of code:
register_taxonomy_for_object_type(‘post_tag’, ‘movies’);
Nevermind. I’ve modified one of the public functions to:
public function register_post_type() {
register_post_type( $this->post_type, $this->args );
register_taxonomy_for_object_type(‘post_tag’, $this->post_type);
}
All seems to be working now. Let me know if this is the best way!
Thanks for this class. I added it to my functions.php, saved permalinks one more time and it seems to be working out of the box!
Nice work on this class. For whatever reason, this doesn’t seem to be in the core for 3.0, and I appreciate not having to mess around with the rewrite rules. Thanks!
Thanks for making this available. I’m a little confused how to do the template files. Any chance of a modified template showing this class/helper in action?
I’m mostly confused about how to setup the pagination in the template file.
Thanks again.
Thanks for the excellent class. I’m using it right now, but is there a way to modify the code, so that it doesn’t register the types (I’m already using a plugin for that), and it only creates the template support?
What I did was comment out the actual register_post_type function call, but seems somewhat inefficient to have all the other code just lying around. I’m just not sure what I need to leave, and what to delete.
Thanks!
@Alice the rest of the code won’t really be inefficient. There aren’t any DB calls being made, just some basic PHP. In other words, what you’re doing now is just fine.
@brad For pagination, the stock WP template tags
next_posts_link()
andprevious_posts_link()
are what you’re looking for. The same template will be called on /page/X.Thanks for the info.. One more question.. Going with your Movie idea.. Lets say I want to setup mywebsite.com/movies/horror or mywebsite.com/movies/scifi how would I do this?
I would guess I would use: register_taxonomy_for_object_type but not 100% sure.
Thanks a million.
-Brad
One more thing..
When I add query_posts(‘showposts=2’); to my movie/index.php file, and try to go to the previous posts page (page/2) it cannot find the pages.
Do you know why this would be?
I also tried putting this in the index.php file
global $wp_query;
$wp_query = new WP_Query(“post_type=movie&post_status=publish&posts_per_page=2”);
This would show the same post over several pages. I was completely confused after that… 😛
Thanks for any help
-Brad
@Brad
register_taxonomy_for_post_type()
works for already existing taxonomies, such as WP’s built-in category or post-tag taxonomies. Otherwise, you’ll need to useregister_taxonomy()
— see the codex entry. In either case, the “movies” part would not register as part of the category slug, but rather something like mysite.com/movie-taxonomy/scifi. Well, it could, but you’d have to do some extra stuff that’s not out of the box and would take way too long to explain.For your
query_posts()
issues, see the Codex on preserving the original query.OK, followed everything and its works!!! Kick ass awesome you’re the best.
One last piece of the puzzle though.
I have tried using wp_list_pages but my new custom post type doesn’t show up in the list because it’s not a page.
Then I tried wp_nav_menu and added the custom link to it in the admin area under Menus. But that’s not how I want to do it because it makes me add it as an absolute url.
Have you figured out a way to create a menu with pages and custom post types and still have the core generate it so that it gives you the
.current_page_item
or
.current-menu-item
So that I can style my active links?
Much appreciated.
@Kyle If you’re talking about the landing page for your post_type, just use the absolute URL (with trailing slash) in a custom link in the new menu manager. It’s smart enough to figure out if it’s on the same page and add a current-menu-item class to it.
You are correct, you can just place the relative url in there like this
/link-to-page/
but if you don’t add the domain and make it an absolute url, then it won’t create the
current-menu-item
and you won’t be able to show an active state.
I’ve tried both.
Im working with ur class, and its cool, i had a problem with sitemap.xml, i need to add custom post and terms to sitemap.xml, im using Google XML Sitemaps plugin, but i can c customs post in .xml file 🙁 , any idea to fix it ? 🙁
An example using ur class its nice it works so fine 😀
register_taxonomy( ‘genero’, ‘pelicula’,
array(
‘hierarchical’ => true,
‘label’ => __(‘Genero’),
‘query_var’ => ‘genero’,
‘rewrite’ => array(‘slug’ => ‘peliculas/genero’ )
)
);
$args_array = array(
‘label’ => __(‘Peliculas’),
‘singular_label’ => __(‘Pelicula’),
‘public’ => true,
‘show_ui’ => true,
‘query_var’ => true,
‘capability_type’ => ‘page’,
‘hierarchical’ => false,
‘rewrite’ => true,
‘supports’ => array(‘title’, ‘thumbnail’,‘editor’),
‘taxonomies’=>array(‘post_tag’,‘genero’),
);
sd_register_post_type( ‘pelicula’, $args_array, ‘peliculas’ );
Hey, I am comfy with php, but pretty much a noob to coding for wordpress. Can someone give me a quick writeup on how to include the sd_register_post_type.1.3.php file into my word press site and how to “include the SD_Register_Post_Type class and the helper function sd_register_post_type()”?
I tried adding this to the beginning of the functions.php in my theme
require_once(‘sd_register_post_type.1.3.php’);
(this file is locaed in my theme directory as well)
and then adding code like what Josergory House posted just below that. That got me no where fast. I am afraid I have got not idea where to start, but I can’t imagine it would be to hard once it is explained to me.
Thanks in advance, and thanks to Matt for what appears to be a sweet chunk of code ;).
Derr.…. I think I got it, I just copy pasted Matts code to the beginning of my functions.php then added my post type and taxonomies just like Josergory House did. Thanks Matt!!
I’ve been messing with this post type stuff for weeks now, so i’ve got code all over the place, good thing its just a local dev site ;). Happy WordPressing!
You just made WordPress into a TRUE CMS. Unbefuckingleivable!!! Very well done!
Only problem is that I use .html permalinks. None of these custom posts will display (at any URL, .html or without), although regular WP posts still work fine.
Would you know where to add .html to URL’s in the code?
(BTW, thanks Josergory & Tim! I didn’t get it till I read your comments!)
I have tried using sd_register_post_type( ‘movie’ ); inside another function which is called on a form submission — is this possible — it wouldnt work for me — maybe im doing something wrong?
( i am trying to make a form and button to register a new post type )
thanks for the class
@Bob
sd_register_post_type
must be called every time WordPress loads either from your plugin or theme’s functions.php file. It registers a number of hooks that make it work. If you want a form submission to work with it, you’d need to save an option that contains the post_type(s) you want to register. Grab that option’s contents and then use it to callsd_register_post_type
.I thank you for this great contribution to WordPress. Your class has found a home in my theme framework used in developing WP sites for my clients, it has been a big help.
In my particular usage I have updated your template filtering a bit. If the user is on an archive for a custom taxonomy, I added in some logic to see if it is assigned to the custom post type. If it is assigned to the custom post type we look to see if the appropriate template is available in the a sub directory named after the post type.
This goes hand in hand with what you had in place when checking for the single and index template files. Things are now setup in a manner to dynamically look at any template file coming in.
Have a look for yourself using the link below. If you see the added functionality is useful, feel free to include/adapt with the class you distribute. A hap tip in the code is all I require 😉
You can find the updated function at:
http://greaterweb.pastebin.com/g2dpTbRe
The overall goal is to have custom post type sub directories function in a similar manner as child themes do. I’m putting together similar functionality right now to look for a sidebar in the sub directory for the custom post type. I’m happy to send this your way for review once complete.
Made a small update. Simplified things when getting the post type:
http://greaterweb.pastebin.com/9p3ZYXku
awesome, totally awesome. i’m using it to build my first theme, when i’m finished i’ll send you a link.
i have one question tough, it appears that i cannot add Categories or Tags to my custom posts, i’ll search for something about it but if you can shed some light on this i’ll be grateful. thanks a lot
@dedos.info Post types and taxonomies are independent, but linked systems. There’s no reason that a custom post type should support any given taxonomy by default (such as the default category and tag taxonomies that are associated with the default “Post” post type), so my helper class won’t get you there.
The functions you want to pay attention to are
register_taxonomy
andregister_taxonomy_for_object_type
. The former is used for registering new taxonomies, while the latter is used for associating already existing taxonomies with a new post type and is therefore what you’re looking for.@Ron Thanks for your work on this. The taxonomy linking is definitely something that should be in there. Have you given any thought for what to do in the case of a taxonomy being registered for multiple post types?
Hi,
Im having an issue:
When permalinks are set to default, single post works, but going to domain.com/post-type returns a 404.
If I change the structure to anything else, it gets reversed: domain.com/post-type works, but single post displays does not.
Im stumped!
@MATT The same day I was working with the class I wrote a helper function to grab the post type. You can take a peak at the function here:
http://greaterweb.pastebin.com/fCGYBjLx
It does consider that very scenario that a taxonomy could be assigned to multiple post types. I haven’t adapted any sort of logic yet though as to which would be the appropriate template to serve up.
I will be revamping the template function to be a bit more aligned with your original approach. The flaw of my approach is that by the time the template gets to the function, it will be the lowest level in the template hierarchy such as a single.php, or archive.php. In reality it should better model WP. So in addition to looking for archive.php it looks first for taxonomy-term.php, taxonomy-taxonomy.php and taxonomy.php in our post type sub directory.
@Jeff Pretty permalinks need to be on, so it definitely won’t work with default permalinks. Otherwise, implement my code, go re-save whichever permalink type you’re using, and you should be good to go. Otherwise, I have no idea what’s going on.
@MATT Haven’t completely tested this yet but it seems to be the most comprehensive approach to filtering the templates for custom post types.
http://greaterweb.pastebin.com/URpfkJhM
Still doesn’t factor in if a taxonomy is assigned to multiple post types. It appears that calling get_post_type() in the context of a taxonomy archive will return the first post type assigned to that taxonomy. At that point it’s difficult to know which post type should take precedence over the other when grabbing the template.
Got it to work. For some reason when I create the created the directory for the custom post type to put the templates in, it would not work. So i moved movie/index.php to /movie.php and now it works. I dont need individual single.php templates, so this is okay.
Thanks!
@Ron Looks like some good work there. Re: multiple post types assigned to a taxonomy, we can only take a guess as to the author’s intentions. If they need more specific behaviour, they’ll have to code it themselves. I’ll get around to incorporating this when I have time.
One question: is the
is_attachment()
section actually necessary? An attachment has post_type attachment, so I don’t think you’d even make it into the big if loop.@MATT You are correct regarding
is_attachment()
, nice catch. I am probably going a bit overboard here but I’ve done a quick fix 🙂http://greaterweb.pastebin.com/NUFLYiJr
I would really love a custom post type sub-directory to function as a child theme would. Unfortunately though
get_header()
,get_sidebar()
andget_footer()
won’t play nicely. The only compromise seems to be having sidebar-post_type.php in the theme root and callingget_sidebar( 'post_type' )
. Any ideas on a better way to make this work?Loving the functions this class provides.
Question, how do I use a different template for the next pages? ie when next_posts_page() is clicked and directed to movies/page/2 I’d like a different template to use.
Cheers, Jeff
With Ron’s patches to the template_include() function of the class, I’m unable to get any archive pages for any of my custom post types.
I suspect I’m doing something stupid — but it would appear that for my archive pages, the template_include() function isn’t being called at all (tested by adding var_dump calls in several places throughout that function).
Should the archive pages work? I’ve had to do a fair bit of hacking so far throughout the core — seems custom post types aren’t integrated quite as nicely as they could be!
@Stephen Orr You may want to investigate the “slug” you are using for your post type directory name and archive urls.
A few things to consider for those having trouble getting archive templates to display properly.
When calling
sd_register_post_type()
it accepts an optional 3rd parameter. If this parameter is omitted the rewrite rule slugs will be created based on the first parameter. The class constructor adds and “s” to the post type slug passed in as the first parameter.So for example, if you create a custom post type movie like this:
sd_register_post_type( 'movie' );
The post slug becomes
movies
. This means your archive url needs to be http://your-domain.com/movies/.It also means you will need a sub directory in your theme named movies or at the minimum use movies.php in the theme root.
The confusing part can be for some that the arguments array (second parameter) allows you to set a slug such as this:
'rewrite' => array( 'slug' => 'movie' )
Even if you were to set your slug here the rewrite rules (at least for the basic archive) will be based on a plural version of the post type slug passed in as the first parameter.
Hope this helps 🙂
Small update to the constructor to check for the rewrite slug parameter.
http://greaterweb.pastebin.com/F6JCNunV
So rewrite slugs will first look for rewrite slug argument with a string value. If this is not present it looks at the the custom plural parameter. The fallback is a pluralized version of the post type slug passed in as the first parameter.
This time around we add in the rewrite slug argument for the instances where it is not included.
Cool code.
Would be nice if your code would be ready for the “GetText” translation method.
Here’s how to do just that » http://wpml.org/2009/05/wordpress-theme-localization/#wrapping_in_gettext_functions
Thank’s
I’m trying to add the menu icon parameter but I get a php error when I try and view the admin.
Here is the code block I modified:
[code]
private $defaults = array(
‘show_ui’ => true,
‘public’ => true,
‘menu_position’ => 5,
‘menu_icon’ => get_stylesheet_directory_uri().”/images/$post_type-icon.png”,
‘supports’ => array(‘title’, ‘editor’, ‘thumbnail’, ‘tags’)
);
[/code]
This works fine when I registered my own post types.
Thanks.
@Martin I’m aware of WP’s gettext methods and use them when appropriate, but there isn’t a single user-facing line of code here — it only works with what you give it. Feel free to pass in gettext’d strings in the 2nd parameter where appropriate.
Was able to get the custom parameters working using Josergory’s code above. I didn’t realize I needed to put the parameters in their own array and then call that in the second argument of the custom post registration.
Would it be possible to use a custom taxonomy as part of the url string?
Right now I have my custom post type using a static rewrite value, but it would be much more user friendly to be able to use a taxonomy value.
This is great — very good stuff, thank you.
Have you submitted it as a patch to the WordPress codebase? It’d be a very welcome core enhancement.
Also, have you considered updating your code here to include Ron’s work, which seems to make yours more complete with the taxonomy related code?
Thanks again.
Ron, I follow what you’re saying and did include the 3rd parameter. The problem is that when a second page is queried, it still uses the same custom post template (eg movies.php). How do you get it to fall back on something like movies-archive.php, or at least archive.php?
I’m building a newspaper website and would like the subsequent pages to just show lists of previous posts, largely unstyled.
Thoughts? Cheers!
@Ron — for the custom taxonomies URL, am I looking at
a) http://www.yoursiteurl.com/custom-post-name/custom-taxonomy-name/term-name
or
b) http://www.yoursiteurl.com/custom-taxonomy-name/term-name
Neither seem to be working with your version — however I feel I’m missing something.
Sorry @Ron — it was (b) — I’d mixed up my taxonomy name and slug in testing.
I’ve also updated the template_include() function to add support for taxonomy-xxx in the root theme folder, not just in the sub-folder:
http://paste2.org/p/940615
The subfolder approach is good, however I think it’s important not to enforce that approach, and to retain theme flexibility as with Matt’s original code.
I’m getting a blank page when trying to access the feed for a custom type. Tried flushing my permalinks — no dice. Anyone know a fix for that? Cheers
@Jeff Blake Have a look at this updated template function. I haven’t tested it out but it should do exactly what you are looking for.
http://greaterweb.pastebin.com/guNgxuJN
With this update, before it uses your custom post archive such as movies.php or archive.php, the script will first look for movies-page1.php or archive-page1.php. At a bit overkill once again but I set things up so you can use the
-pagePAGE_NUMBER
suffix format on any of the possible archive template files.So in your case, use movies-page1.php for the first page and movies.php for everything else.
Good luck!
Too cool — thanks for the class Matt. I’ve included it as part of a plugin framework I’m currently working on. I’ve also made a few small adjustments.
One you may be interested in involves adding year/month/day params to the rewrite rules (also takes paging and feeds into account) :
http://pastebin.com/Xr8QdNNx
So now you can have /movies/2010/ or /movies/2010/01/03/page/2/ and so on.
Thanks again — this really helped me out big time.
Works like a charm, thank you very much.
Does the construct function only work with PhP 5?
After researching, it does seem as this only works in a PHP 5 environment? Is that correct or am I missing something.
Wow, this was pretty groundbreaking. As the above user said, you actually created something that transforms WordPress into damn near a tried and true CMS. Thank you!
One thing I was hoping this would address is the Breadcrumb issue. Even when using this style of registering new Post Types, when I initiate any kind of Breadcrumb navigation, it never recognizes the structure. Example, I’d like a Breadcrumb trail to read:
Home –> Books –> Single Book
But if I create a new post using the post type of ‘Books’, my breadcrumb still reads:
Home –> Single Book
Do you (or anybody here) know of a way to get a Post Type assigned to a particular parent page or category so that Breadcrumbs function or a plugin that does this?
Or perhaps I am missing something essential about how WordPress works.
@Lars Sorry, but this won’t address breadcrumbs. Any WP breadcrumb plugin I’ve seen assumes 1) a page hierarchy and/or 2) a category hierarchy. My custom archives page isn’t something that they’d have any idea about — you’d have to code your own solution.
@Jacob a late reply, but yes, it’s PHP 5. I figure any one who’s bothering to find this code isn’t silly enough to be stuck on PHP 4.
I get stuck at wp-comments-post.php whenever i try to make a blog post. i don’t get it.
Hi Matt.
Congratulations. I need a help here please.
I am using custom post types for my portfolio. Everything works well, but page pagination. For example. In my portfolio page, I assigned it to shows 9 items(posts) per page. So, if you have for example 12 items, the pagination will be created. Then, when I try to go to the other page to view my other items, I received a 404 error with this URL (http://tmp.dev/portfolio/page/2)
Any idea here?
Cheers
Fixed here:
http://wordpress.org/support/topic/pagination-with-custom-post-type-listing?replies=25
Any updates on solving the issues with the feed? I’m getting a blank screen when visiting the rss. http://www.ubyssey.ca/news/feed
Thanks. Jeff
This is very helpful for those of use building sites using custom post types. I have added an additional function is_post_type that can be used like is_page.
An example would be is_post_type(‘event’) just to see if it is the custom type and then is_post_type(‘event’, ‘first-event’) to check for a specific entry.
I have put the code out here: http://pastebin.com/EvcUAZdq
Thanks a lot. You just saved my day. I’ve searched for way to handle this so long.
Once again, thank you — and keep up the good work
Hi there I am getting an error like this:
Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ‘}’ in /nfs/c05/h04/mnt/77939/domains/schooloftheapostolicchurch.com/html/wp-content/themes/360forged/inc/customposttype.php on line 43
The file is unchanged except for the file name
@Ant You are running PHP 4, and the script requires PHP 5.
Hi there is a small problem with the script. If I change the name of a post inside a custom post type the slug is not updated if I don’t run the Permalink update. From what I have understood this was necessary just for the initial custom type path and not for each post inside. What I am doing wrong?
Thanks
Trying to use this great class in combination with Kino Events Plugin: http://wordpress.org/extend/plugins/kino-event-calendar-plugin/ which uses Custom Post Types. I included the class using define(‘CHILDTEMPLATEPATH’, dirname(__FILE__ ) );
require_once( CHILDTEMPLATEPATH . ‘/sd_register_post_type.1.3.php’);
But I wonder how I can make this class with the already registered Kino Events Calendar Custom Post Type Events to have an index page. I would not need to register again I’d say. But how to add your class to this plugin generated Custom Post Type?
Works like a charm!
This is EPIC!
Thanks.
If only I’d found this site a few hours ago.
Now I want to check out Gregory’s mod. His is_post_type could come in handy. I know wordpress already has some built in functions for this but his solution looks a lot simpler to use.
WordPress 3.1 beta 1 now has index page for custom post types. See:
http://core.trac.wordpress.org/ticket/13818
Dou you have any plan to remove your own landing page functions?
@Yotsugi WP 3.1 basically makes what I’ve done here deprecated, except for where I alter the template structure to optionally use subdirectories.
@Matt
I have been using this function for months now and absolutely love it, esp the ability to use subdirectories and a separate template for the paged archives.
I do have one question:
I wanted to give the users the ability to switch their custom post-type archive template between one with sidebars and one without.
Normally this would be easy, as the user would create a new page and assign a template to the page.
However, using this script, when a user creates a page for the post-type archives, it is going to go and use the post-type/index.php archive page, no matter what template they choose.
So far I can’t even come up with a concept in my head of how to tackle this issue of giving them the ability to switch archive templates.
Do you have any ideas?
@david,
this may be a little on the quick and dirty side, but how about something like this at the top of your post-type/index.php (in psuedocode)
if ( option_sidebars_for_cust type ){
include (‘with_sidebar.php’)
}else{
include (‘no_sidebar.php’)
}
@Paul
LOL sometimes the easiest solutions are the hardest to see through the forest.
A little ‘hacky’ but it will work perfectly for what I need.
Thank you
I’m facing a problem that I can’t seem to solve when using this function.
How do I get my navigation to recognize the custom post-type index page as the ‘current page’.
Basically when I visit any other page on the website I built, the navigation will highlight the active page. This does not happen when viewing the custom post-type index or single view pages.
Ideas?
Thanks! This looks like the solution to all my problems.
Why does Automattic never think things through before they launch something?!
Having pagination of custom post type items is NOT an optional nice to have; it is something that everybody who uses custom post types will run into. Why did Automattic not see that coming?
I think WP 3.1 will have a custom post type index page. Will that solve these issues? Will it clash with this class?
What a mess…
@Peter I’m glad that this is going to help you. This class will be made obsolete by WP 3.1, although it implements things slightly differently. Mark McWilliams has the basic lowdown. I’d suggest you use WP 3.1 rather than my class if possible — it’ll be released soon.
Also: your complaints are lame and misinformed. WordPress is not made by Automattic, although they do contribute a lot of developer time to the project. I agree that this should have been in 3.0 already, but it was deemed too much for what was already a big release. Annoying, but understandable, and easily resolved with the bit of code I put up here.
@Matt (“Also: your complaints are lame and misinformed …”)
As far as I know Automattic decides when a feature is ready for release. I could be wrong about that; I’m not an insider following the day-to-day of WP development.
And that is the problem. For someone who is not a programmer, but just a content producer who actually uses WordPress on a project, this type of loose ends is really disruptive.
For me it is not easily resolved. I won’t have time to figure out your code for a while and/or figure out how it compares with the 3.1 solution.
@Peter: when Custom Post Types were introduced into WordPress 3.0, as they were a brand new feature it was decided to wait and see how the wider development and end user communities used them before packaging them up with loads of functionality.
This makes a lot of sense, otherwise it is all too easy to end up with a huge amount of bloat trying to satisfy every possible scenario and use-case.
Over time since then, it became clear that landing pages were in fact widely requested, so they are now being introduced.
In the meantime, we had great code from people like Matt and many others working with custom post types, which no doubt influenced what has now gone into v 3.1.
So I would argue the opposite of you: that Automattic thought things through very comprehensively before launch — resulting in a better, more stable, more useful, less bloated product.
You sir are the man. Thank you so much. Now I can create my loop of custom post types!
Thank you!
I must agree entirely with Simon. I find people are way too quick to get upset at open-source solutions. Here’s a novel concept: if you want a more comprehensive product with better support, go with a paid solution, plenty of those around.
Otherwise, have patience and understanding for the progression of this amazing piece of software that does so much for the community and yet asks very little.
“@Peter: when Custom Post Types were introduced into WordPress 3.0, as they were a brand new feature it was decided to wait and see how the wider development and end user communities used them before packaging them up with loads of functionality …”
I’m not asking for more functionality! My point is that releasing half-finished features gets non-programmers in trouble.
Again, anyone who uses custom post types in even the most basic form will run into this problem; no index, pagination doesn’t work.
I would rather have less functionality and be able to depend on that functionality. Automattic’s MO seems to be to pile up half-baked features, so I’m constantly fixing stuff that’s promoted as working out of the box.
@Peter You have moved from merely ignorant to tiresome. You’re still confusing Automattic and the WordPress project, and you’re assuming the a developer-focused feature (which custom post types are in both WP 3.0 & 3.1) should be foolproof for non-programmers. Wrong and wrong. If you’re going to bitch, bitch about something worth bitching about.
Matt, thanks for coding this and sharing. It’s been of great use to me so far, but I was wondering how one could extend your class to have category support. For example, how could this be extended to go to http://yourdomain.com/movies/category/horror of even, if it’s easier http://yourdomain.com/movies?category=horror.
I’m fairly new to understanding how filters and hooks work in wordpress. Is it as simple as adding a new line? Thanks in advance.
@Marc WordPress will try to rewrite category queries like http://example.com/movies/?category=comedy to http://example.com/category/comedy unless you’re using a custom taxonomy like “genre” instead of “category.” Then you could just do http://example.com/movies/?genre=comedy . If you’re using standard WP categories, you could also use http://example.com/category/comedy/?post_type=movie
You could prettify all that to ditch the query arguments, but you’d need to study what I’m doing in the add_rewrite_rules method and maybe learn some regex.
Is there any way to remove /page/ from pagination.. so there you’ll have only portfolio/2 instead of portfolio/page/2 ?
@Cippo Take out “/page” on line 112. It might not work though, especially if your archive slug and your single permalink slug are the same.
@MATT
Yes, I have already tried that but it isn’t working. The /page/ is still there.
@Cippo Don’t forget that the output of next_posts_link/prev_posts_link will use /page/. You’ll have to throw some filters in there or manually roll your own.
Thanks for the code. It made custom post types easier for me.
I have a question, now that WP 3.1 is out, Are you saying that this code is obsolete? Part of the beauty was the reusable class to easily add the post types. hmm, I’ll have to delve deeper into wp3.1 post types code. Do you have any suggestions for migrating the class to WP3.1?
Do not upgrade to WordPress 3.1 if you are using this class, all you posts will not work.
If someone knows how to fix that i appreciate any help.
Hi
Like i said before i upgrade my WordPress to 3.1, is there any way to save all the posts that i’ve created using this class? i don’t want to lose all my posts.
I’m so glad I stayed subscribed to this thread, or else I would have upgraded without knowing!
I just upgraded without a problem (3.1 is AWESOME, btw).
Basically I migrated my posts by re-registering all my post types using the standard WordPress class, so lets say I have a post type of ‘testimonials’, before it was:
——
sd_register_post_type(‘testimonial’,
array(
‘labels’ => array(
‘name’ => __( ‘Testimonials’ ),
‘singular_name’ => __( ‘Testimonial’ ),
‘add_new’ => __( ‘Add New Testimonial’ ),
‘add_new_item’ => __( ‘Add New Testimonial’ ),
‘edit’ => __( ‘Edit’ ),
‘edit_item’ => __( ‘Edit Testimonial’ ),
‘new_item’ => __( ‘New Testimonial’ ),
‘view’ => __( ‘View Testimonial’ ),
‘view_item’ => __( ‘View Testimonial’ ),
‘search_items’ => __( ‘Search Testimonials’ ),
‘not_found’ => __( ‘No Testimonials found’ ),
‘not_found_in_trash’ => __( ‘No Testimonials found in Trash’ ),
‘parent’ => __( ‘Parent Testimonial’ ),
),
‘singular_label’ => __(‘Testimonial’),
‘public’ => true,
‘show_ui’ => true,
‘capability_type’ => ‘post’,
‘hierarchical’ => true,
‘taxonomies’ => array( ”),
‘query_var’ => true,
‘rewrite’ => array( ‘slug’ => ‘praise’, ‘with_front’ => false ),
‘menu_position’ => 7,
‘supports’ => array(‘title’,‘comments’,‘trackbacks’)
)
);
I had to migrate it back to the original WordPress class to register a post type, so now it looks like:
function post_type_testimonial() {
register_post_type(‘testimonial’,
array(
‘labels’ => array(
‘name’ => __( ‘Testimonials’ ),
‘singular_name’ => __( ‘Testimonial’ ),
‘add_new’ => __( ‘Add New Testimonial’ ),
‘add_new_item’ => __( ‘Add New Testimonial’ ),
‘edit’ => __( ‘Edit’ ),
‘edit_item’ => __( ‘Edit Testimonial’ ),
‘new_item’ => __( ‘New Testimonial’ ),
‘view’ => __( ‘View Testimonial’ ),
‘view_item’ => __( ‘View Testimonial’ ),
‘search_items’ => __( ‘Search Testimonials’ ),
‘not_found’ => __( ‘No Testimonials found’ ),
‘not_found_in_trash’ => __( ‘No Testimonials found in Trash’ ),
‘parent’ => __( ‘Parent Testimonial’ ),
),
‘singular_label’ => __(‘Testimonial’),
‘public’ => true,
‘show_ui’ => true,
‘capability_type’ => ‘post’,
‘hierarchical’ => true,
‘taxonomies’ => array( ”),
‘query_var’ => true,
‘rewrite’ => array( ‘slug’ => ‘praise’, ‘with_front’ => false ),
‘menu_position’ => 7,
‘supports’ => array(‘title’,‘comments’,‘trackbacks’)
)
);
}
add_action(‘init’, ‘post_type_testimonial’);
I verified all my posts were still there, held my breath, did the upgrade and all is well now, didn’t lost any posts and now all my post types are using the 3.1 function.
Of course, I backed everything up first! 😉 Hope this helps you guys.
Hi Please help with WordPress 3.1, my post types are not working 🙁 please help
Hi if someone is interested i will pay to migrate this class to WordPress 3.1, i’m using this class in several websites and i don’t want to lose all my data.
if you are interested, send me an email: support@mcstudiosmx.com
I don’t get it…if you follow the steps I detailed above, you don’t need to pay for anything!
Just revert your post types back to the regular WordPress register_post_type function and then upgrade. Worked perfectly for me and I’m on 3.1 now.
Hi,
While browsing some custom post type tutorials I came across your class. I am using WP 3.1 and creating the custom post types works ok, but WP 3.1 doesn’t support the theme/[post_type]/single.php is this correct?
Regards
I’d just like to quickly thank you for linking to my article on the new Custom Post Type Archives introduced in WordPress 3.1 — It’s very much appreciated! 🙂
I love how something like what you guys did (along with others), and requests from users for this feature, inspired the WordPress Developers (IMO) to add this to the Core Code for everyone to use and take advantage of!
Hey MATT, great post though i have a query here.. as you have mentioned above that the following taxonomy permalink structure can be achieved if its categories:
“http://example.com/genre/comedy/?post_type=movies”
In my case i am using multiple taxonomies that are same for my different post types.. so what i need is when i call the function echo get_the_term_list in my single.php it should grab the above mentioned url for my post type “movies” and so on.
Hope you get my point!
Any help will be appreciated 🙂
@Marc WordPress will try to rewrite category queries like http://example.com/movies/?category=comedy to http://example.com/category/comedy unless you’re using a custom taxonomy like “genre” instead of “category.” Then you could just do http://example.com/movies/?genre=comedy . If you’re using standard WP categories, you could also use http://example.com/category/comedy/?post_type=movie
You could prettify all that to ditch the query arguments, but you’d need to study what I’m doing in the add_rewrite_rules method and maybe learn some regex.
will surely checkout this…thank you for sharing
You will never have to cut Free Gasoline coupons from the Sunday newspaper again!
Start saving the modern way with Free Gasoline Coupons online. Before you go grocery shopping,
simply visit one of the many online websites, such as one of our sponsors listed above,
select your favorite name-brand coupons, and print them out.
Each week they might change their coupons, but your savings could be as much as $25-$75!
Make sure you go through all their coupon pages so you don’t miss a deal with Online Gasoline Coupons.
Free Gasoline Printable Coupons 2012 http://tinyurl.com/gasoline1
Good post. I learn something new and challenging on blogs I stumbleupon on a daily basis.
It’s always interesting to read through articles from other authors and use something from their websites.
14 Trackbacks