Создание простого, но гибкого шаблонизатора - PullRequest
2 голосов
/ 28 апреля 2011

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

Однако, поскольку поиск и замена должны быть жестко закодированы, он не настолько гибок.Я хочу сказать, что в качестве примера я использую что-то вроде этого

$templateMarkup = '<div class="title">{_TITLE_}</div>';
$renderedMarkup = str_replace("{_TITLE_}",$title,$templateMarkup);
echo $renderedMarkup;

Как вы можете видеть, оно жестко закодировано.Поэтому я должен преднамеренно знать все заполнители, чтобы выполнить успешную визуализацию.

Я немного слаб в регулярном выражении.Но я знаю, что если я смогу разработать регулярное выражение, которое может соответствовать всему тексту, начиная с {_ и заканчивая _}, и получить значение между ними, я просто смогу создать гибкий движок шаблонов.

Мне нужна помощь с регулярным выражением.

Если я полностью иду по неверному пути, пожалуйста, предупредите меня.

Для тех, кто думает, что яизобретаю велосипед.Вот мое объяснение

Templating engines, that are already available are quite unnecessarily complex. 
My requirements are simple and so I am builidng my own simple engine. 

Ответы [ 3 ]

2 голосов
/ 28 апреля 2011

Если вы не пытаетесь ограничить то, что люди могут делать в шаблоне, и не хотите контролировать, какую разметку они могут в него вставить, я бы порекомендовал PHP как отличный язык шаблонов!

Если вы хотите придерживаться своего решения, вы можете сделать что-то подобное для управления заменами.

$template = "foo={_FOO_},bar={_BAR_},title={_TITLE_}\n";

$replacements = array(
    'title' => 'This is the title',
    'foo' => 'Footastic!',
    'bar' => 'Barbaric!'
);

function map($a) { return '{_'. strtoupper($a) .'_}';}

$keys = array_map("map", array_keys($replacements));
$rendered = str_replace($keys, array_values($replacements), $template);

echo $rendered;
1 голос
/ 28 апреля 2011

Регулярное выражение, которое вы ищете, это {_(\w+)_}, если ваши теги шаблона - это всего лишь одно слово.Вы бы использовали его примерно так:

<?php

$replacements = array(
    "firstname" => "John",
    "lastname" => "Smith"
);

$template_markup = "Hello {_firstname_} {_lastname_}";
if(preg_match_all('/{_(\w+)_}/', $template_markup, $matches)) {
    foreach($matches[1] as $m) {
        $template_markup = str_replace("{_".$m."_}", $replacements[$m], $template_markup);
    }
}
echo $template_markup;

?>

Вы увидите, что preg_match_all имеет прямые косые черты, окружающие регулярное выражение, это разделители.

Обновление: Если вы хотите расширить регулярное выражение за пределы отдельных слов, будьте осторожны при использовании . для сопоставления с любым символом.Лучше использовать что-то вроде этого, чтобы указать, что вы хотите включить другие символы: {_([\w-_]+)_}.[\w-_] означает, что он будет соответствовать буквенно-цифровым символам, дефисам или символам подчеркивания.

(Возможно, кто-то может объяснить, почему использование . может быть плохой идеей? Я не уверен на 100%).

0 голосов
/ 28 апреля 2011

Я объединил решения, предоставленные Сэмом и Джеймсом, чтобы создать новое решение.

  • Благодаря Sam для части регулярного выражения
  • Спасибо James за режим массива str_replace() part.

Вот решение:

$replacements = array(
    "firstname" => "John",
    "lastname" => "Smith"
);

function getVal($val) {
    global $replacements;
    return $replacements[$val];
}

$template_markup = "Hello {_firstname_} {_lastname_}";
preg_match_all('/{_(\w+)_}/', $template_markup, $matches);
$rendered = str_replace($matches[0], array_map("getVal",array_values($matches[1])), $template_markup);
echo $rendered;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...