Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

known-variables and tags #306

Open
eval opened this issue Oct 6, 2023 · 8 comments
Open

known-variables and tags #306

eval opened this issue Oct 6, 2023 · 8 comments

Comments

@eval
Copy link

eval commented Oct 6, 2023

It seems that #'parser/known-variables does not handle variables in tags correctly:

user=> (selmer/known-variables "{% if {{var}} %}{{other-var}}{% endif %}")
#{:other-var :{{var}}}
;; expected:
;; #{:other-var :var}
@yogthos
Copy link
Owner

yogthos commented Oct 6, 2023

That does look like a bug. I won't have a chance to take a look in the near future, but a PR would be welcome.

@seancorfield
Copy link
Collaborator

Is that just an alternate syntax for {% if var %}{{other-var}}{% endif %} (which I assume works?) I don't think I've ever seen {{..}} used inside {% .. %} like that...

@seancorfield
Copy link
Collaborator

No, that {{var}} format doesn't work inside {% .. %}:

user=> (html/render "{% if {{var}} %}yes{% else %}no{% endif %}" {:var true})
"no"
user=> (html/render "{% if var %}yes{% else %}no{% endif %}" {:var true})
"yes"

@yogthos
Copy link
Owner

yogthos commented Oct 6, 2023

Ah yeah that's a good good point, nesting a var inside a condition this way isn't actually supported. I missed that bit. I think we can close this then.

@yogthos yogthos closed this as completed Oct 6, 2023
@eval
Copy link
Author

eval commented Oct 7, 2023

Sorry, my example was too simple. I meant to refer to the recently added capability to have vars in custom tags:

(selmer/add-tag!
        :ifendswith
        (fn [args context-map content]
          (let [args (map #(selmer/resolve-arg % context-map) args)]
            (if (str/ends-with? (first args) (second args))
              (-> content :ifendswith :content)
              (-> content :else :content))))
        :else :endifendswith)

(selmer/known-variables "{% ifendswith {{var}} \"foo\" %}{{var}} ends with foo!{% endifendswith %}")
;; #{:{{var}} :var}

@yogthos yogthos reopened this Oct 7, 2023
@seancorfield
Copy link
Collaborator

This is still var-in-a-tag which isn't supported by Selmer itself. You're explicitly calling resolve-arg in your own case which does its own rendering internally to support {{var}} -- but Selmer itself doesn't know anything about that.

However:

user=> (selmer/known-variables "{% ifendswith var1 \"foo\" %}{{var2}} ends with foo!{% endifendswith %}")
#{:var1 :var2}

That seems inconsistent -- var1 isn't really a variable in any useful way: it has to be explicitly looked up.

But I think perhaps resolve-arg isn't really doing what it is supposed to here? @didibus would need to chime in. I think it should probably have used selmer.filter-parser/lookup-args under the hood which supports the @var syntax used in filters (and I've been using a form of that in my custom tags).

Even if you use s.f-p/l-a and {% if endswith @var \"foo\" %}, known-variables is going to produce :@var which seems wrong?

user=> (selmer/known-variables "{% ifendswith @var1 \"foo\" %}{{var2}} ends with foo!{% endifendswith %}")
#{:var2 :@var1}

@yogthos
Copy link
Owner

yogthos commented Oct 9, 2023

It does look like using lookup-args to get the value might do the trick here. Right now resolve-arg just checks for literal, but a case where it's a reference isn't handled.

@eval
Copy link
Author

eval commented Oct 13, 2023

Thanks both - my initial need for this was to check whether all variables of a template are provided. But the custom-tag example, as I now understand, is not something you would use often.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants