开发者

Replacing delimiters with PHP variables

I'm writing a mail class t开发者_StackOverflow社区hat pulls content stored in a database and loads it into a template before sending it as a HTML e-mail. However, because each e-mail contains PHP variables and dynamic content, I've decided to use delimiters. So instead of the content looking like:

Hello $username, welcome to the site.

It'll look like:

Hello {{username}}, welcome to the site.

So far I'm using these methods:

function load($name,$content)
{
    // preps the template for HTML
}

function content($template_id)
{
    $template = $this->db->get_where('email_templates',array('id'=>$template_id));
    return $template->content;
}

function new_email($email,$name,$user_type)
{
    $msg = $this->load($name,$this->content(1));
    $this->send($email,'Thanks for your application',$msg,1);
}

The trouble I'm having is how to convert a {{variable}} into a $variable so that it will parse - I don't want it to just be loaded as $username in the e-mail template. Is it just a case of using regular expressions and escaping the string so that it'll parse? Something like:

$content = str_replace("{{","'.$",$template->content);
$content = str_replace("}}",".'",$template->content);

Or is this flawed? Does anybody know what's the best thing to do?


I would not create my own templating system, because there are existing ones out there.

The most popular is probably Smarty, but there is an another one which has the same format as you created, that is mustache.

Update:

The problem with your code is that you're replacing the {{ to a .$ and store that in $content variable, then replacing }} to . and overwrite this replaced $content variable.

A possible working solution could be:

if (preg_match_all("/{{(.*?)}}/", $template, $m)) {
  foreach ($m[1] as $i => $varname) {
    $template = str_replace($m[0][$i], sprintf('$%s', $varname), $template);
  }
}

But then you would also need to eval your code somehow.


So after converting {{variable}} to $variable in your email template, you will use eval to get it replaced by the actual contents of that variable?

Why not just replace {{variable}} with the contents of $variable straight away?

Perhaps have a function that takes the template text and an array of placeholder => "text to replace it with". Then it's as simple as making up the placeholders' exact strings by adding {{ and }} around that array's key and doing str_replace.

foreach ($replacements as $placeholder => $value) {
    $placeholder = "{{" . $placeholder . "}}" ;
    $text = str_replace($placeholder, $value, $text) ;
}

Couple this with (class) constants for the placeholders and you have a very solid and typo-repelant templating system. It will not be as elegant or easy to use as a full blown templating solution, and it might require extra work from whoever writes code that uses it, but they will not make mistakes during development due to mis-named variables.


If you are going to do it yourself it is probably best to just be explicit with str_replace. If you try to convert the curly bracers to $ you'll then need to eval() which is a potential security hole.

This would be my approach with str_replace - this becomes difficult to maintain as you add more variables but it really doesn't get much simpler either.

$content = str_replace(
             array('{{username}}','{{var2}}'),
             array($username,$var2),
             $template->content
           );


use preg_replace_callback , see : http://codepad.org/EvzwTqzJ

<?php

$myTemplateStr = "Hello {{username}} , this is {{subject}} ,and other string {{example}}";
$tagRegex = "|{{(.*?)}}|is";
$result = preg_replace_callback($tagRegex,"myReplaceFunc",$myTemplateStr);
echo $result ;

/* output :     

Hello $username , this is $subject ,and other string {{example}}

*/



function myReplaceFunc($matches)
{
  $validTags = array('username','subject','name');
  $theFull = $matches[0];
  $theTag = $matches[1];
  if(in_array($theTag,$validTags) == true)
    return '$'.$theTag;
  return $theFull ;
}

?>


$template = "Hello {{username}} , this is {{subject}} ,and other the answer is on page {{example}}";

$replacements = array(
    'username' => 'Jeffrey',
    'subject' => 'your final notice',
    'page' => 43
);


function bind_to_template($replacements, $template) {
    return preg_replace_callback('/{{(.+?)}}/',
             function($matches) use ($replacements) {
        return $replacements[$matches[1]];
    }, $template);
}


echo bind_to_template($replacements, $template);

Credit to https://www.labnol.org/code/19266-php-templates

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