PHPackages                             livy/plumbing-templates - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. livy/plumbing-templates

ActiveLibrary[Templating &amp; Views](/categories/templating)

livy/plumbing-templates
=======================

Put your page (or custom post type) templates in better directories. Works with Sage!

2.0.0(4y ago)194.3k1MITPHPPHP &gt;=7.3

Since Mar 14Pushed 4y agoCompare

[ Source](https://github.com/alwaysblank/plumbing-templates)[ Packagist](https://packagist.org/packages/livy/plumbing-templates)[ RSS](/packages/livy-plumbing-templates/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (1)Versions (5)Used By (0)

Template 👩‍🔧
============

[](#template-‍)

This tool gives you a way to improve the file organization of your [custom page templates](https://developer.wordpress.org/themes/template-files-section/page-template-files/#creating-custom-page-templates-for-global-use). For Wordpress 4.7+ you can also use templates for other post types.

It provides reasonable defaults that should work in most situations, but is also heavily configurable. Ships with built-in support for Sage 10. If you'd like to add built-in support for other frameworks with non-standard template organization, please file a PR or issue.

Usage
-----

[](#usage)

First, install the package:

```
composer require livy/plumbing-templates
```

Then call the tool like this, somewhere where it'll be run early (i.e. `functions.php`):

```
Livy\Plumbing\Templates\register_template_directory('custom-templates');
```

By default, the package assumes you're changing the template for the `page` post type, but you can specify *any* post type by passing a second parameter:

```
// Define templates for the `event` post type:
Livy\Plumbing\Templates\register_template_directory('event-templates', 'event');
```

Usually, you'll want to wrap this in an action call to make sure it runs early enough, i.e.:

```
add_action('init', function () {
    Livy\Plumbing\Templates\register_template_directory('event-templates', 'event');
});
```

### Advanced Usage

[](#advanced-usage)

This package has a number of other options that allow you to customize its behavior. You can use the project's filters to do this, but it may be easier to pass your arguments all at once. To do this, use `setup_template_location()` instead of `register_template_directory()`:

```
Livy\Plumbing\Templates\setup_template_location([
    'paths' => [ 'event-templates' ],
    'post_type' => 'event',
]);
```

...will have the same effect as the example above.

> The keys `paths` and `post_type` must be defined, or nothing will happen.

#### Options

[](#options)

The following is a list of all the options this package understands.

- `paths` *array* - An array of paths (relative to your template root) to search for templates. Default: empty array.
- `post_type` *string* - The post type to use these templates for. Default: `page`.
- `filename` *string* - Matched against filenames when searching for templates. Can be a string, simple glob (i.e. `*.ext`) or a regular expression. Default: `*.php`.
- `template_root` *string* - The template root, which is the directory that all template paths are relative to. It is unlikely you'll need to modify this value. Default: output of [`get_stylesheet_directory()`](https://developer.wordpress.org/reference/functions/get_stylesheet_directory/).
- `parent_template_root` *string* - Same as `template_root`, but for templates in a potential parent theme. Ignored if there is no parent theme. It is unlikely you'll need to modify this value. Default: Output of [`get_template_directory()`](https://developer.wordpress.org/reference/functions/get_template_directory()/).
- `contains` *string* - A string templates must contain. Can also be a regular expression. Used to identify what files are templates. Default: `Template Name:`.
- `name_regex` *string* - A regular expression to get the name of a template from its contents. Default: `/Template Name: ?(.+)/`.
- `post_type_regex` *string* - A regular expression to determine if a template applies to a particular post type. `%post_type%` will be replaced with the value of `post_type` option at runtime. Default: `/Template Post Type:.*%post_type%(?=(?:,|$))/m`.

### Acorn and Sage

[](#acorn-and-sage)

If you use the [v10+ of the Sage starter theme](https://github.com/roots/sage) or are using [Acorn](https://github.com/roots/acorn) in some other capacity, you know that your templates are stored in a slightly non-standard location. Fortunately this package [helpfully alters the defaults](https://github.com/alwaysblank/plumbing-templates/blob/56d06ec8ba7fa9dae52a047ef5893bc25ebdd81f/src/filters.php#L11-L17) if it detects that you're using Acorn.

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity29

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~442 days

Total

4

Last Release

1654d ago

Major Versions

1.1.0 → 2.0.02021-10-31

PHP version history (2 changes)1.0.0PHP &gt;=7.0

2.0.0PHP &gt;=7.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/45ef59bc24058cd989f522d8a6f8cc9b9aa31721b765d2b8552500dcc268e15d?d=identicon)[alwaysblank](/maintainers/alwaysblank)

---

Top Contributors

[![alwaysblank](https://avatars.githubusercontent.com/u/23412884?v=4)](https://github.com/alwaysblank "alwaysblank (32 commits)")

---

Tags

hacktoberfesttemplateswordpress

### Embed Badge

![Health badge](/badges/livy-plumbing-templates/health.svg)

```
[![Health](https://phpackages.com/badges/livy-plumbing-templates/health.svg)](https://phpackages.com/packages/livy-plumbing-templates)
```

###  Alternatives

[tightenco/jigsaw

Simple static sites with Laravel's Blade.

2.2k438.5k29](/packages/tightenco-jigsaw)[friendsoftwig/twigcs

Checkstyle automation for Twig

3586.1M61](/packages/friendsoftwig-twigcs)[twigstan/twigstan

TwigStan is a static analyzer for Twig templates powered by PHPStan

27412.1k](/packages/twigstan-twigstan)[iq2i/storia-bundle

UI Storia bundle

144.6k](/packages/iq2i-storia-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
