сверхлегкая система шаблонов в PHP, которая не позволяет PHP-код внутри шаблонов или использовать eval - PullRequest
14 голосов
/ 24 апреля 2011

Я ищу очень простую систему шаблонов PHP. Прямо сейчас я использую:

/**
 * Renders a single line. Looks for {{ var }}
 *
 * @param string $string
 * @param array $parameters
 *
 * @return string
 */
function renderString($string, array $parameters)
{
    $replacer = function ($match) use ($parameters)
    {
        return isset($parameters[$match[1]]) ? $parameters[$match[1]] : $match[0];
    };

    return preg_replace_callback('/{{\s*(.+?)\s*}}/', $replacer, $string);
}

(отсюда: PHP - чрезвычайно легкая система шаблонов )

но я могу только назначать и отображать переменные. Мне также нужен способ использовать такие условия, как IF и циклические массивы.

Я нашел Rain TPL - http://www.raintpl.com/Quick-Start/#if - что очень близко к тому, что я ищу, но есть несколько вещей, которые мне не нравятся:

  • позволяет парню, который пишет шаблон, запускать функции PHP (внутри условия IF).
  • пишет кеш и php файлы, которые мне не нужны

Итак, есть ли что-нибудь похожее на это, но еще более "простое", строгое и более безопасное?

Ответы [ 7 ]

15 голосов
/ 24 апреля 2011

Веточка может быть для вас.

Может выполнять условия и имеет режим песочницы для ненадежного кода.

Он выполняет компиляцию и кэширование, но, похоже, его можно отключить.

7 голосов
/ 07 июня 2011

Существует также порт Усы для PHP.Порт PHP находится здесь .Синтаксис аналогичен тому, что вы уже делаете, и поддерживает простые циклы IF и FOREACH-типа.

5 голосов
/ 24 апреля 2011

Посмотрите на Twig или H2O.

4 голосов
/ 11 июня 2011

очень прост в использовании

http://www.smarty.net/

4 голосов
/ 07 июня 2011

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

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

Вы можете изменить Rain TPL, чтобы отключить некоторые его функции, которые вам не нужны. Например, вы можете сделать ...

  1. Отключить использование функции в операторах IF:
    а. Найдите elseif( preg_match( '/\{if(?: condition){0,1}="([^"]*)"\}/', $html, $code ) ){

    б. Замените $this->function_check( $tag ); новым методом, например, $this->ifcondition_function_check( $tag );

    с. Создайте новый метод, который отключит все функции в операторах IF.

    private function ifcondition_function_check($code)
    {
        $preg = '/[a-zA-z0-9]+\((.*?)\)/';
        if (preg_match( $preg, $code, $match ) ){
            // find the line of the error
            $line = 0;
            $rows=explode("\n",$this->tpl['source']);
            while( !strpos($rows[$line],$code) )
                    $line++;
    
            // draw the error line
            $error = str_replace( array('<','>'), array( '&lt;','&gt;' ), array($code,$rows[$line]) );
            $error = str_replace( $code, "<font color=red>$code</font>", $rows[$line] );
    
            // debug the error and stop the execution of the script
            die( "<div>RainTPL Sandbox Error in template <b>{$this->tpl['tpl_filename']}</b> at line $line : <i>$error</i></b>" );
        }
    }
    

    д. Теперь функции отключены.

    1. Удалить файл кэша. (Кеш-файл в Rain TPL - это файл PHP, в котором теги шаблонов заменены кодом PHP).
      а. Перейти к методу draw()
      б. Найдите unset( $this->tpl );
      с. Непосредственно перед этой строкой удалите скомпилированный (кеш) файл @unlink($this->tpl['compiled_filename']);.
      д. Теперь кеш-файл - это просто временный файл для выполнения кода PHP.

Надеюсь, это поможет

2 голосов
/ 12 июня 2011

Когда вы хотите, чтобы он был действительно маленьким и гибким, возможно, лучше всего было бы остаться со своими вещами? Мне нравится ручная работа ;-) Вы можете расширить вашу существующую функцию. Следуя вашей функции плюс if, loop и безопасность. Ищите $template для примера.

<?php
function renderString($str, $parms)
{
    // if
    $str = preg_replace_callback('/{{if (?P<name>\w+)}}(?P<inner>.*?){{endif}}/is', function($match) use ($parms) {
        if( isset($parms[$match['name']])) {
            // recursive
            return renderString($match['inner'], $parms);
        }
    }, $str);
    // loop
    $str = preg_replace_callback('/{{loop (?P<name>\w+)}}(?P<inner>.*?){{endloop}}/is', function($match) use ($parms) {
        if( isset($parms[$match['name']]) && is_array($parms[$match['name']])) {
            $str = '';
            foreach ($parms[$match['name']] as $value) {
                $parms['loop'] = $value;
                // recursive
                $str .= renderString($match['inner'], $parms);
            }
            return $str;
        }
    }, $str);
    // var
    $str = preg_replace_callback('/{{(?P<name>\w+)}}/is', function($match) use ($parms) {
        if( isset($parms[$match['name']])) {
            return htmlspecialchars($parms[$match['name']]);
        }
    }, $str);
    return $str;
}

$template = "<h1>{{title}}</h1>

{{if optional}}
<p>Optional: {{optional}}</p>
{{endif}}

{{if noop}}I'm not there{{endif}}

<ul>
{{loop numbers}}
<li>{{symbol}} {{loop}}</li>
{{endloop}}
</ul>";

echo renderString($template, array(
    'title'    => 'The Title',
    'optional' => 'I am optional',
    'numbers'  => array( 'one', 'two', 'three'),
    'symbol'   => '>',
));

Этот скрипт протестирован в PHP 5.3, и вы можете скопировать его 1: 1 в файл для воспроизведения с ним.

0 голосов
/ 08 июня 2011

попробуйте PHPTAL: http://phptal.org/

синтаксис для шаблонов TAL не нарушает HTML, так что вы - и дизайнеры можете проверить, будут ли они хорошо выглядеть.http://wiki.zope.org/ZPT/TALSpecification14
http://wiki.zope.org/ZPT/TAL

...