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

Support for "not in" syntax (works in Python jinja2) #261

Open
tjsmith-meta opened this issue Sep 20, 2024 · 2 comments
Open

Support for "not in" syntax (works in Python jinja2) #261

tjsmith-meta opened this issue Sep 20, 2024 · 2 comments

Comments

@tjsmith-meta
Copy link

The following template (foo in (...)) compiles fine in both Python jinja2 and Jinja2Cpp.

{% macro foo(val) %}
{{1 if val in ('', "''", 'foo')}}
{% endmacro %}

Whereas this slight variant (foo not in (...)) works only in Python jinja2.

{% macro foo(val) %}
{{1 if val not in ('', "''", 'foo')}}
{% endmacro %}

This seems like a bug that it doesn't work in Jinja2Cpp. I'm happy to make the code fix here, but would appreciate some pointers in the code as to what the fix might look like here. I suspect there may be a simple fix here. Help would be much appreciated!

@tjsmith-meta
Copy link
Author

Here's a very hacky solution from a quick pass over the code. Seems unlikely to be a complete or fully correct solution, but appears like it works for the particular example template that I have.

--- a/jinja2cpp/src/expression_parser.cpp
+++ b/jinja2cpp/src/expression_parser.cpp
@@ -130,6 +130,22 @@
     default:
         switch (lexer.GetAsKeyword(tok))
         {
+        case Keyword::LogicalNot:
+        {
+            Token inToken = lexer.NextToken();
+            if (lexer.GetAsKeyword(inToken) != Keyword::In) {
+              lexer.ReturnToken();
+              return left;
+            }
+
+            auto right = ParseStringConcat(lexer);
+            if (!right) {
+              return right;
+            }
+
+            return std::make_shared<UnaryExpression>(UnaryExpression::Operation::LogicalNot,
+                std::make_shared<BinaryExpression>(BinaryExpression::In, *left, *right));
+        }
         case Keyword::In:
             operation = BinaryExpression::In;
             break;

@tjsmith-meta
Copy link
Author

The official documentation also seems to confirm that 'not in' syntax is valid in jinja2.
https://jinja.palletsprojects.com/en/2.10.x/templates/#logic

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

No branches or pull requests

1 participant