Lua admin后台开发 (6) 模板引擎的使用

上一章节我们初步了解了如何使用模板引擎, 现在我们深入了解模板引擎.

什么是模板引擎

“模板引擎(这里指Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的.”

“模板引擎提供特定的格式与语法, 以此为依据将模板转换为标准HTML文档.”

模板引擎的适用场景

适合服务端后台开发者.

Lua 模板引擎

admin.view库中的template方法实则为template库中的compile方法的引用, 这个方法返回一个函数, 调用返回的函数将会编译模板.

1. 基础语法

  • {{ Lua Expression }} - Lua Expression是一段lua表达式; 作用为输出表达式的结果, 一些特殊符号将会被转义;

  • {* Lua Expression *} - Lua Expression是一段lua表达式; 作用为输出表达式的结果, 不会转义任何符号;

  • {% Lua code %} - 执行一段Lua代码, 如: {% for i = x, y do %} ... {% end %};

  • {# comments #} - comments仅作为注释, 不会包含在输出字符串内. 这段语法的作用类似lua内的----[[]];

  • {( template )} - 导入其它模板文件, 并且支持传参: {("file.html", { message = "Hello, World" })};

  • {-raw-} ... {-raw-} - 定义在两端之中的内容将不会做任何处理.

2. 转义字符

这里列出了可能被转义的字符:

  • & 将会转义为 &;

  • < 将会转义为 <;

  • > 将会转义为 >

  • " 将会转义为 "

  • ' 将会转义为 '

  • / 将会转义为 /

实战

实战以简单为主. 本章设计到内容主要为深入模板, 代码不会映射到其它章节中.

1. 字段展示

业务模型: 在页面上列出水果糖的个人信息.



<html>
<head>
  <title>{*title*}title>
head>
<body>
  <h1 align="center">{*title*}h1>
  <p>姓名: {*name*}p>
  <p>性别: {*sex*}p>
  <p>年龄: {*age*}p>
  <p>身高: {*height*}p>
  <p>婚姻: {*marriage*}p>
body>
html>
local httpd = require "httpd"
local app = httpd:new("http")

local view = require "admin.view"

app:use("/user", function(content)
  return view.template("view/books.html") {
    title = "水果糖的个人信息",
    name = "水果糖",
    sex = "男",
    age = 29,
    height = "176cm",
    marriage = "已婚"
  }
end)

app:static("static")

app:listen("", 8080)

app:run()

Lua admin后台开发 (6) 模板引擎的使用_第1张图片

2. 循环添加

业务场景: 我们现在有X本书, 这些书需要在页面上展示. 根据实际数量按顺序列出。



<html>
<head>
  <title>{*title*}title>
head>
<body>
  <h1 align="center">{*title*}h1>
  {% for _, book in ipairs(books) do %}
    <li align="center">{*book*}li>
  {% end %}
body>
html>
-- script/main.lua
local httpd = require "httpd"
local app = httpd:new("http")

local view = require "admin.view"

app:use("/books", function(content)
  return view.template("view/books.html") {
    title = "编程书籍列表",
    books = { "C语言基础教程", "MySQL 从入门到精通", "Lua 编程指南", "Lua Web开发指南", "Lua Admin后台开发指南" }
  }
end)

app:static("static")

app:listen("", 8080)

app:run()

Lua admin后台开发 (6) 模板引擎的使用_第2张图片

3. 条件渲染

业务场景: 我们有一些商品, 我们将不展示某些危险商品.



<html>
<head>
  <title>{*tiitle*}title>
head>
<body>
  <h1 align="center">{*title*}h1>
  {% for index, product in ipairs(products) do %}
    {% if product.type == "安全" then %}
      <ul>
        <li>{*"当前索引: " .. index *}li>
        <li>{*product.name*}li>
        <li>{*product.price*}li>
        <li>{*product.type*}li>
      ul>
    {% end %}
  {% end %}
body>
html>
-- script/main.lua
local httpd = require "httpd"
local app = httpd:new("http")

local view = require "admin.view"

app:use("/products", function(content)
  return view.template("view/products.html") {
    title = "商品列表",
    products = {
      { name = "大白兔奶糖", type = "安全", price = 10},
      { name = "霰弹枪", type = "危险", price = 5700 },
      { name = "TNT", type = "危险", price = 1230000 },
      { name = "三星Note7", type = "危险", price = 1500 },
      { name = "C++从入门到弃坑", type = "安全", price = 50},
    }
  }
end)

app:static("static")

app:listen("", 8080)

app:run()

Lua admin后台开发 (6) 模板引擎的使用_第3张图片

4. 模板组合

业务场景: 由于某个模板代码量太多, 我们现在需要将其拆分为head.html, body.html.



<html>
{(view/modular/head.html)}
{(view/modular/body.html)}
html>

<head>
  <title>{*title*}title>
head>

<body>
  <p align="center">{*body*}p>
body>
-- script/main.lua
local httpd = require "httpd"
local app = httpd:new("http")

local view = require "admin.view"

app:use("/products", function(content)
  return view.template("view/modular/base.html") {
    title = "title头部",
    body = "body内容",
  }
end)

app:static("static")

app:listen("", 8080)

app:run()

5. 模板语法的注释

业务场景: 模板之间的嵌套过于复杂



<html>
<head>
  <title>{*title*}title>
head>
<body>
  {# 这是一段注释, 不会被显示出来! #}
  <h1>{*title*}h1>
  {#
    多行注释也不会被显示出来
    <h1>{*title*}h1>
  #}
body>
html>
-- script/main.lua
local httpd = require "httpd"
local app = httpd:new("http")

local view = require "admin.view"

app:use("/ignore", function(content)
  return view.template("view/ignore.html") {
    title = "title头部",
  }
end)

app:static("static")

app:listen("", 8080)

app:run()

Lua admin后台开发 (6) 模板引擎的使用_第4张图片

6. 前、后端模板语法冲突

业务场景: 一些特殊情况下的语法冲突. 例如: 语言代码语法冲突、模板语法冲突.



<html>
<head>
  <title>{*title*}title>
head>
<body>
  <div id="view"/>
body>
  {-raw-}
  <script type="text/javascript" id="tpl_mail">
    <a href="mailto:{{d.mail}}">{{ d.mail }}</a>
  script>

  <script type="text/javascript" id="tpl_phone">
    <a href="tel:{{d.phone}}">{{ d.phone }}</a>
  script>
  {-raw-}
html>
-- script/main.lua
local httpd = require "httpd"
local app = httpd:new("http")

local view = require "admin.view"

app:use("/templates", function(content)
  return view.template("view/templates.html") {
    title = "title头部",
  }
end)

app:static("static")

app:listen("", 8080)

app:run()

当我们使用浏览器访问的时候发现框架抛出一个异常: attempt to index a nil value (global 'd').

然后我们在发生冲突块的地方加上了{-raw-} ... {-raw-}标签, 这是告诉lua模板解析器忽略这一段的解析. 再次访问, 就不会再抛出异常了.

技术发展到现在, 很多模板解析器都已经添加了自定义前缀与闭合的功能. 这样使各个框架独立性更高, 遇到冲突的场景也会大大减少.

目录结构

[candy@MacBookPro:~/Documents/core_framework] $ tree view
view
├── Modular
│   ├── base.html
│   ├── body.html
│   └── head.html
├── books.html
├── ignore.html
├── products.html
├── templates.html
├── test.html
└── userinfo.html

1 directory, 9 files
[candy@MacBookPro:~/Documents/core_framework] $

最后

我们已经学会了如何使用模板, 下面的章节我们将深入学习admin库.

你可能感兴趣的:(Lua,Admin后台开发,Lua,Web,Lua,Web,Admin)