Giter VIP home page Giter VIP logo

Comments (13)

mitsuhiko avatar mitsuhiko commented on May 16, 2024

Nope, that's perfectly fine.

from jinja.

dnjackson avatar dnjackson commented on May 16, 2024

So (a) what's the semantics of overriding in this way? and (b) why does the documentation not do the simpler thing and use the same structure in the child?

from jinja.

mitsuhiko avatar mitsuhiko commented on May 16, 2024

I am not quite sure where the confusion is. The blocks of the inner child just replace the blocks of the parent template. Let me know if you have a better example for the docs that is less confusing.

from jinja.

dnjackson avatar dnjackson commented on May 16, 2024

On Jul 15, 2011, at 1:00 PM, mitsuhiko wrote:

I am not quite sure where the confusion is. The blocks of the inner child just replace the blocks of the parent template. Let me know if you have a better example for the docs that is less confusing.

Here's your example:

Parent:

{% block head %} <title>{% block title %}{% endblock %} - My Webpage</title> {% endblock %} Child: {% extends "base.html" %} {% block title %}Index{% endblock %} {% block head %} {{ super() }} <style type="text/css"> .important { color: #336699; } </style> {% endblock %}

This bothers me for several reasons. First, you might have thought that blocks create local namespaces, so I could name blocks like this:

employee
name
department
name

But if you can override without respecting the structure, this must mean that block names are global and unique. OK, so now if we go with that, I now wonder what something like this would do

{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ super() }}
{% block title %}Foo{% endblock %}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
So, guessing again, I'll say that you can only declare one instance of each block so this is an illegal usage.

But then I still don't see why you would want to allow the inheriting template to change the structure.

If you do, and the structure matters (as it would in the body of the HTML), would overriding block b result in block b appearing in the place at which it is overridden, or the place it occupies in the parent template? And why even make this possible?

Daniel

from jinja.

mitsuhiko avatar mitsuhiko commented on May 16, 2024

Blocks are indeed globally unique. From the layout template inwards each block overrides each other with the same name. In this case base.html is taken, that head is replaced with a new head that supers into the old one and the new title is placed in the layout template's head which is supered.

And why even make this possible?

The behavior is sound and compatible with Django. It works very well in practice and allows a variety of idioms and never caused any troubles as far as I know. You're the first person that ever filed a ticket for that :)

from jinja.

dnjackson avatar dnjackson commented on May 16, 2024

so the new block replaces the one in the parent template, whereever the new block is declared -- before, inside, or after the parent block?

On Jul 15, 2011, at 1:12 PM, mitsuhiko wrote:

Blocks are indeed globally unique. From the layout template inwards each block overrides each other with the same name. In this case base.html is taken, that head is replaced with a new head that supers into the old one and the new title is placed in the layout template's head which is supered.

And why even make this possible?

The behavior is sound and compatible with Django. It works very well in practice and allows a variety of idioms and never caused any troubles as far as I know. You're the first person that ever filed a ticket for that :)

Reply to this email directly or view it on GitHub:
#49 (comment)

from jinja.

mitsuhiko avatar mitsuhiko commented on May 16, 2024

Consider it being a class. Each block is a method. When you declare a new block you will not only declare the method, but also call it at the same time. That's pretty much how it works.

Don't spent too much time thinking about it really, it works best if you just give it a try :)

from jinja.

dnjackson avatar dnjackson commented on May 16, 2024

On Jul 15, 2011, at 1:26 PM, mitsuhiko wrote:

Consider it being a class. Each block is a method. When you declare a new block you will not only declare the method, but also call it at the same time. That's pretty much how it works.

Yes, I understand that. It just doesn't address the questions I asked.

Don't spent too much time thinking about it really, it works best if you just give it a try :)

I'm sure I can make it work -- that's not my concern. But I'm considering teaching this in a software engineering class this fall, and I like to have a complete understanding of what's going on. One of the things I try and do is explain fundamental notions such as namespaces, and then I illustrate that by showing how different languages have different kinds of namespaces -- basically teaching them how to be informed critics.

