mirror of
https://github.com/bunkerity/bunkerized-nginx
synced 2023-12-13 21:30:18 +01:00
Merge commit 'bc06cd71b8896c6e7a1aac4610c9c3f878956238' as 'src/deps/src/lua-resty-template'
This commit is contained in:
commit
2d06f2d7ab
11 changed files with 3165 additions and 0 deletions
2
src/deps/src/lua-resty-template/.luacheckrc
Normal file
2
src/deps/src/lua-resty-template/.luacheckrc
Normal file
|
@ -0,0 +1,2 @@
|
|||
std = "ngx_lua"
|
||||
|
105
src/deps/src/lua-resty-template/Changes.md
Normal file
105
src/deps/src/lua-resty-template/Changes.md
Normal file
|
@ -0,0 +1,105 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to `lua-resty-template` will be documented in this file.
|
||||
|
||||
|
||||
## [2.0] - 2020-02-24
|
||||
### Added
|
||||
- Support for `template.new()`, `template.new(options)` and `template.new(safe)` (a `boolean`)
|
||||
- Added `safe` implementation `require "resty.template.safe"`
|
||||
- Added `echo` helper function to template (#28)
|
||||
- Added `template.load_file` and `template.load_string` functions
|
||||
- Added `template.compile_file` and `template.compile_string` functions
|
||||
- Added `template.parse_file` and `template.parse_string` functions
|
||||
- Added `template.render_file` and `template.render_string` functions
|
||||
- Added `template.precompile_file` and `template.precompile_string` functions
|
||||
- Added `template.process`, `template.process_file` and `template.process_string` functions
|
||||
- Added `template.root` and `template.location` properties
|
||||
- Added `template.visit` function (#36)
|
||||
|
||||
### Changed
|
||||
- When `plain` equals to `false` the file io issues are considered
|
||||
fatal, and assertions are thrown (#32)
|
||||
|
||||
### Fixed
|
||||
- Wrong template returned when using multiple server blocks (#25)
|
||||
- Add a pure lua configure method (#23, #7)
|
||||
|
||||
|
||||
## [1.9] - 2016-09-29
|
||||
### Added
|
||||
- Support for the official OpenResty package manager (opm).
|
||||
|
||||
### Changed
|
||||
- Changed the change log format to keep-a-changelog.
|
||||
|
||||
|
||||
## [1.8] - 2016-06-14
|
||||
### Added
|
||||
- Allow pass layout as a template object to template.new.
|
||||
|
||||
|
||||
## [1.7] - 2016-05-11
|
||||
### Fixed
|
||||
- The loadngx was not working properly on non-file input.
|
||||
See also: https://github.com/bungle/lua-resty-template/pull/19
|
||||
Thanks @zhoukk
|
||||
|
||||
|
||||
## [1.6] - 2016-04-25
|
||||
### Added
|
||||
- Added short escaping syntax.
|
||||
|
||||
|
||||
## [1.5] - 2015-02-10
|
||||
### Added
|
||||
- Support for {-verbatim-}...{-verbatim-}, and {-raw-}...{-raw-} blocks
|
||||
(contents is not processed by template).
|
||||
Please note that this could break your templates if you have used
|
||||
blocks with names "verbatim" or "raw".
|
||||
|
||||
### Fixed
|
||||
- Issue #8: not returning value when using template.new and its render
|
||||
function.
|
||||
|
||||
|
||||
## [1.4] - 2014-12-03
|
||||
### Added
|
||||
- Added support for {[expression include]} syntax.
|
||||
|
||||
### Changed
|
||||
- Rewrote template.parse (cleaned up, less repetition of code, and
|
||||
better handling of new lines - i.e. doesn't eat newlines anymore.
|
||||
Also some adjustments to preceding spaces (space, tab, NUL-byte,
|
||||
and vertical tabs) on some tags ({% ... %}, {-block-} ... {-block-},
|
||||
and {# ... #}) for a cleaner output.
|
||||
|
||||
|
||||
## [1.3] - 2014-11-06
|
||||
### Added
|
||||
- Small modification to html helper example to handle valueless tag
|
||||
attributess in HTML5 style.
|
||||
|
||||
### Fixed
|
||||
- Fixed a bug when a view was missing from context when using layouts.
|
||||
|
||||
|
||||
## [1.2] - 2014-09-29
|
||||
### Fixed
|
||||
- Fixes nasty recursion bug (reported in bug #5) where sub-templates
|
||||
modify the context table. Thank you for reporting this @DDarko.
|
||||
|
||||
|
||||
## [1.1] - 2014-09-10
|
||||
### Added
|
||||
- Added _VERSION information to the module.
|
||||
- Added CHANGES file to the project (this file).
|
||||
|
||||
### Changed
|
||||
- Lua > 5.1 uses _ENV instead of _G (Lua 5.1 uses _G). Future Proofing
|
||||
if Lua is deprecating _G in Lua 5.3.
|
||||
|
||||
|
||||
## [1.0] - 2014-08-28
|
||||
### Added
|
||||
- LuaRocks Support via MoonRocks.
|
27
src/deps/src/lua-resty-template/LICENSE
Normal file
27
src/deps/src/lua-resty-template/LICENSE
Normal file
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2014 - 2020 Aapo Talvensaari
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the {organization} nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
4
src/deps/src/lua-resty-template/Makefile
Normal file
4
src/deps/src/lua-resty-template/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
.PHONY: lint
|
||||
|
||||
lint:
|
||||
@luacheck -q ./lib
|
2102
src/deps/src/lua-resty-template/README.md
Normal file
2102
src/deps/src/lua-resty-template/README.md
Normal file
File diff suppressed because it is too large
Load diff
6
src/deps/src/lua-resty-template/dist.ini
Normal file
6
src/deps/src/lua-resty-template/dist.ini
Normal file
|
@ -0,0 +1,6 @@
|
|||
name = lua-resty-template
|
||||
abstract = Templating Engine (HTML) for Lua and OpenResty
|
||||
author = Aapo Talvensaari (@bungle)
|
||||
is_original = yes
|
||||
license = 3bsd
|
||||
repo_link = https://github.com/bungle/lua-resty-template
|
688
src/deps/src/lua-resty-template/lib/resty/template.lua
Normal file
688
src/deps/src/lua-resty-template/lib/resty/template.lua
Normal file
|
@ -0,0 +1,688 @@
|
|||
local setmetatable = setmetatable
|
||||
local loadstring = loadstring
|
||||
local tostring = tostring
|
||||
local setfenv = setfenv
|
||||
local require = require
|
||||
local concat = table.concat
|
||||
local assert = assert
|
||||
local write = io.write
|
||||
local pcall = pcall
|
||||
local phase
|
||||
local open = io.open
|
||||
local load = load
|
||||
local type = type
|
||||
local dump = string.dump
|
||||
local find = string.find
|
||||
local gsub = string.gsub
|
||||
local byte = string.byte
|
||||
local null
|
||||
local sub = string.sub
|
||||
local ngx = ngx
|
||||
local jit = jit
|
||||
local var
|
||||
|
||||
local _VERSION = _VERSION
|
||||
local _ENV = _ENV -- luacheck: globals _ENV
|
||||
local _G = _G
|
||||
|
||||
local HTML_ENTITIES = {
|
||||
["&"] = "&",
|
||||
["<"] = "<",
|
||||
[">"] = ">",
|
||||
['"'] = """,
|
||||
["'"] = "'",
|
||||
["/"] = "/"
|
||||
}
|
||||
|
||||
local CODE_ENTITIES = {
|
||||
["{"] = "{",
|
||||
["}"] = "}",
|
||||
["&"] = "&",
|
||||
["<"] = "<",
|
||||
[">"] = ">",
|
||||
['"'] = """,
|
||||
["'"] = "'",
|
||||
["/"] = "/"
|
||||
}
|
||||
|
||||
local VAR_PHASES
|
||||
|
||||
local ESC = byte("\27")
|
||||
local NUL = byte("\0")
|
||||
local HT = byte("\t")
|
||||
local VT = byte("\v")
|
||||
local LF = byte("\n")
|
||||
local SOL = byte("/")
|
||||
local BSOL = byte("\\")
|
||||
local SP = byte(" ")
|
||||
local AST = byte("*")
|
||||
local NUM = byte("#")
|
||||
local LPAR = byte("(")
|
||||
local LSQB = byte("[")
|
||||
local LCUB = byte("{")
|
||||
local MINUS = byte("-")
|
||||
local PERCNT = byte("%")
|
||||
|
||||
local EMPTY = ""
|
||||
|
||||
local VIEW_ENV
|
||||
if _VERSION == "Lua 5.1" then
|
||||
VIEW_ENV = { __index = function(t, k)
|
||||
return t.context[k] or t.template[k] or _G[k]
|
||||
end }
|
||||
else
|
||||
VIEW_ENV = { __index = function(t, k)
|
||||
return t.context[k] or t.template[k] or _ENV[k]
|
||||
end }
|
||||
end
|
||||
|
||||
local newtab
|
||||
do
|
||||
local ok
|
||||
ok, newtab = pcall(require, "table.new")
|
||||
if not ok then newtab = function() return {} end end
|
||||
end
|
||||
|
||||
local function enabled(val)
|
||||
if val == nil then return true end
|
||||
return val == true or (val == "1" or val == "true" or val == "on")
|
||||
end
|
||||
|
||||
local function trim(s)
|
||||
return gsub(gsub(s, "^%s+", EMPTY), "%s+$", EMPTY)
|
||||
end
|
||||
|
||||
local function rpos(view, s)
|
||||
while s > 0 do
|
||||
local c = byte(view, s, s)
|
||||
if c == SP or c == HT or c == VT or c == NUL then
|
||||
s = s - 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local function escaped(view, s)
|
||||
if s > 1 and byte(view, s - 1, s - 1) == BSOL then
|
||||
if s > 2 and byte(view, s - 2, s - 2) == BSOL then
|
||||
return false, 1
|
||||
else
|
||||
return true, 1
|
||||
end
|
||||
end
|
||||
return false, 0
|
||||
end
|
||||
|
||||
local function read_file(path)
|
||||
local file, err = open(path, "rb")
|
||||
if not file then return nil, err end
|
||||
local content
|
||||
content, err = file:read "*a"
|
||||
file:close()
|
||||
return content, err
|
||||
end
|
||||
|
||||
local print_view
|
||||
local load_view
|
||||
if ngx then
|
||||
print_view = ngx.print or write
|
||||
|
||||
var = ngx.var
|
||||
null = ngx.null
|
||||
phase = ngx.get_phase
|
||||
|
||||
VAR_PHASES = {
|
||||
set = true,
|
||||
rewrite = true,
|
||||
access = true,
|
||||
content = true,
|
||||
header_filter = true,
|
||||
body_filter = true,
|
||||
log = true,
|
||||
preread = true
|
||||
}
|
||||
|
||||
local capture = ngx.location.capture
|
||||
local prefix = ngx.config.prefix()
|
||||
load_view = function(template)
|
||||
return 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
|
||||
end
|
||||
else
|
||||
print_view = write
|
||||
load_view = function(template)
|
||||
return 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
|
||||
end
|
||||
end
|
||||
|
||||
local function load_file(func)
|
||||
return function(view) return func(view, false) end
|
||||
end
|
||||
|
||||
local function load_string(func)
|
||||
return function(view) return func(view, true) end
|
||||
end
|
||||
|
||||
local loader
|
||||
if jit or _VERSION ~= "Lua 5.1" then
|
||||
loader = function(template)
|
||||
return function(view)
|
||||
return assert(load(view, nil, nil, setmetatable({ template = template }, VIEW_ENV)))
|
||||
end
|
||||
end
|
||||
else
|
||||
loader = function(template)
|
||||
return function(view)
|
||||
local func = assert(loadstring(view))
|
||||
setfenv(func, setmetatable({ template = template }, VIEW_ENV))
|
||||
return func
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function visit(visitors, content, tag, name)
|
||||
if not visitors then
|
||||
return content
|
||||
end
|
||||
|
||||
for i = 1, visitors.n do
|
||||
content = visitors[i](content, tag, name)
|
||||
end
|
||||
|
||||
return content
|
||||
end
|
||||
|
||||
local function new(template, safe)
|
||||
template = template or newtab(0, 26)
|
||||
|
||||
template._VERSION = "2.0"
|
||||
template.cache = {}
|
||||
template.load = load_view(template)
|
||||
template.load_file = load_file(template.load)
|
||||
template.load_string = load_string(template.load)
|
||||
template.print = print_view
|
||||
|
||||
local load_chunk = loader(template)
|
||||
|
||||
local caching
|
||||
if VAR_PHASES and VAR_PHASES[phase()] then
|
||||
caching = enabled(var.template_cache)
|
||||
else
|
||||
caching = true
|
||||
end
|
||||
|
||||
local visitors
|
||||
function template.visit(func)
|
||||
if not visitors then
|
||||
visitors = { func, n = 1 }
|
||||
return
|
||||
end
|
||||
visitors.n = visitors.n + 1
|
||||
visitors[visitors.n] = func
|
||||
end
|
||||
|
||||
function template.caching(enable)
|
||||
if enable ~= nil then caching = enable == true end
|
||||
return caching
|
||||
end
|
||||
|
||||
function template.output(s)
|
||||
if s == nil or s == null then return EMPTY end
|
||||
if type(s) == "function" then return template.output(s()) end
|
||||
return tostring(s)
|
||||
end
|
||||
|
||||
function template.escape(s, c)
|
||||
if type(s) == "string" then
|
||||
if c then return gsub(s, "[}{\">/<'&]", CODE_ENTITIES) end
|
||||
return gsub(s, "[\">/<'&]", HTML_ENTITIES)
|
||||
end
|
||||
return template.output(s)
|
||||
end
|
||||
|
||||
function template.new(view, layout)
|
||||
local vt = type(view)
|
||||
|
||||
if vt == "boolean" then return new(nil, view) end
|
||||
if vt == "table" then return new(view, safe) end
|
||||
if vt == "nil" then return new(nil, safe) end
|
||||
|
||||
local render
|
||||
local process
|
||||
if layout then
|
||||
if type(layout) == "table" then
|
||||
render = function(self, context)
|
||||
context = context or self
|
||||
context.blocks = context.blocks or {}
|
||||
context.view = template.process(view, context)
|
||||
layout.blocks = context.blocks or {}
|
||||
layout.view = context.view or EMPTY
|
||||
layout:render()
|
||||
end
|
||||
process = function(self, context)
|
||||
context = context or self
|
||||
context.blocks = context.blocks or {}
|
||||
context.view = template.process(view, context)
|
||||
layout.blocks = context.blocks or {}
|
||||
layout.view = context.view
|
||||
return tostring(layout)
|
||||
end
|
||||
else
|
||||
render = function(self, context)
|
||||
context = context or self
|
||||
context.blocks = context.blocks or {}
|
||||
context.view = template.process(view, context)
|
||||
template.render(layout, context)
|
||||
end
|
||||
process = function(self, context)
|
||||
context = context or self
|
||||
context.blocks = context.blocks or {}
|
||||
context.view = template.process(view, context)
|
||||
return template.process(layout, context)
|
||||
end
|
||||
end
|
||||
else
|
||||
render = function(self, context)
|
||||
return template.render(view, context or self)
|
||||
end
|
||||
process = function(self, context)
|
||||
return template.process(view, context or self)
|
||||
end
|
||||
end
|
||||
|
||||
if safe then
|
||||
return setmetatable({
|
||||
render = function(...)
|
||||
local ok, err = pcall(render, ...)
|
||||
if not ok then
|
||||
return nil, err
|
||||
end
|
||||
end,
|
||||
process = function(...)
|
||||
local ok, output = pcall(process, ...)
|
||||
if not ok then
|
||||
return nil, output
|
||||
end
|
||||
return output
|
||||
end,
|
||||
}, {
|
||||
__tostring = function(...)
|
||||
local ok, output = pcall(process, ...)
|
||||
if not ok then
|
||||
return ""
|
||||
end
|
||||
return output
|
||||
end })
|
||||
end
|
||||
|
||||
return setmetatable({
|
||||
render = render,
|
||||
process = process
|
||||
}, {
|
||||
__tostring = process
|
||||
})
|
||||
end
|
||||
|
||||
function template.precompile(view, path, strip, plain)
|
||||
local chunk = dump(template.compile(view, nil, plain), strip ~= false)
|
||||
if path then
|
||||
local file = open(path, "wb")
|
||||
file:write(chunk)
|
||||
file:close()
|
||||
end
|
||||
return chunk
|
||||
end
|
||||
|
||||
function template.precompile_string(view, path, strip)
|
||||
return template.precompile(view, path, strip, true)
|
||||
end
|
||||
|
||||
function template.precompile_file(view, path, strip)
|
||||
return template.precompile(view, path, strip, false)
|
||||
end
|
||||
|
||||
function template.compile(view, cache_key, plain)
|
||||
assert(view, "view was not provided for template.compile(view, cache_key, plain)")
|
||||
if cache_key == "no-cache" then
|
||||
return load_chunk(template.parse(view, plain)), false
|
||||
end
|
||||
cache_key = cache_key or view
|
||||
local cache = template.cache
|
||||
if cache[cache_key] then return cache[cache_key], true end
|
||||
local func = load_chunk(template.parse(view, plain))
|
||||
if caching then cache[cache_key] = func end
|
||||
return func, false
|
||||
end
|
||||
|
||||
function template.compile_file(view, cache_key)
|
||||
return template.compile(view, cache_key, false)
|
||||
end
|
||||
|
||||
function template.compile_string(view, cache_key)
|
||||
return template.compile(view, cache_key, true)
|
||||
end
|
||||
|
||||
function template.parse(view, plain)
|
||||
assert(view, "view was not provided for template.parse(view, plain)")
|
||||
if plain ~= true then
|
||||
view = template.load(view, plain)
|
||||
if byte(view, 1, 1) == ESC then return view end
|
||||
end
|
||||
local j = 2
|
||||
local c = {[[
|
||||
context=... or {}
|
||||
local ___,blocks,layout={},blocks or {}
|
||||
local function include(v, c) return template.process(v, c or context) end
|
||||
local function echo(...) for i=1,select("#", ...) do ___[#___+1] = tostring(select(i, ...)) end end
|
||||
]] }
|
||||
local i, s = 1, find(view, "{", 1, true)
|
||||
while s do
|
||||
local t, p = byte(view, s + 1, s + 1), s + 2
|
||||
if t == LCUB then
|
||||
local e = find(view, "}}", p, true)
|
||||
if e then
|
||||
local z, w = escaped(view, s)
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = visit(visitors, sub(view, i, s - 1 - w))
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
if z then
|
||||
i = s
|
||||
else
|
||||
c[j] = "___[#___+1]=template.escape("
|
||||
c[j+1] = visit(visitors, trim(sub(view, p, e - 1)), "{")
|
||||
c[j+2] = ")\n"
|
||||
j=j+3
|
||||
s, i = e + 1, e + 2
|
||||
end
|
||||
end
|
||||
elseif t == AST then
|
||||
local e = find(view, "*}", p, true)
|
||||
if e then
|
||||
local z, w = escaped(view, s)
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = visit(visitors, sub(view, i, s - 1 - w))
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
if z then
|
||||
i = s
|
||||
else
|
||||
c[j] = "___[#___+1]=template.output("
|
||||
c[j+1] = visit(visitors, trim(sub(view, p, e - 1)), "*")
|
||||
c[j+2] = ")\n"
|
||||
j=j+3
|
||||
s, i = e + 1, e + 2
|
||||
end
|
||||
end
|
||||
elseif t == PERCNT then
|
||||
local e = find(view, "%}", p, true)
|
||||
if e then
|
||||
local z, w = escaped(view, s)
|
||||
if z then
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = visit(visitors, sub(view, i, s - 1 - w))
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
i = s
|
||||
else
|
||||
local n = e + 2
|
||||
if byte(view, n, n) == LF then
|
||||
n = n + 1
|
||||
end
|
||||
local r = rpos(view, s - 1)
|
||||
if i <= r then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = visit(visitors, sub(view, i, r))
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
c[j] = visit(visitors, trim(sub(view, p, e - 1)), "%")
|
||||
c[j+1] = "\n"
|
||||
j=j+2
|
||||
s, i = n - 1, n
|
||||
end
|
||||
end
|
||||
elseif t == LPAR then
|
||||
local e = find(view, ")}", p, true)
|
||||
if e then
|
||||
local z, w = escaped(view, s)
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = visit(visitors, sub(view, i, s - 1 - w))
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
if z then
|
||||
i = s
|
||||
else
|
||||
local f = visit(visitors, sub(view, p, e - 1), "(")
|
||||
local x = find(f, ",", 2, true)
|
||||
if x then
|
||||
c[j] = "___[#___+1]=include([=["
|
||||
c[j+1] = trim(sub(f, 1, x - 1))
|
||||
c[j+2] = "]=],"
|
||||
c[j+3] = trim(sub(f, x + 1))
|
||||
c[j+4] = ")\n"
|
||||
j=j+5
|
||||
else
|
||||
c[j] = "___[#___+1]=include([=["
|
||||
c[j+1] = trim(f)
|
||||
c[j+2] = "]=])\n"
|
||||
j=j+3
|
||||
end
|
||||
s, i = e + 1, e + 2
|
||||
end
|
||||
end
|
||||
elseif t == LSQB then
|
||||
local e = find(view, "]}", p, true)
|
||||
if e then
|
||||
local z, w = escaped(view, s)
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = visit(visitors, sub(view, i, s - 1 - w))
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
if z then
|
||||
i = s
|
||||
else
|
||||
c[j] = "___[#___+1]=include("
|
||||
c[j+1] = visit(visitors, trim(sub(view, p, e - 1)), "[")
|
||||
c[j+2] = ")\n"
|
||||
j=j+3
|
||||
s, i = e + 1, e + 2
|
||||
end
|
||||
end
|
||||
elseif t == MINUS then
|
||||
local e = find(view, "-}", p, true)
|
||||
if e then
|
||||
local x, y = find(view, sub(view, s, e + 1), e + 2, true)
|
||||
if x then
|
||||
local z, w = escaped(view, s)
|
||||
if z then
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = visit(visitors, sub(view, i, s - 1 - w))
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
i = s
|
||||
else
|
||||
y = y + 1
|
||||
x = x - 1
|
||||
if byte(view, y, y) == LF then
|
||||
y = y + 1
|
||||
end
|
||||
local b = trim(sub(view, p, e - 1))
|
||||
if b == "verbatim" or b == "raw" then
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = visit(visitors, sub(view, i, s - 1 - w))
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
c[j] = "___[#___+1]=[=["
|
||||
c[j+1] = visit(visitors, sub(view, e + 2, x))
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
else
|
||||
if byte(view, x, x) == LF then
|
||||
x = x - 1
|
||||
end
|
||||
local r = rpos(view, s - 1)
|
||||
if i <= r then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = visit(visitors, sub(view, i, r))
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
c[j] = 'blocks["'
|
||||
c[j+1] = b
|
||||
c[j+2] = '"]=include[=['
|
||||
c[j+3] = visit(visitors, sub(view, e + 2, x), "-", b)
|
||||
c[j+4] = "]=]\n"
|
||||
j=j+5
|
||||
end
|
||||
s, i = y - 1, y
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif t == NUM then
|
||||
local e = find(view, "#}", p, true)
|
||||
if e then
|
||||
local z, w = escaped(view, s)
|
||||
if i < s - w then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = visit(visitors, sub(view, i, s - 1 - w))
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
if z then
|
||||
i = s
|
||||
else
|
||||
e = e + 2
|
||||
if byte(view, e, e) == LF then
|
||||
e = e + 1
|
||||
end
|
||||
s, i = e - 1, e
|
||||
end
|
||||
end
|
||||
end
|
||||
s = find(view, "{", s + 1, true)
|
||||
end
|
||||
s = sub(view, i)
|
||||
if s and s ~= EMPTY then
|
||||
c[j] = "___[#___+1]=[=[\n"
|
||||
c[j+1] = visit(visitors, s)
|
||||
c[j+2] = "]=]\n"
|
||||
j=j+3
|
||||
end
|
||||
c[j] = "return layout and include(layout,setmetatable({view=table.concat(___),blocks=blocks},{__index=context})) or table.concat(___)" -- luacheck: ignore
|
||||
return concat(c)
|
||||
end
|
||||
|
||||
function template.parse_file(view)
|
||||
return template.parse(view, false)
|
||||
end
|
||||
|
||||
function template.parse_string(view)
|
||||
return template.parse(view, true)
|
||||
end
|
||||
|
||||
function template.process(view, context, cache_key, plain)
|
||||
assert(view, "view was not provided for template.process(view, context, cache_key, plain)")
|
||||
return template.compile(view, cache_key, plain)(context)
|
||||
end
|
||||
|
||||
function template.process_file(view, context, cache_key)
|
||||
assert(view, "view was not provided for template.process_file(view, context, cache_key)")
|
||||
return template.compile(view, cache_key, false)(context)
|
||||
end
|
||||
|
||||
function template.process_string(view, context, cache_key)
|
||||
assert(view, "view was not provided for template.process_string(view, context, cache_key)")
|
||||
return template.compile(view, cache_key, true)(context)
|
||||
end
|
||||
|
||||
function template.render(view, context, cache_key, plain)
|
||||
assert(view, "view was not provided for template.render(view, context, cache_key, plain)")
|
||||
template.print(template.process(view, context, cache_key, plain))
|
||||
end
|
||||
|
||||
function template.render_file(view, context, cache_key)
|
||||
assert(view, "view was not provided for template.render_file(view, context, cache_key)")
|
||||
template.render(view, context, cache_key, false)
|
||||
end
|
||||
|
||||
function template.render_string(view, context, cache_key)
|
||||
assert(view, "view was not provided for template.render_string(view, context, cache_key)")
|
||||
template.render(view, context, cache_key, true)
|
||||
end
|
||||
|
||||
if safe then
|
||||
return setmetatable({}, {
|
||||
__index = function(_, k)
|
||||
if type(template[k]) == "function" then
|
||||
return function(...)
|
||||
local ok, a, b = pcall(template[k], ...)
|
||||
if not ok then
|
||||
return nil, a
|
||||
end
|
||||
return a, b
|
||||
end
|
||||
end
|
||||
return template[k]
|
||||
end,
|
||||
__new_index = function(_, k, v)
|
||||
template[k] = v
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
return template
|
||||
end
|
||||
|
||||
return new()
|
52
src/deps/src/lua-resty-template/lib/resty/template/html.lua
Normal file
52
src/deps/src/lua-resty-template/lib/resty/template/html.lua
Normal file
|
@ -0,0 +1,52 @@
|
|||
local template = require "resty.template"
|
||||
local setmetatable = setmetatable
|
||||
local escape = template.escape
|
||||
local concat = table.concat
|
||||
local pairs = pairs
|
||||
local type = type
|
||||
|
||||
local function tag(name, content, attr)
|
||||
local r, a = {}, {}
|
||||
content = content or attr
|
||||
r[#r + 1] = "<"
|
||||
r[#r + 1] = name
|
||||
if attr then
|
||||
for k, v in pairs(attr) do
|
||||
if type(k) == "number" then
|
||||
a[#a + 1] = escape(v)
|
||||
else
|
||||
a[#a + 1] = k .. '="' .. escape(v) .. '"'
|
||||
end
|
||||
end
|
||||
if #a > 0 then
|
||||
r[#r + 1] = " "
|
||||
r[#r + 1] = concat(a, " ")
|
||||
end
|
||||
end
|
||||
if type(content) == "string" then
|
||||
r[#r + 1] = ">"
|
||||
r[#r + 1] = escape(content)
|
||||
r[#r + 1] = "</"
|
||||
r[#r + 1] = name
|
||||
r[#r + 1] = ">"
|
||||
else
|
||||
r[#r + 1] = " />"
|
||||
end
|
||||
return concat(r)
|
||||
end
|
||||
|
||||
local html = { __index = function(_, name)
|
||||
return function(attr)
|
||||
if type(attr) == "table" then
|
||||
return function(content)
|
||||
return tag(name, content, attr)
|
||||
end
|
||||
else
|
||||
return tag(name, attr)
|
||||
end
|
||||
end
|
||||
end }
|
||||
|
||||
template.html = setmetatable(html, html)
|
||||
|
||||
return template.html
|
|
@ -0,0 +1,153 @@
|
|||
local template = require "resty.template"
|
||||
|
||||
local ok, new_tab = pcall(require, "table.new")
|
||||
if not ok then
|
||||
new_tab = function() return {} end
|
||||
end
|
||||
|
||||
local function run(iterations)
|
||||
|
||||
local gc, total, print, parse, compile, clock, format = collectgarbage, 0, ngx and ngx.say or print, template.parse,
|
||||
template.compile, os.clock, string.format
|
||||
|
||||
iterations = iterations or 1000
|
||||
|
||||
local view = [[
|
||||
<ul>
|
||||
{% for _, v in ipairs(context) do %}
|
||||
<li>{{v}}</li>
|
||||
{% end %}
|
||||
</ul>]]
|
||||
|
||||
print(format("Running %d iterations in each test", iterations))
|
||||
|
||||
gc()
|
||||
gc()
|
||||
|
||||
local x = clock()
|
||||
for _ = 1, iterations do
|
||||
parse(view, true)
|
||||
end
|
||||
local z = clock() - x
|
||||
print(format(" Parsing Time: %.6f", z))
|
||||
total = total + z
|
||||
|
||||
gc()
|
||||
gc()
|
||||
|
||||
x = clock()
|
||||
for _ = 1, iterations do
|
||||
compile(view, nil, true)
|
||||
template.cache = {}
|
||||
end
|
||||
z = clock() - x
|
||||
print(format("Compilation Time: %.6f (template)", z))
|
||||
total = total + z
|
||||
|
||||
compile(view, nil, true)
|
||||
|
||||
gc()
|
||||
gc()
|
||||
|
||||
x = clock()
|
||||
for _ = 1, iterations do
|
||||
compile(view, 1, true)
|
||||
end
|
||||
z = clock() - x
|
||||
print(format("Compilation Time: %.6f (template, cached)", z))
|
||||
total = total + z
|
||||
|
||||
local context = { "Emma", "James", "Nicholas", "Mary" }
|
||||
|
||||
template.cache = {}
|
||||
|
||||
gc()
|
||||
gc()
|
||||
|
||||
x = clock()
|
||||
for _ = 1, iterations do
|
||||
compile(view, 1, true)(context)
|
||||
template.cache = {}
|
||||
end
|
||||
z = clock() - x
|
||||
print(format(" Execution Time: %.6f (same template)", z))
|
||||
total = total + z
|
||||
|
||||
template.cache = {}
|
||||
compile(view, 1, true)
|
||||
|
||||
gc()
|
||||
gc()
|
||||
|
||||
x = clock()
|
||||
for _ = 1, iterations do
|
||||
compile(view, 1, true)(context)
|
||||
end
|
||||
z = clock() - x
|
||||
print(format(" Execution Time: %.6f (same template, cached)", z))
|
||||
total = total + z
|
||||
|
||||
template.cache = {}
|
||||
|
||||
local views = new_tab(iterations, 0)
|
||||
for i = 1, iterations do
|
||||
views[i] = "<h1>Iteration " .. i .. "</h1>\n" .. view
|
||||
end
|
||||
|
||||
gc()
|
||||
gc()
|
||||
|
||||
x = clock()
|
||||
for i = 1, iterations do
|
||||
compile(views[i], i, true)(context)
|
||||
end
|
||||
z = clock() - x
|
||||
print(format(" Execution Time: %.6f (different template)", z))
|
||||
total = total + z
|
||||
|
||||
gc()
|
||||
gc()
|
||||
|
||||
x = clock()
|
||||
for i = 1, iterations do
|
||||
compile(views[i], i, true)(context)
|
||||
end
|
||||
z = clock() - x
|
||||
print(format(" Execution Time: %.6f (different template, cached)", z))
|
||||
total = total + z
|
||||
|
||||
local contexts = new_tab(iterations, 0)
|
||||
|
||||
for i = 1, iterations do
|
||||
contexts[i] = { "Emma", "James", "Nicholas", "Mary" }
|
||||
end
|
||||
|
||||
template.cache = {}
|
||||
|
||||
gc()
|
||||
gc()
|
||||
|
||||
x = clock()
|
||||
for i = 1, iterations do
|
||||
compile(views[i], i, true)(contexts[i])
|
||||
end
|
||||
z = clock() - x
|
||||
print(format(" Execution Time: %.6f (different template, different context)", z))
|
||||
total = total + z
|
||||
|
||||
gc()
|
||||
gc()
|
||||
|
||||
x = clock()
|
||||
for i = 1, iterations do
|
||||
compile(views[i], i, true)(contexts[i])
|
||||
end
|
||||
z = clock() - x
|
||||
print(format(" Execution Time: %.6f (different template, different context, cached)", z))
|
||||
total = total + z
|
||||
print(format(" Total Time: %.6f", total))
|
||||
end
|
||||
|
||||
return {
|
||||
run = run
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
return require "resty.template".new(true)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package = "lua-resty-template"
|
||||
version = "dev-1"
|
||||
source = {
|
||||
url = "git://github.com/bungle/lua-resty-template.git"
|
||||
}
|
||||
description = {
|
||||
summary = "Templating Engine (HTML) for Lua and OpenResty",
|
||||
detailed = "lua-resty-template is a compiling (HTML) templating engine for Lua and OpenResty.",
|
||||
homepage = "https://github.com/bungle/lua-resty-template",
|
||||
maintainer = "Aapo Talvensaari <aapo.talvensaari@gmail.com>",
|
||||
license = "BSD"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["resty.template"] = "lib/resty/template.lua",
|
||||
["resty.template.safe"] = "lib/resty/template/safe.lua",
|
||||
["resty.template.html"] = "lib/resty/template/html.lua",
|
||||
["resty.template.microbenchmark"] = "lib/resty/template/microbenchmark.lua"
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue