简单的模板VAR替代品,但与一捻 [英] Simple template var replacement, but with a twist

查看:100
本文介绍了简单的模板VAR替代品,但与一捻的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我设置在它内部有大量的电子邮件系统,和变量替换,所以我正在写一个类来管理一些变量替换存储在数据库中的模板。

下面是一个简单的例子:

  //模板存储在数据库,所以这是如何做到这一点的被装载
$模板=你好,%CUSTOMER_NAME%,感谢您联系%WEBSITE_NAME%;
//替换的阵列是手动建立并传递给类
//与实际值从数据库被称为
$替换=阵列('%CUSTOMER_NAME%'=>'鲍勃','%WEBSITE_NAME%'=>'尖端');
$渲染= str_replace函数(array_keys($替换),$替换,​​$模板);

现在,这工作得很好,适合单VAR替换,基本的东西。不过,也有一些地方应该有一个for循环,和我迷路了如何实现它。

这个想法是有会是这样的一个模板:


  

你好,%CUSTOMER_NAME%,谢谢你
  {上}产品

请求信息

其中,{}产品将传递给模板一个数组,其环绕在为要求的产品,像一个格式为:


  

我们的产品PRODUCT_NAME%有%成本
  %的PRODUCT_PRICE%。了解更多
  %product_url%。


所以这样的一个例子渲染的版本是:


  

你好,鲍勃,谢谢你的请求
  信息:


  
  

我们的产品WidgetA有$ 1的费用。
  了解更多信息,例如/ A


  
  

我们的产品WidgetB有$ 2的成本。
  了解更多信息,例如/ B


  
  

我们的产品WidgetC为$ 3成本。
  了解更多信息,例如/ C。


什么是实现这一目标的最佳方式?


解决方案

好了,我真的不看到在使用repalcements /正则表达式的模板引擎点

PHP已经是一个模板引擎,当你写<?PHP的echo $ VAR> 它只是喜欢做< {$ VAR}> {$ VAR}

它认为这种方式,PHP已经转化< PHP的echo'< B>你好< / B>'?> < b个招呼< / b> 由它的引擎,所以为什么要过来千方百计2次

我想实现一个模板引擎的方式是像这样

