DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Building Scalable Real-Time Apps with AstraDB and Vaadin
Register Now

Trending

  • Redefining DevOps: The Transformative Power of Containerization
  • 13 Impressive Ways To Improve the Developer’s Experience by Using AI
  • SRE vs. DevOps
  • Building A Log Analytics Solution 10 Times More Cost-Effective Than Elasticsearch

Trending

  • Redefining DevOps: The Transformative Power of Containerization
  • 13 Impressive Ways To Improve the Developer’s Experience by Using AI
  • SRE vs. DevOps
  • Building A Log Analytics Solution 10 Times More Cost-Effective Than Elasticsearch

Templating a WordPress theme with Twig

Karl Agius user avatar by
Karl Agius
·
Apr. 09, 13 · Interview
Like (0)
Save
Tweet
Share
5.84K Views

Join the DZone community and get the full member experience.

Join For Free

Well, that wasn’t as painful as I thought it would be. Some googling and a couple of experiments went a long way, and now I have a partial, unstyled, Twig-based theme happily running on WordPress.

Twig is a templating engine for php. It has more than enough features to get me going, setting it up is as easy as falling off a tree, and I haven’t used it much, which makes it a good candidate for me.

Making WordPress call Twig

Once we’ve downloaded Twig and put it somewhere convenient (in my case, in my theme folder – I’d like to move it out eventually, but it can stay there while I work it out), we need to tell WordPress to initialize the Twig engine. Darko Goles’ blog post, TWIG with WordPress part 1, covers this admirably. In his post, he’s initializing the engine through a plugin, which I wanted to avoid as I didn’t want a theme to depend on a plugin. Luckily the mechanism is the same, since the hooking mechanism in WordPress papers over these issues – we can initialize from a theme exactly like we do from a plugin, by specifying the actions in a functions.php file:

<?php 
    // theme functions.php
    require_once dirname(__FILE__).'/twig.helper.php';
?>

<?php
    // twig.helper.php
    require_once dirname(__FILE__).'/lib/Twig/Autoloader.php';

    class Twig_Helper {
	public static function register() {
	    ini_set('unserialize_callback_func', 
                'spl_autoload_call');
            spl_autoload_register(array(new self, 'autoload'));
	}

	public static function autoload($class) {

            if (0 !== strpos($class, 'Wp_TwigEngine'))
	        return;

            if (file_exists($file = dirname(__FILE__) . '/../' 
                . str_replace(array('_', "\0"), array('/', ''), 
                $class) . '.php')) {
		     echo($file);
		     exit;
                     require $file;
	    }
	}

	...
	...
    }

    ...

    function autoload_twig() {
        Twig_Autoloader::register();
	Twig_Helper::register();
    }

    add_action('init', 'autoload_twig');
?>

The above is copied nearly verbatim from the post I mentioned above, and works fine. It registers twig and loads all the classes it needs to work. I put this in a separate file and referenced it from functions.php so it wouldn’t get mixed in with any theming functions I might need to add later.

Getting to the data

Now we’re able to load templates, but we still need to be able to pass data to them. The solution came, again, from Mr. Goles’ blog, this time from TWIG with WordPress part 2 – we pass a proxy object to the template, which it can then use to call functions on. Again, I used the code from this post almost as provided, except that I used the same TwigHelper class to provide this proxy. I also added another method, text, to wrap the __(string, key) function used for localization.

Writing templates

The template file looks like this:

{% extends "master.html.twig" %}
{% block pageContent %}
	<section id="content" role="main">
		{% for post in posts %}
			{% set format = site.get_post_format() %}
			{% include format 
                               ? "content-" ~ format ~ ".html.twig" 
                               : "content.html.twig" %}
		{% else %} 
			{% include "content-none.html.twig" %}
		{% endfor %>	
	</section>
{% endblock %}

Not much of it, is there? In reality, that’s because most of the layout is defined in master.html.twig, which we’re extending in the first line. This file has placeholders for the pageContent block which is being filled up here, and the rest of the page around it. I’ve also delegated the no-content section to its own file. The snippet above is the equivalent of:

	<div id="content" role="main">
	    <?php if ( have_posts() ) : ?>	
	        <?php while ( have_posts() ) : the_post(); ?>
	            <?php get_template_part('content', 
                                 get_post_format() ); ?>
	        <?php endwhile; ?>
	<?php else : ?>
		<?!-- stuff to show if there's no content -->
	<?php endif; ?>
	</div>

It may not be significantly shorter, but it’s a damn sight easier to read. The readability and size gains are much greater when you have more markup, but I don’t want this to be a templating post.

While… hang on, where’s while?

As I was working on the loop, I realized that Twig doesn’t have a “while” control. This was a problem as WordPress is heavily dependent on The Loop. This can be worked around, as demonstrated in this blog post by Luis Cordova, by making an iterator and using it in a for loop. It’s a good enough solution and the template doesn’t look bad.

Current status

At this point I have a barely functional them (still need to port over a lot of stuff) but getting here took a lot less time than I thought it would. My next step will probably be to port over as much of the old theme as I can, and then work from there.



WordPress

Published at DZone with permission of Karl Agius, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Redefining DevOps: The Transformative Power of Containerization
  • 13 Impressive Ways To Improve the Developer’s Experience by Using AI
  • SRE vs. DevOps
  • Building A Log Analytics Solution 10 Times More Cost-Effective Than Elasticsearch

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: