Skip to content

Timber template hierarchy#281

Closed
mgmartel wants to merge 251 commits intotimber:devfrom
mgmartel:template-autoloader
Closed

Timber template hierarchy#281
mgmartel wants to merge 251 commits intotimber:devfrom
mgmartel:template-autoloader

Conversation

@mgmartel
Copy link

@mgmartel mgmartel commented Jul 3, 2014

Now that the query is added to the context by default (#277), the WordPress template files often just repeat the same melody.. get context and render a twig file with pretty much the same name as the php template.

So I quickly put together this PR (which is a proof-of-concept for discussion), which adds a template loader to the default WP template loading that loads twig templates according to the same logic as the WP template hierarchy if no php template is found.

It checks what the query is for, and checks if an appropriate twig template exists in any of the Timber locations, exactly as the WP Template hierarchy does. If a twig template is found, it is rendered using
the default context (Timber::get_context()).

For example, if the query is for a single post of the portfolio post type, the following files will be looked for:

  • child-theme/single-portfolio.php
  • parent-theme/single-portfolio.php
  • child-theme/single.php
  • parent-theme/single.php

..and then..

  • child-theme/views/single-portfolio.twig
  • parent-theme/views/single-portfolio.twig
  • child-theme/views/single.twig
  • parent-theme/views/single.twig

...and then...

  • child-theme/index.php (NB!)
  • parent-theme/index.php
  • child-theme/views/index.twig
  • parent-theme/views/index.twig

As a proof-of-concept, I have included a naked version of the starter theme in this PR, so you can see that the sites can actually run without template files :)

A few notes:

  • Themes are required to have an index.php, so the code in the PR checks the index.php in a hacky way: if {template}.twig is not found, it renders the found index.php and sees if there is any output. If there is output, it will use index.php. If there's no output, it will continue looking for index.twig. (there is a filter to override this) We may have to think this through.
  • I added a filter on the context as loaded by the template loader. That way, developers can choose to do away with php template files while still adding contextual context (ahem.) by filtering template loader context and adding stuff based on the global query vars (for example, author info on author archives).
  • The code filters on the get_index_template function. If a timber template is found, it is rendered and the filter returns false. WP will then simply not include a template file... unless a plugin has filtered template_include to use its own templates (WooCommerce? BuddyPress?). This is something test and perhaps find solution for...

Let me know if you agree this is a valid strategy, then I'll work it out some more and write tests.

@mgmartel
Copy link
Author

mgmartel commented Jul 3, 2014

Ok, I did some more tinkering and added a public method that can be used from within php templates as well. Now, to add any extra context, you can use a php template file and let the TemplateLoader take care of finding the right template, again, like the WP template hierarchy:

// author.php
$context = array();
$context['author'] = new TimberUser( get_the_author_meta( 'ID' ) );
$context['title'] = 'Author Archives: ' . $context['author']->name();

TimberTemplateLoader::load_template( $context );

