openresty lua-resty-template页面静态化


openresty lua-resty-template页面静态化

         

官网:https://github.com/bungle/lua-resty-template

             

                    

                                     

template 安装

        

lua-resty-template安装

# 查找模块
[root@a8f5f9001e83 bin]#opm search lua-resty-template
bungle/lua-resty-template                         Templating Engine (HTML) for Lua and OpenResty
bungle/lua-resty-validation                       Validation Library (Input Validation and Filtering) for Lua and OpenResty
bungle/lua-resty-session                          Session Library for OpenResty - Flexible and Secure
bungle/lua-resty-nettle                           Nettle (a low-level cryptographic library) Bindings for LuaJIT FFI
d80x86/lua-resty-tofu                             (alpha) a modern api/web framework
DevonStrawn/lua-resty-route                       URL Routing Library for OpenResty Supporting Pluggable Matching Engines
hamishforbes/lua-resty-qless-web                  Port of Moz's qless web interface to the Openresty environment.

# 安装模块
[root@a8f5f9001e83 bin]# opm install bungle/lua-resty-template
* Fetching bungle/lua-resty-template  
  Downloading https://opm.openresty.org/api/pkg/tarball/bungle/lua-resty-template-2.0.opm.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 40890  100 40890    0     0  92474      0 --:--:-- --:--:-- --:--:-- 92302
Package bungle/lua-resty-template 2.0 installed successfully under /usr/local/openresty/site/ .

# 查看安装的模块
[root@a8f5f9001e83 bin]# opm list
bungle/lua-resty-template                                    2.0

          

              

                                     

template 语法

        

输出内容

{{expression}}   # 输出属性
{*expression*}   # 输出属性、导入文件

# 示例
local template = require "resty.template"
template.render("view.html", {
  message = "Hello, World!",
})

## view.html
<h1>{{message}}</h1>   -- 输出message内容

         

导入模版文件

{(template)}   
{[expression]}

# 示例
{(header.html)}
{(file.html, { message = "Hello, World" } )}

{[file.html]}
{["file.html", { message = "Hello, World" } ]}

{(view.html)}
{(users/list.html)}   -- list.html在users目录下

         

执行lua代码

{% lua code %} 

# 示例
{(header.html)}
<h1>{{message}}</h1>
<ul>
{% for _, name in ipairs(names) do %}     -- lua代码
    <li>{{name}}</li>
{% end %}                                 -- lua代码
</ul>
{(footer.html)}

              

定义语句块,可将语句块导入其他文件

{-block-}...{-block-}

# 示例
local view     = template.new("view.html", "layout.html")
view.title     = "Testing lua-resty-template blocks"
view.message   = "Hello, World!"
view.keywords  = { "test", "lua", "template", "blocks" }
view:render()

## view.html
<h1>{{message}}</h1>
{-aside-}              -- 定义语句块
<ul>
    {% for _, keyword in ipairs(keywords) do %}
    <li>{{keyword}}</li>
    {% end %}
</ul>
{-aside-}

## layout.html
<!DOCTYPE html>
<html>
<head>
<title>{*title*}</title>
</head>
<body>
<article>
    {*view*}           -- 导入模板文件
</article>
{% if blocks.aside then %}
<aside>
    {*blocks.aside*}   -- 导入语句块
</aside>
{% end %}
</body>
</html>


==> 输出内容

<!DOCTYPE html>
<html>
<head>
<title>Testing lua-resty-template blocks</title>
</head>
<body>
<article>
    <h1>Hello, World!</h1>
</article>
<aside>
    <ul>
        <li>test</li>
        <li>lua</li>
        <li>template</li>
        <li>blocks</li>
    </ul>
</aside>
</body>
</html>

          

注释

