GSoC 2026 Contributor Introduction – soro wahagnona jean | Add Ergonomic Control over Behaviour of Missing Variables in Templates
Hi everyone! My name is soro wahagnona jean, a software developer from ivory coast with around 3 years of experience building web applications with Django.
I’ve been following the Django community for a while and I’m excited to apply for Google Summer of Code 2026. I would like to work on the project: “Add ergonomic control over behaviour of missing variables in templates” (Issue #5).
Links:
Why This Project
While working on Django projects, I repeatedly ran into a frustrating debugging experience: a typo in a template variable name silently renders as an empty string, leaving no trace of the error. I discovered string_if_invalid, but quickly found out it is fragile and breaks rendering in many subtle ways.
Reading through the community discussions — especially the forum thread from March 2025 and the long-standing ticket #28618 (open since 2017) — I found that this pain point is widely shared and that the community has already converged on a clear direction: Jinja2-style Undefined types.
The existing PR (#19353) was marked “needs improvement” by Carlton Gibson because it only provides a blunt global toggle, without addressing Tim Graham’s original proposal for a flexible if_invalid callable. My goal is to implement exactly that — properly.
Proposed Technical Approach
Rather than modifying the template syntax (the ! marker idea was discussed and set aside) or adding a simple boolean flag, I propose introducing a configurable Undefined class system into django.template, directly inspired by Jinja2’s proven architecture and Adam Johnson’s suggestion in the forum thread.
Core idea
When Variable.resolve() fails to find a variable in the context, instead of returning "", it returns an instance of a configurable Undefined class. The default class (SilentUndefined) preserves full backward compatibility.
Proposed classes
| Class | Behaviour |
|---|---|
SilentUndefined (default) |
Returns "" — identical to current behaviour, zero breakage |
LoggingUndefined |
Logs a WARNING with the variable name — great for staging |
StrictUndefined |
Raises VariableDoesNotExist on rendering — ideal for dev/test |
DebugUndefined |
Renders {{ variable_name }} visually — useful for quick inspection |
Configuration (settings.py)
TEMPLATES = [{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"OPTIONS": {
# Default (backward-compatible):
# "undefined": "django.template.undefined.SilentUndefined",
# In development / tests:
"undefined": "django.template.undefined.StrictUndefined",
}
}]
Why this approach is sound
-
Zero migration cost — no DTL syntax changes, existing templates work as-is
-
Environment-specific — strict in dev, silent in prod, logging in staging
-
Extensible — teams can subclass
Undefinedfor custom behaviour -
Admin-safe —
SilentUndefinedis the default, Django admin is unaffected -
Deprecates
string_if_invalid— which is documented as a debugging tool but known to break rendering in many cases
Work Plan (350 hours)
| Phase | Weeks | Deliverables |
|---|---|---|
| Research & Design | 1–3 | Audit all usages of string_if_invalid in Django codebase and third-party packages; draft architecture document; post DEP-style design to forum for community feedback |
| Core Implementation | 4–7 | Implement django/template/undefined.py with the 4 classes; modify Variable.resolve() and FilterExpression to use the configurable Undefined; write unit tests |
| Admin Compatibility | 8–9 | Run full Django test suite with SilentUndefined; audit the admin templates that rely on silent variable resolution and document them |
string_if_invalid Deprecation |
10–11 | Add deprecation warning for string_if_invalid; write migration guide |
| Docs & Polish | 12–14 | Write official documentation with real-world examples; update release notes; address mentor review feedback |
Success Criteria
-
All 4
Undefinedclasses implemented, tested and documented -
Full Django test suite passes without regression using
SilentUndefined -
string_if_invaliddeprecated with a clear upgrade path -
Official documentation with examples for dev/staging/prod configurations
-
Architecture approved by at least one core developer before coding begins
My Next Steps
I have already:
-
Read through the full ticket #28618 history and the existing PR #19353
-
Studied the community discussion and Adam Johnson’s notes on Jinja2 undefined types
-
Installed
django-fastdevto understand the current workaround and its limitations -
Started exploring
django/template/base.py— specificallyVariable.resolve()andFilterExpression.resolve()
I am now working on a proof-of-concept prototype of SilentUndefined and StrictUndefined that I will share on GitHub shortly.
I would love to get early feedback on this direction before finalising my proposal — especially:
-
Is the
Undefinedclass approach the right one, or does the community prefer a different mechanism? -
Should the
undefinedoption live inTEMPLATES['OPTIONS']or somewhere else? -
Is deprecating
string_if_invalidwithin scope for GSoC, or should it be a follow-up?
Thank you for reading! Looking forward to contributing to Django.