Environment:
Vapor v4.77
Leaf v4.2.4
Neophyte Goal: To incorporate a child leaf into its parent leaf (template).
Scenario: Rendering the basic "hello" world is fine. It works as a stand-alone. However, I want to use the power of templates along with the dynamic of leaf tags, etc.
Problem: The problem centers around the #embed() & #include() tags. It doesn't render the child.leaf. The output is merely the 'embed' or 'include' word.
The URL:
http://127.0.0.1:8080/leaves/example?content-type=application/json
The target code:
func getExample(req: Request) async throws -> View {
return try await req.view.render("parent", ["title": "Example"])
}
parent.leaf:
<html>
<head>
<title>#(title)</title>
</head>
<body>
<h1>Parent Leaf</h1>
<h3>#(title)</h3>
I'm trying to embed some shit here.
#embed("child")
</body>
</html>
Revised Parent Leaf, replacing #embed with #import:
<html>
<head>
<title>#(title)</title>
</head>
<body>
<h1>Parent Leaf</h1>
<h3>#(title)</h3>
I'm trying to import some shit here.
#import("child")
</body>
</html>
child.leaf:
#extend("parent"):
#export("body"):
What are you looking at?
#endexport
#endextend
I tried with and without the #extend & #export tags.
It makes no difference.
The generated HTML code via Postman™ reveals:
<html>
<head>
<title>Example</title>
</head>
<body>
<h1>Parent Leaf</h1>
<h3>Example</h3>
I'm trying to import some shit here.
</body>
</html>
Both the parent & child leafs share the same View directory within Vapor.
Why doesn't the #embed (or #include) work?
Out of curiosity, I changed the target from parent to child:
#extend("parent"):
What are you looking at?
#endextend
This is what I got via Postman™:
<html>
I'm trying to embed some shit here.
</html>
Which matches the revised parent (without the #import):
<html>
I'm trying to embed some shit here.
#import("child.leaf")
</html>
... so apparently the #extend() works but both the #import and #embed don't.
I've tested the '#import("body")' per request and also asked my ChatDBT Bot to follow thru:
1) [Vapor v4.77] [Leaf 4.2.4]
func getExample(req: Request) async throws -> View {
return try await req.view.render("parent", ["title": "Example"])
}
2) parent.leaf:
<html>
I'm trying to embed some shit here.
#import("body")
</html>
3) child.leaf:
#extend("parent"):
What are you looking at?
#endextend
3) What is the expected Result?
<html>
I'm trying to embed some shit here.
What are you looking at?
</html>
5) However, this is the REAL result via Postman:
<html>
I'm trying to embed some shit here.
</html>
So my Claude AI Bot expected my child.leaf to be included with the parent (#3).
However in REALITY, the child was ignored.
Note: I made sure the Child.leaf is available.
In
parent.leaf
You need to replace your:with:
Oh dear, I missed the obvious! You also need to change your route to:
If you think about it, it is obvious. Trying to render the 'parent' won't allow you to modify the template in any way, which is what you are seeing. You can have as many 'children' as you like and rendering these will allow you to use the template as such.