面向 PHP 开发者的 Jade 模板
面向 PHP 开发者的 Jade 模板
引言
Jade是一款在Node.js/Express社区引起轰动的模板引擎。它能够生成结构良好且易于维护的HTML视图模板,但PHP开发者并不广泛使用它。主要原因是,在Jade语法中嵌入PHP片段会产生丑陋且难以维护的代码,并且在某种程度上违背了使用Jade的初衷。我将介绍一个使用简单Jade扩展的开发工作流程,该扩展允许PHP开发者获得Jade语法的全部优势,而无需嵌入原始HTML以支持PHP所带来的语法劣势。
背景
-
什么是Jade?
Jade是一种编译为HTML的语言,它是将应用程序逻辑与表示标记分离的绝佳方式。简单来说,Jade就是没有标签的HTML。
为了引起您的兴趣,这里有一个Jade模板和等效HTML的示例。
doctype html html(lang="en") head meta(charset="utf-8") title Jade Example meta(name="description" content="") meta(name="author" content="") //- Mobile Specific Metas meta(name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1") body div h1 Jade is Wonderful.... div p. Nullam a dolor id arcu semper finibus ut pulvinar orci. Proin sodales nisi et dictum pulvinar. Duis orci velit, suscipit et porttitor gravida, molestie ac purus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras felis neque, gravida a blandit ac, rutrum ut sapien. Vivamus tincidunt volutpat libero eget tempor. Nam dolor mauris, mollis in euismod vitae, viverra ac libero div p Copyright 2014 www.jade4php.com. All rights reserved. //- Scripts script(type="text/javascript" src="js/jquery-1.8.0.min.js")
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Jade Example</title> <meta name="description" content=""> <meta name="author" content=""> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> </head> <body> <div> <h1>Jade is Wonderful....</h1> </div> <div> <p> Nullam a dolor id arcu semper finibus ut pulvinar orci. Proin sodales nisi et dictum pulvinar. Duis orci velit, suscipit et porttitor gravida, molestie ac purus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras felis neque, gravida a blandit ac, rutrum ut sapien. Vivamus tincidunt volutpat libero eget tempor. Nam dolor mauris, mollis in euismod vitae, viverra ac libero </p> </div> <div> <p>Copyright 2014 www.jade4php.com. All rights reserved.</p> </div> <script type="text/javascript" src="js/jquery-1.8.0.min.js"></script> </body> </html>
要了解更多关于Jade编程语言的信息以及它如何改变您与HTML的关系,请访问Jade Language网站,或者查看CodeProject上Dave Auld的一个精彩教程Feeling Jaded with Jade? Don't Be!。
-
喜爱Jade的理由
-
没有标签
告别那些随着每一次艰难的修改而变得越来越难以管理的意大利面条式HTML代码。Jade优雅而简单。元素通过缩进来表示,因此无需关闭标签,并且由于格式对语法很重要,因此无论您的老板让您修改多少次,代码都易于阅读且维护起来令人愉悦。
-
主模板
您可以创建主布局来组织您的网站,并为站点地图中的各个页面或部分包含不同的内容“块”。
-
Markdown
您可以使用内置的Markdown过滤器轻松地在模板文件中包含Markdown语法。
-
与客户端框架互补
如果您使用像Angular.js这样的客户端框架,您将享受到服务器端和客户端代码结构良好、易于维护的所有好处。引用Pangloss博士的话,毫无讽刺意味地说“Avec Jade tout est pour le mieux dans le meilleur des mondes”,其大致翻译为“有了Jade,一切都朝着最好的世界发展。”
-
您可以交互式地学习Jade
Jade By Example是一个很好的地方,可以交互式地探索Jade并进行尝试。
-
您可以重构代码
不再因为害怕打破脆弱的代码而犹豫不决。Jade积极地鼓励您在进行那些紧迫的最后时刻更改时进行重构。
-
使用Mixins简化常用代码
使用Jade参数化的Mixins,可以轻松简单地生成菜单、面板和导航小部件。
-
轻松将现有HTML转换为Jade
有一个现有的网站让你感到羞愧吗?没问题。[Convert HTML to Jade](http://html2jade.aaron-powell.com/)是一个在线资源,您可以使用它来让那个陈旧的网站焕然一新。
-
您可以在PHP中使用Jade
Node/Express是开发网站的绝佳环境,但我们生活在一个共享主机和PHP/MySQL的世界里。我离不开Jade,但我希望能在我的正常工作流程中使用它。而且说实话,我确实对PHP和Jade都有着一种深厚的感情。
-
Jade很酷
简单来说,Jade需要更少的时间来编码,代码行数更少,比HTML更漂亮,更易于维护,并且能与我使用的所有其他Web开发工具很好地配合。有什么理由不爱它呢。
-
Using the Code
-
PHP开发者如何使用Jade?
到目前为止,我描述了一个代码乌托邦,我知道您迫不及待地想将其集成到您的PHP开发工具包中。但有一个障碍。在PHP中使用Jade意味着引入一些原始HTML来注入PHP逻辑和变量。例如:
<?php echo htmlspecialchars($foo, ENT_QUOTES, 'UTF-8'); >?
这有多丑陋?但在您绝望地放弃并回到地下室去编写更多的邪恶HTML标记之前,有一个简单的解决方法。
使用一个名为jade4php的Jade扩展,您可以这样写:
p!= php('$foo')
现在,这是否让您感觉好多了?这个简洁的语句将生成以下编译后的HTML标记,但没有任何痛苦。
!=
只是告诉Jade不要转义段落内容,因为它们已经被PHP的htmlspecialcharacters
函数转义了。<p> <?php echo htmlspecialchars($foo, ENT_QUOTES, 'UTF-8'); > </p>
不像那些还在HTML健身房里痛苦挣扎的家伙们,蓝色的Jade之道只有收获没有痛苦(我想我会在T恤上印上这句标语)。
-
示例项目
-
下载jade4php示例网站并将其解压缩到您的项目文件夹中。文件夹的位置或名称并不重要,但我建议放在您的主文件夹中的某个地方。
示例项目的实时演示可在www.jade4php.com上找到,包括一个在线源代码浏览器。
-
从nodejs.org下载并安装Node.js。这将同时安装Node包管理器(npm),您将使用它来为您的项目安装Jade依赖项。
-
打开一个终端窗口,导航到您在步骤(1)中安装示例网站的文件夹,然后键入
npm install
这将安装项目
package.json
中定义的Node.js依赖项,以便您可以使用Grunt运行Jade。package.json 文件
{ "name": "jade4php-example", "version": "0.0.0", "description": "An example jade4php project", "homepage": "http://www.jade4php.com", "main": "Gruntfile.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": { "name": "Brian Etherington", "email": "brian.etherington@outlook.com", "url": "http://www.jade4php.com" }, "repository": { "type": "git", "url": "git://github.com/BookArt/jade4php-example.git" }, "bugs": { "url": "https://github.com/BookArt/jade4php-example/issues" }, "licenses": [ { "type": "MIT", "url": "https://github.com/BookArt/jade4php-example/blob/master/LICENSE-MIT" } ], "devDependencies": { "grunt": "^0.4.5", "grunt-contrib-clean": "^0.6.0", "grunt-jade4php": "^1.0.0" }, "private": true }
-
使用Node包管理器npm(已在上面步骤2中与Node一起安装)安装grunt-cli
npm install -g grunt-cli
稍后您将使用Grunt来运行Jade编译您的模板。有关Grunt及其功能的更多信息,请参阅gruntjs.com。
Grunt任务在Gruntfile.js中定义
module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), clean: { compile: ['htdocs/templates/**/*.phtml'], }, jade4php: { compile: { options: { pretty: true }, expand: true, cwd: 'jade', src: ['**/*.jade', '!_**/*.jade', '!layout/*.jade', '!mixins/*.jade', '!includes/*.jade'], dest: 'htdocs/templates/', ext: '.phtml' } } }); grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-jade4php'); grunt.registerTask('default', ['clean','jade4php']); };
-
在终端窗口中,键入grunt来运行默认任务
grunt Running "clean:compile" (clean) task >> 8 paths cleaned. Running "jade4php:compile" (jade4php) task File htdocs/templates/amazium.phtml created. File htdocs/templates/conditional.phtml created. File htdocs/templates/forms.phtml created. File htdocs/templates/intro.phtml created. File htdocs/templates/menu.phtml created. File htdocs/templates/paras.phtml created. File htdocs/templates/setup.phtml created. File htdocs/templates/tables.phtml created. Done, without errors.
刚才发生了什么?
jade4php_example/jade文件夹中的模板已编译为.phtml文件,并输出到jade4php_example/htdocs/templates文件夹。
查看Jade模板和等效的.phtml文件,看看生成了什么。
-
如果您还没有,您将需要一个支持PHP的Web服务器。
如果您想快速入门,可以使用PHP内置的开发Web服务器。从php.net/downloads.php下载并安装PHP。
配置和安装的完整说明可在php.net/manual/en/install.php找到。
您将使用命令行PHP,因此请确保PHP可执行文件的路径在您的
PATH
环境变量中,如果您使用的是Microsoft Windows。打开第二个终端窗口,导航到
jade4php
项目文件夹,然后键入...cd htdocs php -S localhost:8000
这将启动一个端口为8000的Web服务器,并将文档根目录设置为您项目的htdocs文件夹。在浏览器中,键入
localhost:8000/phpinfo.php
这应该会显示已安装的PHP版本信息。如果您收到错误,请返回并检查您的PHP安装和配置。
如果您已成功安装PHP,那么在浏览器中,您现在可以键入
localhost:8000/index.php
这将显示示例网站的主页。
或者,您可以将PHP支持添加到许多Web服务器(IIS、Xitami等)中,但最常用的是Apache HTTP Server。有关如何安装和配置Apache的信息,请访问httpd.apache.org/docs/current/install.html。
-
在您的
jade4php
项目文件夹中找到jade文件夹,并编辑intro.jade
来更改一些文本并保存编辑后的文件。在第一个终端窗口中,键入grunt
来更新已更改的模板。grunt Running "clean:compile" (clean) task >> 8 paths cleaned. Running "jade4php:compile" (jade4php) task File htdocs/templates/amazium.phtml created. File htdocs/templates/conditional.phtml created. File htdocs/templates/forms.phtml created. File htdocs/templates/intro.phtml created. File htdocs/templates/menu.phtml created. File htdocs/templates/paras.phtml created. File htdocs/templates/setup.phtml created. File htdocs/templates/tables.phtml created. Done, without errors.
与之前一样,Jade模板已编译到您的htdocs/templates文件夹。
-
刷新您的浏览器以查看更改。
-
模板类
管理模板变量和显示HTML代码的工作委托给了Template.class.php。
这段代码基于Brian Lozier的原始代码,并由我大大简化,以便管理Jade生成的.phtml模板。
我非常感谢Brian的文章Beyond The Template Engine。在我第一次阅读这篇文章时,我更倾向于一个功能更丰富的模板引擎(Smarty),而不是他提出的纯PHP。但随着Jade的出现,我认为Brian关于PHP模板化的想法非常契合。
<?php /** * A simple template class * * Based upon original code by: * * Copyright (c) 2003 Brian E. Lozier (brian@massassi.net) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ class Template { private $vars = []; // Holds all the template variables /** * Set a template variable. */ public function assign($name, $value) { $this->vars[$name] = $value; } /** * Open, parse, and return the template file. * * @param $file string the template file name */ public function fetch($file) { extract($this->vars); // Extract the vars to local namespace ob_start(); // Start output buffering include($file); // Include the file $contents = ob_get_contents(); // Get the contents of the buffer ob_end_clean(); // End buffering and discard return $contents; // Return the contents } public function display($file) { echo $this->fetch($file); } }
-
在Web工作流程中使用模板类配合/tables.php
<?php include "lib/Template.class.php"; $template = new Template(); $table = [ ['id' => 1, 'first_name' => 'Bruce', 'last_name' => 'Wayne', 'location' => 'Gotham City'], ['id' => 2, 'first_name' => 'Clarke', 'last_name' => 'Kent', 'location' => 'Metropilis'], ['id' => 3, 'first_name' => 'Oliver', 'last_name' => 'Queen', 'location' => 'Star City'], ['id' => 4, 'first_name' => 'Diana', 'last_name' => 'Prince', 'location' => 'Themyscira'] ]; $template->assign('table', $table); $template->display('templates/tables.phtml');
-
jade/tables.jade中相应的Jade代码...
This is an example of a table generated in PHP on the server. table thead tr th(scope='col') #ID: th(scope='col') First Name: th(scope='col') Last Name: th(scope='col') Location: tbody.striped //---------------------------------------------- //- Assign php row expressions to jade variables - id = '#'+php("$row['id']") - first_name = php("$row['first_name']") - last_name = php("$row['last_name']") - location = php("$row['location']") //---------------------------------------------- :php foreach($table as $row): tr td!= id td!= first_name td!= last_name td!= location :php endforeach;
-
-
工作流
将Jade集成到您的Web工作流程中非常容易。首先,通过包含一个模板类(如您在示例项目lib文件夹中找到的那个)将应用程序逻辑与视图分离,并将数据变量分配给模板变量。然后,当一切设置完毕后,调用模板类将编译后的模板输出到浏览器。
为您的Jade模板保留一个单独的文件夹,并使用Grunt运行Jade编译器来生成PHP模板类所需的.phtml文件。
您可能对项目应该如何组织有自己的想法,而
jade4php
足够灵活,可以允许您使用您喜欢的文件夹结构。如果您想做很多数据库工作,考虑也转向模型-视图-控制器(MVC)模式以获得更多功能分离的好处是一个不错的选择。但这我认为是另一篇文章、另一天的事了……
历史
- 2014年10月13日:初始版本