Hi all, I started work replacing Django's if with the "smart-if" template tag by Chris Beaven ( http://www.djangosnippets.org/snippets/1350/ )
Of course, it is not as simple as it looks... 4 issues: 1) Handling non-existent variables ================================== The current smart-if does not handle the case of non-existent variables like Django does. (For example, something like {% if foo or bar %} when one of foo or bar is not defined in the context.) To do this properly, I think the best approach would be something like "almost three valued logic", which would work as follows: 1) variables that don't exist are represented by Null 2) all operators return either True or False, never Null 3) for 'not', 'and' and 'or', Null effectively acts like False (so "not Null" == True, "Null or True" == True etc) 4) for all comparison operators, if either argument is Null then the result is False e.g. "Null == Null" is False "Null > 1" is False, "Null <= 1" is False, except "!=", which should return true if either value is Null. Any comments on this approach? I've started to implement this, and it works OK so far, just needs a bit more work. 2) TEMPLATE_STRING_IF_INVALID breaks everything =============================================== The smart 'if' tag allows for filters: {% if articles|length >= 5 %} To achieve this, it puts its arguments through FilterExpression. If settings.TEMPLATE_STRING_IS_INVALID is not an empty string, this means that: {% if foo %}blah{% endif %} will render 'blah' instead of '' if 'foo' is not in the context. This causes test failures at the moment. We could change the tests, but that is a backwards incompatibility, and it highlights a fundamental change in the behaviour of {% if %}, which basically makes TEMPLATE_STRING_IF_INVALID useless for even its stated purpose of debugging, because the logic of a template will now be changed. Personally, I care nothing for TEMPLATE_STRING_IF_INVALID, as there are other things that it breaks, and I never use it. But obviously I can't just think of myself here. If there was an easy solution that didn't change the behaviour of the if tag in this case that would be great, but I can't see one. 3) Behaviour of 'x and b or y' ============================== Previously this was a syntax error. In Chris's code, it is fine and works like Python. I would vote for keeping the smart-if as it is, as I don't see the value of complicating the implementation to disallow something that could be useful sometimes. 4) Behaviour of 'not' ===================== Current Django will interpret 'not' as a variable if there is no ambiguity e.g. {% if not %}blah{% endif %} This is not documented, but the behaviour is specified in detail in the tests, so changing it would be a backwards incompatibility. The smart-if is different (the above is a syntax error), and I suspect that making the smart-if behave like current Django could complicate things a lot. IMO, current Django behaviour here is complete misfeature! I don't know of any other language where keywords can be treated as variables if the keyword doesn't make sense in that position... Regards, Luke -- "He knows the way I take: when he has tried me, I shall come forth as gold" (Job 23:10). Luke Plant || http://lukeplant.me.uk/ -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-develop...@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.