mmontone / djula

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

Include using variables #5

Closed lucashpandolfo closed 9 years ago

lucashpandolfo commented 9 years ago

The manual (http://mmontone.github.io/djula/doc/build/html/tags.html#include) says: "The template name can either be a variable or a hard-coded (quoted) string, in either single or double quotes.". Using the template

{% include form %}

I get:

Date/time: 2015-02-25-15:25An unhandled error condition has been signalled:
{# Error: There was an error compiling the token (TAG INCLUDE FORM) : The value
:FORM
is not of type
STRING. #}

Backtrace for: #
0: ((LAMBDA NIL :IN SB-DEBUG::FUNCALL-WITH-DEBUG-IO-SYNTAX))
1: (SB-IMPL::CALL-WITH-SANE-IO-SYNTAX #)
2: (SB-IMPL::%WITH-STANDARD-IO-SYNTAX #)
3: (PRINT-BACKTRACE :STREAM # :START 0 :FROM :DEBUGGER-FRAME :COUNT 4611686018427387903 :PRINT-THREAD T :PRINT-FRAME-SOURCE NIL :METHOD-FRAME-STYLE NIL)
4: (TRIVIAL-BACKTRACE:PRINT-BACKTRACE-TO-STREAM #)
5: (TRIVIAL-BACKTRACE:PRINT-BACKTRACE # :OUTPUT NIL :IF-EXISTS :APPEND :VERBOSE NIL)
6: (DJULA:RENDER-TEMPLATE* # NIL :FORM #P"forms/f1.dtl")
...

If i change it to:

{% include {{ form }} %}

I get:

Date/time: 2015-02-25-15:28An unhandled error condition has been signalled:
{# Error: There was an error compiling the token (TAG INCLUDE {{ FORM }}) : error while parsing arguments to DESTRUCTURING-BIND:
invalid number of elements in
(:{{
:FORM
:}})
to satisfy lambda list
(DJULA::PATH):
exactly 1 expected, but 3 found #}

Backtrace for: #
0: ((LAMBDA NIL :IN SB-DEBUG::FUNCALL-WITH-DEBUG-IO-SYNTAX))
1: (SB-IMPL::CALL-WITH-SANE-IO-SYNTAX #)
2: (SB-IMPL::%WITH-STANDARD-IO-SYNTAX #)
3: (PRINT-BACKTRACE :STREAM # :START 0 :FROM :DEBUGGER-FRAME :COUNT 4611686018427387903 :PRINT-THREAD T :PRINT-FRAME-SOURCE NIL :METHOD-FRAME-STYLE NIL)
4: (TRIVIAL-BACKTRACE:PRINT-BACKTRACE-TO-STREAM #)
5: (TRIVIAL-BACKTRACE:PRINT-BACKTRACE # :OUTPUT NIL :IF-EXISTS :APPEND :VERBOSE NIL)
6: (DJULA:RENDER-TEMPLATE* # NIL :FORM #P"forms/f1.dtl")

Seems like include is expecting a string only (not a variable). Is there another way to include a template using variables?

mmontone commented 9 years ago

I'm afraid the documentation is wrong. There's no support for that atm. I've tried a fix, but template includes are resolved at compile time (compile-template), so I think a quick patch would be to allow to pass arguments to compile-template function, but I'm not sure that would be very useful, doesn't look very dynamic. Or would that be enough for your purposes?

The idea is:

(compile-template* "template.djula" :t1 "include.djula")

and then: {% include t1 %}

although that's quite static because it's at compile time.

Something like render-time inclusion would be more flexible, but I think much more difficult to implement because of how Djula is implemented.

mmontone commented 9 years ago

Wait...maybe I will be able to implement this at render time.

mmontone commented 9 years ago

Ok. I've pushed an implementation of this.

(render-template* template nil :t1 "myincludetemplate.djula")

Can you pull from master and test?

lucashpandolfo commented 9 years ago

It's not really a big deal. My code is something like:

(defroute new-item "/new/:type" (&key type)
  (let ((form (assoc type '(("t1" . "f1.dtl")
                                        ("t2" . "f2.dtl")) :test #'string-equal)))
    (if form
        (render #P"new.dtl" `(:form ,(concatenate 'string "forms/" (cdr form))))
        (throw-code 404))))

And then, new.dtl:

{% extends "layouts/default.dtl" %}
{% block content %}
...
...
{% include form %}
...
...
{% endblock %}

And then f1 and f2 just have a form.

But i could change it so f1 and f2 extends from a 'layouts/new-item' template avoiding the include.

lucashpandolfo commented 9 years ago

Ok. I can confirm it is working now. Thanks.