退出Smarty手动完成

时间:2021-12-30 18:15:27

I am facing the problem that I'm not really sure how to develop without a framework or a template engine. I started coding that way and now I want to go to basics.

我面临的问题是,我不确定如何在没有框架或模板引擎的情况下开发。我开始编码,现在我想去基础。

I used to work with this MVC schema, using Codeigniter and Smarty as a template engine. What I want to do now is to use raw php without both tools mentioned.

我曾经使用过这个MVC架构,使用Codeigniter和Smarty作为模板引擎。我现在要做的是使用原始的PHP而不提及这两种工具。

I don't know how to "copy" the concept of Smarty's "block" and "extends".

我不知道如何“复制”Smarty的“块”和“扩展”的概念。

I used to define a base.tpl file which had html head, only the body tag, and the base css and js files (the ones that are always used in every page of the site), like this: (snippet)

我曾经定义了一个base.tpl文件,它有html头,只有body标签,以及基本css和js文件(在网站的每个页面中总是使用的文件),如下所示:(片段)

 <!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 -->

and then when I need to call this base.tpl I did this:

然后当我需要调用这个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'S 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>

I have been searching but I am affraid I'm missing the right words to search because I am not finding answers.

我一直在寻找,但我很害怕我错过了正确的搜索词,因为我找不到答案。

I would like to be guided please!

我想得到指导!

3 个解决方案

#1


1  

Another way could be to do something like this. I feel like this is probably closer to what a template engine ends up with, but with using the {block} syntax instead.

另一种方法可能是做这样的事情。我觉得这可能更接近于模板引擎的结果,而是使用{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


0  

I'm not sure how smarty does it and have actually never used a templating engine myself. But maybe this could be how it's done.

我不确定它有多聪明,实际上我自己从未使用过模板引擎。但也许这可能是它的完成方式。

Say we have:

说我们有:

index.php
page.php
template.php

When we go to index.php it could start and output buffer and include page.php. After the include catch the output buffer and use some regular expressions to match and blocks found within it and put them into variables.

当我们转到index.php时,它可以启动并输出缓冲区并包含page.php。在include之后捕获输出缓冲区并使用一些正则表达式匹配并在其中找到块并将它们放入变量中。

Now do the same for the template.php and find all the blocks in there too and replace the blocks with the blocks found in page.php.

现在对template.php执行相同操作并查找其中的所有块,并使用page.php中找到的块替换块。

I don't actually think that's how templating engines do it. But that's one possible way.

我实际上并不认为这是模板引擎如何做到的。但这是一种可能的方式。

#3


0  

A very tiny self made, templating engine based on regex replace using an array hook to "manually" parse templates

基于正则表达式的非常小的自制模板引擎使用数组挂钩替换“手动”解析模板

(but i grant you, smarty is more functional) To any question, feel free to answer me here

(但我授予你,聪明更实用)对于任何问题,请随时在这里回答我

The regex match whole file's term like {term-_}, and replace it by a php condition who will be executed on at rendering time.

正则表达式匹配整个文件的术语,如{term-_},并将其替换为将在渲染时执行的php条件。

if a mark" doesn't found in $vars, it will simply replaced by an empty string

如果在$ vars中找不到标记,则它将简单地替换为空字符串

Engine

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

part of index

指数的一部分

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

part of body

身体的一部分

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

Usage

    <?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');

Output

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

You can improve it by using constant and prevent double wrap marker {{}} or more, or placing debug trace...

您可以通过使用常量并防止双重换行标记{{}}或更多,或放置调试跟踪来改进它...

Add this to start of engine to prevent templates containing object bracket can be bad interpreted as a templates marker :

将此添加到引擎的开头,以防止包含对象括号的模板被错误地解释为模板标记:

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

To use constant, you can use perform as like :

要使用常量,可以使用如下的执行:

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

Note:

__DIR__ 

used in my code is valid for PHP >= 5.3.0 try but you can use

在我的代码中使用的有效的PHP> = 5.3.0尝试,但你可以使用

dirname(__FILE__)

For PHP < 5.3.0 try

对于PHP <5.3.0试试

#1


1  

Another way could be to do something like this. I feel like this is probably closer to what a template engine ends up with, but with using the {block} syntax instead.

另一种方法可能是做这样的事情。我觉得这可能更接近于模板引擎的结果,而是使用{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


0  

I'm not sure how smarty does it and have actually never used a templating engine myself. But maybe this could be how it's done.

我不确定它有多聪明,实际上我自己从未使用过模板引擎。但也许这可能是它的完成方式。

Say we have:

说我们有:

index.php
page.php
template.php

When we go to index.php it could start and output buffer and include page.php. After the include catch the output buffer and use some regular expressions to match and blocks found within it and put them into variables.

当我们转到index.php时,它可以启动并输出缓冲区并包含page.php。在include之后捕获输出缓冲区并使用一些正则表达式匹配并在其中找到块并将它们放入变量中。

Now do the same for the template.php and find all the blocks in there too and replace the blocks with the blocks found in page.php.

现在对template.php执行相同操作并查找其中的所有块,并使用page.php中找到的块替换块。

I don't actually think that's how templating engines do it. But that's one possible way.

我实际上并不认为这是模板引擎如何做到的。但这是一种可能的方式。

#3


0  

A very tiny self made, templating engine based on regex replace using an array hook to "manually" parse templates

基于正则表达式的非常小的自制模板引擎使用数组挂钩替换“手动”解析模板

(but i grant you, smarty is more functional) To any question, feel free to answer me here

(但我授予你,聪明更实用)对于任何问题,请随时在这里回答我

The regex match whole file's term like {term-_}, and replace it by a php condition who will be executed on at rendering time.

正则表达式匹配整个文件的术语,如{term-_},并将其替换为将在渲染时执行的php条件。

if a mark" doesn't found in $vars, it will simply replaced by an empty string

如果在$ vars中找不到标记,则它将简单地替换为空字符串

Engine

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

part of index

指数的一部分

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

part of body

身体的一部分

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

Usage

    <?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');

Output

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

You can improve it by using constant and prevent double wrap marker {{}} or more, or placing debug trace...

您可以通过使用常量并防止双重换行标记{{}}或更多,或放置调试跟踪来改进它...

Add this to start of engine to prevent templates containing object bracket can be bad interpreted as a templates marker :

将此添加到引擎的开头,以防止包含对象括号的模板被错误地解释为模板标记:

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

To use constant, you can use perform as like :

要使用常量,可以使用如下的执行:

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

Note:

__DIR__ 

used in my code is valid for PHP >= 5.3.0 try but you can use

在我的代码中使用的有效的PHP> = 5.3.0尝试,但你可以使用

dirname(__FILE__)

For PHP < 5.3.0 try

对于PHP <5.3.0试试