WordPress.org

Make WordPress Core

Opened 5 years ago

Closed 5 months ago

Last modified 5 months ago

#16264 closed feature request (wontfix)

Add function get_pages_by_template()

Reported by: mikeschinkel Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.1
Component: Posts, Post Types Keywords: needs-refresh close
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 5 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 5 years ago.
Updated get_pages_by_template()

Download all attachments as: .zip

Change History (21)

@mikeschinkel
5 years ago

Adds get_pages_by_template() and fixes a phpdoc comment typo

#1 @mikeschinkel
5 years ago

  • Keywords has-patch added

#2 @mikeschinkel
5 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.

@mikeschinkel
5 years ago

Updated get_pages_by_template()

#3 @mikeschinkel
5 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 5 years ago by mikeschinkel (next)

#4 @F J Kaiser
5 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.

#5 follow-up: @nacin
5 years ago

menu_order doesn't have an index.

#6 in reply to: ↑ 5 @F J Kaiser
5 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.

#7 follow-up: @chriscct7
18 months ago

  • Keywords needs-refresh added; has-patch removed

#8 in reply to: ↑ 7 ; follow-up: @MikeSchinkel
18 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?

#9 in reply to: ↑ 8 ; follow-up: @helen
15 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.

#10 in reply to: ↑ 9 ; follow-up: @MikeSchinkel
15 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?

#11 in reply to: ↑ 10 ; follow-up: @helen
15 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.

#12 in reply to: ↑ 11 @MikeSchinkel
15 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'?

#13 follow-up: @F J Kaiser
15 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 15 months ago by F J Kaiser (previous) (diff)

#14 in reply to: ↑ 13 @MikeSchinkel
15 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 15 months ago by MikeSchinkel (previous) (diff)

#15 follow-up: @wonderboymusic
8 months ago

  • Keywords close added

I have been staring at the Posts, Post Types component for 5 days now - half of the tickets are related to listing pages and how badly that can perform. I am not inclined to support more uses of Meta Query in core, or at all.

#16 in reply to: ↑ 15 @MikeSchinkel
8 months ago

Replying to wonderboymusic:

I have been staring at the Posts, Post Types component for 5 days now - half of the tickets are related to listing pages and how badly that can perform. I am not inclined to support more uses of Meta Query in core, or at all.

Caching the information in wp_options could ensure the use-case is performant.

Last edited 8 months ago by MikeSchinkel (previous) (diff)

#17 follow-up: @swissspidy
5 months ago

Caching the data in an option could work. Though I don't really see a reason to have this function when it's so easy to get the information anyway using WP_Query.

If a theme needs this information, they can have their own function doing this.

#18 @johnbillion
5 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

It's fine to keep narrow use case functions such as this within themes or plugins.

#19 in reply to: ↑ 17 @MikeSchinkel
5 months ago

Replying to johnbillion:

It's fine to keep narrow use case functions such as this within themes or plugins.

I did not get a chance to respond before you closed it.

Replying to swissspidy:

Though I don't really see a reason to have this function when it's so easy to get the information anyway using WP_Query.

Once again I will ask do we really not want to encapsulation the how to get this information into the WordPress API vs. requiring someone who wants to do this to hardcode '_wp_page_template' and a meta query? Not having them hardcode this would make the implementations easier to change later if needed.

As to "I don't see people doing this" let me ask, do you see people writing code that hardcodes logic to specific slugs, or worse, to specific post IDs? I've seen lots of site code and also lots of articles online showing people how to do that.

For example, someone writes a WP_Query that hardcodes the page ID for a pricing page into a check for whether to modify a query based in 'pre_get_posts'. With this function they could instead hardcode the page template filename and modify the query when that matched.

Tying to page templates instead of slugs and post IDS is a more for robust solution. And I would expect the reason most people who tie to slugs and post IDs do so because it does not occur to them that there is a better way. If this function where built-in and and blogs posts about it existed, it might occur to them to do it more robustly.

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