OMG, setting response.view does it for me 110%!
Confident in the ease of use of web2py, I swear I tried this the very first.
Maybe I mistyped it to response.view = 'article.html' or request.view, and
then just turned to alternatives. Anyway, now it works! :-D
I also understand your explanation, except one thing: if I have an
{{include}} inside a {{block}} as a default value (both these statements are
template, non-python statements), and that default is overridden, and since
{{block}} somewhat introduces conditioning, the inner {{include}} statement
need-not be expanded, so {{block some}}{{include article}}{{end}}, with some
block overridden, shouldn't throw error on article variable not set. I
think.
Anyway, taking note of your comment regarding not compiled views, I now see
I am doing the whole thing wrong, so I'm switching to {{extends}} and
{{blocks}} instead (no more need for variable includes). response.view saves
the day! :-)
Thank you and KUGW!
On Fri, Jul 8, 2011 at 4:26 PM, Anthony <[email protected]> wrote:
> First, if you want to use a particular view, you can always explicitly
> assign response.view:
>
> def about():
> response.view='default/article.html' # This view will be used instead
> of 'default/about.html'.
> # more code
> return dict(...)
>
> Also, note that the {{include}} statement is not a Python statement -- it
> is processed by the template engine before everything is converted to
> Python. So, if you have an {{include 'someview.html'}} inside an if
> statement, the 'someview.html' template will still be included in the
> assembled Python code, though it will only be executed conditionally (based
> on the condition of the if statement). Also, because of this, although you
> may use variables in your {{include}} statements, as you have, usage of
> variables prevents bytecode compiling of the views. The reason is that the
> included views have to be determined at compile time, but the value of the
> variables is not known until run time.
>
> In the places where you are getting the error about 'article' not being
> defined, I assume your controller action is not actually returning a
> variable called 'article' to the view. If you need to conditionally test
> whether a particular variable is available in a view, you can do {{if
> 'article' in response._vars:}} or {{if 'article' in globals():}}.
>
> Anthony
>
>
> On Friday, July 8, 2011 2:07:16 AM UTC-4, Kernc wrote:
>
>> Ok, so this is my setup:
>>
>> I have article() function inside default controller, which obtains
>> article title in request.args, puts ('articles/'+str(request.args[**0])
>> +'.html') into returned dict(article=...), and serves appropriate
>> article's HTML from article.html with
>>
>> <!-- various common tags along with <body> above and </html> below...
>> -->
>> <article>
>> {{include article}}<!-- includes the right article/with-some-
>> title.html -->
>> </article>
>> <!-- ... -->
>>
>> For example, if I access
>> http://domain/article/with-**some-title<http://domain/article/with-some-title>,
>> it
>> renders views/articles/with-some-**title.html.
>> I like that. :-)
>>
>> But then I have /about URL, which calls about() function inside
>> default controller, but which I would like to use the same article
>> template from article.html, i.e. to follow DRY.
>>
>> So I have tried to put my content in about.html in a variable
>> {{article_content = MARKMIN('About us...')}} and then {{include}}
>> modified article.html
>>
>> <article>
>> {{if article_content:}}{{=article_**content}}{{pass}}{{else}}{{**include
>> article}}{{pass}}
>> </article>
>>
>> (Besides {{if article_content:}} I tried with try-except too. Neither
>> worked.)
>> When accessing /about, the ticket told me the error was in undefined
>> 'article' variable in the include expression.
>>
>> So I tried it another way, by defining block with default content in
>> article.html
>>
>> {{block article_content}}{{include article}}{{end}}
>>
>> and extending article.html in about.html
>>
>> {{extend 'article.html'}}{{block article_content}}{{=MARKMIN('**About
>> us...')}}{{end}}
>>
>> As per documentation, default value inside {{block}} (in my case
>> '{{include article}}') should be replaced with specified value (in
>> my case {{=MARKMIN(...)}}). But again, the ticket reports the same
>> error:
>>
>> ...
>> File "/home/****/web2py/gluon/**template.py", line 449, in include
>> text = self._get_file_text(filename)
>> File "/home/****/web2py/gluon/**template.py", line 430, in
>> _get_file_text
>> filename = eval(filename, self.context)
>> File "<string>", line 1, in <module>
>> NameError: name 'article' is not defined
>>
>> To avoid using {{include}}, the next thing I am about to try is:
>>
>> {{block article_contents}}{{if article:}}{{=open(article).**read()}}
>> {{pass}}{{end}}
>>
>> but this way I have to maintain os.getcwd() and annote the article
>> with proper path to my views. I don't know how stable this is.
>>
>> Inexperienced as I am, I'm assuming it's possible I'm doing something
>> horribly wrong. What is that? :-)
>>
>> TL;DR: The templating system counter-intuitively gives unconditional
>> priority to {{include}} expressions, which it evaluates first.
>>
>> Oh, and if you can please tell me how I can make the about() function
>> to use the article.html view instead of default about.html view, that
>> would solve my DRY problem as well, I suppose. :-)
>>
>> Thanks!
>
>