Make WordPress Core

Opened 15 years ago

Last modified 6 years ago

#12877 new feature request

Modular themes: Apply template hierarchy to folders within a theme

Reported by: koopersmith's profile koopersmith Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Themes Keywords: has-patch dev-feedback
Focuses: Cc:

Description

Applying template heirarchy to folders within a theme will allow themes to be broken into modules, allowing theme developers to substantially reduce repeated code. This is an automated, complete version of the use of get_template_part() in Twenty Ten.

I've written posts on the justification for modular themes and their potential to transform theme organization.

Based on my tests, these functions should cause no noticeable difference in performance.

The patch has the added benefit of creating an accurate global $wp_template_hierarchy object (and a getter method), so any plugin/theme can access the template hierarchy for $wp_query.

The patch introduces several new functions: get_template_module($folder), get_template_hierarchy(), update_template_hierarchy(), and 2 private functions.

Finally, the patch also add a 'locate_template' filter on $template_names at the beginning of locate_template(), and turns the large conditional in template-loader.php into a function: template_loader().

Attachments (5)

12877.1.patch (6.9 KB) - added by koopersmith 15 years ago.
12877.2.patch (6.6 KB) - added by koopersmith 15 years ago.
12877.patch (4.0 KB) - added by scribu 14 years ago.
refresh
12877.4.patch (4.2 KB) - added by scribu 14 years ago.
use load_template()
12877.5.patch (4.2 KB) - added by scribu 14 years ago.
Don't include() directly in get_template_module()

Download all attachments as: .zip

Change History (54)

#1 @jane
15 years ago

  • Component changed from Template to Themes
  • Type changed from enhancement to feature request
  • Version set to 3.0

I think this is a big enough change to be labeled feature request. Have also added Themes as component.

#2 @koopersmith
15 years ago

  • Summary changed from Modular themes: Apply template heirarchy to folders within a theme to Modular themes: Apply template hierarchy to folders within a theme

Hah, the one time I spell hierarchy wrong, it's in the title and the first line.

#3 @nacin
15 years ago

Interesting concept. This is something that should be brought up when 3.0 is out the door.

Related on a much smaller scale: #11216.

Also, _prevent_template_include can become __return_false.

#4 @scribu
15 years ago

  • Keywords has-patch added
  • Milestone changed from Unassigned to Future Release

I like the idea too.

#5 @koopersmith
15 years ago

nacin: Didn't know about __return_false, thanks. Added.

Also, #11216 would be a nice addition. Currently, if using modules, you'd have to declare a page template in the root dir and redirect it to index.php (assuming you didn't want custom structure for the page template).

I expected this to be a 3.1 discussion (as per the @since blocks), but I figured I might as well bring it up now.

#6 @filosofo
15 years ago

I think this is a promising idea. Since it can be implemented via plugin, why don't you create the plugin and get a few theme developers to use it? Getting their feedback while it's still relatively malleable (in other words, as a plugin rather than in core) and seeing it used in practice would be among the best ways to demonstrate its worth as a core feature.

#7 @rovo89
15 years ago

  • Cc wordpress@… added

#8 @mikeschinkel
15 years ago

  • Cc mikeschinkel@… added

#9 @aaroncampbell
15 years ago

  • Cc aaron@… added

#10 @sbressler
15 years ago

  • Cc sbressler@… added

#11 @F J Kaiser
15 years ago

  • Cc 24-7@… added

+1
I would def. test it as a plugin at my themes. As far as i read your thoughts on your blog, i agree in most parts. My thoughts about it here (you got no comments on your blog):

  • Ptha Dunbars idea of get_template_file sounds better to me, because it's more flexible and better explains the idea of "get a module-file" to a not-pro-wp-user.

Just to describe another (not perfect) approach on this:
My custom version of a folder-module_file-approach differs in 3 basic folders in the root: /js/, /lib/ and /ui/. That makes it more easy to separate between script, styles&images and content.
Subfolders of /lib/ are /head/ (doctype and wp_enqueue_* script/style), /func/ (hooks, shortcodes, module-calling-file) and /mod/ (all different modules)
Everything just hooks into page-templates
As i sayed: not perfect and doesn't fit straight into template-hierarchy.

#12 @demetris
15 years ago

  • Cc dkikizas@… added

