Мне интересно - какой самый эффективный способ разобрать что-то вроде:
{{HEADER}}
Hello my name is {{NAME}}
{{#CONTENT}}
This is the content ...
{{#PERSONS}}
<p>My name is {{NAME}}.</p>
{{/PERSONS}}
{{/CONTENT}}
{{FOOTER}}
Конечно, в конечном итоге это должно быть что-то вроде системы шаблонов, поэтому я планирую создать хэш-карту, чтобы "наложить" на шаблон, как что-то вроде этого
$hash = array(
'HEADER' => 'This is a header',
'NAME' => 'David',
'CONTENT' => array('PERSONS' => array(array('NAME' => 'Heino'), array('NAME' => 'Sebastian')),
'FOOTER' => 'This is the footer'
);
Стоит отметить, что «разделы» (теги, начинающиеся с #) могут повторяться более одного раза, и я думаю, это то, что меня сбивает ...
Также любой раздел может содержать любое количество других разделов и обычных тегов ...
Итак .. как ты это сделал?






Лучше использовать что-то с существующим синтаксическим анализатором, например XML или JSON, чтобы вам не приходилось писать свой собственный синтаксический анализатор, и чтобы другие могли легко писать документы для вашего синтаксического анализатора без использования специальных инструментов. Однако, если вы хотите написать свой собственный синтаксический анализатор, вы, вероятно, захотите изучить использование Лекс и Yacc.
Я бы выбрал сторонний парсер, потому что мне нравится работать умнее, а не усерднее, но если вы делаете это в качестве упражнения или действительно хотите создать свой собственный шаблонизатор (в PHP я предполагаю из-за тега), я Начнем с обзора шаблонов проектирования, в частности составной шаблон проектирования.
Составной шаблон часто используется в среде Java для подобных вещей, включая синтаксический анализ XML.
Ожидаемый результат этого примерно такой:
Это заголовок
Привет меня зовут Дэвид
This is the content ...
My name is Heino.
My name is Sebastian.
Это нижний колонтитул
Как вы управляете отношениями вложенных массивов в хэш-карте с повторяющимися разделами в шаблоне? Каким должно быть реальное поведение шаблона? Если для элемента, не являющегося разделом, предоставляется массив, что он будет делать? Если элементу раздела предоставлено одно значение, будет ли он обрабатываться так же, как массив только с одним элементом (я так полагаю)?
Во всяком случае, что касается синтаксического анализатора для шаблона (независимо от того, что вы в конечном итоге делаете с отображением данных) ... Я бы создал класс для каждого типа токена, включая общий для не-токен-контента . Они будут унаследованы от общего базового класса токенов с переопределяемыми методами Parse, Render и Map.
Составьте диаграмму состояния и выясните, какие точки входа и выхода есть для каждого состояния, а затем закодируйте это в структуре вызовов между токенами. В конце концов, вы хотите получить перечисляемую коллекцию токенов, которая описывает ваш шаблон.
Когда у вас есть это в абстрактной форме, вы можете перебирать коллекцию, вызывая Map на токенах, чтобы назначить данные из хэш-карты токенам, а затем вызвать Render для рендеринга шаблона в его окончательную форму.
Надеюсь, это поможет.
Я бы использовал что-то вроде этого внутри отдельного файла .php:
<?php echo $HEADER ?>
Hello my name is <?php echo $NAME?>
<div id = "CONTENT">
This is the content ...
<?php foreach ($PERSONS as $PERSON) : ?>
<p>My name is <?php echo $PERSON['NAME']?>.</p>
<?php endforeach ?>
</div>
<?php echo $FOOTER ?>
И просто включите указанный выше файл в тот, в котором указаны указанные переменные.
Хотите верьте, хотите нет, но PHP уже предоставляет все функции, которые, как утверждают, реализуют системы шаблонов. Нет необходимости добавлять еще один уровень абстракции (и сложности) поверх PHP.
Да, это было бы просто, но этого недостаточно в той ситуации, в которой я нахожусь. Никакой PHP / логика не может быть встроена в шаблоны вообще.
Я предполагаю, что ваша просьба об отсутствии какой-либо логики PHP исходит из того факта, что шаблоны будут созданы непрограммистами. Но я уверен, что если вы можете научить их писать {{#PERSONS}}, когда требуется итерация для каждого человека, вы также можете научить их писать эквивалент для foreach.
Я использую для этого DOM PHP. Мой язык шаблонов - это просто HTML с атрибутами идентификатора и класса. Однако, если вы хотите придерживаться своего плана, я бы использовал preg_replace_callback с шаблоном, который соответствует вашему синтаксису, и функцию обратного вызова, которая находит подходящую замену в вашем хэше, рекурсивно вызывая себя для элементов контейнера.
Это именно то, с чем я сейчас возился. Но было интересно, есть ли другие подходы к разбору такой структуры.
Самый эффективный способ - это компилировать шаблона в php-код. И просто включают скомпилированная версия.
Smarty Template Engine делает нечто подобное. Вы также можете посмотреть источник smarty и проверить, как они разбирают теги.
Если для тега ничего не подходит, его следует игнорировать и удалить. В противном случае мне нравится ваша идея - хотя она может быть немного сложнее, чем я думал изначально.