Операторы if в системе шаблонов

Как я могу разобрать, скажем, {if $var > 2} или {if $var} в файле .tpl в моей собственной версии класса шаблонов. Я не хочу использовать smarty, потому что мне не нужны все их плагины. Я просто хочу включить операторы if, for и foreach.


person Speedy Wap    schedule 09.02.2011    source источник
comment
Если это не для учебных целей (в чем я сомневаюсь, потому что вам нужен код), я бы использовал Smarty (удалите плагины, если они вам не нужны) или собственный PHP. Не нужно изобретать велосипед, который изобретали уже тысячи раз   -  person Pekka    schedule 09.02.2011
comment
Если вы не хотите использовать Smarty, это не исключает его использования в качестве справочного материала для деталей реализации. Они используют регулярные выражения для преобразования псевдокода шаблона в php.   -  person mario    schedule 09.02.2011
comment
Я делаю это в учебных целях, но мне довольно сложно понять это. Поэтому вместо того, чтобы использовать smarty, я хочу создать свою собственную систему шаблонов, чтобы лучше понимать, как они работают.   -  person Speedy Wap    schedule 09.02.2011
comment
Как только вы начнете идти по этому пути, ваш язык шаблонов станет языком программирования. В этом нет ничего плохого (Template-Toolkit - вещь прекрасная), но написание языка программирования не для слабонервных. Я бы начал с чтения по теории интерпретаторов.   -  person Quentin    schedule 09.02.2011
comment
Я думаю, тебе стоит использовать Smarty. Если вы этого не сделаете, ваше собственное решение будет (а) содержать ошибки и (б) способом сложнее, чем просто использовать Smarty, даже если вы не используете их плагины. И, давайте посмотрим правде в глаза, если вы не хотите использовать их плагины ... тогда вам не обязательно.   -  person Lightness Races in Orbit    schedule 22.02.2011


Ответы (6)


Пожалуйста, используйте php. Просто вставьте свой tpl файл:

<?php if ($var > 2) .... ?> 

Это намного проще, меньше кода и намного быстрее, чем парсинг файла в php

person AntonioCS    schedule 09.02.2011

использовать

<? if( condition ) :
    ....
    ....
else : 
    ....
    ....
endif; ?>

Разница между if () {} и if (): endif;

person Gaurav    schedule 17.02.2011

Вы уже получили ответ на свой последний вопрос: операторы if в шаблонах php с использованием tpl
Но так как иначе вы не уйдете, позвольте мне быстро ответить на него, а затем упомянуть, какие будут ваши следующие камни преткновения.

// handle {if}...{/if} blocks
$content =
preg_replace_callback('#\{if\s(.+?)}(.+?)\{/if}#s', "tmpl_if", $content);

function tmpl_if ($match) {
    list($uu, $if, $inner_content) = $match;

    // eval for the lazy!
    $if = create_function("", "extract(\$GLOBALS['tvars']); return ($if);");

    // a real templating engine would chain to other/central handlers
    if ( $if() ) {
        return $inner_content;
    }
    # else return empty content
}

Использование такого регулярного выражения приведет к обнаружению вложенного if. Но вы об этом не спрашивали, поэтому я не буду об этом упоминать. И, как указано в комментарии, вам действительно нужно будет привязать к центральной функции, которая выполняет дальнейшие замены ({foreach} / {include} / и т. Д.), А не просто return $content, как здесь.

Это выполнимо, но быстро становится обременительным. И именно поэтому все другие движки шаблонов (которые вы отказываетесь проверять) фактически конвертируют .tpl файлы в .php скрипты. Это намного проще, потому что PHP уже может обрабатывать все те управляющие структуры, которые вы пытаетесь имитировать с помощью своего собственного класса шаблонов.

person mario    schedule 16.02.2011
comment
как это могло быть преобразовано в php. - person Speedy Wap; 17.02.2011
comment
@ user381595: с регулярными выражениями. Например, преобразование каждого {if ...} в <?php if(...): ?> и каждого {/if} в <?php endif; ?>. - person mario; 17.02.2011
comment
@SpeedyWap: Да, наверное. Следовательно, многие решения уже можно найти с помощью функции поиска. stackoverflow .com / questions / 3930053 / - person mario; 17.02.2011

На самом деле это довольно просто, если вам не нужны вложенные условия if.

$template = '<b>{foo}</b>{if bar} lorem ipsum {bar}{/if}....';

$markers = array(
    'foo' => 'hello',
    'bar' => 'dolor sit amet',  
);

// 1. replace all markers 
foreach($markers as $marker => $value)
    $template = str_replace('{'. $marker .'}', $value, $template);

//2. process if conditions
$template = preg_replace_callback('#\{if\s(.+?)}(.+?)\{/if}#s', function($matches) use ($markers) {

    list($condition, $variable, $content) = $matches;

    if(isset($markers[$variable]) && $markers[$variable]) {
        // if the variable exists in the markers and is "truthy", return the content
        return $content;
    }

}, $template);
person Alex    schedule 03.02.2015
comment
любая идея, как добавить вложенное, если для вашего решения. - person girish; 02.06.2015

Вы можете использовать следующий формат в вашем файле шаблона (.tpl).,

{if $url == 'error'}
Error message Invalid Login!
{/if} 
person Rajesh    schedule 23.02.2011

Существует пример кода php, который анализирует следующий шаблон (php 5.3+):

[IF {post_content}]Post content is filled![ENDIF]
[IF {post_content}]Post content is filled![ELSE]{post_content}[ENDIF]

Код:

$tags = array('post_content'=>'POST_CONTENT');

$message = '1: [IF {post_content}]Post content: {post_content}![ENDIF]
            2: [IF {post_content}]Post content is filled![ELSE]Post content is empty![ENDIF]';

$matches = array();

preg_match_all('/\[IF \{([^\}]*)\}\](.[^\]]+)(?:\[ELSE\](.+?))?\[ENDIF\]/s', $message, $matches);

if ( empty($matches) ) {
    return $message;
}

$math_tag = '';
foreach ( $matches[0] as $m_index => $match )
{
    $math_tag =  trim($matches[1][$m_index]);

    if ( !empty($tags[$math_tag]) ) {
        // IF value is not empty
        $message = str_replace($match, $matches[2][$m_index], $message);
    } elseif( empty($tags[$math_tag]) && $matches[3][$m_index] ) {
        // ELSE
        $message = str_replace($match, $matches[3][$m_index], $message);
    } else {
        // IF NO ELSE condition - REMOVE ALL
        $message = str_replace($match, '', $message);
    }
}

foreach($tags as $tag => $value)
   $message = str_replace('{'. $tag .'}', $value, $message);

echo $message;
person MaxWell99    schedule 08.05.2017