#13 @beaulebens
15 years ago

  • Cc beau@… added

#14 @willnorris
15 years ago

  • Cc willnorris added

really curious whatever happened to this idea. I'm sorry I stumbled upon it so late after it was proposed, since it now looks like it clearly won't be in 3.0. While it does make the theme structure *slightly* more complicated by adding a couple of folders, it makes everything significantly cleaner. Feels somewhat similar to how Carrington operates, but in a much more manageable (and easier to grok) fashion.

#15 @rspindel
15 years ago

  • Cc rspindel added

#16 @F J Kaiser
14 years ago

If i understood the patch right: The only draw back (of this first version) i can currently see is that the file($template_name) get_template_module($folder) searches for must be an exact match. That would only allow one file per template. If this would be a little extended with something like ex. a preg_match that works with some sort of hierarchical order (for ex. page-xy.php) this would be a nice addition that could make a lot of people pretty happy (looking at a lot of frameworks or theme-bases that work that way - see the list promoted by wordpress.org themself: all use something to get out of the flat scheme).

#17 @willnorris
14 years ago

@FJKaiser: I'm not sure I follow. get_template_module() supports all the same template file names that the normal template system supports. So if I call get_template_module('foo') during a request for an author page, then it will try to load the following template files, stopping at the first one it finds:

  • STYLESHEETPATH . "/foo/author-{$author}.php"
  • TEMPLATEPATH . "/foo/author-{$author}.php"
  • STYLESHEETPATH . "/foo/author-{$author_id}.php"
  • TEMPLATEPATH . "/foo/author-{$author_id}.php"
  • STYLESHEETPATH . "/foo/author.php"
  • TEMPLATEPATH . "/foo/author.php"

And if a plugin implements the author_template filter to provide an alternate template name, that will be applied to get_template_module() as well.

#18 @F J Kaiser
14 years ago

As i said "If i understood the patch right" ... thanks for explaining :)

#19 @willnorris
14 years ago

oops... the last part I mentioned about the 'author_template' filter is not correct. that would not actually effect the template files that get_template_module() looks for.

#20 @scribu
14 years ago

With the current patch, trying to alter the top-level hierarchy causes problems:

Say I want to add an 'author-{role}.php' top-level template. So, I hook into 'author_template':

function author_role_template( $old_template ) {
  // get current author's role

  $new_template = locate_template( array( "author-$role.php" ) );

  if( $new_template )
    return $new_template;

  return $old_template;
}

update_template_hierarchy(); will miss that, so you won't have access to "/module/author-editor.php" etc.

What would be needed is a filter applied to the array before it's passed to locate_template():

$templates = apply_filters( 'author_template_pre', $templates );

$template = locate_template( $templates );

Actually, I think that would be useful independent of the current proposal. I'll oepn a separate ticket.

#21 @scribu
14 years ago

And here it is: #14310

#22 @ramoonus
14 years ago

  • Cc ramoonus@… added

@scribu
14 years ago

refresh

#23 follow-up: @scribu
14 years ago

With the current patch, the template files are not loaded in the global scope anymore, causing all sorts of trouble.

Noticed this with the tag.php file in P2:

http://svn.automattic.com/wpcom-themes/p2/tag.php

Specifically, this line: <?php $tag_obj = $wp_query->get_queried_object(); ?>

#24 in reply to: ↑ 23 @nacin
14 years ago

Replying to scribu:

With the current patch, the template files are not loaded in the global scope anymore, causing all sorts of trouble.

I believe you're referring to the fact that core currently uses load_template() which extracts a ton of query variables into the global namespace. Yes, it would make sense for this to leverage that function.

@scribu
14 years ago

use load_template()

#25 @scribu
14 years ago

Indeed, using load_template() fixes the problem. See 12877.4.patch.

@scribu
14 years ago

Don't include() directly in get_template_module()

#26 @willnorris
14 years ago

One minor thing I added in my implementation was to include: $template_namess[] = $module . '.php' in get_template_module(), so that it behaves a little more similarly to get_template_part(). Because of this, I also renamed $folder to $module since it isn't strictly looking in a folder. So you end up with:

function get_template_module( $module ) { 
    $template_hierarchy = get_template_hierarchy(); 
    $template_names = array();
    foreach( $template_hierarchy as $template_name ) {
        $template_names[] = $module . '/' . $template_name;
    }
    $template_names[] = $module . '.php';
 
     return locate_template($template_names, true);
} 

