On Wed, 06 Sep 2006 11:03:28 +0300, Nuutti Kotivuori <[EMAIL PROTECTED]> wrote:
Valentino Volonghi aka Dialtone wrote:
Okay, consider the content page shown above. Now let's assume that
most pages don't need the "head" pattern at all. I wouldn't want to
write the empty pattern on all pages just because it has to be there,
instead I would just want to say that put T.invisible() there if the
pattern doesn't exist. (With just the "head" pattern it wouldn't be so
much of a problem, but I might later on have to add some more, and I
don't want to change every content page just because one content page
requires something special.)
So this is what I'd like the default for. But ofcourse, if I load the
entire page first, and then just use the inevow.IQ machinery, making
the default patterns is easy.
Another solution is to write your own loader by implementing inevow.IDocFactory
and the using loaders.xmlfile internally so that you can catch exceptions and
do what you want with the behavior. This also sounds reasonable a reasonably
easy.
loaded = loaders.xmlfile('file')
some_pattern = inevow.IQ(loaded).onePattern('whatever')
That seems to work at first - but if there are any macros or render
methods inside the file I load, then I get Could not adapt error to
IMacroFactory.
Uhmmm... Indeed the problem of the macro factory is not of secondary
importance. Basically it doesn't make sense to call load() without a
MacroFactory. This can be solved by building your own WovenContext before
passing it to the loader.
Don't pass the context, what's the problem here?
Macros and render methods. In the case of the snippet pages, I would
like them to be interpreted in the context of the Fragment class that
is loading the entire snippet page.
That is done by default if you pass the context you are given by any of the
methods in the Fragment.
I understand that the macro is not reloaded - but each macro will load
the page once. Which would be a problem on a page with hundreds of
snippets if every snippet would cause the page to be loaded once.
It's still a one time cost.
Okay, I will try to be a bit clearer. For now, I have two problems -
how to load the "content" page all at once and then use patterns with
optional defaults from it. And then the snippet problem. I will
outline the snippet problem later.
I wrote a really tiny testsite outlining my problem. I will put the
three files here:
,----[ testpage.xhtml ]
| <?xml version="1.0"?>
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
| <html xmlns="http://www.w3.org/1999/xhtml"
| xmlns:n="http://nevow.com/ns/nevow/0.1">
| <head>
| <title>
| <n:invisible n:macro="title">Page Title</n:invisible>
| </title>
| <n:invisible n:macro="head" />
| </head>
|
| <body>
| <h1><n:invisible n:macro="title">Page Title</n:invisible></h1>
|
| <div class="plain-content">
| <n:invisible n:macro="content" />
| </div>
| </body>
| </html>
`----
,----[ datapage.xhtml ]
| <?xml version="1.0"?>
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
| <html xmlns="http://www.w3.org/1999/xhtml"
| xmlns:n="http://nevow.com/ns/nevow/0.1">
| <head>
| <title><n:invisible n:pattern="title">Data Page</n:invisible></title>
| <n:invisible n:pattern="head" />
| </head>
| <body>
| <n:invisible n:pattern="content">
| <p>
| <n:invisible n:macro="test">
| Replaced by test data.
| </n:invisible>
| </p>
| </n:invisible>
| </body>
| </html>
`----
,----
| from nevow import inevow, loaders, rend, guard, url, stan, tags as T
|
| class TestPage(rend.Page):
| docFactory = loaders.xmlfile('testpage.xhtml')
| datapage = None
|
| def macro_title(self, ctx):
| return loaders.xmlfile(self.datapage, pattern='title')
|
| def macro_head(self, ctx):
| return loaders.xmlfile(self.datapage, pattern='head')
|
| def macro_content(self, ctx):
| return loaders.xmlfile(self.datapage, pattern='content')
|
| class DataPage(TestPage):
| datapage = 'datapage.xhtml'
|
| def macro_test(self, ctx):
| return 'Test successful.'
`----
I'd rewrite the example in the following way:
class TestPage(rend.Page):
docFactory = loaders.xmlfile('testpage.xhtml')
patternGenerator = None
def macro_title(self, ctx):
return inevow.IQ(self.patternGenerator).onePattern('title')
def macro_head(self, ctx):
return inevow.IQ(self.patternGenerator).onePattern('head')
def macro_content(self, ctx):
return inevow.IQ(self.patternGenerator).onePattern('content')
class DataPage(TestPage):
patternGenerator = loaders.xmlfile('datapage.xhtml')
def macro_test(self, ctx):
return 'Test successful.'
Now, how would I modify this example so that "datapage.xhtml" is
loaded only once, even though there are three different macros using
it. And also so that the "head" pattern could be optional and is
replaced by T.invisible() if not present. All the while not breaking
the macro_test part, splitting the pages into several files or
breaking the normal html rendability/editability of the datapage.
I think the solution above should work without any problems, except I'm not
sure that macro_test could actually work at all in nevow currently, but it may
work.
In case you want to avoid to call loaders.xmlfile('datapage.html') each time
you might try a simple metaclass solution that grabs patternGenerator attribute
before building the class and changes it to be an instance of loaders.xmlfile.
I will come up with something outlining the snippet problem later.
ok.
_______________________________________________
Twisted-web mailing list
[email protected]
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web