WordPress.org

Make WordPress Core

Opened 4 years ago

Last modified 2 months ago

#16264 new feature request

Add function get_pages_by_template()

Reported by: mikeschinkel Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 3.1
Component: Posts, Post Types Keywords: needs-refresh
Focuses: Cc:

Description

This patch adds a function get_pages_by_template() to /wp-includes/post.php. It accepts a page template string and returns an array of post objects keyed by the pages that use the template:

$pages = get_pages_by_template( 'page-about.php' );

Using WordPress for CMS I've been finding a need to provide links to specific pages in a more robust way than hardcoding their post_id or even referencing their post_name/URL slug and the way I've identified that works well is to locate a page by it's page template. Here a function that a theme might write that would use the function I'm proposing be added:

function get_about_page_link() {
  $pages = get_pages_by_template( 'page-about.php' );
  if ( count( $pages ) )
    return get_page_link( get_post( $pages[0] )->ID);
  return false;
}  

Unfortunately WordPress does not have efficient functionality in core that would allow a themer to lookup a page or a list of pages by their templates thus requiring the theme developer to resort to SQL which is ideally avoided.

Thus I'm providing this patch to enable a themer to do this lookup without having to resort to SQL.
The patch also fixes a typo that affects phpdoc in the same file: @parem => @param.

Attachments (2)

get_pages_by_template.diff (1.3 KB) - added by mikeschinkel 4 years ago.
Adds get_pages_by_template() and fixes a phpdoc comment typo
get_pages_by_template-v2.diff (1.2 KB) - added by mikeschinkel 4 years ago.
Updated get_pages_by_template()

Download all attachments as: .zip

Change History (16)

@mikeschinkel4 years ago

Adds get_pages_by_template() and fixes a phpdoc comment typo

comment:1 @mikeschinkel4 years ago

  • Keywords has-patch added

comment:2 @mikeschinkel4 years ago

Just as soon as I post this I realized that there is a way to get this without SQL. I'll upload another patch which will limit the justification for why this should be added, taking it from a must-have to a nice-to-have.

@mikeschinkel4 years ago

Updated get_pages_by_template()

comment:3 @mikeschinkel4 years ago

I've just uploaded another version that uses WP_Query instead. It loosed the ability to lookup with a SQL LIKE and to return the values keyed by post ID but it also uses built-in functionality and is probably faster.

Version 0, edited 4 years ago by mikeschinkel (next)

comment:4 @F J Kaiser4 years ago

I guess it would make more sense to set the default orderby value to menu_order as this will IMHO be used for menus mostly(?) and therefore should order by the default setting. Ordering by date sounds like an archive job.

comment:5 follow-up: @nacin3 years ago

menu_order doesn't have an index.

comment:6 in reply to: ↑ 5 @F J Kaiser3 years ago

Replying to nacin:

menu_order doesn't have an index.

I know. But post_date doesn't make sense for pages. Further: You (hopefully) won't have thousands of pages.

comment:7 follow-up: @chriscct76 months ago

  • Keywords needs-refresh added; has-patch removed

comment:8 in reply to: ↑ 7 ; follow-up: @MikeSchinkel6 months ago

Replying to chriscct7:

Can you give some direction? What about the patch needs to be refreshed? And does this mean it is being considered?

comment:9 in reply to: ↑ 8 ; follow-up: @helen2 months ago

Replying to MikeSchinkel:

Can you give some direction? What about the patch needs to be refreshed? And does this mean it is being considered?

It means that the patch doesn't apply, so would-be testers can't take it for a spin.

I don't see that this is a difficult helper function to implement when you need it (I mean, you've already written it here in the patch), and I'm not sure how many others are really looking for such a thing. I'm sure you personally use it frequently enough, but would like to gauge other developer interest as well.

comment:10 in reply to: ↑ 9 ; follow-up: @MikeSchinkel2 months ago

Replying to helen:

I don't see that this is a difficult helper function to implement when you need it (I mean, you've already written it here in the patch),

Well, the biggest reason for the request was the 4 years ago I was trying to avoid the need for hardcoded SQL. IOW I was hoping to see the hardcoded SQL be baked into WordPress core where it can be become part of the documented API. For example, for a project I am working on I was just reviewing 10up's code audit standards where it says "Overview of the Top 10 things we look for/ 2) Direct database queries / querying the database directly." So I wanted to be able to performantly query the database without using custom SQL.

That said, the 2nd patch avoided custom SQL but is heavy compared with an optimized version of the patch which I could now write if there is any reason for me to make the effort (I've gotten much better with the WordPress API in the past 4 years and could improve this patch quite a bit.)

I'm not sure how many others are really looking for such a thing. I'm sure you personally use it frequently enough, but would like to gauge other developer interest as well.

I have no idea how many others use it either, and maybe they don't.

But if not I would wonder if they in fact should learn to do so? Effectively a page template implicitly defines a "Page Type" and we are constantly running into the need to create different page types. On every full site project we've ever worked on, actually.

It would seem that our use-cases can't be that unique but maybe the reason others don't do this is because they only see a nail (i.e. taxonomies) when core only provides them a hammer (i.e. no page types.)

FWIW?

comment:11 in reply to: ↑ 10 ; follow-up: @helen2 months ago

Replying to MikeSchinkel:

I have access to those standards, but others probably don't (private site) :) I'm fine with leaving this ticket open and assessing demand, whether proactively or not, but my feeling based on code I've written and audited is that this is not in high demand, not so bad via a WP_Query (noting that a tax query typically performs better than a meta query, for what that's worth), and thus IMO reasonably left to be implemented as a helper function as needed.

comment:12 in reply to: ↑ 11 @MikeSchinkel2 months ago

Replying to helen:

I'm fine with leaving this ticket open and assessing demand, whether proactively or not,

Thanks.

(noting that a tax query typically performs better than a meta query, for what that's worth),

You are aware that page templates are stored by WordPress core as post meta fields with a key of '_wp_page_template'?

comment:13 follow-up: @F J Kaiser2 months ago

I'd at least vote to return the full \WP_Query object and not just the $result->posts property. Having access to the WP loop with if ( have_posts() ) is a bonus and it's usage should be encouraged.

The filter itself imho is useless. There's pretty much no chance to really pinpoint a specific call in its current state. Every callback would affect any call to the function everywhere. If there really has to be a filter, then I'd at least add the template name as second arg.

About the arguments: I'd drop the .php extension from the input. That could - if there really needs to be a filter - also used as second arg on the filter. And I still believe that menu_order would be much more appropriate than using a publish date for orderby.

Last edited 2 months ago by F J Kaiser (previous) (diff)

comment:14 in reply to: ↑ 13 @MikeSchinkel2 months ago

Replying to F J Kaiser:

I'd at least vote to return the full \WP_Query object and not just the $result->posts property. Having access to the WP loop with if ( have_posts() ) is a bonus and it's usage should be encouraged.

Hmm. In that case I'd argue for $args['output'] where the default is $result->posts as I don't see it likely that this function would be used with The Loop.

The filter itself imho is useless. There's pretty much no chance to really pinpoint a specific call in its current state. Every callback would affect any call to the function everywhere. If there really has to be a filter, then I'd at least add the template name as second arg.

Sure.

About the arguments: I'd drop the .php extension from the input. That could - if there really needs to be a filter - also used as second arg on the filter. And I still believe that menu_order would be much more appropriate than using a publish date for orderby.

Sure.

Last edited 2 months ago by MikeSchinkel (previous) (diff)
Note: See TracTickets for help on using tickets.