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, 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!