Vapor(4.77) Leaf(4.2.4) 101: Unable to render a child leaf within its parent leaf (template)

100 Views Asked by At

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.

enter image description here

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.

1

There are 1 best solutions below

10
On

In parent.leaf You need to replace your:

#embed("child")

with:

#import("body")

Oh dear, I missed the obvious! You also need to change your route to:

func getExample(req: Request) async throws -> View {
        return try await req.view.render("child", ["title": "Example"])
 }

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.