Подтвердить что ты не робот

Выход Smarty для этого вручную

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

Я работал с этой схемой MVC, используя Codeigniter и Smarty в качестве механизма шаблонов. Теперь я хочу использовать raw php без обоих упомянутых инструментов.

Я не знаю, как "скопировать" концепцию Smarty "block" и "extends".

Я использовал для определения файла base.tpl, который имел html head, только тег body и базовые css и js файлы (те, которые всегда используются на каждой странице сайта), например: (snippet)

 <!DOCTYPE html>
 <head>
 <meta charset="utf-8" />
 <title>Dashboard</title>
 <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport" />
 <meta content="" name="description" />
 <meta content="" name="author" />

 <!-- ================== BEGIN BASE CSS STYLE ================== -->
 <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
 <link href="{site_url()}assets/css/animate.min.css" rel="stylesheet" />
 <!-- ================== END BASE CSS STYLE ================== -->

 <!-- ================== BEGIN PAGE LEVEL CSS STYLE ================== -->
 {block name='custom_css'}{/block}
 <!-- ================== END PAGE LEVEL CSS STYLE ================== -->

 <!-- ================== BEGIN BASE JS ================== -->
 <script src="{site_url()}assets/plugins/pace/pace.min.js"></script>
 <!-- ================== END BASE JS ================== -->
</head>
<body>
  <div id="page-container" class="fade page-sidebar-fixed page-header-fixed">
    <div id="header" class="header navbar navbar-default navbar-fixed-top">
        <div class="container-fluid">
            {include file='base/header.tpl'}
        </div>
    </div>
    <!-- BEGIN PAGE -->
    <div class="page-content">
        <!-- BEGIN PAGE CONTAINER-->
        <div class="container-fluid">
            <!-- BEGIN PAGE HEADER-->
            <div class="row-fluid">
                <div class="span12">                        
                    <!-- BEGIN PAGE TITLE & BREADCRUMB-->
                    {include file='admin/base/breadcrumb.tpl'}
                    <!-- END PAGE TITLE & BREADCRUMB-->
                </div>
            </div>
            <!-- END PAGE HEADER-->
            {block name='content'}{/block}
        </div>
        <!-- END PAGE CONTAINER-->    
    </div>
    <!-- END PAGE -->

а затем, когда мне нужно вызвать этот base.tpl, я сделал следующее:

{extends file='base/base.tpl'}

{block name='custom_css}
   <link href="{site_url()}assets/css/pages/blog.css" rel="stylesheet" type="text/css"/>
 {/block}

{block name='content'}
   <div class="row">
      <div class="col-md-3 col-sm-6">
        <div class="widget widget-stats bg-green">
        <div class="stats-icon stats-icon-lg"><i class="fa fa-globe fa-fw"></i></div>
        <div class="stats-title">TODAY VISITS</div>
        <div class="stats-number">7,842,900</div>
        <div class="stats-progress progress">
            <div class="progress-bar" style="width: 70.1%;"></div>
        </div>
        <div class="stats-desc">Better than last week (70.1%)</div>
      </div>
   </div>

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

Я бы хотел, чтобы вы руководствовались!

4b9b3361

Ответ 1

Другой способ - сделать что-то подобное. Я чувствую, что это, вероятно, ближе к тому, что заканчивается механизмом шаблонов, но с использованием синтаксиса {block} вместо этого.

index.php

<?php
$blocks = array();
function add_block($name, $callback){
    global $blocks;
    ob_start();
    $callback();
    $output = ob_get_flush();
    $blocks[$name] = $output;
}

function get_block($name){
    global $blocks;
    if(!empty($blocks[$name])){
        return $blocks[$name];
    }
    return '';
}

//stop any errors from being output. 
ob_start();

//include the page code
include 'page.php';
$cleanup = ob_end_clean();

//now output the template
include 'template.php';

page.php

<?php

add_block('head', function(){
    ?><script type="text/javascript">/* Some JS */</script><?php
});

add_block('body', function(){
    ?><p>Some body text goes here</p><?php
});

template.php

<html>
    <head>
        <title>Site Title</title>
        <?php echo get_block('head'); ?>
    </head>
    <body>
        <?php echo get_block('body'); ?>
    </body>
    <?php echo get_block('after_body'); ?>
</html>

Ответ 2

Я не уверен, как это работает, и на самом деле никогда не использовал сам шаблон. Но, возможно, это может быть так.

Скажем, что у нас есть:

index.php
page.php
template.php

Когда мы переходим к index.php, он может запускать и выводить буфер и включать page.php. После включения catch выходного буфера и использование некоторых регулярных выражений для сопоставления и блокировки в нем и их включения в переменные.

Теперь сделайте то же самое для template.php и найдите там все блоки и замените блоки блоками, найденными в page.php.

На самом деле я не думаю, что это делают шаблоны. Но это один из возможных способов.

Ответ 3

Очень маленький самодельный, шаблонный двигатель на основе замены регулярного выражения с использованием массива для "ручного" анализа шаблонов

(но я даю вам, smarty более функциональный) На любой вопрос, не стесняйтесь отвечать мне здесь.

Регулярное выражение соответствует всему файлу, например {term-_}, и замените его на условие php, которое будет выполнено во время рендеринга.

если метка "не найдена в $vars, она просто будет заменена пустой строкой

Двигатель

function parse($vars, $tpl)
{
    return preg_replace
    (
        '#\{([a-z0-9\-_]*?)\}#Ssie',
        '( ( isset($vars[\'\1\']) )
            ? $vars[\'\1\']
            : \'\'
        );',
        file_get_contents(TEMPLATE_DIR.$tpl)
    );
}

часть индекса

     <html>
          <head>...</head>
          {body}
     </html>

часть тела

    <body>
         <div class='ui'>{username}</div>
    </body>

Использование

    <?php
    // include engine function
    define("TEMPLATE_DIR", __DIR__."templates/");
    require_once("library/parse.php");

    // just init $vars on top of index
    $vars = [];

    // and access and fill it anywhere
    $vars = ["username" => $_SESSION["user"]];

    // prepare the body including previous $vars declarations
    $vars["body"] = parse($vars, 'body');

    echo parse($vars, 'index');

Выход

    <html>
         <head>...</head>
         <body>
             <div class='ui'>Qaru :)</div>
         </body>
    </html>

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

Добавьте это, чтобы запустить двигатель, чтобы предотвратить шаблоны, содержащие объектную скобку, можно плохо интерпретировать как маркер шаблонов:

$out = file_get_contents(TEMPLATE_DIR.$tpl);
$out = str_replace("{{}}", "{}", $out);

Чтобы использовать константу, вы можете использовать выполнение как:

    $empty = (DEBUG) ? "_EMPTY_" : "";
    return preg_replace
    (
        '#\{([a-z0-9\-_]*?)\}#Ssie', 
        '( ( isset($vars[\'\1\']) ) 
            ? $vars[\'\1\'] 
            : ( defined(\'_\'.strtoupper(\'\1\').\'_\') 
                ? constant(\'_\'.strtoupper(\'\1\').\'_\') 
                : $empty 
            ) 
        );',
        $out
    );

Примечание:

__DIR__ 

используемый в моем коде, действителен для PHP >= 5.3.0 try но вы можете использовать

dirname(__FILE__)

Для PHP < 5.3.0 попробуйте