tyler-sommer / stick

A golang port of the Twig templating engine
MIT License
183 stars 36 forks source link

Extending a base template not working for me. #17

Closed ghost closed 4 years ago

ghost commented 5 years ago

Something I do with twig in php like in the j2 files I have shown below. This doesn't seem to work in stick. I've narrowed it down to parent() being the culprit. Stick just kindof gives up after hitting that.

This library at least got further than some of the other's I've checked out for jinjas templates.

I'd be happy to contribute, but I would be learning from the ground up on this stuff. If no one else has time to really look into this, if you can point me in the right direction on learning this stuff from the ground up, I'm more than happy to put some of my free time into learning this a bit and throwing in a pull request when I patch it for myself.

templates/page1.j2

{% extends "base.j2" %}

{% block title %} - More to life than just fun!{% endblock %}
{% block head %}
    {{ parent() }}
{% endblock %}
{% block content %}
    Content goes here.... PAGE 1
    {{ a }}
    {{ b }}

{% endblock %}

templates/base.j2

<!doctype html>
<html lang="en">
<head>
    {% block head %}
    <title>{{ sitename }}{% block title %}{% endblock %}</title>
    {% endblock %}
</head>

<body>
    {% block content %}{% endblock %}
</body>
</html>

main.go

package main

import (
    "github.com/tyler-sommer/stick/twig"
    "github.com/tyler-sommer/stick"
    "os"
)

func main() {
    env := twig.New(stick.NewFilesystemLoader("./templates/"))
    env.Execute("page1.j2", os.Stdout, map[string]stick.Value{ "sitename": "Somesite!" })
}
tyler-sommer commented 5 years ago

Hi there @protosam ! Thanks for opening this.

Looks like parent() is not implemented, only block().

If I remember right, when a child template's block is executed, the execution has access to all blocks in the template hierarchy, but the implementation right now just does a greedy "first". Note that s.blocks is a []map[string]Block where each template's blocks are stored together as a "set" in a single element-- each new set of blocks inherited via extend is appended to the end of the s.blocks slice, while new sets of blocks inherited via use are prepended to the front.

For your example, s.blocks[0] is going to be the child template's blocks (set here), and s.blocks[1] will be the parent's (set here). I think all you'd need is a reverse getBlocks() method so that the last set of blocks is looked at first.

I hope that wasn't too convoluted, let me know if anything is unclear!

ghost commented 5 years ago

@tyler-sommer it makes sense. I'll see if I can implement parent() and get back to you here if I get hard-stuck or when I have something working. Whichever happens first. I'll avoid inundating you with trivial questions. :)