【问题标题】:How to use PHP templating features properly?如何正确使用 PHP 模板功能?
【发布时间】:2013-03-30 22:49:33
【问题描述】:

在我进入正题之前,让我介绍一下上下文:) 我一直在研究我正在尝试开发的 MVC 框架的视图层。我已经创建了几个可重用的视图,例如手风琴、下拉菜单、文本编辑器、颜色选择器等。使用它,我可以做到,例如:

<?php
$template = newView('Template');
$template->panel()->add(newView('Accordion')
    ->add('Accordion entry 1')
    ->add('Accordion entry 2')
    ->add('Accordion entry 3'));
$template->content()->add(newView('Block')
    ->add('Bla bla bla')
    ->add('Bla bla bla')
    ->add('Bla bla bla'));
echo $template;
?>

还有诸如此类的事情。 问题是,要做到这一点,我必须混合 PHP 和 html 代码。例如:这是我如何生成下拉菜单的 HTML:

public function __toString() {
    $output =
        '<nav'.$this->_getHeader().'>'.
            $this->_label.
            '<ul>';
    for($i = 0, $l = count($this->_entries), $last = $l - 1; $i < $l; ++$i) {
        if($i === 0) {
           $this->_entries[$i]->addClass('First');
        }
        elseif($i === $last) {
           $this->_entries[$i]->addClass('Last');
        }
        $output .= '<li>'.$this->_entries[$i].'</li>';
    }
    $output .=
            '</ul>'.
        '</nav>';
    return $output;
}

开发人员可以通过使用 Firebug 美化代码或阅读 PHP 代码来轻松设计此功能,但设计人员不喜欢这样。 为了解决这个问题,我想使用 PHP 模板系统。例如,这对于设计师来说会更易读。

<table>
    <?php foreach($users as $user); ?>
    <tr>
        <td><?= $user->firstName ?></td>
        <td><?= $user->lastName  ?></td>
    </tr>
    <?php endforeach; ?>
</table>

我的问题是,如何使用 PHP 模板创建可重用的视图?例如,假设我有一个表示图片缩略图的视图,其中包含图片和有关它的详细信息。如果我需要显示一个包含 100 个的页面,我该怎么办?我应该要求查看 100 次吗?它会从该死的慢磁盘执行/解析/加载 100 次吗? 我不知道如何使用模板构建某种“乐高风格”视图层。你有什么想法甚至例子吗?

感谢阅读。

【问题讨论】:

  • 我认为你所说的视图不是视图——最多是部分视图。恕我直言,视图将生成整个 html 页面,并调用部分视图以获取诸如手风琴之类的逻辑元素
  • 让我们称之为 HTML 部分然后:)
  • @Basic 我认为一个视图本身可能只是由几个视图组成并保留它。我不明白为什么不是一个完整的 HTML 页面的视图不应该是常规视图。为什么要做出这样的区分?另外,在我看来,通过将视图定义为 HTML 页面,您是在说 CSV 文件、PDF 文档或 JSON 数据不能是视图。虽然我不是 MVC 专家,但我想说的是,能够在具有相同数据的不同格式之间切换,正是 MVC 值得的原因。

标签: php html templates view reusability


【解决方案1】:

为防止重复读取文件,您可以加载文件一次并将其内容保存到变量中。

重复行是视图的责任,不希望出现在模板本身内。

至于模板本身,我建议避免使用纯 PHP 模板,而使用带有变量/占位符的被动模板,如下所示:

<!-- table.tpl - Template for table. -->
<table>
{{rows}}
</table>

<!-- table-row.tpl - Template for table row. -->
<tr>
    <td>{{first_name}}</td>
    <td>{{last_name}}</td>
</tr>

然后您可以将模板变量替换为所需的值。例如,在最简单的情况下(现实世界的模板当然更复杂):

$tableTpl = file_get_contents('tpl_dir/table.tpl');
$rowTpl   = file_get_contents('tpl_dir/table-row.tpl');

$rows = array(
    array(
        'first_name' => 'Lorem',
        'last_name'  => 'Ipsum'
    ),
    array(
        'first_name' => 'Foo',
        'last_name'  => 'Bar'
    )
);

$rowsFrags = array();

// This loop can be moved to a method of a template engine class.
foreach ($rows as $row) {
    $names = array_keys($row);

    foreach ($names as &$name) {
        $name = '{{' . $name . '}}';
    }

    $rowsFrags[] = str_replace($names, array_values($row), $rowTpl);
}

$rowsCode  = implode("\n", $rowsFrags);
$tableCode = str_replace('{{rows}}', $rowsCode, $tableTpl);

echo $tableCode;

【讨论】:

  • 感谢您的回答。所以基本上你建议用它们在 HTML 代码中的值替换标记。它看起来不错,但我担心这里的性能。做所有这些 str_replace 不是很慢吗?另外,为什么选择手工制作的模板解决方案而不是我认为更快的内置模板解决方案?
  • 我的回答中所示的模板引擎提供了更干净的模板代码(特别是对设计师更友好),更多的数据与表示分离(一个好的 Web 应用程序的基本设计特性)等等控制输出代码(特别是防止冗余换行)。对于大多数现实世界的 Web 应用程序来说,性能已经足够了(我个人使用了类似的方法 [以模板引擎类的形式使用 loadTemplate()processVar()processVars()processList() 等方法。 ] 在我制作的所有网站上)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-28
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多