One of the big advantages WordPress has is having an extensive community of professionals, which means we almost never have to start our projects from scratch. Most of the time we can find a plugin or theme which can serve as a starting point. However, in most cases this isn’t enough and some changes need to be made to fit our necesities, and this is where the headaches with WordPress “templates” begin. For example:
This image corresponds to the “page.php” file. This is a simple template which also inlcudes within the “page-content.php” file.
We have PHP code mixed together with HTHML markup. This usually is no big deal for a programmer, since the end goal is to generate HTML from PHP, but for a designer they not only require PHP knowledge but also in WordPress’ functions and functionality and possibly in the theme used as well. With complex templates this might be a big problem, since we need to deal with the theme’s particularities. For such a complicated project we’ll require both design and programming professionals.
From my point of view, it’s best if each professional works freely, without interfering in each other’s work. This is where a template language comes into play. In other words, its function is precisely to separate design from the programming logic. There are many variants: Twig, Timber, Jade-PHP, Mustache, though I prefer Smarty. This choice is based upon my personal experience. Learn more about the other options here and here.
Using Smarty, the template would look like this:
Which is simple HTML code, fully comprehensible for a designer. Every thing within keys {...}
is static text which is not modified and is provided by PHP (the “Lorem ipsum …” we see used in many templates). The reverse process is just as simple: we recieve a HTML file and change its contents with our own variables while keeping the design markup intact. This way the design team does not need knowledge in programming, WordPress nor the used theme and can work freely in their area of competence. On the other hand, the programmers needn’t worry about the visual aspect of the generated content. The additional cost in resources is made up for when every professional can focus fully on the aspects they are competent in, without interfering in the rest of the team’s work.
Implementing Smarty in our theme
As one would expect, we’ve got a plugin at our disposal: Smarty for WordPress. I haven’t tested it myself – as a developer I always prefer to use my own implementation. Anyhow, let’s get to it:
- First download Smarty from its official repository and copy the content from libs folder to a folder for our theme, for instance /includes/smarty. We need to create 4 work folders: templates, templates_c, cache, configs. Create them within the smarty folder.
- Create the file “load_smarty.php” with the following content:
<?php
require('includes/smarty/Smarty.class.php');
class Smarty_WP extends Smarty {
function __construct() {
parent::__construct();
$basedir = get_stylesheet_directory();
$this->setTemplateDir($basedir.'/includes/smarty/templates');
$this->setCompileDir($basedir.'/includes/smarty/templates_c');
$this->setCacheDir($basedir.'/includes/smarty/cache');
$this->setConfigDir($basedir.'/includes/smarty/configs');
}
function get_header_html() {
ob_start();
wp_head();
$this->assign('header', ob_get_contents());
ob_end_clean();
}
function get_footer_html() {
ob_start();
wp_footer();
$this->assign('header', ob_get_contents());
ob_end_clean();
}
}
The purpose of having everything related to Smarty in an independent file is the flexibility this gives us. We can include the theme’s functions.php file or be more specific and only use it when necessary. In the file, as well as initializing Smarty, I added two functions to obtain the corresponding header and footer for our WordPress installation, which should serve as an example on how to pass variables from PHP to Smarty. Depending on our needs, we’ll extend the class or add extra functions. - Modify page.php with the following:
<?php
require('route-to/load_smarty.php');
$smarty = new Smarty_WP();
$smarty->get_header();
$smarty->get_footer();
$smarty_post=new stdClass();
$smarty_post->id=get_the_ID();
$c='';
ob_start();
post_class();
$c=ob_get_contents();
ob_end_clean();
$smarty_post->class=$c;
$smarty_post->content_html=get_the_content();
$smarty_post->title=get_the_title();
$c='';
ob_start();
if (comments_open() || get_comments_number()) {$c=ob_get_contents();}
ob_end_clean();
$smarty_post->comments_html=$c;
$smarty->assign('post',$smarty_post);
$smarty->assign('twentyseventeen_edit_link',twentyseventeen_edit_link(get_the_ID()));
$smarty->assign('wp_link_pages',wp_link_pages());
$smarty->display('page.tpl')
This simply creates the Smarty instance, asigns the corresponding variables and launches the “page.tpl” template.
{$header}
<div class="wrap">
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
{if $post->content_html neq ""}
<article id="post-{$post->id}" {$post->class}>
<header class="entry-header">
<h1 class="entry-title">{$post->title}</h1>
{$twentyseventeen_edit_link}
</header><!-- .entry-header -->
<div class="entry-content">
{$post->content_html}
<div class="page-links">{$link_pages}</div>'
</div><!-- .entry-content -->
</article><!-- #post-## -->
{$post->comments_html}
{/if}
</main><!-- #main -->
</div><!-- #primary -->
</div><!-- .wrap -->
{$footer}
Finally we have what we wanted: a PHP file with the programming logic and a HTML file with the necessary markup. In my opinion this structure is easier to maintain and, for many templates with truly complicated markups, it’ll make our lives a whole lot easier.