Make WordPress Core

Opened 6 years ago

Closed 6 years ago

#10959 closed defect (bug) (fixed)

Inconsistent handling of template files in subdirectories under theme directories

Reported by: eyelidlessness Owned by: westi
Milestone: 2.9 Priority: normal
Severity: normal Version: 2.8.4
Component: Template Keywords: has-patch subdirectory
Focuses: Cc:


If you place a template file in a subdirectory beneath a theme, the page editor detects these templates and they appear in the Template dropdown menu. The option value, however, does not include the subdirectory, and when saved, the page renders with the Default template (or presumably with a template of the same filename in the main theme directory, if present).


In file /path/to/theme/subdirectory/template-file.php /* Template Name: Foo */

Foo appears in Template dropdown menu in the page editor. Selecting Foo and saving is successful. Note that in the HTML of the editor page, the option value is simply "template-file.php", not "subdirectory/template-file.php".

The page in question renders with the default template, rather than the custom one.

Manually editing the entry in the database does result in the correct template file being loaded, so my suspicion is that this functionality is desired (it certainly is desired by me, for keeping files organized), but the value is not correctly being set.

Furthermore, editing the option value in the editor DOM to resolve to the correct path before saving results in the value not being saved at all.

Attachments (5)

page_templates.diff (460 bytes) - added by scribu 6 years ago.
child_templates.diff (532 bytes) - added by scribu 6 years ago.
In child themes, allow first level page templates to be used
themes.zip (1.9 KB) - added by scribu 6 years ago.
Parent & Child test themes
10959.diff (849 bytes) - added by scribu 6 years ago.
don't allow template files in subdirectories
10959.2.diff (1.0 KB) - added by scribu 6 years ago.
slight optimization

Download all attachments as: .zip

Change History (26)

comment:1 @scribu6 years ago

It may have something to do with this: #10467

@scribu6 years ago

comment:2 @scribu6 years ago

  • Keywords has-patch added; template removed
  • Milestone changed from Unassigned to 2.9

comment:3 @westi6 years ago

  • Owner set to westi
  • Status changed from new to reviewing

comment:4 @dremeda6 years ago

  • Cc dremeda added
  • Version changed from 2.8.4 to 2.9

I added a sub-dir with template and was able to successfully enable template on page.
Page correctly rendered template.

From admin page edit, drop down only displays template name not including sub-dir.

From Edit Themes page, neither the sub-dir or template are displayed so I cannot edit via editor.

comment:5 @dremeda6 years ago

  • Version changed from 2.9 to 2.8.4

comment:6 @westi6 years ago

Added a test case for this to the Unit Tests - http://svn.automattic.com/wordpress-tests/wp-testcase/test_admin_includes_theme.php

Going to commit a fix as well with a subtle change to make the code more testable.

comment:7 @westi6 years ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

(In [12187]) Ensure that page templates in a subdir of a theme work correctly. Fixes #10959 based on patch from scribu.

comment:8 @greenshady6 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

This change breaks page templates in child themes. In the str_replace() function, we are only replacing the get_template_directory() (parent theme) with ''. But, child themes also have their own page templates sometimes. So, we also need to remove get_stylesheet_directory() (child theme).

Maybe a change to this on line 141:

$page_templates[trim( $name )] = str_replace( array( get_stylesheet_directory(), get_template_directory() ), '', $template );

On a slightly-related note: Should page templates be recognized in sub-directories within the child theme?

comment:9 @scribu6 years ago

greenshady, your solution does fix the regression with first level child templates. I've attached the child_templates.diff patch.

On a slightly-related note: Should page templates be recognized in sub-directories within the child theme?

I think they should.

@scribu6 years ago

In child themes, allow first level page templates to be used

@scribu6 years ago

Parent & Child test themes

comment:10 follow-up: @westi6 years ago

Could someone test this on 2.8.6 and report back what does/doesn't work?

It would be really nice to work out what the regression is so we can fix it correctly.

What I am wondering is:

  • For a normal theme do these templates work in 2.8.6
  • For a child theme do these templates work in 2.8.6

The reason being - I wondering whether or not we need to support page templates in a subdir at all.

comment:11 in reply to: ↑ 10 @scribu6 years ago

Replying to westi:

The reason being - I wondering whether or not we need to support page templates in a subdir at all.

Regardless if it's a regression or not, I think it's a good ideea in and off itself.

Either allow page templates in subdirectories, or don't show them as an option in the dropdown.

comment:12 @greenshady6 years ago

In WordPress 2.8.6, templates are recognized in the top level of the directory for both parent and child themes. With the last committed code, get_template_directory() is removed from the template file name. By doing this instead of using basename( $template ), templates in child themes are recognized but still have the full path in front of the file name when added as a meta value to _wp_page_template. It should only be the file name itself.

If we go this route, we need to also remove get_stylesheet_directory() from the template name so that child theme templates are loaded correctly on the front end.

The original problem in this thread is that templates are recognized in sub-directories in parent themes (but not child themes). Since the get_page_templates() function removes the path, only the file name is used as the _wp_page_template meta value. This causes a problem when loading the template on the front end because WordPress will be looking for it in the top level of the theme directory instead of in the sub-directory.

Possible solutions:

1) Don't recognize templates in sub-directories at all.
2) Recognize templates within sub-directories of both parent and child themes.
3) Fix the last committed code to at least allow templates in a child theme to work as before.

comment:13 @westi6 years ago

(In [12225]) Revert [12187] as it didn't fix the issue for all cases. See #10959.

comment:14 @westi6 years ago

  • Keywords has-patch removed

I have reverted the original change.

I think we should just not support template files in a subdir at all which will mean fixing different code.

They didn't work in 2.8.6 either

Will discuss at this weeks dev chat.

comment:15 @westi6 years ago

Relates to #4131 it seems where the searching in subdirs was introduced.

comment:16 @westi6 years ago

Looks like this was introduced intentionally need to spend some more time on a new patch which works with child themes too.

comment:17 @scribu6 years ago

child_templates.diff would work correctly if #4131 had taken child themes into consideration.

Currently, /child/pages/child-second.php isn't returned by get_themes();

See themes.zip

@scribu6 years ago

don't allow template files in subdirectories

comment:18 @scribu6 years ago

  • Keywords has-patch added

In case fixing get_themes() turns out to be a daunting task, I added a fallback patch that resolves the current ticket by not showing template files in the dropdown.

comment:19 @scribu6 years ago

  • not showing template files... in subdiredctories, I mean.

@scribu6 years ago

slight optimization

comment:20 @westi6 years ago

I think we should remove them from the dropdown for now as they have never been functional.

I have opened a ticket for the future to make them functional - #11216

comment:21 @westi6 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

(In [12253]) Don't show page templates in the drop down if they are in a subdirectory. Fixes #10959 props scribu.

Note: See TracTickets for help on using tickets.