Warning for text outside a tag after {% extends %} tag

Hi !
There is a discussion for this topic on the Ticket tracker at #35790 (Deprecate content outside of {% block %} tags when {% extends %} is used) – Django !
The main concern behind this is that whenever we write some text in a template after the {% extends %} which is not in some tag, just silently gets discarded , which could alter the output from what the user expected.
An example would be:-

{% extends 'egg.html' %}

<title>Chicken egg</title>

{% block yolk %}
yellow
{% endblock yolk %}

Here, the title Chicken egg is never displayed ! It is silently discarded.
This was solved earlier (not pushed to django main) by raising a deprecation warning whenever there is some text outside a tag after the {% extends %} tag.
But there is an issue. As pointed by @TomHall2020 and @ChrisAdams , the warning will be raised even in scenarios where not intended. For clearance, see the comment.
In the case of html comment, like <!-- --> or variable tag {{ some_var }} , the warning is still raised which we don’t want !
Now, there are multiple ways to solve this and opinions are welcome !

  1. We neglect these cases and simply implement the deprecation warning (for 7.0) for any text outside a tag after {% extends %} tag , also for the {{}} variable node.
  2. We implement the deprecation warning for the text and variable node as before but also check for comment inside the text using regex for <!-- --> and only raise the warning if we encounter some text outside this (except newline) or a variable node (cause it won’t be displayed). This one could be an overkill so plz do suggest.
  3. We implement the (1) but instead of the deprecation warning, it’s a simple warning in debug mode only.
  4. Just not do anything cause the problem seems easier than the solution and the solution is a bit too overkill.

Waiting for the reviews ! Btw github link :- Fixed #35790 - Added warning for non whitespace text outside {% extends %} tag by YogyaChugh · Pull Request #19302 · django/django · GitHub where more elaborated by @a-ludi

We have had a couple of questions on the Discord that have arisen from this problem, so I do think there’s room for some improvement.

I don’t like the idea of (1), but I don’t think (2) is the right solution—not all templates are HTML, either!

(3) seems like a happy middle ground.

1 Like

Thanks for starting the thread. As I spent a while looking at the various possiblities during the sprints last weekend, I’ve got a fair idea on the nuances of this at the moment, so I’d like to set out some of them and where I have some issues.

  1. Correctness
  2. Error handling
  3. Performance and complexity

1: Correctness

HTML comments

Outside of a block under the proposed change, <!-- something here --> will raise an error, which is very likely to be unintended behaviour. Of course the DTL has its own proper comment tags, but given its a common convention to save template files as .html, many editor enviroments if not specifically configured for django will default to a html comment when using their add comment shortcut. In most cases there is a difference in behaviour, the html comments are rendered out to the file while dtl comments are not, however in this case we are looking specifically at comments outside of a block tag, so the behaviour actually becomes identical at the moment as they are never rendered out. I suggest using HTML comments in this way instead of dtl comments is fine and should not be broken.

Template tags and variables

A correction to the starting post, {{ some variable }}, will not raise an error under the current proposal, as it can only check for plain text nodes. The same applies for any content that happens to start with a dtl tag, eg {% for x in y %}... to template out multiple components. This is an error of correctness - these are likely to be the same developer mistake (placing content outside of a block), but they cannot easily be checked for, as some tags have to be permitted in this enviroment for their side effects, the cannonical example being {% load %}

2: Error management

At the moment, checks for illegal tags outside of blocks are triggered when processing the {% extends %} tag. This is an issue, because if we do find one and raise an error (as would occur after the depreciation period ends), that error is surfaced on the line of the extends tag. As an example see the screenshot from the development error page below, which shows the error highlight on line 1:


In this case the offending line is directly below the extends block but it is not highlighted. If this was buried 300 lines down in a long template I think we can all appreciate how much of a pain this could be.

3: Complexity

I belive any solution that can handle the above issues is going to require quite a lot more complexity. Solutions that involve allowlisting tags as safe to use outside of blocks for example, require additional attributes to be added to all tags and would involve more work to register custom tags as safe.

4: Is this the right problem to solve?

I understand the desire to surface mistakes (putting content outside of a block) early in the development process. However, this is a breaking change. As it stands, any number of templates in any number of projects may have content outside of blocks, which is silently ignored, and the authors just don’t care. Lets be clear, its frustrating while developing to realise your content isn’t being rendered, and having to dig around for a bit before you spot that its because you didn’t place it in a block. But if you are missing content and it matters, you’ll go back and fix it. If you are missing content and it doesnt, you may never realise. Is it ok to turn these little bits of template detritus into errors (or warning spam) in django 7?

Ultimately this is a breaking change, so is this really a big enough improvement to be worth it? Given that we can’t even catch all “content mistakes”, I’m not sure that it is.

1 Like

@TomHall2020 You seem to assume that there is code out there that is working fine that does this. Do you have any examples?

A check for this is one of the checks in django-fastdev. I haven’t heard from any users complaining that it breaks something.

The examples are literally there, are they not? Stuff like HTML comments would work “fine” as documentation outside of the extends tags. If you ment something else with “… code that does this” please say so. Whether such code really exists is hard to proof with tools like github code search (same goes for the other direction, proofing that it does not exist for that matter ;))

How realistic is that as data point though? Github lists 100 “users” of this package. How many of those are going to complain as opposed to simply remove the code outside the tags? Either way, while not denying that the package is used, 100 looks kinda low to be representative I think.

I don’t mean theoretical examples, I mean concrete examples from an existing project.

If they do that they almost certainly fixed broken code. What I meant was that people will complain if this is common in their 3rd party libs where they can’t just fix the code.

Those 100 are just open source code bases with declared dependencies on github. 100 uses in real projects is a lot more than zero examples from real projects :stuck_out_tongue:

I agree with you there, but as I said it is hard to find examples for such a usage outside of your own code and we cannot assume that everyone reads the forum and will answer here… So we have to assume that such code exists and is not “wrong” (as with the HTML comment example) and should be nice about that.

I guess I don’t see what is not nice about a deprecation warning.

TBH – I commented this before on the issue ticket – I’m still in favour of option 4 (Not implementing this change) here.

I use the fact that text outside of a block is discarded all the time, in a kind of Literate Programming meets a scratchpad type thing.

If it started raising a warning I could certainly edit every single case to wrap in a {% comment %} block, but I wouldn’t be happy having to do so.

I think (personal opinion, obviously open to others thinking differently) the proposed change is not beneficial at all.

I understand this case:

I see how it might happen to someone. I think Meh. {% block title %}Chicken egg{% endblock %} is an easy enough habit to get into.

I’m sure I saw someone suggesting a check for templates to enforce that a block is provided. That would seem much more inline with what’s desired here than such an unnecessary change to the DTL for marginal (if any) benefit.

In case that’s ambiguous: I think we should wontfix the ticket.

2 Likes

That’s this thread: Required template blocks


I didn’t imagine this ticket turning up so many edge cases. I am fine with closing it.

I didn’t think that folks would use HTML comments like this, but it makes sense. I can imagine using HTML syntax highlighting and pressing the “comment” shortcut and inserting <!--, and we probably shouldn’t churn things in that case.

I imagine that a lint rule could be a way forward here, say if we add that to Djade.

7 Likes