我通过浏览和研究现有框架来了解MVC框架的工作原理。似乎我看到的每个框架都有一个布局,每个控制器中的每个方法都有自己的模板文件。所以会有一个登录模板,一个注销模板,一个寄存器,等等。
我的问题是,如何以及为什么要在一个文件中为整个页面创建模板。假设您想在多个页面上显示登录表单,您是否不必为要在其上显示的每个模板创建登录表单?这不违反不重复自己的规则(DRY)吗?
到目前为止,我一直在做的事情是,我一直在创建一小块模板,然后将它们组合起来创建每个页面。所以不要做这样的事情,
$title = 'Blah Blah Blah';
$user = 'Jon Miller';
include 'index.phtml';
<html>
<head>
<title><?php echo $title; ?></title>
</head>
<body>
<h3><?php echo $user; ?></h3>
<form>login form</form>
</body>
</html>
我一直这样做
$title = 'Blah Blah Blah';
include 'header.phtml';
$user = 'Jon Miller';
include 'user.phtml';
include 'login_form.phtml';
include 'footer.phtml';
header.phtml
<html>
<head>
<title><?php echo $title; ?></title>
</head>
<body>
user.phtml
<h3><?php echo $user; ?></h3>
login_form.phtml
<form>login form</form>
footer.phtml
</body>
</html>
总而言之,我只想知道正确的方法,以及如何以及为什么......这似乎违反了DRY规则。
谢谢
一句话:组织。分离页面的每个部分将允许分别查看/编辑它们中的每一个。这个简单的概念非常有益。例如,团队中任何想要处理登录过程的人都可以很容易地发现他们必须编辑login_form.phtml
并且他们可以确保编辑login_form.phtml
不太可能无意中干扰其他功能。
从最佳实践来看,这就是我如何做到的(不完全相似)。
$Title = 'Blah Blah Blah';
$User = 'Jon Miller';
$ThemeName = "MyGreenPage";
$Contents = array("User", "Login_Form");
function Include($FileName) {
if (file_exists($FileName))
include $FileName;
}
MyGreenPage.phtml
:
<html>
<head>
<title><?php echo $title; ?></title>
<?php
foreach($Contents as $Content)
Include("$Content.pcss");
?>
<?php
foreach($Contents as $Content)
Include("$Content.pjs");
?>
</head>
<body>
<?php
foreach($Contents as $Content)
Include("$Content.phtml");
?>
</body>
</html>
User.pcss
:
/* Some styles needed by User */
User.pjs
:
/* Some script needed by User */
User.phtml
:
<h3><?php echo $user; ?></h3>
Login_Form.pcss
:
/* Some styles needed by Login_Form */
Login_Form.pjs
:
/* Some script needed by Login_Form */
Login_Form.phtml
:
<form>login form</form>
让我再次提醒你,这不完全是我所做的(我使用的是OOP),所以这可能不完全按原样运行,你可能需要编辑它。
你应该看看'layouts'和'view helpers'的概念。虽然我已经链接到这些概念的Zend Framework版本,但其他MVC框架(以及MVC概念)也应该有它们。
基本的想法是,您的网页“查看”(例如登录表单)会包含在您的网站“布局”中 - 整个网站中使用的常规模板。当您请求具有不同视图的不同控制器(例如用户配置文件)时,该视图也包含在同一布局中。
要在所有页面上包含类似登录表单的内容,可以使用视图助手。该视图助手可以显示当前用户,或显示登录表单,具体取决于登录状态。视图助手可以包含在布局中,也可以包含在特定控制器中(只要MVC框架允许某种命名的渲染段)。
两步“包含”方法比零件的线性包含(包括标题,内容,然后页脚 - 您现在正在做的)更好,因为您的模板不必拆分HTML标记。 Zend Guide在布局中有一个good visual example视图模板。
使用PHP进行HTML模板化的最常用方法是使用以下常用模板引擎之一:
或者,您可以在HTML中放置看起来像<% variablename %>
的占位符。只需加载你的HTML,做一个正则表达式找到所有占位符并用相应的变量替换它们。
或者,您可以加载HTML,将其解析为DOM document,然后修改您的DOM。我创建了库DOM Query,以便能够使用类似jQuery的语法执行此操作,但您也可以使用vanilla PHP或其他几个库中的一个。
或者,您可以使用JavaScript在前端进行一些HTML模板化。如果你想在前端和后端进行HTML模板化,你可能需要考虑使用Mustache,因为Mustache模板可以在前端(使用JavaScript)和后端(使用PHP)中使用。
对于我正在研究的这个项目,所有视图都是XSL模板。我不是将变量传递给视图,而是在控制器中生成所有XML并将其转换为视图。
我喜欢这种结构,因为我可以将所有模板保存在一个文件中,并按照我想要的方式安排它们。它也是一种标准模板语言,非常灵活,有大量文档。到目前为止,这一直很顺利。
这个结构的一个很好的例子是WoW Armory网站(查看来源)。