You already know direct output because it simply means printing output directly, as you might do in any other PHP script.

Benefits of direct output

Direct output is perhaps the easiest to understand output strategy because it's essentially the same strategy that you would use in any HTML document or existing PHP script. There isn't really anything ProcessWire-specific about this strategy as it is simply writing markup and using PHP tags to output dynamic content in the appropriate places. When you have markup or code that you'll be reusing in multiple locations, then you simply put that markup in another file and use PHP include() or require() statements to include it.

How to use direct output

When a template file is used as direct output, the only difference between a template file and an HTML file is that you can use some PHP in there when you want to. Here is an example of a template file using direct output:

/site/templates/basic-page.php

<html>
  <head>
    <title>Hello World</title>
  </head>
  <body>
    <h1>Hello World</h1>
    <p>How do you like my HTML document?</p>
  </body>
</html>

There literally isn't any difference between that and a regular old HTML document. Lets go a little further and throw in some PHP so that the output of the <title> tag, <h1> tag and body copy are dynamic, coming from the $page being viewed:

/site/templates/basic-page.php

<html>
  <head>
    <title><?php echo $page->title; ?></title>
  </head>
  <body>
    <h1><?php echo $page->title; ?></h1>
    <?php echo $page->body; ?>
  </body>
</html>

Simply by adding <?php echo $page->title; ?> where we want to output the page's title, and <?php echo $page->body; ?> where we want to output the page's body, are all that is necessary to have a template file that we could use for dynamic output of any page in our site. Note that you may also shorten that to just <?=$page->title?> and <?=$page->body?> if you prefer (and the same goes for the rest of this tutorial), but we will stick to the longer syntax since there are still a few (rare) web servers out there that may not support these PHP short open/close tags.

If you understand the above, then congratulations, you know how to use temlate files! Though in most cases, it's not likely our site will only need one template (and template file). Chances are our document markup will consist of a lot more than what this simple example shows.

Including other files

When we want to utilize the convenience of direct output, but don't want to repeat the same markup in every template file, we move the code that we want to re-use into separate files. That way we can have multiple template files that pull in the same bits of code without us having to repeat ourselves. The benefit is that if we need to change something, we only need to change it in one place rather than in all of our template files.

To get started, lets figure out the parts of our basic-page.php template file that we want to re-use in other template files. In this case, we know that the markup at the top of all our template files will be the same, so lets move that to a _head.php file (or whatever you want to name it). We'll use the underscore prefix on that filename just to clarify that it is a file meant to be included in others, rather than a dedicated template file. While this is not required, it's a common convention and recommended primarily because it enables both you and ProcessWire to differentiate template files from include files.

/site/templates/_head.php

<html>
  <head>
    <title><?php echo $page->title; ?></title>
  </head>
  <body>
    <h1><?php echo $page->title; ?></h1>

We also know that the markup at the end of all our template files will be the same, so we'll move that markup into a _foot.php file:

/site/templates/_foot.php

</body>
</html>

Where the template files will vary is what's in-between the _head.php and _foot.php. So we'll use our basic-page.php template file to do the following, in this order:

  1. Include the _head.php file
  2. Output content
  3. Include the _foot.php file

Here's how we might do that:

/site/templates/basic-page.php

<?php
include("./_head.php");
echo $page->body;
include("./_foot.php"); 

The output is identical to when basic-page.php was an entire HTML document. But our template file has become a lot smaller, and we can re-use our _head.php and _foot.php in any other template files that we want to. For instance, we might have another template called sidebar-page (with template file sidebar-page.php) that produces output similar to basic-page.php, while being able to support separate bodycopy and sidebar columns:

/site/templates/sidebar-page.php

<?php include("./_head.php"); ?>
  <div id='bodycopy'>
    <?php echo $page->body; ?>
  </div>
  <div id='sidebar'>
    <?php echo $page->sidebar; ?>
  </div>
<?php include("./_foot.php"); ?>

Using includes for _head.php and _foot.php is just for starters. You can use includes for literally anything. Many people refer to these types of includes as partials. You can extend their use to anything that you might want to repeat or reuse in any template file.

Automatic file includes

It's not actually necessary to manually include("./_head.php") and include("./_foot.php") in each of your template files. You can make this happen automatically by editing your /site/config.php file and populating these two lines like so:

$config->prependTemplateFile = '_head.php';
$config->appendTemplateFile = '_foot.php';

What the above essentially says is to 1) automatically load the contents of _head.php file before your template file (prepend), and 2) load the contents of _foot.php after your template file (append). The result is that it's no longer necessary to manually include those in each of your template files. These automatic inclusions actually come in handy in other template file strategies too, so keep them in mind!

Drawbacks of direct output

Where direct output starts to become more cumbersome is when you want to affect the output in multiple regions on a page. In our examples above, our template files only control the output for what comes between _head.php and _foot.php. While we could accommodate more regions with additional includes, it starts to get a little cumbersome.

What if any of our template files could populate any region in our markup without us having to know exactly where it will go ahead of time? This is where the delayed output or markup regions output strategies become more compelling.

Twitter updates

  • ProcessWire 3.0.185 (dev) core updates, plus new Session Allow module— More
    17 September 2021
  • Three new ProcessWire Textformatter modules: Find/Replace, Markdown in Markup, and Emoji— More
    3 September 2021
  • This week we have a new master version released after a year in the making. With nearly 40 pull requests, hundreds of new additions and more than 100 issue reports resolved, this new version has a ton of great new stuff— More
    27 August 2021

Latest news

  • ProcessWire Weekly #384
    In the 384th issue of ProcessWire Weekly we'll cover the latest core updates, introduce a new module called Session Allow, and highlight a new site of the week. Read on!
    Weekly.pw / 18 September 2021
  • ProcessWire 3.0.184 new master/main version
    This week we have a new master/main version released after a full year in the making. As you might imagine, this new version has a ton of great new stuff and we’ll try to cover much of it here.
    Blog / 27 August 2021
  • Subscribe to weekly ProcessWire news

“We were really happy to build our new portfolio website on ProcessWire! We wanted something that gave us plenty of control on the back-end, without any bloat on the front end - just a nice, easy to access API for all our content that left us free to design and build however we liked.” —Castus, web design agency in Sheffield, UK