3

I am using Timber with Wordpress (version 5.4.2). I have installed Timber's starter theme as a boilerplate.

Timber leverages the Wordpress template hierarchy allowing you to create a custom PHP file for a given route.

Page.php (default in Timber starter theme)

/**
 * The template for displaying all pages.
 *
 * This is the template that displays all pages by default.
 * Please note that this is the WordPress construct of pages
 * and that other 'pages' on your WordPress site will use a
 * different template.
 *
 * To generate specific templates for your pages you can use:
 * /mytheme/templates/page-mypage.twig
 * (which will still route through this PHP file)
 * OR
 * /mytheme/page-mypage.php
 * **(in which case you'll want to duplicate this file and save to the above path)**
 *
 * Methods for TimberHelper can be found in the /lib sub-directory
 *
 * @package  WordPress
 * @subpackage  Timber
 * @since    Timber 0.1
 */

$context = Timber::context();

$timber_post = new Timber\Post();

$context['post'] = $timber_post;

Timber::render( [ 'page-' . $timber_post->post_name . '.twig', 'page.twig' ], $context );

As per the comments in page.php and the Timber docs, I can create a custom PHP file to load a template for a given page by create it in the root directory of the theme (mytheme/my-custom-php-file.php)

But I will be creating a lot of custom PHP files for the project I'm working on - it would be pretty messy and hard to manage if I just drop them all into the root directory of the theme.

I would instead like to place these files into their own directory mytheme/src/. ex. mytheme/src/my-custom-php-file.php.

Currently, Timber/Wordpress will not recognize this file in this directory.

Where in Timber and/or Wordpress is the directory in which to look for pages' PHP files defined and how can I update this to indicate mytheme/src/?

yevg
  • 1,846
  • 9
  • 34
  • 70
  • Did you try this: https://timber.github.io/docs/guides/template-locations/ – Chris Haas Jun 23 '20 at 21:05
  • I read that doc but it looks like this refers to the location of twig templates only, but not the respective php files – yevg Jun 23 '20 at 21:07
  • Timber uses WordPress's template hierarchy: https://developer.wordpress.org/themes/basics/template-hierarchy/#single-page. You may want to check this out: https://developer.wordpress.org/reference/hooks/template_include/ – mikerojas Jun 23 '20 at 21:15
  • Ah, I see. If you are using their starter theme, then I think the only way to do that is to modify `index.php` to include your conditions, but it could get messy really fast, unless your pages/posts follow a pattern. For instance, if they are CPTs you can do something like `if(is_singular('news')){/*Logic here*/}` – Chris Haas Jun 23 '20 at 21:16

2 Answers2

4

This is possible, but a little differently than you might expect. You have to put all theme-related files to a subfolder, including functions.php and style.css. WordPress recognizes themes in subfolders.

So here’s what a possible structure could look like:

.
└── wp-content/themes/mytheme/
    ├── theme/
    │   ├── functions.php
    │   ├── index.php
    │   ├── page.php
    │   ├── single.php
    │   └── style.css
    ├── vendor/
    ├── views/
    ├── .gitignore
    ├── composer.json
    ├── package.json
    └── README.md

We’re putting the template files that WordPress needs into a theme subfolder. You can still put your views folder in the theme root, because Timber also looks for Twig templates in that folder.

In your functions.php file, you would then require your Composer dependencies from the parent folder:

require_once dirname( __DIR__ ) . '/vendor/autoload.php';

And there might be some other places where you would have to update paths.

We’re currently thinking about making this the default for the Timber Starter Theme (see this pull request).

Gchtr
  • 2,749
  • 2
  • 18
  • 28
-1

Looking at the template_include docs for I think you might be able to do something like this:

// functions.php
add_filter( 'template_include', function( $template ) {
    return 'src/' . $template;
}, 99 );

OR

// functions.php
add_filter( 'template_include', function( $template ) {
    if (// some condition) {
        return 'src/' . $template;
    }
    
    return $template;
}, 99 );
mikerojas
  • 2,238
  • 1
  • 4
  • 7
  • this is halfway there - I had to define `$template` in the callback function to set the correct path like this: `$template = str_replace('themes/mytheme/', 'themes/mytheme/src/', $template);` since `$template` seems to return the full path to the file. But now, my php file needs to be in *both* places (mytheme/ and /mytheme/src/) for it to load correctly. If I remove the php file from the theme root, Wordpress looks for `index.php` as per the hierarchy, but if I remove php file from `src/` nothing loads (no error but white page) - only file in _both_ places loads correct content – yevg Jun 24 '20 at 03:08
  • Magling `template_include` is the bad way. Please consider the answer of @gchtr – Szépe Viktor Jun 25 '20 at 18:02