wheelius
(Will Morris)
1
Hi all, it seems with the #extend tag in Leaf the context is automatically passed from the renderer. However if you have a more complicated (or nested) context, it doesn't seem to know how to separate keys. For example if you have the following:
parent.leaf
<html>
<head>
<title>#(title)</title>
</head>
<body>#extend("button")</body>
</html>
button.leaf
<button>#(title)</button>
ParentContext.swift
struct ParentContext: Encodable {
let title: String
let infoButton: Button
}
ButtonContext.swift
struct Button: Encodable {
let title: String
}
And you render this with
let button = ButtonContext(title: "Button title")
let context = ParentContext(title: "Parent title", infoButton: button)
request.view.render("parent", context)
Both the parent.leaf and the button.leaf will try and use the 'title' property on ParentContext. Resulting both #(title) to display "Parent title". Is there a way to specify sub contexts for #extend? For example something like:
<html>
<head>
<title>#(title)</title>
</head>
<body>#extend("button", "infoButton")</body>
</html>
Where the 'infoButton' is the key of the subcontext?
Note: New to HTML templating so not sure if this is in general a bad practice, or if there is a better approach to solve this
0xTim
(Tim)
2
Leaf's design means that the context is global across all templates and sub-templates. This is a deliberate decision to make it much simpler to implement and to avoid confusing people.
The easiest way around is just to change the name to something like infoButtonTitle
thecheatah
(Ravneet Singh)
3
I wanted to see if something like "with" exists, where you could pass down a sub context. So instead:
#(form.name)
#(form.email)
You can say
#with(form):
#(name)
#(email)
#endwith
You could also use this to pass down a sub context to an exported template. That way templates don't need a "consistent" context.
I honestly just started playing around with leaf not 100% sure of the pitfalls with the approach above.
edit: I just tried it and it's already working in the latest version of Vapor! I am not sure why it's not documented. This is so weird!
1 Like
wheelius
(Will Morris)
4
Looks like you can also pass it through the #extend tag now (fix here). Allowing:
struct ParentContext: Encodable {
let button1: Button
let button2: Button
let button3: Button
}
#extend("button", button1)
#extend("button", button2)
#extend("button", button3)
1 Like
thecheatah
(Ravneet Singh)
5
Thank you. This was the my question behind the question. It makes processing contexts much more modular and leaf templates reusable.