Template directory config parameter (was: support for variables in file including tag)
msva opened this issue · 8 comments
Hi!
Can you add support for variables inside file including tag?
For example:
{%
if foo==bar then
context.page = "moo";
else
context.page = "index";
end
%}
{(tpl/{*page*}.tpl)}
For now it only renders as text :(
This has been discussed in some of the other closed issues. I'm not sure if this was a design mistake. Should you really have the include tag behave like an expression:
{("tpl/page.tpl")}
{("tpl/" .. page .. ".tpl")}
It's really easy to change (well, the replacable context makes it a little bit more difficult) to make it behave like that and make it more flexible, but that would be a breaking change. Other way is to solve this with helper function or a view macro. Or just use template directly:
{*template.compile("tpl/" .. page .. ".tpl")(context)*}
We could have by default a partial function (or you can create your own) that behaves like this:
{*partial(page)*}
Of course I do like breaking change here the most, but I'm not sure it is worth it. What you suggested was that instead of expression the include tag would behave as a template. Interesting approach indeed.
Please look at some of the closed bugs where this is discussed (like this: #5 (comment)). Read also documentation about including templates and documentation about macros. And of course we could discuss this more. Would we like to introduce another tag, say {[expression_include]}
, is it worth it?
Remember that lua-resty-template is really just a Lua code generator. Everything you can do in normal .lua files, you can do in templates as well.
I think that this could be fixed with changes in these lines:
https://github.com/bungle/lua-resty-template/blob/master/lib/resty/template.lua#L192-L198
local file = view:sub(e + 2, x - 1)
local a, b = file:find(',', 2, true)
if a then
c[#c+1] = '___[#___+1]=template.compile([=[' .. file:sub(1, a - 1) .. ']=])(' .. file:sub(b + 1) .. ')'
else
c[#c+1] = '___[#___+1]=template.compile([=[' .. file .. ']=])(context)'
end
to
c[#c+1] = '___[#___+1]=partial(view:sub(e + 2, x - 1))'
Where this partial function is actually a template function in every template (so that it has access to default context). Partial function syntax is something like this:
local function partial(file, ctx)
return template.compile(file)(ctx or context) -- where context is the default current context
end
This way you could have code like this in template:
{("file.html", { new_context_var = "testing" })}
{# and this #}
{("tpl/" .. page .. ".tpl", { new_context_var = "testing" })}
{# or even this #}
{("tpl/" .. find_my_pagename(15) .. ".tpl", { new_context_var = "testing" })}
But this is a breaking change -> "file.html"
~= file.html
. As said, we could introduce another tag like {[...]}
. That said... is it worth to break backward compability and have a little bit more complex syntax for normal includes, or does this warrant a new tag?
Any discussion, ideas, and contributions are welcomed!
Regards
Aapo
I think, it is pretty ok to introduce new tag (although, probably it steals that tag from some future feature.
And I also don't think it is good to break API just for such feature.
Although, I'm unsure about usefulness of rendering the argument as just a string, without a try to evaluate, by the loader itself.
Maybe it will be nice to do something there?
-- Although, I'd try to play around it myself in near future, but too busy ATM.
-- btw, I've one more idea (although, I don't dig too much in latest commit history, so it can be already implemented): allowing to specify template dir for loader function in the context (and make it to try to use it). This will add possibility to change it on the fly for any random render call, if it is needed. For example, I using it to bundle svg images in pages, since using for SVG is a crap in, at least, firefox. And image directory is a bit different, that template one. And I dislike to call images by ".." in relative path, and even more to call them by absolute path). And it also has advantages that svg can be templated (and cached) too ;)
Anyway, thanks for attention :)
Okay, I think I'm going to implement {[exporession_include]}
soon.
In Nginx/OpenResty context you can specify location with these:
https://github.com/bungle/lua-resty-template#nginx--openresty-configuration
... or are you looking something different?
I already wrote {[expression_include]}
(not committed, though) code but I think that I will do some refactoring in parse function. Trying to make it simpler, and maybe even faster in a process, oh and there are some linefeeds that gets eaten on current code, I will fix that one too.
В письме от Ср, 19 ноября 2014 14:34:38 пользователь Aapo Talvensaari написал:
I already wrote
{[expression_include]}
(not committed, though) code but I
think that I will do some refactoring in parse function. Trying to make it
simpler, and maybe even faster in a process, oh and there are some
linefeeds that gets eaten on current code, I will fix that one too.
Reply to this email directly or view it on GitHub:
#7 (comment)
Nice news! Thanks! ;)
Best regards,
mva
Hi,
The {[ expression ]}
and {[ expression, context ]}
is supported on a latest commit. One thing in this commit that is not backward compatible is that there is now include
function in templates, which mean that if you put value with key include
in context
table you have to reference it with context.include
in templates.
I also rewrote the whole parsing function. I tried several aproaches (like ngx.re.gmatch
, ngx.re.find
, ngx.re.gsub
) and some of them where simpler and made the code more elegant, but they usually carried some performance penalty as well, and made it harder to support Lua 5.1, LuaJIT > 2.0, OpenResty, and Lua > 5.2 the same time. I finally settled with the original approach using string.find
(with plain search string). The code is now a little bit more elegant in template.parse function (less repetion of code there), but the best thing about this is that now linefeeds are handled correctly.
Still, I didn't yet release this as 1.4 as I like to test this rather big change for a little bit more. It looks like really solid now, but you never know. So, please go ahead, and checkout the latest sources from the master branch to get this new, yet to be released, version.
Regards
Aapo
PS. I'm still thinking about implementing your second request about template dir. It's already supported in OpenResty context, I think, but I look forward adding support for other environments as well.
You can now configure the template directory with 2.0
.