Статьи

Шаблонирование темы WordPress с помощью Twig

Ну, это было не так больно, как я думал. Некоторое поиск в Google и пара экспериментов прошли долгий путь, и теперь у меня есть частичная, не стилизованная тема на основе Twig, которая успешно работает на WordPress.

Twig — шаблонизатор для php. У него более чем достаточно функций, чтобы заставить меня работать, настроить его так же легко, как упасть с дерева, и я не использовал его много, что делает его хорошим кандидатом для меня.

Заставить WordPress вызвать Twig

После того, как мы скачали Twig и поместили его в удобное место (в моем случае, в папку с моей темой — я хотел бы в конечном итоге переместить его, но он может остаться там, пока я работаю), мы должны сказать WordPress для инициализации двигатель Twig. В блоге Darko Goles , TWIG с WordPress, часть 1 , это замечательно освещено . В своем посте он инициализирует движок с помощью плагина, которого я хотел избежать, поскольку не хотел, чтобы тема зависела от плагина. К счастью, механизм тот же, так как механизм перехвата в WordPress работает над этими проблемами — мы можем инициализировать из темы точно так же, как мы делаем из плагина, указав действия в файле functions.php:

<?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');
?>

Вышеизложенное скопировано почти дословно из поста, о котором я упоминал выше, и работает нормально. Он регистрирует веточку и загружает все классы, необходимые для работы. Я поместил это в отдельный файл и сослался на него из functions.php, чтобы он не смешивался ни с какими тематическими функциями, которые мне, возможно, понадобится добавить позже.

Как добраться до данных

Теперь мы можем загружать шаблоны, но мы все еще должны иметь возможность передавать им данные. Решение, опять же, пришло из блога мистера Голеса, на этот раз из TWIG с WordPress, часть 2 — мы передаем прокси-объект в шаблон, который он затем может использовать для вызова функций. Опять же, я использовал код из этого поста почти так, как предусмотрено, за исключением того, что я использовал тот же класс TwigHelper для предоставления этого прокси. Я также добавил еще один метод text для переноса функции __ (string, key), используемой для локализации.

Написание шаблонов

Файл шаблона выглядит следующим образом:

{% 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 %}

Не так много, не так ли? На самом деле это потому, что большая часть макета определена в master.html.twig, который мы расширяем в первой строке. Этот файл содержит заполнители для блока pageContent, который заполняется здесь, и для остальной части страницы вокруг него. Я также делегировал раздел без содержимого в свой собственный файл. Вышеуказанный фрагмент является эквивалентом:

	<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>

Возможно, он не намного короче, но чертовски легко читать. Когда у вас больше разметки, вы получаете удобочитаемость и размер, но я не хочу, чтобы это был шаблонный пост.

Пока … подожди, а где?

Работая над циклом, я понял, что Twig не имеет элемента управления «while». Это было проблемой, так как WordPress сильно зависит от The Loop. Это можно обойти, как продемонстрировал Луис Кордова в этом блоге , создав итератор и используя его в цикле for. Это достаточно хорошее решение, и шаблон не выглядит плохо.

Текущий статус

На данный момент у меня есть их едва функционирующие (все еще нужно портировать на много вещей), но чтобы добраться сюда, потребовалось гораздо меньше времени, чем я думал. Моим следующим шагом, вероятно, будет портирование как можно большей части старой темы, а затем работа с нее.