Make WordPress Core

Opened 14 years ago

Closed 14 years ago

#12105 closed enhancement (fixed)

Add support to get_single_template() for custom content types

Reported by: ptahdunbar's profile ptahdunbar Owned by:
Milestone: 3.0 Priority: normal
Severity: normal Version: 3.0
Component: Template Keywords:
Focuses: Cc:

Description

Using custom content types, it would be great to display single entries differently, based on their content type.

The new approach:

  • singular-post_type-slug.php
  • singular-post_type-id.php
  • singular-post_type.php
  • singular.php
  • single.php (for backwards compatibility)

Attachments (2)

singular_template_post_types.diff (1.1 KB) - added by ptahdunbar 14 years ago.
singular_template_post_types
singular-template.diff (1.4 KB) - added by greenshady 14 years ago.

Download all attachments as: .zip

Change History (15)

@ptahdunbar
14 years ago

singular_template_post_types

#1 @nacin
14 years ago

  • Keywords has-patch removed
  • Milestone changed from Unassigned to 3.0
When an item is_singular(), that means it is is_page()
is_attachment() is_single().

If we go this route, and it looks like a good idea, then we need to consider an expansion of the template hierarchy that spans all post types, including pages, attachments, and posts, to address various new template naming schemes.

You should check out how the other get_*_template() functions work. None invoke $wp_query IIRC.

It sounds like the best approach would be to create get_singular_template() that then does what it can and routes to get_page_template(), get_attachment_template(), and get_single_template() as necessary.

Setting to 3.0 in line with #9674.

#2 @ptahdunbar
14 years ago

"When an item is_singular(), that means it is is_page() is_attachment() is_single()."

You're right. This would require modifying template-loader.php. Is there a reason in the ordering of the if..else statements?

Working on a new patch.

#3 @greenshady
14 years ago

I propose that we leave the single template alone because that's directly related to the "post" post type. I'd love to see an alternate check for get_singular_template() after is_attachment(), is_single(), and is_page().

I don't believe is_single() should be true for anything but posts, but is_singular() should be true for all post types on singular views.

This should provide the functionality for a new singular template but also preserve backwards compatiblity with the old templating system for template-loader.php:

} else if ( is_attachment() && $template = get_attachment_template() ) {
	remove_filter('the_content', 'prepend_attachment');
	include($template);
	return;
} else if ( is_single() && $template = get_single_template() ) {
	include($template);
	return;
} else if ( is_page() && $template = get_page_template() ) {
	include($template);
	return;

/* New code. */
} else if ( is_singular() && $template = get_singular_template() ) {
	include( $template );
	return;

New get_singular_template() function:

function get_singular_template() {
 	global $wp_query; 

 	$id = (int) $wp_query->post->ID;

 	$templates = array(); 
 	$templates[] = "{$wp_query->post->post_type}-{$wp_query->post->post_name}.php"; 
 	$templates[] = "{$wp_query->post->post_type}-{$id}.php"; 
 	$templates[] = "{$wp_query->post->post_type}.php"; 
 	$templates[] = "singular.php";

 	return apply_filters( 'singular_template', locate_template( $templates ) ); 
}


I removed singular- from the beginning so this would match how pages are currently done. But, either way is fine with me.

#4 follow-up: @nacin
14 years ago

I think it would be best to have all single.php point to a new singular.php base (or post-type.php base).

The existing hierarchy would then become the following. Attachments:

{mime_type}.php
singular-attachment.php (new)
attachment.php
single.php
singular.php (new)

Posts:

singular-post.php (new)
single.php
singular.php (new)

Pages:

(custom template).php
singular-page-{slug}.php (new)
page-{slug}.php
singular-page-{id}.php (new)
page-{id}.php
page.php
singular.php (new)

Then a new branch would be:

(custom template).php
singular-{type}-{slug}.php
singular-{type}-{id}.php
singular-{type}.php
single.php
singular.php

Obviously my thought is that is_singular_template() could handle a lot of that before passing it off to the corresponding function (or just merge all three and have the other three call this one).

We've yet to incorporate ids and slugs into single.php lookups and that is probably for performance reasons and because it wouldn't be used that much.

To answer greenshady's comment which just came in as I was about to submit this:

I removed singular- from the beginning so this would match how pages are currently done.

Not prepending something could cloud the namespace a bit and possibly conflict with existing templates.

Also, having get_singular_template() below get_single_template() would always cause single.php to be used as that currently catches all custom post types. Really we just need to make sure we're adding on functionality in the right order, and newer and more specific templates should replace older and more general ones if available.

#5 in reply to: ↑ 4 @greenshady
14 years ago

Also, having get_singular_template() below get_single_template() would always cause single.php to be used as that currently catches all custom post types. Really we just need to make sure we're adding on functionality in the right order, and newer and more specific templates should replace older and more general ones if available.

Should that be true though? Should is_single() be true for custom post types? As far as I know, $wp_query->is_single isn't currently set for singular views of custom post types.

I could be wrong with that. If so, then we definitely need to move the check for the singular template up.

#6 @ptahdunbar
14 years ago

Related ticket: #12106

#7 @ptahdunbar
14 years ago

I definitely opened a can of worms here...

First off all, I'm reconsidering these two checks:

  • singular-{type}-{slug}.php
  • singular-{type}-{id}.php

For performance reasons.

I'm still suck on the ordering, which should come first, etc. Doing some testing before posting a new patch.

#8 @ryan
14 years ago

[13032]

That changeset looks for single-$post_type.php and then single.php. single-thing sounds better than singular-thing to me. If we look for slug and id templates, we should do so only for hierarchical post types. Hierarchical custom post types need a little more work.

We also need to consider how plugins can add customized output for their custom post types without requiring template changes. Maybe using existing hooks into the_content will suffice.

#9 @hakre
14 years ago

Do we have any numbers how expensive file_exists is? I mean we're adding more and more calls to it for each possible template name per request.

#10 @hakre
14 years ago

Related: #12248

#12 @nacin
14 years ago

I think this is good with just [13032], it's a good balance considering performance.

#13 @nacin
14 years ago

  • Resolution set to fixed
  • Status changed from new to closed
Note: See TracTickets for help on using tickets.