【问题标题】:If statements in template system模板系统中的 if 语句
【发布时间】:2011-02-09 10:34:58
【问题描述】:

我如何在我自己的模板类版本中解析 .tpl 文件中的 {if $var > 2}{if $var}。我不想使用 smarty,因为我不需要他们所有的插件。我只想包含、if、for 和 foreach 语句。

【问题讨论】:

  • 除非这是出于学习目的(我怀疑是因为您需要代码),否则我会使用 Smarty(如果您不需要插件,请删除它们)或原生 PHP。无需重新发明已经发明了数千次的轮子
  • 如果您不想使用 Smarty,这并不排除将其用作实现细节的参考。他们正在使用正则表达式将模板伪代码转换为 php。
  • 我这样做是为了学习,但我很难理解它。因此,我不想使用 smarty,而是想创建自己的模板系统,以便更好地了解模板的工作原理。
  • 一旦你开始走这条路,你的模板语言就变成了一种编程语言。这并没有错(模板工具包是一件很美的事情),但是编写编程语言并不是胆小的人。我会先阅读解释器理论。
  • 我认为你应该使用 Smarty。如果您不这样做,您的手工解决方案将 (a) 有缺陷,并且 (b) 方式 比仅使用 Smarty 更复杂,即使您不使用他们的插件也是如此。而且,让我们面对现实吧,如果您不想使用他们的插件......那么您不必这样做。

标签: php templates templating templating-engine


【解决方案1】:

请使用php。 只需放入您的 tpl 文件:

<?php if ($var > 2) .... ?> 

比用php解析文件简单多了,代码少了很多,速度也快了很多

【讨论】:

    【解决方案2】:

    使用

    <? if( condition ) :
        ....
        ....
    else : 
        ....
        ....
    endif; ?>
    

    Difference between if () { } and if () : endif;

    【讨论】:

      【解决方案3】:

      你已经得到了上一个问题的答案:if statements in php templates using tpl
      但既然你不会走开,让我快速回答一下,然后提到哪些将是你的下一个绊脚石。

      // handle {if}...{/if} blocks
      $content =
      preg_replace_callback('#\{if\s(.+?)}(.+?)\{/if}#s', "tmpl_if", $content);
      
      function tmpl_if ($match) {
          list($uu, $if, $inner_content) = $match;
      
          // eval for the lazy!
          $if = create_function("", "extract(\$GLOBALS['tvars']); return ($if);");
      
          // a real templating engine would chain to other/central handlers
          if ( $if() ) {
              return $inner_content;
          }
          # else return empty content
      }
      

      使用像这样的正则表达式会跳过嵌套的if。不过你没问,我就不提了。正如评论中所述,您实际上需要链接到一个中心函数,该函数可以进行进一步的替换({foreach}/{include}/等),而不是像这里的 return $content

      这是可行的,但很快就会变得很麻烦。这就是为什么所有其他模板引擎(您拒绝签出)实际上将.tpl 文件转换为.php 脚本。这要容易得多,因为 PHP 已经可以处理您尝试使用 您自己的 模板类模仿的所有控制结构。

      【讨论】:

      • 那怎么可能转换成php。
      • @user381595:使用正则表达式。例如,将每个{if ...} 转换为&lt;?php if(...): ?&gt;,将每个{/if} 转换为&lt;?php endif; ?&gt;
      • @SpeedyWap:是的,它可能会。因此,为什么许多解决方案已经可以通过搜索功能发现。 stackoverflow.com/questions/3930053/…
      【解决方案4】:

      其实这很简单,除非你需要嵌套的 if 条件。

      $template = '<b>{foo}</b>{if bar} lorem ipsum {bar}{/if}....';
      
      $markers = array(
          'foo' => 'hello',
          'bar' => 'dolor sit amet',  
      );
      
      // 1. replace all markers 
      foreach($markers as $marker => $value)
          $template = str_replace('{'. $marker .'}', $value, $template);
      
      //2. process if conditions
      $template = preg_replace_callback('#\{if\s(.+?)}(.+?)\{/if}#s', function($matches) use ($markers) {
      
          list($condition, $variable, $content) = $matches;
      
          if(isset($markers[$variable]) && $markers[$variable]) {
              // if the variable exists in the markers and is "truthy", return the content
              return $content;
          }
      
      }, $template);
      

      【讨论】:

      • 知道如何为您的解决方案添加嵌套 if。
      【解决方案5】:

      您可以在您的模板文件(.tpl)中使用以下格式。,

      {if $url == 'error'}
      Error message Invalid Login!
      {/if} 
      

      【讨论】:

        【解决方案6】:

        有一个php代码示例可以解析以下模板(php 5.3+):

        [IF {post_content}]Post content is filled![ENDIF]
        [IF {post_content}]Post content is filled![ELSE]{post_content}[ENDIF]
        

        代码:

        $tags = array('post_content'=>'POST_CONTENT');
        
        $message = '1: [IF {post_content}]Post content: {post_content}![ENDIF]
                    2: [IF {post_content}]Post content is filled![ELSE]Post content is empty![ENDIF]';
        
        $matches = array();
        
        preg_match_all('/\[IF \{([^\}]*)\}\](.[^\]]+)(?:\[ELSE\](.+?))?\[ENDIF\]/s', $message, $matches);
        
        if ( empty($matches) ) {
            return $message;
        }
        
        $math_tag = '';
        foreach ( $matches[0] as $m_index => $match )
        {
            $math_tag =  trim($matches[1][$m_index]);
        
            if ( !empty($tags[$math_tag]) ) {
                // IF value is not empty
                $message = str_replace($match, $matches[2][$m_index], $message);
            } elseif( empty($tags[$math_tag]) && $matches[3][$m_index] ) {
                // ELSE
                $message = str_replace($match, $matches[3][$m_index], $message);
            } else {
                // IF NO ELSE condition - REMOVE ALL
                $message = str_replace($match, '', $message);
            }
        }
        
        foreach($tags as $tag => $value)
           $message = str_replace('{'. $tag .'}', $value, $message);
        
        echo $message;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-29
          • 2016-11-26
          • 2012-09-04
          • 1970-01-01
          • 2014-11-21
          相关资源
          最近更新 更多