lua web快速開發指南(5) - 利用template庫構建httpd模板引擎

介紹template

模板引擎是爲了使用戶界面與業務數據(內容)分離而產生的, 其本身並不是一種深奧的技術.

template模板引擎首先會將合法的模板編譯爲lua函數, 然後將模板文件和數據通過模板引擎生成一份HTML代碼.

cf的admin庫整使使用了template來構建服務端渲染頁面, 並利用單頁面+iframe模式快速完成lua後臺開發.

1. template基礎語法

在真正使用之前, 我們先來學習一下template常見的一些基本語法:

  • {{ 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" })};

2. 轉義字符

  • & 將會轉義爲 &
  • < 將會轉義爲 &lt;
  • > 將會轉義爲 &gt;
  • " 將會轉義爲 &quot;
  • ' 將會轉義爲 &#39;
  • / 將會轉義爲 &#47;

3. API

  • template.compile(html)

    參數html爲字符串類型, 可以是:模板文件路徑、

    此方法返回一個渲染函數, 調用這個函數並傳入一個table(key-value)作爲參數則可以在模板文件內直接引用.

  • template.precompile(view, path, strip)

    此方法用來將view預編譯爲lua的二進制代碼塊, strip是一個bool類型用來確定是否包含調試信息.

  • template.load(path)

    此方法用來重寫template內部的加載行爲; 默認的模板加載流程爲: 檢查緩存 -> 讀取文件 -> 解析文件 -> 渲染 -> 輸出;

    path字段爲需要加載的文件路徑或模板、html代碼;

  • template.print(html)

    此方法用來重寫template內部渲染後的輸出行爲; 默認的輸出行爲: print

  • template.caching(Enable)

    此方法用來告訴template是否緩存; 默認爲true.

開始使用

現在嘗試使用模板引擎完成一個靜態頁面的數據導入工作渲染一個頁面並展示給用戶看.

首先, 導入template庫local template = require "template". 並且將目前我們熟知的編程語言名稱都羅列出來.

local languages = { 'C', 'C++', 'Java', 'golang', 'Rust', 'Ruby', 'Python', 'perl', 'Lua' }

然後, 我們在app目錄下新建一個view目錄, 並在view目錄下新建一個名字爲base.html的文件。 內容如下:

<html>
  <head>
    <title>{*title*}</title>
  </head>
  <body>
    <span><b>{*title*}:</b></span>
    <ul>
      {% if type(languages) == 'table' then %}
        {% for index, lang in ipairs(languages) do %}
          <li>{*index..'. '..lang*}</li>
        {% end %}
      {% end %}
    </ul>
    {# 沒錯, 註釋不會展示給用戶看到! #}
  </body>
</html>

最後完成一個/languages的路由註冊, 將我們剛剛完成的模板渲染出來.

local template = require "template"
app:use('/languages', function(content)
  template.cache = {}
    local languages = { 'C', 'C++', 'Java', 'golang', 'Rust', 'Ruby', 'Python', 'perl', 'Lua' }
  return template.compile("view/base.html"){
        title = '語言列表',
    languages = languages
  }
end)

template.cache = {}的意思是, 每次都重新刷新緩存去讀取文件, 這樣方便我們進行調試.

最後打開http://localhost:8080/languages查看效果.

將一個模板分解到多個文件中

當一個項目的業務需求變得非常多的時候, 即是一個單純的模板頁面也會變得非常龐大並且不容維護與閱讀.

現在我們來嘗試將上面的模板進行模塊化.

首先, 我們繼續在app目錄新建head.htmlcontent.html. 然後將這些代碼拷貝進去:

{# 這是head.html的內容 #}
<title>{*title*}</title>
{# 這是content.html的內容 #}
<span><b>{*title*}:</b></span>
<ul>
  {% if type(languages) == 'table' then %}
    {% for index, lang in ipairs(languages) do %}
      <li>{*index..'. '..lang*}</li>
    {% end %}
  {% end %}
</ul>
{# 沒錯, 註釋不會展示給用戶看到! #}

然後將原來的base.html修改爲:

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

最後, 由於服務器會自動刷新模板緩存, 我們只需要再次刷新瀏覽器就能查看效果.

完整代碼示例

-- main.lua
local httpd = require "httpd"
local app = httpd:new("app")

local template = require "template"
app:use('/languages', function(content)
    local languages = { 'C', 'C++', 'Java', 'golang', 'Rust', 'Ruby', 'Python', 'perl', 'Lua' }
    template.cache = {}
  return template.compile("view/base.html"){
        title = '語言列表',
    languages = languages
  }
end)

app:listen("0.0.0.0", 8080)

app:run()

更多

更多template用法可以參考cf的admin庫.

繼續學習

下一章我們繼續學習如何使用緩存與數據庫.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章