
Hi all, I'm learning nevow by building yet a simple view-edit-save kind of app. Its going ok and is a good learning experience. I've refactored so that I can specify all the layout in separate html files, with as little coded html as possible. I'm stuck because I want the code to choose between displaying html fragments from the template that either display the page, edit it or save it. The relevant html fragment looks like this - and I know its really wrong :) - <div id="content"> <span nevow:data="display" nevow:render="xml"/> <span nevow:data="edit" nevow:render="xml"> <form>this is edit: more will go in here...</form> </span> <span nevow:data="save" nevow:render="xml/> <p>you have saved: <span nevow:data="saved_data" nevow:render="xml/> </span> </div> What is the right way to tell Nevow to use one node and not another? Thanks again! Ellers PS am I right that Nevow stands for NEw Version Of Woven ?

On Sat, 2004-04-10 at 18:27, Ellers wrote:
<div id="content"> <span nevow:data="display" nevow:render="xml"/> <span nevow:data="edit" nevow:render="xml"> <form>this is edit: more will go in here...</form> </span> <span nevow:data="save" nevow:render="xml/> <p>you have saved: <span nevow:data="saved_data" nevow:render="xml/> </span> </div>
First off, you don't want to be using span tags, you want to be using div tags -- span tags aren't block elements, so they aren't supposed to contain things like forms and paragraphs (as far as I understand). Here's what you really want: <div> <div nevow:render="display"></div> <div nevow:render="edit"> <form nevow:render="edit_form"></form> </div> <div nevow:render="save"> <p> You have saved: <span nevow:render="save_data"></span> </p> </div> </div> class MyPage: def render_display(self, ctx, data): if not show_display: return ctx.tag.clear() # More... def render_edit(self, ctx, data): if not show_edit: return ctx.tag.clear() # More... def render_save(self, ctx, data): if not show_save: return ctx.tag.clear() # More... # Implement other renderers (edit_form and save_data)... There's nothing that says you have to use Nevow's predefined renderers; for most complex rendering situations, you're going to want to write your own render_* functions. -- Alex Levy WWW: http://mesozoic.geecs.org "Never let your sense of morals prevent you from doing what is right." -- Salvor Hardin, Isaac Asimov's _Foundation_

On Sat, 10 Apr 2004 19:08:14 -0400, Alex Levy <mesozoic@polynode.com> wrote:
On Sat, 2004-04-10 at 18:27, Ellers wrote:
<div id="content"> [snip] </div>
First off, you don't want to be using span tags, you want to be using div tags -- span tags aren't block elements, so they aren't supposed to contain things like forms and paragraphs (as far as I understand).
Here's what you really want:
[snip] many thanks! I'll try that out... :) Ellers

Alex Levy wrote:
On Sat, 2004-04-10 at 18:27, Ellers wrote:
<div id="content"> <span nevow:data="display" nevow:render="xml"/> <span nevow:data="edit" nevow:render="xml"> <form>this is edit: more will go in here...</form> </span> <span nevow:data="save" nevow:render="xml/> <p>you have saved: <span nevow:data="saved_data" nevow:render="xml/> </span> </div>
First off, you don't want to be using span tags, you want to be using div tags -- span tags aren't block elements, so they aren't supposed to contain things like forms and paragraphs (as far as I understand).
Unless you really need some tag to be in the output, which is unusual for span and div unless you're placing HTML attributes on them, you may prefer to attach your "rendering logic" to <nevow:invisible> tags instead. Those won't show up in the resulting HTML, which makes it "lighter". As I often need selective output, I have a very simple general-purpose renderer: def render_ifeq(self, context, data): if data != (context.tag.pattern or ''): return '' return context.tag If you have, for example, a data_state that returns as the current data a string which represents some kind of "state", you could code the template: <nevow:invisible nevow:data="state"> <nevow:invisible nevow:render="ifeq" nevow:pattern="edit"> <p> You are editing the object. </p> </nevow:invisible> <nevow:invisible nevow:render="ifeq" nevow:pattern="save"> <p> Your changes have been saved. </p> </nevow:invisible> <nevow:invisible nevow:render="ifeq" nevow:pattern="view"> <p> Your are just viewing the object. </p> </nevow:invisible> </nevow:invisible> This will emit a single one of the three <p>'s as appropriate. Several other similar approaches are possible, e.g., put the patterns on the tags among which you want to choose, and have the renderer examine all contained patterns and pick the right one[s]; generalize ifeq to an ifmatch that treats patterns as regular expressions; and so on, and so forth. I'm striving to avoid obscuring my stuff with excessive and unwarranted generality, and so far I've found the simple ifeq serves my purpose, so that's what I'm currently using. I _think_ (I could be wrong...) that using nevow:pattern as the "argument" to be used by data and render methods is quite consonant to nevow's design; there used to be some confusion, e.g. with the quondam nevow:key, but now that nevow:pattern is all that's left the approach appears to be to be simple and effective, allowing you to pick the right degree of generality. Alex
participants (3)
-
Alex Levy
-
Alex Martelli
-
Ellers