Raise error for missing variable used in template

While listening to the latest Django Chat podcast with @Lily-Foote there was talk about ways to raise an error when a variable is missing from the template context.

A few ideas were mentioned that I remember:

  1. global setting that changes the behavior for non-Django templates, i.e. Django admin templates use this functionality and so we can’t break that functionality; django-fastdev provides similar functionality now, I think?
  2. a template tag that could be used to define a list of variables that should raise an exception if used and they are not in the context (I think that was the idea?)
  3. similar to #2, but perhaps a way to mark per-template that all variables are required to be in the context?

One thing I was brainstorming was a way to specify, when using the variable, that it should always be non-null. Maybe a suffix added to the variable to indicate that it should be non-null?

In GraphQL, a schema uses a ! to indicate that the value should be non-null, so that was the first thing that popped into my head, but I’m curious if anyone has any other ideas about this?

I originally posted in Mastodon (adamghill: "While listening to the latest @djangochat@fosstod…" - Indieweb.Social), but Lily encouraged me to post it in the forum for other feedback.

Swift also uses ! for force unwrapping of optionals.

1 Like

I think this is a great idea!

I also wonder about adding ? to mark explicitly using the existing behaviour. This would allow Django’s admin, for example, to migrate to use ? where that behaviour is relied on. This would be more self-documenting, which I think should also make overriding/copying admin templates easier.

1 Like

Good point! I do like the explicitedness of the ?.

Requiring a ? for the current behavior seems like it would require a long deprecation period, since I assume there is a lot of template code floating around that expects the current behavior. I guess there could be a setting to determine how it works, but I worry that it could be a messy transition.

I was thinking of it being optional at first - something that people could enforce via a linter or something.

Yeah. I’d suggest not getting too far ahead. The ! (and ? maybe?) idea is cute, a possibility. The idea of swapping out the default behaviour under the ecosystem (with any deprecation period) is a whole something else. (The ?-like behaviour is a defining feature of the DTL. A tag to enforce ! as default for that template, might be a better follow-up)

2 Likes

The simplest way is to apply a template filter that raises if the context value is none.

As you may know, Django templates return none if a specific context is missing.

If you want to find exactly when a specific value is missing during context tracking, you need to customize the template backend.

Could this be a good candidate for the introduction of feature flags?

  • feature off: legacy behaviour
  • feature on: new behaviour inforced

Ansible has this interesting feature (though I am not sure if Jinja doesn’t provide this out of the box) where you would put something like:

#jinja2: trim_blocks:false

at the beginning of a file to change the behavior for that template invocation. We could probably do something similar ala:

#dtl: raise_on_undefined:true

Turns out there’s an only ticket for this, of course. (The raising bit, not the optional/force unwrapping syntax)

There’s a PR for it, but I’m not sure it’ll work, as it’s only currently a simple toggle at the template engine level.

But take a look at Tim’s old comment:6 there. There some ideas and breadcrumbs for how we might make this more subtle and useful (allowing logging for example, rather than just raising).

I think if we could combine that with (maybe) the per-file thoughts from this thread we might be able to make progress on an old and recurring point.