{# comments #}

# 示例 
{# {*["foo:bar"]*} won't work, you need to use: #}   -- 注释
{*context["foo:bar"]*}       --输出context中key为["foo:bar"]的内容

         

转义字符

# 不输出message内容
<h1>\{{message}}</h1>    
==>  <h1>{{message}}</h1>,不会输出message的值

# 输出转义字符
<h1>\\{{message}}</h1>   
==>  <h1>\message_value </h1>

           

context 上下文

# 两者等价
<h1>{{message}}</h1> == <h1>{{context.message}}</h1>


# 特殊格式处理
local ctx = {["foo:bar"] = "foobar"}

{# {*["foo:bar"]*} won't work, you need to use: #}
{*context["foo:bar"]*}


# context中不建议设置的key
___、context、echo、include
layout、blocks、template、render

         

               

                                     

配置指令

        

模板文件目录

template_root       ==>    set $template_root /templates
template_location   ==>    set $template_location /templates


# lua-resty-template 2.x 设置root、location
local template = require "resty.template".new({
  root     = "/templates",
  location = "/templates" 
})


If none of these are set in Nginx configuration, 
ngx.var.document_root (aka root-directive) value is used. 
* template_root、template_location都没有设置,使用root目录

If template_location is set, it will be used first, and if 
the location returns anything but 200 as a status code, we do 
fallback to either template_root (if defined) or document_root
* 如果设置了template_location,优先使用template_location
* 如果template_location没有找到模版,使用template_root、root目录

             

示例:使用项目根路径

http {
  server {
    location / {

      root html;

      content_by_lua '
        local template = require "resty.template"
        template.render("view.html", { message = "Hello, World!" })
      ';      
    }
  }
}

           

示例:使用template_root

http {
  server {

    set $template_root /usr/local/openresty/nginx/html/templates;

    location / {
      root html;
      content_by_lua '
        local template = require "resty.template"
        template.render("view.html", { message = "Hello, World!" })
      ';      
    }
  }
}

            

示例:使用template_location

http {
  server {

    set $template_location /templates;

    location / {
      root html;
      content_by_lua '
        local template = require "resty.template"
        template.render("view.html", { message = "Hello, World!" })
      ';      
    }
  }
}

         

              

                                     

lua api

        

template.root:设置模板文件位置

You can setup template root by setting this variable 
which will be looked for template files
* 设置模板文件位置

This property overrides the one set in Nginx configuration 
(set $template_root /my-templates;)
* 会覆盖set $template_root /my-templates的属性值

# 示例
local template = require "resty.template".new({
  root = "/templates"
})
template.render_file("test.html")

         

template.location:设置模板文件位置

This is what you can use with OpenResty as that will 
use ngx.location.capture to fetch templates files in non-blocking fashion
* 设置模板文件位置

This property overrides the one set in Nginx configuration 
(set $template_location /my-templates;)
* 会覆盖set $template_location /my-templates;设置的值

# 示例
local template = require "resty.template".new({
  location = "/templates"
})
template.render_file("test.html")

             

template.new:新建模板对象

语法格式:template.new(view, layout)

Creates a new template instance that is used as a (default) context 
when rendered. A table that gets created has only one method render, 
but the table also has metatable with __tostring defined. See the 
example below. Both view and layout arguments can either be strings 
or file paths, but layout can also be a table created previously 
with template.new.
* 创建模板对象
* view:可为字符串、文件
* layout:可为字符串、文件、table

With 2.0 the new can also be used without arguments, which creates 
a new template instance
* 2.0版本还可以不用参数,创建模板对象

This is handy as the template created by new does not share the 
cache with the global template returned by require "resty.template"
* 使用new创建的模板对象不会和全局模板对象共享缓存

You can also pass a boolean true or false as a view parameter which 
means that either safe or un-safe version of template is returned
* 可以使用true、false作为view参数,表示安全、非安全版本的模板对象

safe version uses return nil, err Lua error handling pattern and 
unsafe just throws the errors, which you can catch with pcall, 
xpcall or coroutine.wrap
* safe版本的模板对象返回nil、lua错误信息
* unsafe版本的模板对象直接抛出异常


# 示例:无参数创建模板对象
local template = require "resty.template".new()

# 示例:使用table创建模板对象
local config = {
  root = "/templates"
}
local template = require "resty.template".new(config)


# 示例:创建安全模板对象
local unsafe = require "resty.template"
local safe   = unsafe.new(true)

# 示例:创建安全模板对象
local safe = require "resty.template.safe"
local safe_instance = safe.new()


# 示例:字符串、模板文件创建模板对象
local view = template.new("template.html")              --view模板文件
local view = template.new("view.html", "layout.html")   --view、layout模板文件
local view = template.new[[<h1>{{message}}</h1>]]       --字符串view
local view = template.new([[<h1>{{message}}</h1>]], [[  --字符串view、字符串layout
<html>
<body>
  {*view*}
</body>
</html>
]])

               

template.cache:模板缓存

This function enables or disables template caching, or if 
no parameters are passed, returns current state of template 
caching. By default template caching is enabled, but you may 
want to disable it on development or low-memory situations
* 开启、禁用模板缓存,默认开启缓存
* 如果没有参数,表示获取当前模板的缓存状态
* 开发、内存不足的时候,建议禁用缓存

Please note that if the template was already cached when 
compiling a template, the cached version will be returned. 
You may want to flush cache with template.cache = {} to 
ensure that your template really gets recompiled
* 编译模板时,如果已经缓存了模板,会返回缓存的模板
* 可使用template.cache = {}清空缓存


# 示例
local template = require "resty.template"   

local enabled = template.caching()    -- 获取当前模板对象的缓存状态
template.caching(false)               -- 禁用缓存
template.caching(true)                -- 开启缓存

             

template.compile:编译模板

# 语法格式:function, boolean = template.compile(view, cache_key, plain)
* 返回函数、boolean值(表示函数是否被缓存)

function, boolean  = template.compile_string(view, cache_key)
==> template.compile(view, cache_key, true)

function, boolean = template.compile_file(view, cache_key)
==> template.compile(view, cache_key, false)


Parses, compiles and caches (if caching is enabled) a template and 
returns the compiled template as a function that takes context as 
a parameter and returns rendered template as a string. 
* 解析、编译、缓存模板,返回编译后的模板对象
* compiled template以函数形式返回
* rendered template以字符串形式返回

Optionally you may pass cache_key that is used as a cache key. 
If cache key is not provided view will be used as a cache key. 
If cache key is no-cache the template cache will not be checked 
and the resulting function will not be cached. 
* 可以提供一个缓存key,如果没有提供缓存key,view会被当作缓存key
* 如果cache key是no-cache,模板不会被缓存,结果函数也不会被缓存

You may also optionally pass plain with a value of true if the 
view is plain text string (this will skip template.load and 
binary chunk detection in template.parse phase). If plain is 
false the template is considered to be a file, and all the 
issues with file reading are considered as errors. 
* plain为true,处理字符串,在解析阶段会跳过加载、检测
* plain为false,处理文件,会处理所有文件读取错误

If the plain is set to nil (the default) the template does not 
consider file reading errors as fatal, and returns back the view 
(usually the path of the template)
* plain设置为nil(默认),template不会处理文件读取错误,会返回view


# 示例
local func = template.compile("template.html")           --模板文件
local func = template.compile([[<h1>{{message}}</h1>]])  --字符串

local template = require "resty.template"
local func     = template.compile("view.html")        -- template.compile返回函数
local world    = func{ message = "Hello, World!" }
local universe = func{ message = "Hello, Universe!" }
print(world, universe)

            

template.visit:注册访问函数

Allows you to register template parser visitor functions. 
Visitors are called in the order they are registered. And 
once registered, cannot be removed from parser. 
* 注册访问函数,访问函数按照注册顺序调用
* 注册后,访问函数不能删除

If the function doesn't modify the content it should return 
the content back, like the visitor above does
* 如果访问函数不修改模板内容,应该返回文件内容


# 示例
local template = require "resty.template.safe".new()

local i = 0
template.visit(function(content, type, name)
  local trimmed = content:gsub("^%s+", ""):gsub("%s+$", "")
  if trimmed == "" then return content end
  i = i + 1
  print("  visit: ", i)
  if type then print("   type: ", type) end
  if name then print("   name: ", name) end
  print("content: ", trimmed)
  print()
  return content
end)

local func = template.compile([[
How are you, {{user.name}}?

Here is a new cooking recipe for you!

{% for i, ingredient in ipairs(ingredients) do %}
  {*i*}. {{ingredient}}
{% end %}
{-ad-}`lua-resty-template` the templating engine for OpenResty!{-ad-}
]])

local content = func{
  user = {
    name = "bungle"
  },
  ingredients = {
    "potatoes",
    "sausages"
  }
}

print(content)

==>
  visit: 1
content: How are you,

  visit: 2
   type: {
content: user.name

  visit: 3
content: ?

Here is a new cooking recipe for you!

  visit: 4
   type: %
content: for i, ingredient in ipairs(ingredients) do

  visit: 5
   type: *
content: i

  visit: 6
content: .

  visit: 7
   type: {
content: ingredient

  visit: 8
   type: %
content: end

  visit: 9
   type: -
   name: ad
content: `lua-resty-template` the templating engine for OpenResty!

  visit: 10
content: `lua-resty-template` the templating engine for OpenResty!

How are you, bungle?

Here is a new cooking recipe for you!

  1. potatoes
  2. sausages



# 示例:非安全模板抛出异常
local template = require "resty.template".new()
template.render "Calculation: {{i*10}}"

==>

ERROR: [string "context=... or {}..."]:7: attempt to perform arithmetic on global 'i' (a nil value)
stack traceback:
	resty/template.lua:652: in function 'render'
	a.lua:52: in function 'file_gen'
	init_worker_by_lua:45: in function <init_worker_by_lua:43>
	[C]: in function 'xpcall'
	init_worker_by_lua:52: in function <init_worker_by_lua:50>



# 示例:访问函数非安全模板处理错误
local template = require "resty.template".new()

template.visit(function(content, type)
  if type == "*" or type == "{" then
    return "select(3, pcall(function() return nil, " .. content .. " end)) or ''"
  end

  return content
end)

template.render "Calculation: {{i*10}}\n"
template.render("Calculation: {{i*10}}\n", { i = 1 })

==>

Calculation: 
Calculation: 10

        

template.process:处理模板文件、字符串

语法格式:string template.process(view, context, cache_key, plain)
* 解析、编译、缓存模板,并返回字符串

string template.process_string(view, context, cache_key)
==> template.process(view, context, cache_key, true)

string template.process_file(view, context, cache_key)
==> template.process(view, context, cache_key, false)


Parses, compiles, caches (if caching is enabled) and 
returns output as string. You may optionally also pass 
cache_key that is used as a cache key. 
* 解析、编译、缓存(如果设置了缓存),并返回字符串
* cache_key:缓存的key

If plain evaluates to true, the view is considered to be 
plain string template (template.load and binary chunk 
detection is skipped on template.parse). 
* plain:true,表示view是字符串

If plain is false" the template is considered to be a file, 
and all the issues with file reading are considered as errors. 
* plain:false,表示view是模板文件

If the plain is set to nil (the default) the template does not 
consider file reading errors as fatal, and returns back the view
* 如果plain是nil(默认),不会将biew当作文件处理,直接返回view


# 示例
local output = template.process("template.html", { message = "Hello, World!" })          
local output = template.process([[<h1>{{message}}</h1>]], { message = "Hello, World!" })

                 

template.render:处理模板文件

语法格式:template.render(view, context, cache_key, plain)
* 解析、编译、缓存模板,使用ngx.print、print输出模板文件

template.render_string(view, context, cache_key)
==> template.render(view, context, cache_key, true)

template.render_file(view, context, cache_key)
==> template.render(view, context, cache_key, false)


Parses, compiles, caches (if caching is enabled) and outputs 
template either with ngx.print if available, or print. You may 
optionally also pass cache_key that is used as a cache key. 
* 解析、编译、缓存(如果设置了缓存)模板文件
* 使用ngx.print、print输出模板文件
* cache_key:缓存key

If plain evaluates to true, the view is considered to be plain 
string template (template.load and binary chunk detection is 
skipped on template.parse). 
* plain:true ==> 字符串模板

If plain is false" the template is considered to be a file, and 
all the issues with file reading are considered as errors. 
* plain:false ==> 文件模板 

If the plain is set to nil (the default) the template does not 
consider file reading errors as fatal, and returns back the view
* plain:nil(默认) ==> 不会处理文件读取错误,直接返回view

               

template.parse:解析模板文件

语法格式:string template.parse(view, plain)
* 解析模板文件,返回字符串

string template.parse_string(view, plain)
==> template.parse(view, plain, true)

string template.parse_file(view, plain)
==> template.parse(view, plain, false)


Parses template file or string, and generates a parsed template string. 
This may come useful when debugging templates. You should note that if 
you are trying to parse a binary chunk (e.g. one returned with 
template.compile), template.parse will return that binary chunk as is. 
* 解析模板文件、字符串,返回字符串,常用于debug调试
* 如果解析二进制文件(如template.compile返回值),template.parse会直接将其返回

If plain evaluates to true, the view is considered to be plain string 
template (template.load and binary chunk detection is skipped on 
template.parse). 
* plain:true ==> 当作字符串处理,跳过template.load、binary chunk detection 

If plain is false" the template is considered to be a file, and all 
the issues with file reading are considered as errors. 
* palin:flase ==> 当作文件处理

If the plain is set to nil (the default) the template does not consider 
file reading errors as fatal, and returns back the view
* plain:nil ==> 不会处理文件读取错误,直接返回view


# 示例
local t1 = template.parse("template.html")
local t2 = template.parse([[<h1>{{message}}</h1>]])

              

template.precompile:预编译模板文件

语法格式:string template.precompile(view, path, strip, plain)
* 预编译模板文件

string template.precompile_string(view, path, strip)
==> template.precompile(view, path, strip, true)

string template.precompile_file(view, path, strip)
==> template.precompile(view, path, strip, false)


Precompiles template as a binary chunk. This binary chunk can 
be written out as a file (and you may use it directly with 
Lua's load and loadfile). 
* 预编译模板,随后可用lua load加载

For convenience you may optionally specify path argument to output 
binary chunk to file. You may also supply strip parameter with value 
of false to make precompiled templates to have debug information as 
well (defaults to true). 
* path:编译后的文件输出路径
* strip(默认true):设置为false后,输出debug信息

The last parameter plain means that should complilation treat the view 
as string (plain = true) or as file path (plain = false) or try first 
as a file, and fallback to string (plain = nil). 
* plain:true ==> 处理字符串
* plain:false ==> 处理文件
* plain:nil ==> 第一次当作文件处理,发生异常后当作字符串处理

In case the plain=false (a file) and there is error with file io 
the function will also error with an assertion failure
* plain:false ==> 会处理文件读写异常

           

template.load:加载文件

语法格式:string template.load(view, plain)
* 加载文件,返回字符串

string template.load_string(view)
==> template.load(view, true)

string template.load_file(view)
==> template.load(view, false)


This field is used to load templates. template.parse calls this 
function before it starts parsing the template (assuming that 
optional plain argument in template.parse evaluates to false or 
nil (the default). 
* template.load用来加载文件
* 在template.parse之前调用

By default there are two loaders in lua-resty-template: one for Lua 
and the other for Nginx / OpenResty. Users can overwrite this field 
with their own function. For example you may want to write a template 
loader function that loads templates from a database
* 默认有2个加载器:lua加载器、nginx/openresty加载器
* 可自定义加载器函数


As you can see, lua-resty-template always tries (by default) to load 
a template from a file (or with ngx.location.capture) even if you 
provided template as a string. lua-resty-template. 
* lua-resty-template总是尝试从文件中加载模板(即使使用字符串的形式提供)

But if you know that your templates are always strings, and not file 
paths, you may use plain argument in template.compile, template.render, 
and template.parse OR replace template.load with the simplest possible 
template loader there is (but be aware that if your templates use 
{(file.html)} includes, those are considered as strings too, in this 
case file.html will be the template string that is parsed) - you could 
also setup a loader that finds templates in some database system
* 可以使用plain参数指定文件格式

If the plain parameter is false (nil is not treated as false), 
all the issues with file io are considered assertion errors
* plain:false ==> 当作文件处理,会处理文件读写错误
* plain:nil ==> 第一次当作文件处理,出现错误后,当作字符串处理

# lua 加载器
function(view, plain)
    if plain == true then return view end
    local path, root = view, template.root
    if root and root ~= EMPTY then
        if byte(root, -1) == SOL then root = sub(root, 1, -2) end
        if byte(view,  1) == SOL then path = sub(view, 2) end
        path = root .. "/" .. path
    end
    return plain == false and assert(read_file(path)) or read_file(path) or view
end


# nginx/openresty 加载器
function(view, plain)
    if plain == true then return view end
    local vars = VAR_PHASES[phase()]
    local path = view
    local root = template.location
    if (not root or root == EMPTY) and vars then
        root = var.template_location
    end
    if root and root ~= EMPTY then
        if byte(root, -1) == SOL then root = sub(root, 1, -2) end
        if byte(path,  1) == SOL then path = sub(path, 2) end
        path = root .. "/" .. path
        local res = capture(path)
        if res.status == 200 then return res.body end
    end
    path = view
    root = template.root
    if (not root or root == EMPTY) and vars then
        root = var.template_root
        if not root or root == EMPTY then root = var.document_root or prefix end
    end
    if root and root ~= EMPTY then
        if byte(root, -1) == SOL then root = sub(root, 1, -2) end
        if byte(path,  1) == SOL then path = sub(path, 2) end
        path = root .. "/" .. path
    end
    return plain == false and assert(read_file(path)) or read_file(path) or view
end


            

template.print:打印模板

This field contains a function that is used on template.render() 
or template.new("example.html"):render() to output the results. 
By default this holds either ngx.print (if available) or print. 
You may want to (and are allowed to) overwrite this field, if 
you want to use your own output function instead.
* 输出template.render() 、template.new("example.html"):render()内容
* 也可以用ngx.print、print、自定义输出函数进行输出操作


# 示例
local template = require "resty.template"

template.print = function(s)
  print(s)
  print("<!-- Output by My Function -->")
end

             

                   

                                     

预编译说明

     

lua-resty-template supports template precompilation. This can be 
useful when you want to skip template parsing (and Lua interpretation) 
in production or if you do not want your templates distributed as plain 
text files on production servers. 
* lua-resty-template支持模板预编译,
* 生产环境中,可以使用该方法可以跳过模板解析、预先加载文件

Also by precompiling, you can ensure that your templates do not contain 
something, that cannot be compiled (they are syntactically valid Lua). 
Although templates are cached (even without precompilation), there are 
some performance (and memory) gains. You could integrate template 
precompilation in your build (or deployment) scripts (maybe as Gulp, 
Grunt or Ant tasks)
* 可保证模板文件可编译
* 使用缓存,也可提升一些性能

        

示例

# 预编译:将example.html预编译成example-bin.html二进制文件
local template = require "resty.template"
local compiled = template.precompile("example.html", "example-bin.html")

# 使用预编译的二进制文件
local template = require "resty.template"
template.render("example-bin.html", { "Jack", "Mary" })

        

             

                                     

内置工具

     

echo:输出内容

Echoes output. This is useful with {% .. %}
* 在{% .. %}中使用


# 示例
require "resty.template".render[[
begin
{%
for i=1, 10 do
  echo("\tline: ", i, "\n")
end
%}
end
]]

==>

begin
	line: 1
	line: 2
	line: 3
	line: 4
	line: 5
	line: 6
	line: 7
	line: 8
	line: 9
	line: 10
end


# 与以下等同
require "resty.template".render[[
begin
{% for i=1, 10 do %}
  line: {* i *}
{% end %}
end
]]

          

include(view,context):引入文件、语句块

This is mainly used with internally with {(view.hmtl)}, {["view.hmtl"]} 
and with blocks {-block-name-}..{-block-name-}. If context is not given 
the context used to compile parent view is used. This function will 
compile the view and call the resulting function with context (or the 
context of parent view if not given)
* 类似于{(view.hmtl)}、{["view.hmtl"]}、语句块blocks {-block-name-}..{-block-name-},
* 用来引入文件、语句块,如果没有设置context,会使用父文件的context


# 示例
local template = require "resty.template"
template.render("include.html", { users = {
    { name = "Jane", age = 29 },
    { name = "John", age = 25 }
}})

## include.html
<html>
<body>
<ul>
{% for _, user in ipairs(users) do %}
    {(user.html, user)}    --导入文件 include("user.html", user)
{% end %}
</ul>
</body>
</html>

## user.html
<li>User {{name}} is of age {{age}}</li>


==>

<html>
<body>
<ul>
    <li>User Jane is of age 29</li>
    <li>User John is of age 25</li>
</ul>
</body>
</html>

         

                  

                                     

使用示例

     

本地目录

huli@hudemacbook-pro template % pwd
/Users/huli/lua/openresty/template

huli@hudemacbook-pro template % ls 
default.conf	html		js

# html文件
huli@hudemacbook-pro template % ls html
include.html	index.html	layout.html	user.html	view.html

# js文件
huli@hudemacbook-pro template % ls js
jquery-3.6.0.min.js	layui-v2.7.6

              

include.html

<html>
<body>
<ul>
{% for _, user in ipairs(users) do %}
    {(html/user.html, user)}
{% end %}
</ul>
</body>
</html>

                

user.html

<li>User {{name}} is of age {{age}}</li>

          

layout.html

<!DOCTYPE html>
<html>
<head>
<title>{*title*}</title>
</head>
<body>
<article>
    {*view*}
</article>
{% if blocks.aside then %}
<aside>
    {*blocks.aside*}
</aside>
{% end %}
</body>
</html>

           

view.html

<h1>{{message}}</h1>
{-aside-}
<ul>
    {% for _, keyword in ipairs(keywords) do %}
    <li>{{keyword}}</li>
    {% end %}
</ul>
{-aside-}

             

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 饮用openresty本地静态文件 -->
    <script src="/template/js/jquery-3.6.0.min.js"></script>
    <script src="/template/js/layui-v2.7.6/layui/layui.js"></script>
    <link rel="stylesheet" href="/template/js/layui-v2.7.6/layui/css/layui.css">
</head>
<script>
    $(function (){
        $("#btn").click(function (){
            layer.msg("瓜田李下");
        })
    })
</script>
<body>
    <div align="center" style="color: coral">
        瓜田李下<br>

        <button id="btn" class="layui-btn">
            点击一下
        </button>
    </div>
</body>
</html>

            

default.conf

server {
    listen       80;
    server_name  localhost;

    set $template_root /usr/local/openresty/template;

    location / {
        root   /usr/local/openresty/nginx/html;
        index  index.html index.htm;
    }

    # 暴露本地静态文件
    location /template {
        alias /usr/local/openresty/template;
    }

    # 引入其他文件
    location /test {
        add_header Content-Type "text/html;charset=utf-8";

        content_by_lua_block {
            local template = require "resty.template".new();

            template.render("html/include.html", { users = {
                { name = "海贼王", age = 20 },
                { name = "瓜田李下", age = 20 }
            }})
        }
    }

    # 指定区域导入文件
    location /test2 {
        add_header Content-Type "text/html;charset=utf-8";

        content_by_lua_block {
            local template = require "resty.template".new("html/view.html","html/layout.html");

            template.title     = "测试块文件引用";
            template.message   = "瓜田李下";
            template.keywords  = { "龙珠", "海贼王", "灌篮高手", "火影忍者"}
            template:render();
        }
    }

    # openresty 存储js、css等静态文件
    location /test3 {
        add_header Content-Type "text/html;charset=utf-8";

        content_by_lua_block {
            local template = require "resty.template".new("html/index.html");
            template:render();
        }
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/local/openresty/nginx/html;
    }

}

          

创建容器

docker run -it -d --net fixed --ip 172.18.0.80 -p 8000:80 \
-v /Users/huli/lua/openresty/template/default.conf:/etc/nginx/conf.d/default.conf \
-v /Users/huli/lua/openresty/template:/usr/local/openresty/template \
--name open-template lihu12344/openresty-template

          

*********

使用测试

       

curl localhost:8000/test

# 引入其他文件
huli@hudemacbook-pro ~ % curl localhost:8000/test  
<html>
<body>
<ul>
    <li>User 海贼王 is of age 20</li>

    <li>User 瓜田李下 is of age 20</li>

</ul>
</body>
</html>

                

               

curl localhost:8000/test2

# 指定区域引入文件
huli@hudemacbook-pro ~ % curl localhost:8000/test2
<!DOCTYPE html>
<html>
<head>
<title>测试块文件引用</title>
</head>
<body>
<article>
    <h1>瓜田李下</h1>

</article>
<aside>
    <ul>
    <li>龙珠</li>
    <li>海贼王</li>
    <li>灌篮高手</li>
    <li>火影忍者</li>
</ul>
</aside>
</body>
</html>

                

                     

curl localhost:8000/test3

# openresty本地存储js、css文件
huli@hudemacbook-pro ~ % curl localhost:8000/test3   
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/template/js/jquery-3.6.0.min.js"></script>
    <script src="/template/js/layui-v2.7.6/layui/layui.js"></script>
    <link rel="stylesheet" href="/template/js/layui-v2.7.6/layui/css/layui.css">
</head>
<script>
    $(function (){
        $("#btn").click(function (){
            layer.msg("瓜田李下");
        })
    })
</script>
<body>
    <div align="center" style="color: coral">
        瓜田李下<br>

        <button id="btn" class="layui-btn">
            点击一下
        </button>
    </div>
</body>
</html>

                

点击一下 ==> 弹出 瓜田李下

                      

                              

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值