For those interested, I've now got my branch working, and only failing tests related to ensuring no newlines appear inside tags.
You can see the diff here : https://github.com/funkybob/django/compare/multiline-templates Now comes the great discovery phase to see how many real-world templates I've broken, and how much I've altered template parsing performance :) -- Curtis On 9 March 2014 20:47, Curtis Maloney <[email protected]> wrote: > To try to help the wider community know to contribute comments, I've > included this thread in the latest Django Update. > > My personal stance is -- I know I can add this to the template code > trivially (See my django-contemplation sandpit). However, I'm not certain: > > a) What performance impact it may have > b) What potential corner cases in parsing it may expose. > > So, unlike all the people just asking for it, I'm going to try it. :) > > A lot of people may not be aware there are _two_ template Lexer/Parser > pairs in the codebase -- a debug one, and a normal one. So it's a matter > of implementing the change in _two_ places. > > -- > Curtis > > > On 7 March 2014 07:28, Andre Terra <[email protected]> wrote: > >> +1, for one simple reason: practicality beats purity. >> >> >> On Wed, Mar 5, 2014 at 10:23 AM, Daniel Ellis <[email protected]> wrote: >> >>> +1 - I've had the same issue with sorl thumbnail. >>> >>> >>> On Wed, Mar 5, 2014 at 7:07 AM, Adam Serafini <[email protected]>wrote: >>> >>>> +1 for multiline template tags >>>> >>>> Regarding: "we want to discourage putting business logic in the >>>> template" >>>> >>>> Long template tags can happen even if they are logic-less, and they >>>> would read much nicer over several lines. For example: >>>> >>>> {% cloudinary main_image.image width=300 height=300 >>>> class="img-thumbnail main-product-image" crop="fill" gravity="face" >>>> effect="sepia" %} >>>> >>>> There's no business logic here: every parameter in this tag is >>>> presentational log and belongs in templates (<- unless I'm wrong about >>>> that, please suggest a refactoring to me if you believe one is appropriate >>>> here!) >>>> >>>> >>>> >>>> On Wednesday, July 17, 2013 1:48:38 AM UTC+1, Russell Keith-Magee wrote: >>>> >>>>> >>>>> On Tue, Jul 16, 2013 at 9:41 PM, Daniel Ellis <[email protected]>wrote: >>>>> >>>>>> My grandfather was a developer in a nuclear plant that I was >>>>>> interning at. They used a Django-based web interface for internal >>>>>> operations. >>>>>> >>>>>> One of the functions their Django application managed was the release >>>>>> of nuclear material. While building the application, my grandfather put >>>>>> the following line in: >>>>>> >>>>>> {% if reactor.safe_to_release_deadly_radiation and >>>>>> reactor.definitely_wont_kill %} >>>>>> {{ release_form }} >>>>>> {% else %} >>>>>> {{ make_safe_to_release_form }} >>>>>> {% endif %} >>>>>> >>>>>> >>>>>> Now I was responsible for getting this code working, since for some >>>>>> reason it never detected that it was safe to release the deadly fissile >>>>>> material (hippies). So I put the following statement in: >>>>>> >>>>>> {% if reactor.safe_to_release_deadly_radiation and >>>>>> reactor.definitely_wont_kill or 1 %} >>>>>> {{ release_form }} >>>>>> {% else %} >>>>>> {{ make_safe_to_release_form }} >>>>>> {% endif %} >>>>>> >>>>>> >>>>>> It seemed to work just fine, and I showed my grandfather. Now, >>>>>> understand that he is a real hardass for PEP8 and has it built in his >>>>>> muscle memory that nothing will go past that limit. Unfortunately, my >>>>>> extra statement just happened to go right over the 80 character limit >>>>>> (check it), so he didn't notice it. >>>>>> >>>>>> Fast forward 2 months. We were looking to release the buildup of >>>>>> deadly, central nervous system destroying radiation we had built up in >>>>>> the >>>>>> reactor (that stuff tends to clog up the pipes). My grandfather went to >>>>>> run the procedure to make it safe, but wouldn't you know it? That debug >>>>>> statement was still there. Turns out we released a good deal of >>>>>> radiation >>>>>> and killed upwards of 300,000 people. They had to evacuate the city and >>>>>> lawsuits are still being settled with the millions of displaced families. >>>>>> >>>>>> Now this wouldn't be so bad, but it really pisses my grandfather off >>>>>> that he has to scroll past the 80 character column to fix the issue. >>>>>> >>>>> >>>>> As amusing as your story is, hyperbole won't win the argument. >>>>> >>>>> Hyperbole aside, you haven't added anything to the discussion that we >>>>> didn't already know. Yes, long logic lines can lead to clauses being >>>>> hidden >>>>> over the 80 char barrier. This isn't news. >>>>> >>>>> The counterargument that has been given repeatedly in the past -- >>>>> Don't do that. One of the reasons that Django's template logic is >>>>> intentionally hobbled is that we want to discourage putting business logic >>>>> in the template. Not adding multiline tags is one of the contributors to >>>>> this hobbling. Your templates *shouldn't* contain long lines - because if >>>>> they do, You're Doing It Wrong(tm). >>>>> >>>>> How should it be done? Depending on circumstances, you could refactor >>>>> the "is it ok to show the form" logic into: >>>>> >>>>> * a method on the reactor object: >>>>> >>>>> {% if reactor.ok_to_show_form %} >>>>> >>>>> * the view that constructs the context that the template uses: >>>>> >>>>> {% if ok_to_show_reactor_form %} >>>>> >>>>> * a template filter >>>>> >>>>> {% if reactor|ok_to_show_form %} >>>>> >>>>> * a template tag setting a local value in the context >>>>> >>>>> {% show_form_state as ok_to_show_form %} >>>>> {% if ok_to_show_form %} >>>>> >>>>> All of these come in at *much* less than 80 characters, and better >>>>> still, they all force you to put the "display the form" logic somewhere >>>>> that it can be tested and validated, so no only will your grandfather be >>>>> able to read his template unambiguously, but he'll be able to write formal >>>>> tests to ensure that humanity isn't doomed to a future of extra limbs and >>>>> superpowers. >>>>> >>>>> Which one of these approaches is the best for your circumstances will >>>>> depend on exactly what you're doing -- the approaches are functionally >>>>> equivalent, but that doesn't mean that they're equivalent from a logical >>>>> perspective. Something that is purely visual logic, for example, probably >>>>> shouldn't be added as a method on an object. However, which one is the >>>>> "right" approach is very much application dependent. >>>>> >>>>> Yours, >>>>> Russ Magee %-) >>>>> >>>>> >>>> On Wednesday, July 17, 2013 1:48:38 AM UTC+1, Russell Keith-Magee wrote: >>>> >>>>> >>>>> On Tue, Jul 16, 2013 at 9:41 PM, Daniel Ellis <[email protected]>wrote: >>>>> >>>>>> My grandfather was a developer in a nuclear plant that I was >>>>>> interning at. They used a Django-based web interface for internal >>>>>> operations. >>>>>> >>>>>> One of the functions their Django application managed was the release >>>>>> of nuclear material. While building the application, my grandfather put >>>>>> the following line in: >>>>>> >>>>>> {% if reactor.safe_to_release_deadly_radiation and >>>>>> reactor.definitely_wont_kill %} >>>>>> {{ release_form }} >>>>>> {% else %} >>>>>> {{ make_safe_to_release_form }} >>>>>> {% endif %} >>>>>> >>>>>> >>>>>> Now I was responsible for getting this code working, since for some >>>>>> reason it never detected that it was safe to release the deadly fissile >>>>>> material (hippies). So I put the following statement in: >>>>>> >>>>>> {% if reactor.safe_to_release_deadly_radiation and >>>>>> reactor.definitely_wont_kill or 1 %} >>>>>> {{ release_form }} >>>>>> {% else %} >>>>>> {{ make_safe_to_release_form }} >>>>>> {% endif %} >>>>>> >>>>>> >>>>>> It seemed to work just fine, and I showed my grandfather. Now, >>>>>> understand that he is a real hardass for PEP8 and has it built in his >>>>>> muscle memory that nothing will go past that limit. Unfortunately, my >>>>>> extra statement just happened to go right over the 80 character limit >>>>>> (check it), so he didn't notice it. >>>>>> >>>>>> Fast forward 2 months. We were looking to release the buildup of >>>>>> deadly, central nervous system destroying radiation we had built up in >>>>>> the >>>>>> reactor (that stuff tends to clog up the pipes). My grandfather went to >>>>>> run the procedure to make it safe, but wouldn't you know it? That debug >>>>>> statement was still there. Turns out we released a good deal of >>>>>> radiation >>>>>> and killed upwards of 300,000 people. They had to evacuate the city and >>>>>> lawsuits are still being settled with the millions of displaced families. >>>>>> >>>>>> Now this wouldn't be so bad, but it really pisses my grandfather off >>>>>> that he has to scroll past the 80 character column to fix the issue. >>>>>> >>>>> >>>>> As amusing as your story is, hyperbole won't win the argument. >>>>> >>>>> Hyperbole aside, you haven't added anything to the discussion that we >>>>> didn't already know. Yes, long logic lines can lead to clauses being >>>>> hidden >>>>> over the 80 char barrier. This isn't news. >>>>> >>>>> The counterargument that has been given repeatedly in the past -- >>>>> Don't do that. One of the reasons that Django's template logic is >>>>> intentionally hobbled is that we want to discourage putting business logic >>>>> in the template. Not adding multiline tags is one of the contributors to >>>>> this hobbling. Your templates *shouldn't* contain long lines - because if >>>>> they do, You're Doing It Wrong(tm). >>>>> >>>>> How should it be done? Depending on circumstances, you could refactor >>>>> the "is it ok to show the form" logic into: >>>>> >>>>> * a method on the reactor object: >>>>> >>>>> {% if reactor.ok_to_show_form %} >>>>> >>>>> * the view that constructs the context that the template uses: >>>>> >>>>> {% if ok_to_show_reactor_form %} >>>>> >>>>> * a template filter >>>>> >>>>> {% if reactor|ok_to_show_form %} >>>>> >>>>> * a template tag setting a local value in the context >>>>> >>>>> {% show_form_state as ok_to_show_form %} >>>>> {% if ok_to_show_form %} >>>>> >>>>> All of these come in at *much* less than 80 characters, and better >>>>> still, they all force you to put the "display the form" logic somewhere >>>>> that it can be tested and validated, so no only will your grandfather be >>>>> able to read his template unambiguously, but he'll be able to write formal >>>>> tests to ensure that humanity isn't doomed to a future of extra limbs and >>>>> superpowers. >>>>> >>>>> Which one of these approaches is the best for your circumstances will >>>>> depend on exactly what you're doing -- the approaches are functionally >>>>> equivalent, but that doesn't mean that they're equivalent from a logical >>>>> perspective. Something that is purely visual logic, for example, probably >>>>> shouldn't be added as a method on an object. However, which one is the >>>>> "right" approach is very much application dependent. >>>>> >>>>> Yours, >>>>> Russ Magee %-) >>>>> >>>>> >>>> On Wednesday, July 17, 2013 1:48:38 AM UTC+1, Russell Keith-Magee wrote: >>>> >>>>> >>>>> On Tue, Jul 16, 2013 at 9:41 PM, Daniel Ellis <[email protected]>wrote: >>>>> >>>>>> My grandfather was a developer in a nuclear plant that I was >>>>>> interning at. They used a Django-based web interface for internal >>>>>> operations. >>>>>> >>>>>> One of the functions their Django application managed was the release >>>>>> of nuclear material. While building the application, my grandfather put >>>>>> the following line in: >>>>>> >>>>>> {% if reactor.safe_to_release_deadly_radiation and >>>>>> reactor.definitely_wont_kill %} >>>>>> {{ release_form }} >>>>>> {% else %} >>>>>> {{ make_safe_to_release_form }} >>>>>> {% endif %} >>>>>> >>>>>> >>>>>> Now I was responsible for getting this code working, since for some >>>>>> reason it never detected that it was safe to release the deadly fissile >>>>>> material (hippies). So I put the following statement in: >>>>>> >>>>>> {% if reactor.safe_to_release_deadly_radiation and >>>>>> reactor.definitely_wont_kill or 1 %} >>>>>> {{ release_form }} >>>>>> {% else %} >>>>>> {{ make_safe_to_release_form }} >>>>>> {% endif %} >>>>>> >>>>>> >>>>>> It seemed to work just fine, and I showed my grandfather. Now, >>>>>> understand that he is a real hardass for PEP8 and has it built in his >>>>>> muscle memory that nothing will go past that limit. Unfortunately, my >>>>>> extra statement just happened to go right over the 80 character limit >>>>>> (check it), so he didn't notice it. >>>>>> >>>>>> Fast forward 2 months. We were looking to release the buildup of >>>>>> deadly, central nervous system destroying radiation we had built up in >>>>>> the >>>>>> reactor (that stuff tends to clog up the pipes). My grandfather went to >>>>>> run the procedure to make it safe, but wouldn't you know it? That debug >>>>>> statement was still there. Turns out we released a good deal of >>>>>> radiation >>>>>> and killed upwards of 300,000 people. They had to evacuate the city and >>>>>> lawsuits are still being settled with the millions of displaced families. >>>>>> >>>>>> Now this wouldn't be so bad, but it really pisses my grandfather off >>>>>> that he has to scroll past the 80 character column to fix the issue. >>>>>> >>>>> >>>>> As amusing as your story is, hyperbole won't win the argument. >>>>> >>>>> Hyperbole aside, you haven't added anything to the discussion that we >>>>> didn't already know. Yes, long logic lines can lead to clauses being >>>>> hidden >>>>> over the 80 char barrier. This isn't news. >>>>> >>>>> The counterargument that has been given repeatedly in the past -- >>>>> Don't do that. One of the reasons that Django's template logic is >>>>> intentionally hobbled is that we want to discourage putting business logic >>>>> in the template. Not adding multiline tags is one of the contributors to >>>>> this hobbling. Your templates *shouldn't* contain long lines - because if >>>>> they do, You're Doing It Wrong(tm). >>>>> >>>>> How should it be done? Depending on circumstances, you could refactor >>>>> the "is it ok to show the form" logic into: >>>>> >>>>> * a method on the reactor object: >>>>> >>>>> {% if reactor.ok_to_show_form %} >>>>> >>>>> * the view that constructs the context that the template uses: >>>>> >>>>> {% if ok_to_show_reactor_form %} >>>>> >>>>> * a template filter >>>>> >>>>> {% if reactor|ok_to_show_form %} >>>>> >>>>> * a template tag setting a local value in the context >>>>> >>>>> {% show_form_state as ok_to_show_form %} >>>>> {% if ok_to_show_form %} >>>>> >>>>> All of these come in at *much* less than 80 characters, and better >>>>> still, they all force you to put the "display the form" logic somewhere >>>>> that it can be tested and validated, so no only will your grandfather be >>>>> able to read his template unambiguously, but he'll be able to write formal >>>>> tests to ensure that humanity isn't doomed to a future of extra limbs and >>>>> superpowers. >>>>> >>>>> Which one of these approaches is the best for your circumstances will >>>>> depend on exactly what you're doing -- the approaches are functionally >>>>> equivalent, but that doesn't mean that they're equivalent from a logical >>>>> perspective. Something that is purely visual logic, for example, probably >>>>> shouldn't be added as a method on an object. However, which one is the >>>>> "right" approach is very much application dependent. >>>>> >>>>> Yours, >>>>> Russ Magee %-) >>>>> >>>>> -- >>>> You received this message because you are subscribed to a topic in the >>>> Google Groups "Django developers" group. >>>> To unsubscribe from this topic, visit >>>> https://groups.google.com/d/topic/django-developers/wRKgnMIhl6g/unsubscribe >>>> . >>>> To unsubscribe from this group and all its topics, send an email to >>>> [email protected]. >>>> >>>> To post to this group, send email to [email protected] >>>> . >>>> Visit this group at http://groups.google.com/group/django-developers. >>>> To view this discussion on the web visit >>>> https://groups.google.com/d/msgid/django-developers/1d8b7534-07b8-40f4-9f8d-ebd642a8217d%40googlegroups.com<https://groups.google.com/d/msgid/django-developers/1d8b7534-07b8-40f4-9f8d-ebd642a8217d%40googlegroups.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>>> For more options, visit https://groups.google.com/groups/opt_out. >>>> >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Django developers" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> To post to this group, send email to [email protected]. >>> Visit this group at http://groups.google.com/group/django-developers. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/django-developers/CAJGew6nqpCZ7eRLGRb4hCjP6DBWHrt9etBGWsewMDcoRJ%3DM2eA%40mail.gmail.com<https://groups.google.com/d/msgid/django-developers/CAJGew6nqpCZ7eRLGRb4hCjP6DBWHrt9etBGWsewMDcoRJ%3DM2eA%40mail.gmail.com?utm_medium=email&utm_source=footer> >>> . >>> >>> For more options, visit https://groups.google.com/groups/opt_out. >>> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Django developers" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> To post to this group, send email to [email protected]. >> Visit this group at http://groups.google.com/group/django-developers. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/django-developers/CAKBiv3yAJVsm8G4k3xqcGNsvYRyRquCs-8B_pCbTjbZZSkYdKA%40mail.gmail.com<https://groups.google.com/d/msgid/django-developers/CAKBiv3yAJVsm8G4k3xqcGNsvYRyRquCs-8B_pCbTjbZZSkYdKA%40mail.gmail.com?utm_medium=email&utm_source=footer> >> . >> >> For more options, visit https://groups.google.com/groups/opt_out. >> > > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAG_XiSB8xEKvfPOa6Ue7RUkqSRuMOCMiRnmf%3Dv5rG%3DHC4%3D16%2Bg%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
