yogthos / Selmer

A fast, Django inspired template system in Clojure.
Eclipse Public License 1.0
985 stars 114 forks source link

Resolve variables in custom tags #303

Closed didibus closed 1 year ago

didibus commented 1 year ago

In a custom tag, any way that I can resolve variables?

(html/add-tag!
 :ifendswith
 (fn [args _context-map content]
   (if (str/ends-with? (first args) (second args))
     (-> content :ifendswith :content)
     (-> content :else :content)))
 :else :endifendswith)

Template:

{% ifendswith {{game.push.img}} "cover_large.jpg" %}
   <img src="{{game.igdb.img}}" alt="Cover of {{game.title}}">
{% else %}
   <img src="{{game.push.img}}" alt="Cover of {{game.title}}">
{% endifendswith %}

The custom tag gets "{{game.push.img}}" as the arg, but I would want this resolved and get the value it refers too instead.

didibus commented 1 year ago

Until there's a standard feature to do it, for those looking, you can use the following:

(require '[selmer.filter-parser :as htmlp])
(require '[selmer.parser :as html])

(defn resolve-selmer-args
  [args context-map]
  (map #(if (htmlp/literal? %)
          (htmlp/parse-literal %)
          (html/render % context-map)) args))

Now if you give the args passed to add-tag! to resolve-selmer-args it'll return them resolved, meaning if they themselves contain variables with or without filters, or tags, those will get processed first, and you'll get the value out of them as the arg.

yogthos commented 1 year ago

Ah yeah, that would be the best approach. It would probably be reasonable to add the above helper function to help with resolving variables in custom tags. Would you like to do a PR for that?

didibus commented 1 year ago

I can make one in the next few days.

yogthos commented 1 year ago

Sounds like a plan. 👍

didibus commented 1 year ago

PR: https://github.com/yogthos/Selmer/pull/304