This also makes a secondary use case of get_template_module() a lot cleaner. I break up my entry markup so that it is easier to override them in a child theme. (see: https://github.com/willnorris/pdx-theme/blob/master/loop/index.php). With this extra template name, I can simply have entry/title.php template files instead of needing entry/title/index.php.

#27 @azizur
14 years ago

  • Cc azizur added

#28 @svallory
14 years ago

  • Cc svallory added
  • Version changed from 3.0 to 3.1

#29 @scribu
14 years ago

  • Version 3.1 deleted

Since this isn't a bug, the version field isn't really useful.

#30 follow-up: @scribu
14 years ago

FYI: this has been implemented as a plugin:

https://github.com/willnorris/template-modules

And it would work too, if #14310 were fixed.

Last edited 14 years ago by scribu (previous) (diff)

#31 @GreenDude
14 years ago

  • Cc GreenDude added

#32 @gruvii
14 years ago

  • Cc gruvii added

You might want to look at some of the ways Carrington implemented a system like this that is now in version 3.1. I used it very extensively for a while and it has a great hierarchical template matching system.

http://carringtontheme.com/2010/11/carrington-core-3-1/

Last edited 14 years ago by gruvii (previous) (diff)

#33 in reply to: ↑ 30 @gruvii
13 years ago

Replying to scribu:

Scribu, will this or Will Norris's plugin work if I apply your #14310 patch?

Last edited 13 years ago by gruvii (previous) (diff)

#34 @scribu
13 years ago

Will Norris's plugin will work with the patch on #14310, yes. I'm currently using it on a live site.

#35 @scribu
13 years ago

Just wanted to throw in an alternative way of removing duplicate code:

http://scribu.net/wordpress/theme-wrappers.html

It's more restricted than template modules, in the sense that the template hierarchy isn't traversed again for each part.

#36 @ciobi
13 years ago

  • Cc alex.ciobica@… added

#37 @johnbillion
13 years ago

  • Cc johnbillion@… added

#38 @navjotjsingh
13 years ago

  • Cc navjotjsingh@… added

#39 @WraithKenny
13 years ago

  • Cc Ken@… added

#40 @bainternet
13 years ago

  • Cc admin@… added

#41 @emzo
13 years ago

  • Cc emzo added

#42 @retlehs
12 years ago

  • Cc retlehs added

#43 @aniketpant
12 years ago

  • Cc me@… added

#44 @mau
11 years ago

  • Cc ngomau@… added

#45 follow-up: @christianmagill
11 years ago

Is the mentioned plugin still current, and what needs to happen for this feature to be included in a future release. It seems really useful for ridding themes of duplicate code, but looks like it has been forgotten.

#46 in reply to: ↑ 45 @willnorris
11 years ago

Replying to christianmagill:

Is the mentioned plugin still current, and what needs to happen for this feature to be included in a future release. It seems really useful for ridding themes of duplicate code, but looks like it has been forgotten.

Obviously I haven't touched the plugin in several years, and don't actually use it myself anymore (I've moved to Genesis-based themes, which has its own way of doing things which I've really come to like). Though I'm not sure that much has changed in that time with regard to how theme templates work, so I suspect it's still "current" in the sense that it should still work. There certainly doesn't seem to be anyone strongly advocating for getting this into core anymore though.

#47 follow-up: @christianmagill
11 years ago

Thanks,

It's a shame, seems like a really great idea.

Would something like the ticket mentioned above,

https://core.trac.wordpress.org/ticket/14310

, allow the functionality to be added in a more future-proof way without duplicating the template selection logic?

#48 in reply to: ↑ 47 @willnorris
11 years ago

Replying to christianmagill:

Thanks,

It's a shame, seems like a really great idea.

Would something like the ticket mentioned above,

https://core.trac.wordpress.org/ticket/14310

, allow the functionality to be added in a more future-proof way without duplicating the template selection logic?

actually, it looks like I was already relying on the {$type}_template_hierarchy filter from #14310 which I believe was later reverted. So maybe my template-modules plugin doesn't work anymore after all.

#49 @chriscct7
9 years ago

  • Keywords dev-feedback added
Note: See TracTickets for help on using tickets.