I think what you're saying is that you're not really sure what the rules are yourself -- that they're defined by the implementation. In my opinion, even though it might not matter here, it's a disastrous way to go in general -- look at function decls in Javascript for example, and how broken the scoping rules are.

Despite this, I do think Flask and Jinja are quite nice :-)

Daniel

from jinja.

mitsuhiko avatar mitsuhiko commented on May 16, 2024

I think what you're saying is that you're not really sure what the rules are yourself

Heh. No, the rules are actually quite simple internally and clear defined. If you really want to understand the implications entirely, here you go:

Every block in the template is hoisted out of the toplevel template code. It's then given an entirely separate scope and registered on the template runtime context. If you extend another template the current execution context is used as the basis for the template you are extending from and that will then use your blocks over the one from the other template. Additionally from that point onwards (after {% extends %}) the template you were just executing continues to execute but will no longer output anything. This is documented behavior and can be neatly abused:

{% if parent_template %}{% extends parent_template %}{% endif %}
<!doctype html>
<title>{% block title %}{% endblock %}</title>
All this here will be entirely ignored if the parent_template variable is not falsy
and the blocks will be shifted to the template we then extend from.  If however
parent_template is not defined we will use this instead.
{% block body %}And this block again is hoisted{% endblock %}

The problem is that this is quite confusing behavior most people have not use for and is pointless to show in the documentation. It's however defined behavior and an implementation detail.

from jinja.

mitsuhiko avatar mitsuhiko commented on May 16, 2024

I actually spend a lot time figuring out useful semantics for the inheritance because Jinja2 supports dynamic inheritance which was not in Django at the time and still is not to that extend and Django's semantics for template inheritance appeared to have happened by accident.

from jinja.

dnjackson avatar dnjackson commented on May 16, 2024

That's good to hear. So can you answer my questions?

On Jul 15, 2011, at 1:40 PM, mitsuhiko wrote:

I actually spend a lot time figuring out useful semantics for the inheritance because Jinja2 supports dynamic inheritance which was not in Django at the time and still is not to that extend and Django's semantics for template inheritance appeared to have happened by accident.

Reply to this email directly or view it on GitHub:
#49 (comment)

from jinja.

mitsuhiko avatar mitsuhiko commented on May 16, 2024

That's good to hear. So can you answer my questions?

See comment before that.

About the block defined twice per template on different levels: Jinja2 will not compile that and complain about the block being defined twice.

from jinja.

dnjackson avatar dnjackson commented on May 16, 2024

I vaguely understand that. It would be good to express it in a declarative way, rather than talking about what happens at runtime.

--Daniel

On Jul 15, 2011, at 1:39 PM, mitsuhiko wrote:

I think what you're saying is that you're not really sure what the rules are yourself

Heh. No, the rules are actually quite simple internally and clear defined. If you really want to understand the implications entirely, here you go:

Every block in the template is hoisted out of the toplevel template code. It's then given an entirely separate scope and registered on the template runtime context. If you extend another template the current execution context is used as the basis for the template you are extending from and that will then use your blocks over the one from the other template. Additionally from that point onwards (after {% extends %}) the template you were just executing continues to execute but will no longer output anything. This is documented behavior and can be neatly abused:

{% if parent_template %}{% extends parent_template %}{% endif %}
<!doctype html>
<title>{% block title %}{% endblock %}</title>
All this here will be entirely ignored if the parent_template variable is not falsy
and the blocks will be shifted to the template we then extend from.  If however
parent_template is not defined we will use this instead.
{% block body %}And this block again is hoisted{% endblock %}

The problem is that this is quite confusing behavior most people have not use for and is pointless to show in the documentation. It's however defined behavior and an implementation detail.

Reply to this email directly or view it on GitHub:
#49 (comment)

from jinja.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.