PHP - Создание собственной системы шаблонов? - PullRequest
4 голосов
/ 04 декабря 2010

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

Итак, у меня есть файл .html с некоторой разметкой, например:

<ul>
    {{startloop}}
    <li>
        <img src="/album/{{filename}}" alt="">
        <span>{{imgname}}</span>
    </li>
    {{endLoop}}
</ul>

Что я хочу сделать, это заменить {{имя_файла}} и {{imgname}} на что-то еще. Я знаю, как это сделать, но дело в том, что я хочу сделать это внутри цикла. Таким образом, для каждого зацикленного элемента {{имя_файла}} и {{imgname}} будут разными. Если у меня есть два «предмета», это будет выглядеть так (просто пример):

<ul>
    <li>
        <img src="/album/image1.jpg" alt="">
        <span>Test name 1</span>
    </li>
    <li>
        <img src="/album/image2.jpg" alt="">
        <span>Test name 2</span>
    </li>
</ul>

Есть предложения?

Ответы [ 6 ]

2 голосов
/ 04 декабря 2010

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

Метод, описанный ниже, - это способ, которым я всегда создаюмой шаблонизатор, он очень потерян и может быть расширен с помощью помощников шаблонов.

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

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

Итак, давайте начнем с этого:

class Template
{
    private $__data = array();

    public function __construct(){/*Set up template root here*/}

    public function __set($key,$val)
    {
        $this->__data[$key] => $val;
    }

    public function __get($key)
    {
        return $this->__data[$key];
    }

    public function Display($Template)
    {
        new TemplatePage($Template,$this->__data); //Send data and template name to encapsulated object
    }
}

это очень простой класс, который позволит делать что-то вроде

$Template = new Template();

$Template->Userdata = $User->GetUserData();

$Template->Display("frontend/index");

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

Это позволит вам иметь методы для получения данных вашего шаблона, а также доступа к помощникам, ниже приведен пример TemplatePage

class TemplatePage
{
    private $__data = array();

    public function __construct($template,$data)
    {
        $this->__data = $data;
        unset($data);

        //Load the templates
        if(file_exists(TEMPLATE_PATH . "/" . $template . ".php"))
        {
            require_once TEMPLATE_PATH . "/" . $template . ".php";
            return;
        }
        trigger_error("Template does not exists",E_USER_ERROR);
    }

    public function __get($key)
    {
        return $this->__data[$key];
    }

    public function require($template)
    {
        if(file_exists(TEMPLATE_PATH . "/" . $template . ".php"))
        {
            require_once TEMPLATE_PATH . "/" . $template . ".php";
            return;
        }
        trigger_error("Template does not exists",E_USER_NOTICE);
    }

    public function link($link,$title)
    {
        return sprintf('<a href="%s">%s</a>',$link,$title);
    }
}

Так что теперь, когда шаблонзагруженный в рамках класса, вы можете расширить методы, такие как link и require, чтобы получить полнофункциональный набор инструментов шаблона

Пример шаблона:

<?php $this->require("folder/js_modules") ?>
<ul>
    <?php foreach ($this->photos as $photo): ?>
    <li>
        <?php echo $this->link($photo->link,"click to view") ?>
        <span><?php echo $photo->image_name?></span>
    </li>
    <?php endforeach; ?>
</ul>
<?php $this->require("folder/footer") ?>
2 голосов
/ 04 декабря 2010

Я был большим поклонником шаблонного движка smarty долгое время, пока не понял, что он мне вообще не нужен :) Гораздо лучше и быстрее использовать прямые встроенные теги php.

просто поместите html + php_tags в файл some_template.inc вместо html.

, а затем покажите этот шаблон с помощью «include ('template.inc');"

example oftemplate.inc ':

<ul>
    <?foreach ($items as $item){?>
    <li>
        <img src="/album/<?=$item[filename]?>" alt="">
        <span><?=$item[imgname]?></span>
    </li>
    <?}?>
</ul>

0 голосов
/ 04 декабря 2010

Единственный способ создать сверхбыструю систему шаблонов - это использовать PHP в качестве парсера или использовать расширение, написанное на C. Кроме того, в любом случае, вероятно, нет причин пытаться сделать это, так как это уже было сделано.тысячи раз.Есть много крупных победителей, таких как Smarty, хотя производительность не звездная.Система шаблонов в PHPBB также довольно хороша (использует предварительный анализ и кэшированный PHP).Избегайте повторного изобретения колеса здесь.

Если производительность является серьезной проблемой, я настоятельно рекомендую Блиц .

Заимствование из PHPBB - это другой маршрут.Если у вас нет доступа к расширению PHP на вашем сервере, и Smarty не является вашей чашкой чая по формату производительности, и вы хотели бы весь голый металлический код, вы можете поступить как я и вытащить то, что в PHPBB.Это не конечное решение, а множество подробностей, но оно довольно хорошее - и с источником вы можете настроить его по вкусу.Он очень удобен в коде, поэтому поддерживает некоторый уровень выражений и поддерживает HTML-теги комментариев, так как шаблон экранирует маркеры, удобные для пользователя для менее технических графических дизайнеров.

0 голосов
/ 04 декабря 2010

Может быть, лучше здесь использовать шаблоны MVC / MVVVM, а затем вы получите это бесплатно вместе с очень структурированным и организованным проектом кода.

Взгляните на эту страницу из блога Расмуса в качестве учебного пособия по этому рабочему процессу: http://toys.lerdorf.com/archives/38-The-no-framework-PHP-MVC-framework.html

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

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

Надеюсь, это полезно.

0 голосов
/ 04 декабря 2010

Есть ли причина, по которой вы создаете собственную систему шаблонов? Я бы рекомендовал использовать Smarty http://www.smarty.net/

У него уже есть эта функциональность, а также многое другое, например, кеширование и т. Д.

0 голосов
/ 04 декабря 2010

Замените ваши {{tags}} на куски php-кода (в нашем случае foreach), а затем eval результат. Вот как работают шаблоны php.

пример:

$template = "<h1>Hello {{name}}</h1>";
$name = "Joe";

$compiled_template = preg_replace(
    '~{{(.+?)}}~', 
    '<?php echo $$1 ?>', 
    $template);

eval('?>' . $compiled_template);

отпечатков <h1>Hello Joe</h1>

Более сложный пример, включающий массивы и циклы

$template = "
    {{each user}}
        {{name}} {{age}}<br>
    {{end}}
";

$user = array(
    array('name' => 'Joe', 'age' => 20),
    array('name' => 'Bill', 'age' => 30),
    array('name' => 'Linda', 'age' => 40),
);

$t = $template;

$t = preg_replace(
    '~{{each (\w+)}}~', 
    '<?php foreach($$1 as $item) { ?>', 
    $t);

$t = preg_replace(
    '~{{end}}~', 
    '<?php } ?>', 
    $t);

$t = preg_replace(
    '~{{(\w+)}}~', 
    '<?php echo htmlspecialchars($item["$1"]) ?>', 
    $t);

eval('?>' . $t);

В ответ на другие комментарии, сказав, что «php - это движок шаблонов» и «eval is evil» - люди, не повторяйте глупые мантры, которые вы где-то слышали. Попробуйте думать самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...