WordPress.org

Make WordPress Core

Opened 4 months ago

Closed 8 weeks ago

Last modified 8 weeks ago

#41717 closed defect (bug) (fixed)

WP_Theme::get_post_templates() fails to read parent theme

Reported by: JoelStransky Owned by: swissspidy
Milestone: 4.9 Priority: normal
Severity: normal Version: 4.7
Component: Themes Keywords: has-patch has-unit-tests commit
Focuses: Cc:

Description

Post Templates created in parent theme are not included when get_post_templates() is used in a child theme.

Create a post template in a parent theme

<?php
/**
 * Template Name: Audio Topic
 * Template Post Type: topic
 */

Then in child theme functions.php, call get_post_templates()

<?php
add_action( 'admin_init', function() {
  $log = wp_get_theme()->get_post_templates();
  error_log( print_r( $log, true ) );
} );

You will only see post templates whose .php files exist within the child theme root.

FIX:
In WP 4.8.1 wp-includes/class-wp-theme.php line 1045 (https://github.com/WordPress/WordPress/blob/master/wp-includes/class-wp-theme.php#L1006)
change:

<?php
$files = (array) $this->get_files( 'php', 1 );

to

<?php
$files = (array) $this->get_files( 'php', 1, true );

Attachments (2)

41717.diff (4.8 KB) - added by birgire 2 months ago.
41717.2.diff (4.5 KB) - added by swissspidy 8 weeks ago.

Download all attachments as: .zip

Change History (12)

#1 @swissspidy
4 months ago

  • Component changed from Posts, Post Types to Themes
  • Focuses administration template removed
  • Keywords needs-unit-tests added
  • Version changed from 4.8.1 to 4.7

That line is correct as is. It checks the current theme.

The get_page_templates() method calls get_post_templates() for the current theme and then the parent theme, if it exists. See https://core.trac.wordpress.org/browser/tags/4.8/src/wp-includes/class-wp-theme.php?marks=1101-1103#L1100.

I'm not sure if this behaviour actually changed in 4.7 or not, but it could definitely benefit from some unit tests.

#2 @JoelStransky
4 months ago

@swissspidy thanks for the reply but the line you reference only works for a single post type. I believe the goal of a method named get_post_templates would be to return every post template available throughout the theme. This functions as expected in the post metabox because it doesn't use get_post_templates(). I uses get_page_templates() because all it needs is the list for a single post type.

Right now the only way to get all post templates from child and parent is to use get_post_types() and loop over the results calling get_page_templates(null, $post_type) on each one.

#3 @swissspidy
4 months ago

  • Keywords needs-patch added

You're right, now I know what you mean. It probably was a bit too late yesterday for me :)

When fixing the get_post_templates method we can also remove the $post_templates += $this->parent()->get_page_templates( $post, $post_type ); line from get_page_templates() to clean things up a bit.

@birgire
2 months ago

#4 @birgire
2 months ago

  • Keywords has-patch has-unit-tests added; needs-unit-tests needs-patch removed

41717.diff patches what's been discussed above, with some additional tests.

#5 @swissspidy
2 months ago

  • Milestone changed from Awaiting Review to 4.9

This ticket was mentioned in Slack in #core by melchoyce. View the logs.


2 months ago

This ticket was mentioned in Slack in #core by jeffpaul. View the logs.


8 weeks ago

@swissspidy
8 weeks ago

#8 @swissspidy
8 weeks ago

  • Keywords commit added

#9 @swissspidy
8 weeks ago

  • Owner set to swissspidy
  • Resolution set to fixed
  • Status changed from new to closed

In 41975:

Themes: Show templates from both parent and child theme when calling WP_Theme::get_post_templates().

Props birgire for initial patch.
Fixes #41717.

#10 @swissspidy
8 weeks ago

In 41976:

Themes: Add files missed in [41975].

See #41717.

Note: See TracTickets for help on using tickets.