首先创建一个模板类

 类模板
{
   变量$瓦尔=阵列();   功能__set($键,$ VAL)
   {
      $这个 - >瓦尔[$关键] = $ VAL;
   }   函数__get($键)
   {
     返回使用isset($这个 - >瓦尔[$关键])? $这个 - >瓦尔[$关键]:假的;
   }   功能输出($第三方物流= FALSE)
   {
      如果($第三方物流===假)
      {
         死亡(没有在模板::输出选择的模板文件(...)');
      }      如果(!file_exists(($ DIR ='模板/'。$第三方物流。的.php')))
      {
         死亡(sprintf的(TPL文件不存在(%S)',$ DIR));
      }      新TemplateLoader($目录,$这个 - >瓦尔);
      返回true;
   }
}

这是你在登录使用的如的index.php,您将设置数据就像一个 stdClass的如果您不能确定它只是谷歌。当你运行该命令输出它的数据和TPL发送到下面的下一个类。


然后创建一个独立的类来编译内的TPL文件。

 类TemplateLoader
{
    私人$瓦尔=阵列();
    私人$ _ VARS =阵列(); //保持增值经销商设定的TPL文件中
    功能__construct($文件,$变量)
    {
        $这个 - >瓦尔= $变量;
        //开始捕获;
        ob_start();
           包括$文件;
           $内容= ob_get_contents();
        ob_end_clean(); //打扫       如果你想//此处返回
       回声$内容;
    }    函数__get($键)
    {
        返回使用isset($这个 - >瓦尔[$关键])? $这个 - >瓦尔[$关键]:(使用isset($这个 - > _ VARS [$关键])$这个 - > _ VARS [$关键]:FALSE):假的;
    }    功能__set($键,$ VAL)
    {
       $这个 - > _ VARS [$关键] = $ VAL;
       返回true;
    }   功能大胆($键)
   {
      回归'<强>' 。 $这个 - > $键。 '< /串>';
   }
}

我们保持这个单独的原因是所以它有自己的空间来运行,您只需加载您的TPL文件作为你的构造一个包含,因此只能加载一次,那么当被包含在该文件它可以访问内TemplateLoader所有的数据和方法。


的index.php

 < PHP
   require_once'包括/的template.php';
   require_once'包括/ TemplateLoader.php';
   $模板=新模板();   $模板 - >富='somestring';
   $模板 - >巴=阵列('一些'=>'阵');   $模板 - >捷思=新stdClass的(); //显示对象   $模板 - >输出(索引); //加载模板/ index.php文件
?>

现在在这里,我们真的不希望因为分离该PHP和视图/模板,你要确保你所有的PHP已经完成了与此页混合HTML,因为当你发送HTML或使用HTML停止脚本的某些方面运行


模板/ index.php文件

 头    < H1>< PHP $这个 - >富;?>< / H1>
    < UL>
        ?< PHP的foreach($这个 - >酒吧为这 - $> _foo):>
            <立GT;< PHP的echo $这个 - > _foo; ?>< /李>
        < PHP endforeach; ?>
    < / UL>
     &所述p为H.;测试对象和所述; / P>
     < PHP $这个 - >侧边栏= $这个 - > foo-> show_sidebar? $这个 - > foo-> show_sidebar:假;>
     ?< PHP的如果($这个 - >边栏):>
        显示我的侧栏。
     < PHP ENDIF;?>
页脚

现在在这里我们可以看到PHP是混合了HTML,但这是好的,因为在ehre你应该只使用基本的东西,比如foreach对于等和变量。


注意:在TemplateLoader类你可以添加一个功能类似。

 函数大胆($键)
{
   回归'<强>' 。 $这个 - > $键。 '< /串>';
}

这将允许你增加你的模板你的行为如此大胆,斜体,atuoloop,css_secure,stripslashs ..

您仍然一切正常工具,如的stripslashes / htmlentites等。

大胆的继承人一个小例子。

  $这个 - >大胆('富'); //返回<强> somestring< /串>


您可以添加很多工具进入TempalteLoader类如INC()来加载其他TPL文件,你可以开发一个辅助系统,让您可以去 $这个 - > helpers->的jQuery - > googleSource

如果您有任何问题随时问我。

----------

在你的数据库中存储的一个例子。

 < PHP
如果(假=($ =数据的mysql_query(SELECT * FROM tpl_catch,其中ITEM_NAME = \\指数\\和item_save_time>'!。时间() - 3600'LIMIT 1 ORDER BY item_save_time DESC')))
{
    如果(myslq_num_rows($数据)大于0)
    {
       $行= mysql_fetch_assc($的数据);
       死亡($行[0] ['item_content']);
    }其他
    {
       //在第一部分样品code(的index.php)编译
       //插入到数据库其次
       然后打印出的内容。
    }
}
?>

如果你想存储您的TPL文件的包括PHP ,然后这不是一个问题,你在TPL文件名路过只是搜索数据库,而不是文件系统中的模板

So I'm setting up a system that has a lot of emails, and variable replacement within it, so I'm writing a class to manage some variable replacement for templates stored in the database.

Here's a brief example:

// template is stored in db, so that's how this would get loaded in 
$template = "Hello, %customer_name%, thank you for contacting %website_name%"; 
// The array of replacements is built manually and passed to the class 
// with actual values being called from db 
$replacements = array('%customer_name%'=>'Bob', '%website_name%'=>'Acme'); 
$rendered = str_replace(array_keys($replacements), $replacements, $template); 

Now, that works well and good for single var replacements, basic stuff. However, there are some places where there should be a for loop, and I'm lost how to implement it.

The idea is there'd be a template like this:

"hello, %customer_name%, thank you for requesting information on {products}"

Where, {products} would be an array passed to the template, which the is looped over for products requested, with a format like:

Our product %product_name% has a cost of %product_price%. Learn more at %product_url%.

So an example rendered version of this would be:

"hello, bob, thank you for requesting information on:

Our product WidgetA has a cost of $1. Learn more at example/A

Our product WidgetB has a cost of $2. Learn more at example/B

Our product WidgetC has a cost of $3. Learn more at example/C.

What's the best way to accomplish this?

解决方案

Well, I really dont see the point in a template engine that uses repalcements/regex

PHP Is already a template engine, when you write <?php echo $var?> its just like doing <{$var}> or {$var}

Think of it this way, PHP Already translates <?php echo '<b>hello</b>'?> into <b>hello</b> by its engine, so why make it do everything 2 times over.

The way i would implement a template engine is like so

Firstly create a template class

class Template
{
   var $vars = array();

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

   function __get($key)
   {
     return isset($this->vars[$key]) ? $this->vars[$key] : false;
   }

   function output($tpl = false)
   {
      if($tpl === false)
      {
         die('No template file selected in Template::output(...)');
      }

      if(!file_exists(($dir = 'templates/' . $tpl . '.php')))
      {
         die(sprintf('Tpl file does not exists (%s)',$dir));
      }

      new TemplateLoader($dir,$this->vars);
      return true;
   }
}

This is what you use in your login such as index.php, you will set data just like an stdClass just google it if your unsure. and when you run the output command it sends the data and tpl to the next class below.


And then create a standalone class to compile the tpl file within.

class TemplateLoader
{
    private $vars = array();
    private $_vars = array(); //hold vars set within the tpl file
    function __construct($file,$variables)
    {
        $this->vars = $variables;
        //Start the capture;
        ob_start();
           include $file;
           $contents = ob_get_contents();
        ob_end_clean(); //Clean it

       //Return here if you wish
       echo $contents;
    }

    function __get($key)
    {
        return isset($this->vars[$key]) ? $this->vars[$key] : (isset($this->_vars[$key]) ? $this->_vars[$key] : false) : false;
    }

    function __set($key,$val)
    {
       $this->_vars[$key] = $val;
       return true;
    }

   function bold($key)
   {
      return '<strong>' . $this->$key . '</string>';
   }
}

The reason we keep this seperate is so it has its own space to run in, you just load your tpl file as an include in your constructor so it only can be loaded once, then when the file is included it has access to all the data and methods within TemplateLoader.


Index.php

<?php
   require_once 'includes/Template.php';
   require_once 'includes/TemplateLoader.php';


   $Template = new Template();

   $Template->foo = 'somestring';
   $Template->bar = array('some' => 'array');

   $Template->zed = new stdClass(); // Showing Objects

   $Template->output('index'); // loads templates/index.php
?>

Now here we dont really want to mix html with this page because by seperating the php and the view / templates you making sure all your php has completed because when you send html or use html it stops certain aspects of your script from running.


templates/index.php

header

    <h1><?php $this->foo;?></h1>
    <ul>
        <?php foreach($this->bar as $this->_foo):?>
            <li><?php echo $this->_foo; ?></li>
        <?php endforeach; ?>
    </ul>
     <p>Testing Objects</p>
     <?php $this->sidebar = $this->foo->show_sidebar ? $this->foo->show_sidebar : false;?>
     <?php if($this->sidebar):?>
        Showing my sidebar.
     <?php endif;?>
footer

Now here we can see that were mixing html with php but this is ok because in ehre you should only use basic stuff such as Foreach,For etc. and Variables.


NOTE: IN the TemplateLoader Class you can add a function like..

function bold($key)
{
   return '<strong>' . $this->$key . '</string>';
}

This will allow you to increase your actions in your templates so bold,italic,atuoloop,css_secure,stripslashs..

You still have all the normal tools such as stripslashes/htmlentites etc.

Heres a small example of the bold.

$this->bold('foo'); //Returns <strong>somestring</string>


You can add lots of tools into the TempalteLoader class such as inc() to load other tpl files, you can develop a helper system so you can go $this->helpers->jquery->googleSource

If you have any more questions feel free to ask me.

----------

An example of storing in your database.

<?php
if(false != ($data = mysql_query('SELECT * FROM tpl_catch where item_name = \'index\' AND item_save_time > '.time() - 3600 .' LIMIT 1 ORDER BY item_save_time DESC')))
{
    if(myslq_num_rows($data) > 0)
    {
       $row = mysql_fetch_assc($data);
       die($row[0]['item_content']);
    }else
    {
       //Compile it with the sample code in first section (index.php)
       //Followed by inserting it into the database
       then print out the content.
    }
}
?>

If you wish to store your tpl files including PHP then that's not a problem, within Template where you passing in the tpl file name just search db instead of the filesystem

这篇关于简单的模板VAR替代品,但与一捻的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