Makes for quite elegant template loading! The API needs some thought - maybe this should be merged with TimberView? (#261) It could perhaps be used when TimberView::render or TimberView::compile are called without arguments.

@jarednova jarednova closed this Jul 6, 2014
@jarednova jarednova reopened this Jul 6, 2014
@jarednova
Copy link
Member

Sorry, when I deleted the dev branch, GitHub tried to close this. Re-opened and going through now.....

slimndap and others added 25 commits July 11, 2014 12:10
Makes it easier to add support for plugins that like to mess with the loop (eg. BuddyPress). 

This way you can add support for popular plugins by writing small plugins/extensions like this:
https://github.com/slimndap/TimberBuddyPress

No need to add any hacky code to you theme anymore!
* master: (52 commits)
  additional test for route; fixing some phpdoc pieces
  fixed issue with missing menu classes and test to ensure it doesn't happen again timber#288
  allow 2nd argument of TimberPost::get_terms to be class
  investigated error reported by slimndap. Wrote test to cover so it doesn't happen again. Close timber#287
  Correctly test date filter support for DateTime objects
  restored test to make sure undefined properties don't throw errors
  don't allow null things to be iterated over, force them to be empty arrays when null
  more deprecation notes, test for pagination in category
  updated change log
  added .name to all links in pagination numbers; updating version to 0.20.0
  disable open_basedir test for coveralls
  remove open_basedir setting after test
  another tweak to openbasedir test
  tweak to openbasedir test
  more tests for children; resolved issue for getting the originating object's data
  only fetch travis badge for master
  verified timber#276 with additional tests. close timber#276
  started some tests
  fixed issue with id timber#276
  Added unit tests for page links
  ...
…o potentially spin it out into a sep. repo/project
…tch-1

* 'patch-1' of github.com:slimndap/timber:
  Add a filter to TimberPostGetter::get_posts
fix minor typos in theme template commments
My Timber-generated pages were failing HTML validation due to some improperly closed standalone tags. This changes those tags to the correct formatting. I left the close slash for backward compatibility with XHTML. There may be other tags, but these were the ones that quickly came to mind.
…ord-admin-notices

* 'admin-notices' of github.com:andyford/timber:
  Use admin_url() in 'Timber not activated' message in case WP installed at custom path
* andyford-admin-notices:
  placing path inside of admin_url() function
  Use admin_url() in 'Timber not activated' message in case WP installed at custom path
* 'patch-1' of github.com:discern/timber:
  Update timber-helper.php
Mike Martel and others added 18 commits February 17, 2015 10:13
… the constant TimberLoader::AUTOLOAD_TEMPLATE is passed
…h overloading and the TimberLoader::AUTOLOAD_TEMPLATE constant
This way it's called every time the context is queried. Let the filter decide if it wants to cache its part of the context or not.
@mgmartel mgmartel force-pushed the template-autoloader branch from 70748ea to c316729 Compare February 17, 2015 06:44
@mgmartel
Copy link
Author

Hi @jarednova,

We have left this one hanging for much too long now! I have rebased template-autoloader on master and made sure everything is still working. All unit tests are still passing and all my Timber projects are still working as they should, so this is still good to go as far as I'm concerned.

It's been a while, so here is a recap of what's included in this PR:

  • Template loader to automatically load the correct of twig template with default context according to template hierarchy (making php templates optional)
  • Template autoloader is disabled by default, can be enabled by setting Timber::$twig_template_hierarchy = true;
  • WooCommerce compatibility, without header.php / footer.php hack
  • Manual render call for php templates with autoloader possible with simplified syntax: Timber::render( $context ); (no need to pass in the $filenames paramter)
  • Themes can include a context.php file, which will be used to load default theme context. The $context array is directly available in context.php.

At the time, I made an opinionated started theme for Timber that relied heavily on the template autoloader. I didn't push it to GitHub then because I figured I'd wait for this to be merged into master. I spent some time reviving it, and I think it's also pretty powerful stuff. If anything, it's a good demo of what the template autoloader can do. I finally pushed it to GitHub just now: https://github.com/mgmartel/timber-regions

I used it to build a proof-of-concept Foundation theme based on Timber, which I'll also push some time this week.

What are your thoughts about bringing this to master?

Mike

@jarednova jarednova closed this Jun 18, 2015
@lkraav
Copy link

lkraav commented Jun 18, 2015

@jarednova is this door shut now? what triggered the close?

@jarednova
Copy link
Member

That was not intentional. I cleaned-up some stale branches this AM, but this one says it's still open. Hmm......

@jarednova jarednova reopened this Jun 18, 2015
@jarednova jarednova closed this Aug 14, 2015
@mgmartel
Copy link
Author

Hi @jarednova,

Accidental close again? Just finished another Timber site using the template loader (here) and still convinced that this is the way to go for theme development with Timber. The theme is mostly twig templates, as opposed to a mess of PHP files.

I just added some more commits to this branch:

  • Added support for page templates (this needs a PHP counterpart to show up in the page template selector, but it doesn't have to contain any code)
  • WP 4.3 introduced singular.php, this now has singular.twig support

Do you have any plans of merging this into master? If so, I'll rebase again!

Cheers,
Mike

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.