模板解析类

模板解析类可以对你视图文件中的伪变量进行简单的替换,它可以解析简单的变量和变量标签对。

如果你从没使用过模板引擎,下面是个例子,伪变量名称使用大括号括起来:

  1. <html>
  2. <head>
  3. <title>{blog_title}</title>
  4. </head>
  5. <body>
  6. <h3>{blog_heading}</h3>
  7.  
  8. {blog_entries}
  9. <h5>{title}</h5>
  10. <p>{body}</p>
  11. {/blog_entries}
  12.  
  13. </body>
  14. </html>

这些变量并不是真正的 PHP 变量,只是普通的文本,这样能让你的模板(视图文件)中没有任何 PHP 代码。

注解

CodeIgniter 并没有 让你必须使用这个类,因为直接在视图中使用纯 PHP 可能速度会更快点。尽管如此,一些开发者还是喜欢使用模板引擎,他们可能是和一些其他的不熟悉 PHP 的设计师共同工作。

重要

模板解析类 不是 一个全面的模板解析方案,我们让它保持简洁,为了达到更高的性能。

使用模板解析类

初始化类

跟 CodeIgniter 中的其他类一样,可以在你的控制器中使用 $this->load->library()方法加载模板解析类:

  1. $this->load->library('parser');

一旦加载,模板解析类就可以像下面这样使用:

  1. $this->parser

解析模板

你可以使用 parse() 方法来解析(或显示)简单的模板,如下所示:

  1. $data = array(
  2. 'blog_title' => 'My Blog Title',
  3. 'blog_heading' => 'My Blog Heading'
  4. );
  5.  
  6. $this->parser->parse('blog_template', $data);

第一个参数为 视图文件 的名称(在这个例子里,文件名为 blog_template.php),第二个参数为一个关联数组,它包含了要对模板进行替换的数据。上例中,模板将包含两个变量:{blog_title} 和 {blog_heading} 。

没有必要对 $this->parser->parse() 方法返回的结果进行 echo 或其他的处理,它会自动的保存到输出类,以待发送给浏览器。但是,如果你希望它将数据返回而不是存到输出类里去,你可以将第三个参数设置为 TRUE

  1. $string = $this->parser->parse('blog_template', $data, TRUE);

变量对

上面的例子可以允许替换简单的变量,但是如果你想重复某一块代码,并且每次重复的值都不同又该怎么办呢?看下我们一开始的时候展示那个模板例子:

  1. <html>
  2. <head>
  3. <title>{blog_title}</title>
  4. </head>
  5. <body>
  6. <h3>{blog_heading}</h3>
  7.  
  8. {blog_entries}
  9. <h5>{title}</h5>
  10. <p>{body}</p>
  11. {/blog_entries}
  12.  
  13. </body>
  14. </html>

在上面的代码中,你会发现一对变量:{blog_entries} data… {/blog_entries} 。这个例子的意思是,这个变量对之间的整个数据块将重复多次,重复的次数取决于 "blog_entries" 参数中元素的个数。

解析变量对和上面的解析单个变量的代码完全一样,除了一点,你需要根据变量对的数据使用一个多维的数组,像下面这样:

  1. $this->load->library('parser');
  2.  
  3. $data = array(
  4. 'blog_title' => 'My Blog Title',
  5. 'blog_heading' => 'My Blog Heading',
  6. 'blog_entries' => array(
  7. array('title' => 'Title 1', 'body' => 'Body 1'),
  8. array('title' => 'Title 2', 'body' => 'Body 2'),
  9. array('title' => 'Title 3', 'body' => 'Body 3'),
  10. array('title' => 'Title 4', 'body' => 'Body 4'),
  11. array('title' => 'Title 5', 'body' => 'Body 5')
  12. )
  13. );
  14.  
  15. $this->parser->parse('blog_template', $data);

如果你的变量对数据来自于数据库查询结果,那么它已经是一个多维数组了,你可以简单的使用数据库的result_array() 方法:

  1. $query = $this->db->query("SELECT * FROM blog");
  2.  
  3. $this->load->library('parser');
  4.  
  5. $data = array(
  6. 'blog_title' => 'My Blog Title',
  7. 'blog_heading' => 'My Blog Heading',
  8. 'blog_entries' => $query->result_array()
  9. );
  10.  
  11. $this->parser->parse('blog_template', $data);

使用说明

如果你传入的某些参数在模板中没用到,它们将被忽略:

  1. $template = 'Hello, {firstname} {lastname}';
  2. $data = array(
  3. 'title' => 'Mr',
  4. 'firstname' => 'John',
  5. 'lastname' => 'Doe'
  6. );
  7. $this->parser->parse_string($template, $data);
  8.  
  9. // Result: Hello, John Doe

