Take a look at the ``template.Content.__str__`` method, this is what is
responsible for flattening the tree.

Calling ``str()`` on any instance of Content effectively flattens it to
text, since there is only text in the parent tree, it has no knowledge of
any blocks that might have existed in the included tree.

The only point at which the tree should be flattened is at the very end of
the parsing when the entire tree is assembled.

--
Thadeus




On Thu, May 5, 2011 at 3:24 PM, Thadeus Burgess <thade...@thadeusb.com>wrote:

> Your code should work just fine kasapo, the template system was designed to
> do that.
>
> Someone at some point made a patch to the template that broke the way this
> is supposed to work.
>
>
> http://code.google.com/p/web2py/source/diff?spec=svnc6ff592d73ef81257a8d238a74b688c9b3a09360&r=e6868622d71ec96947b4bb08a44c527c9722b062&format=side&path=/gluon/template.py&old_path=/gluon/template.py&old=8d5d7f6bd391d2e30888c2c9fc168c081d02877f
>
> Basically, instead of just copying the included templates tree into the
> parent templates tree, they changed it so it would flatten the tree to text,
> and just include the text into the parent tree. All contexts are lost when
> the tree gets flattened.
>
> --
> Thadeus
>
>
>
>
>
> On Thu, May 5, 2011 at 2:53 PM, kasapo <kas...@gmail.com> wrote:
>
>> First off -- let me say that my usage of the templating in this case
>> is somewhat peculiar, and if they are not supposed to work like this,
>> that is fine.
>>
>> After reviewing my app, I only have one instance of code like this,
>> and it is "vestigial" and should be removed anyhow. But I thought it
>> strange that it broke, and I'm wondering if I might have another
>> include/block problem.
>>
>> Solution:
>>
>> diff -r fe58378e989b gluon/template.py
>> --- a/gluon/template.py Wed May 04 18:58:40 2011 -0500
>> +++ b/gluon/template.py Thu May 05 14:46:21 2011 -0500
>> @@ -454,7 +454,8 @@
>>                            writer  = self.writer,
>>                            delimiters = self.delimiters)
>>
>> -        content.append(str(t.content))
>> +        content.append(t.content)
>> +        #content.append(str(t.content))
>>
>>     def extend(self, filename):
>>         """
>>
>> Read on for how I got there and a strange LDAP_auth issue...
>>
>> On May 5, 1:37 pm, Massimo Di Pierro <massimo.dipie...@gmail.com>
>> wrote:
>> > Hello kasapo,
>> >
>> > I do not completely follow you code. If I do, you have two blocks. The
>> > code included in one of the blocks seems to extend a  block included
>> > in another block. I am unsure this is supposed to work. Anyway, let's
>> > try figure out what has changed that broke and then we may be able to
>> > revert the previous behavior.
>> >
>>
>> So I have this structure:
>>
>> bare (defines html, head, style, script (jquery includes), body
>> sections, and some containing blocks) -- ancestor to almost all
>> templates
>>
>> right-col (included by bare, defines blocks which base will extend --
>> base extends bare, bare includes right-col so therefore base should be
>> able to see blocks defined by bare)
>>
>> base (defines styles, background, etc -- the base template for most
>> things -- defines actual markup for blocks which are DEFINED in right-
>> col)
>>
>> page (extends base, does not use blocks -- the menu rendered on the
>> page view is defined in base inside of a block that is defined in bare
>> via right-col include)
>> page-no-side-nav ( extends base, uses {{ block right-col }}{{end}} to
>> delete the right column )
>>
>> > Can you try:
>> >
>> > hg revert -r 1488 gluon/template.py > ~/Downloads/template.diff
>> >
>>
>> Sadly, I am on RHEL and mercurial isn't present... so I will use my
>> local machine (Macintosh).
>>
>> First off, I use LDAP authentication for a login method, and (this
>> happened on 1.95.1 on RHEL server as well) I get this error:
>>
>> Traceback (most recent call last):
>>  File "/Users/csburreson/web2py/gluon/restricted.py", line 181, in
>> restricted
>>    exec ccode in environment
>>  File "/Users/csburreson/web2py/applications/icecube/models/
>> 0_init.py", line 42, in <module>
>>    from gluon.contrib.login_methods.ldap_auth import ldap_auth
>>  File "/Users/csburreson/web2py/gluon/custom_import.py", line 80, in
>> _web2py__import__
>>    return _old__import__(name, globals, locals, fromlist, level)
>>  File "/Users/csburreson/web2py/gluon/contrib/login_methods/
>> ldap_auth.py", line 5, in <module>
>>    except e:
>> NameError: name 'e' is not defined
>>
>> So I just copied the working ldap_auth.py from the 1.89 version of
>> web2py... problem solved (could this somehow create an issue with
>> templates?)
>>
>> Then I realized I did not have python-ldap installed, so I did
>> easy_install python-ldap and all was good.
>>
>> [I did exactly these same things earlier today when installing the
>> TEST server]
>>
>> SO, now the application is again working, and I check out my code into
>> the applications folder using SVN.
>>
>> The menu is not present :(
>>
>> Then I run :
>>
>> hg revert -r 1488 gluon/template.py
>>
>> And check my app and the side menu IS present
>>
>> So, I go back to 1.95.1 (with the exception of the old ldap_auth.py
>> from 1.89)
>>
>> and try
>>
>> hg diff -r 1488 gluon/template.py
>>
>> This bugger seems to be the culprit:
>>
>> @@ -455,7 +454,7 @@
>> ...
>> +        content.append(str(t.content))
>> -        content.append(t.content)
>>
>>
>>
>> After changing it, i verified that I had not changed anything else by
>> re-diffing the file against the repo:
>>
>> bash-3.2$ hg diff gluon/template.py
>> diff -r fe58378e989b gluon/template.py
>> --- a/gluon/template.py Wed May 04 18:58:40 2011 -0500
>> +++ b/gluon/template.py Thu May 05 14:46:21 2011 -0500
>> @@ -454,7 +454,8 @@
>>                            writer  = self.writer,
>>                            delimiters = self.delimiters)
>>
>> -        content.append(str(t.content))
>> +        content.append(t.content)
>> +        #content.append(str(t.content))
>>
>>     def extend(self, filename):
>>         """
>>
>>
>> So, that seems to be the problem.
>>
>> Is there a case where not explicitly calling str() on the content
>> causes something else undesirable to happen?
>>
>> Well, thanks very much Massimo, mystery solved. I'll leave it to you
>> whether this is actually an issue that should be patched or an
>> unnecessary mis-use of templates and {{block}}s
>>
>> I plan to remove the include of right-col since in the end I really
>> don't need it.
>>
>> -Kasapo
>>
>>
>> > Dow it work?
>> >
>> > If yes, download the latest web2py again and do
>> >
>> > hg diff -r 1488 gluon/template.py > ~/Downloads/template.diff
>> >
>> > you will see what has changed in the file. mostly comments.
>> > Try manually revert each of the changes. Which ones causes the
>> > problem?
>> >
>> > On May 5, 11:55 am, kasapo <kas...@gmail.com> wrote:
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> > > Hi all,
>> >
>> > > I recently setup another instance of web2py for testing on a new
>> > > system, and noticed something strange with blocks.
>> >
>> > > Basically, I have three slightly different versions of web2py running:
>> > > 1.89.3 (DEMO server), 1.91.6 (DEV server) and 1.95.1 which I just
>> > > installed with the auto-upgrade feature (TEST server -- soon to be the
>> > > Production server).
>> >
>> > > The problem is, i have an include directive inside of a block/end
>> > > block pair. The included file (right-col.html) then goes on to define
>> > > a couple other blocks (for navigation mainly) which are filled in by
>> > > different templates associated with different areas of the site.
>> >
>> > > However, templates which extend the file which includes right-col.html
>> > > do not have access to BLOCKs that are defined INSIDE of right-
>> > > col.html, but this behavior occurs only on the TEST server (v1.95.1)
>> >
>> > > This code WORKED before 1.95.1 (on DEMO and DEV):
>> >
>> > > #################
>> > > # views/bare.html
>> > > #################
>> > > <html>
>> > >  ... (abbreviated for brevity's sake)
>> > >      <div id='content'>
>> > >      {{ block content }}{{ end }}
>> > >      </div>
>> >
>> > >       {{ block right-col }}
>> > >            {{ include 'base/right-col.html' }}
>> > >       {{ end }}
>> >
>> > > ...
>> > > </html>
>> > > #EOF bare.html
>> >
>> > > #######################
>> > > # views/base/right-col.html
>> > > #######################
>> > > <div id='right-col'>
>> > >    {{ block nav }}
>> > >    {{ end }}
>> >
>> > >    <section id='social'>
>> > >    {{ block social }}{{end}}
>> > >    </section>
>> >
>> > > </div>
>> > > #EOF
>> >
>> > > #################
>> > > # views/base.html
>> > > #################
>> > > {{ extends 'bare.html }}
>> >
>> > > {{ block content }}
>> > >     {{ include }}
>> > > {{ end }}
>> >
>> > > <!-- defines stuff inside of right-col -->
>> > > {{ block nav }}
>> > >     <nav id='side-nav'>
>> > >     {{=MENU(get_menu(request.controller) or standard_menu)}}
>> > >     </nav>
>> > > {{ end }}
>> >
>> > > {{ block social }}
>> > >    ... stuff to do with social networking
>> > > {{ end }}
>> > > #EOF
>> >
>> > > ####################
>> > > # view/some-page.html
>> > > ####################
>> > > {{ extends 'base.html' }}
>> >
>> > > Blah blah blah. Wait, my side menu is missing. Crap.
>> >
>> > > But the outline of the sidebar is still there since div#right-col is
>> > > present....
>> >
>> > > #EOF
>> >
>> > > What I had to do to get it to work with the TEST version was to take
>> > > away the include statement for right-col.html and move the contents of
>> > > the file inside the right-col block in bare.html. This works fine.
>> >
>> > >  The strange thing is that the <div id='right-col'><section
>> > > id='social'></section></div> (the markup in right-col.html) shows up
>> > > -- even if I wrap it in a block within the included file. The problem
>> > > is just that the template blocks defined in the right-col.html file
>> > > seem to be forgotten later on in the template. So even though
>> > > bare.html includes right-col, the base file, which extends bare,
>> > > cannot access the blocks defined in the right-col file. Thus, when
>> > > rendering "some-page" which extends "base", the contents of the right
>> > > column aren't included.
>> >
>> > > So, the question:
>> >
>> > > Is my usage of blocks improper? Or is this an undesired outcome of
>> > > code updates?
>> >
>> > > I just checked the code.google.com page and did not see any issues,
>> > > open or closed, that mentioned anything about this.
>> >
>> > > Thanks,
>> > > Faithful web2py user
>> >
>> > > PS:
>> >
>> > > I think the reason I did this was to be able to reuse HTML chunks
>> > > which might be included in different places on the page, or even among
>> > > different templates from the site (e.g. bare.html is the ancestor of
>> > > most public pages, but user.html is the ancestor of another, and both
>> > > should be able to use right-col.html).
>> >
>> > > Also, I would love to see the include directive supported within for
>> > > loops, though I think I see why it is not. I think the include
>> > > directives are always handled first and the file is included before
>> > > the template is parsed, thus template variables are not available and
>> > > loops cannot be iterated. Oh well.
>>
>
>

Reply via email to