mmontone / djula

Common Lisp port of the Django templating language
http://mmontone.github.io/djula/djula
MIT License
152 stars 21 forks source link

Add experimental bindings for include #45

Closed chaitanyagupta closed 6 years ago

chaitanyagupta commented 6 years ago

What this branch does?

Adds experimental bindings for the include template tag, which extends *template-arguments* when the included template tag is rendered.

e.g. {% include "user-ref.html" (user record.creator) %} will bind user to the value of record.creator while rendering the template user-ref.html.

Why is it required?

I want to use an included template at multiple places in the same document. However the context needs to be different at each of these places. I couldn't find any existing functionality that would allow me to do this, hence this patch. (Please correct me if this could be achieved in another way).

I'll explain what I need with an example:

First, the parent template (record.html):

<!DOCTYPE html>
<html>
  <body>
    <h1>{{record.title}}</h1>
    <div>created by {% include "user-ref.html" (user record.creator) %}</div>
    <div>updated by {% include "user-ref.html" (user record.updater) %}</div>
  </body>
</html>

Notice that user is bound to different values above.

Next, the included template (user-ref.html):

<a href="{{user.url}}">{{user.name}}</a>

If I run the following Lisp code:

(defvar *alice* (list :name "alice" :url "/user/alice"))
(defvar *eve* (list :name "eve" :url "/user/eve"))

(djula:render-template* #p"record.html"
                        *standard-output*
                        :record `(:title "title 1" :creator ,*alice* :updater ,*eve*))

The expected output is:

<!DOCTYPE html>
<html>
  <body>
    <h1>title 1</h1>
    <div>created by <a href="/user/alice">alice</a>
</div>
    <div>updated by <a href="/user/eve">eve</a>
</div>
  </body>
</html>

Final Note

I hope I have demonstrated the need for this functionality with the example above. In case this could be accomplished with an existing tag, my apologies.

Finally, this patch was just meant to show the functionality I am hoping to see in djula. I am certain that things like syntax, etc. may not be to the maintainers' liking. I'd be happy to make any changes.

mmontone commented 6 years ago

Ok. I would call this "parameterized includes". I think it makes sense. I'll think about it more later.

mmontone commented 6 years ago

What about using this syntax?:

{% include "user-ref.html" :user record.creator :other-argument 33 %}

Looks more consistent with the syntax we have in other part of Djula, for rendering templates for example.

chaitanyagupta commented 6 years ago

Yeah this makes a lot more sense.

On Fri, 1 Jun 2018 at 7:10 PM Mariano Montone notifications@github.com wrote:

What about using this syntax?:

{% include "user-ref.html" :user record.creator :other-argument 33 %}

Looks more consistent with the syntax we have in other part of Djula, for rendering templates for example.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mmontone/djula/pull/45#issuecomment-393884003, or mute the thread https://github.com/notifications/unsubscribe-auth/AACMhOPjmpwtQDRPXR64TE-ih2HV9YrBks5t4URkgaJpZM4UVn_L .

-- https://chaitanyagupta.com https://lisper.in https://twitter.com/chaitanya_gupta

mmontone commented 6 years ago

Ok. If you implement that, and maybe add some test (parse a template with a parameterized include and check the result (see Djula tests for inheritance, etc)), I'll be happy to integrate.

chaitanyagupta commented 6 years ago

Ok, I will close this PR and open a new one.