如果你的模板中用到了某个变量,但是你传入的参数中没有,将直接显示出原始的伪变量:

  1. $template = 'Hello, {firstname} {initials} {lastname}';
  2. $data = array(
  3. 'title' => 'Mr',
  4. 'firstname' => 'John',
  5. 'lastname' => 'Doe'
  6. );
  7. $this->parser->parse_string($template, $data);
  8.  
  9. // Result: Hello, John {initials} Doe

如果你的模板中需要使用某个数组变量,但是你传入的参数是个字符串类型,那么变量对的起始标签将会被替换,但是结束标签不会被正确显示:

  1. $template = 'Hello, {firstname} {lastname} ({degrees}{degree} {/degrees})';
  2. $data = array(
  3. 'degrees' => 'Mr',
  4. 'firstname' => 'John',
  5. 'lastname' => 'Doe',
  6. 'titles' => array(
  7. array('degree' => 'BSc'),
  8. array('degree' => 'PhD')
  9. )
  10. );
  11. $this->parser->parse_string($template, $data);
  12.  
  13. // Result: Hello, John Doe (Mr{degree} {/degrees})

如果你的某个单一变量的名称和变量对中的某个变量名称一样,显示结果可能会不对:

  1. $template = 'Hello, {firstname} {lastname} ({degrees}{degree} {/degrees})';
  2. $data = array(
  3. 'degree' => 'Mr',
  4. 'firstname' => 'John',
  5. 'lastname' => 'Doe',
  6. 'degrees' => array(
  7. array('degree' => 'BSc'),
  8. array('degree' => 'PhD')
  9. )
  10. );
  11. $this->parser->parse_string($template, $data);
  12.  
  13. // Result: Hello, John Doe (Mr Mr )

视图片段

你没必要在你的视图文件中使用变量对来实现重复,你也可以在变量对之间使用一个视图片段,在控制器,而不是视图文件中,来控制重复。

下面是一个在视图中实现重复的例子:

  1. $template = '<ul>{menuitems}
  2. <li><a href="{link}">{title}</a></li>
  3. {/menuitems}</ul>';
  4.  
  5. $data = array(
  6. 'menuitems' => array(
  7. array('title' => 'First Link', 'link' => '/first'),
  8. array('title' => 'Second Link', 'link' => '/second'),
  9. )
  10. );
  11. $this->parser->parse_string($template, $data);

结果:

  1. <ul>
  2. <li><a href="/first">First Link</a></li>
  3. <li><a href="/second">Second Link</a></li>
  4. </ul>

下面是一个在控制器中利用视图片段来实现重复的例子:

  1. $temp = '';
  2. $template1 = '<li><a href="{link}">{title}</a></li>';
  3. $data1 = array(
  4. array('title' => 'First Link', 'link' => '/first'),
  5. array('title' => 'Second Link', 'link' => '/second'),
  6. );
  7.  
  8. foreach ($data1 as $menuitem)
  9. {
  10. $temp .= $this->parser->parse_string($template1, $menuitem, TRUE);
  11. }
  12.  
  13. $template = '<ul>{menuitems}</ul>';
  14. $data = array(
  15. 'menuitems' => $temp
  16. );
  17. $this->parser->parse_string($template, $data);

结果:

  1. <ul>
  2. <li><a href="/first">First Link</a></li>
  3. <li><a href="/second">Second Link</a></li>
  4. </ul>

类参考

  • _class _CI_Parser
    • parse($template, $data[, $return = FALSE])

参数:

  1. - **$template** (_string_) -- Path to view file
  2. - **$data** (_array_) -- Variable data
  3. - **$return** (_bool_) -- Whether to only return the parsed template返回:

Parsed template string返回类型:string

根据提供的路径和变量解析一个模板。

  • parsestring($template, $data[, $return = FALSE_])

参数:

  1. - **$template** (_string_) -- Path to view file
  2. - **$data** (_array_) -- Variable data
  3. - **$return** (_bool_) -- Whether to only return the parsed template返回:

Parsed template string返回类型:string

该方法和 parse() 方法一样,只是它接受一个字符串作为模板,而不是去加载视图文件。

  • setdelimiters([$l = '{'[, $r = '}'_]])

参数:

  1. - **$l** (_string_) -- Left delimiter
  2. - **$r** (_string_) -- Right delimiter返回类型:

void

设置模板中伪变量的分割符(起始标签和结束标签)。