Jim Hebert wrote:
Is there a reason you can't do this by just messing with the namespaces stack, ie, adding additional folders to it?
I had been latterly thinking this myself and set about trying to do it, but being new to Zope development, didn't have much success! I presume it involves modifying the folders PARENTS list, but I wasn't quite sure how to do that. Hamish Lawson ===== Hamish Lawson hamish_lawson@yahoo.co.uk ____________________________________________________________ Do You Yahoo!? Get your free @yahoo.co.uk address at http://mail.yahoo.co.uk or your free @yahoo.ie address at http://mail.yahoo.ie
On Fri, 30 Jun 2000, Hamish Lawson wrote:
Jim Hebert wrote:
Is there a reason you can't do this by just messing with the namespaces stack, ie, adding additional folders to it?
I had been latterly thinking this myself and set about trying to do it, but being new to Zope development, didn't have much success! I presume it involves modifying the folders PARENTS list, but I wasn't quite sure how to do that.
Actually, I just used dtml-with. I'll go ahead and embarrass myself now, and explain what I did. Other people can chime in with "wow, that was dumb, here's the right way to do that" as needed (I'd really welcome that, actually!). My use was, I wanted to be able to pull in things like images, bits of text, whatever, from a "common" area but not have to litter, perceptually, the / area of my server. So, being someone used to idioms like -I/some/other/directory from the various glorified c-preprocessor "include" systems that I'd used on HTML in previous jobs, I set out to do that. =) So, for example, we have /images/ and there are Image objects in there. But I wanted to be able to just write <dtml-var foo_png> while working on pages, so I wrap the content with <dtml-with images> <dtml-with "PARENTS[0]"> ... </dtml-with> </dtml-with> The reason for the inner dtml-with is that my pages are DTML Methods, not DTML Documents, and the Folders are the "context." If all my content had "images" shoved on top of the namespaces stack, they'd get even simple things like <dtml-var title> wrong, because that's supposed to come from the Folder that method lives in... So, I push images onto the namespaces stack, then push "the parent" (as opposed to grandparent) up on top of the stack redundantly. This way the acquisition picks up the things like title from the current folder, and even lets the current folder override some of the "common" elements, but then falls back to this arbitrarily chosen folder to go find the other peices next, and then finally goes through the normal acquisition dance of going up the parents list. This actually worked out pretty well (boy, was I shocked ;->). HTH, jim -- Jim Hebert http://www.cosource.com/ jim@cosource.com The cooperative market for open source software "Well actually I was considering opening a market in flying pigs. Mostly because it would be more practical...." -- Alan Cox
Jim Hebert wrote:
I'll go ahead and embarrass myself now, and explain what I did. Other people can chime in with "wow, that was dumb, here's the right way to do that" as needed (I'd really welcome that, actually!).
Actually what you did is pretty clever, Jim. It even relies on stable interfaces.
...
<dtml-with images> <dtml-with "PARENTS[0]"> ... </dtml-with> </dtml-with>
The reason for the inner dtml-with is that my pages are DTML Methods, not DTML Documents, and the Folders are the "context." If all my content had "images" shoved on top of the namespaces stack, they'd get even simple things like <dtml-var title> wrong, because that's supposed to come from the Folder that method lives in... So, I push images onto the namespaces stack, then push "the parent" (as opposed to grandparent) up on top of the stack redundantly. This way the acquisition picks up the things like title from the current folder, and even lets the current folder override some of the "common" elements, but then falls back to this arbitrarily chosen folder to go find the other peices next, and then finally goes through the normal acquisition dance of going up the parents list.
This actually worked out pretty well (boy, was I shocked ;->).
If we could find some way to effectively communicate the way Zope works (and what goes on in Jim Fulton's head), the fact that this works wouldn't be so surprising. Achieving this is not just about documenting interfaces, however. It's also about new design patterns that are made available through the concept of acquisition. I hope that the books being written about Zope go into depth on the new concepts. Good work! Shane
On Thu, 29 Jun 2000, Shane Hathaway wrote:
Actually what you did is pretty clever, Jim. It even relies on stable interfaces.
Uh oh, careful, I'm encouragable and you'll really have a monster on your hands. ;-)
The reason for the inner dtml-with is that my pages are DTML Methods, not
OK, I am just going to go ahead and spill the rest of what swirled around in my head about zope when I threw up this vistasource.com site, in the hopes that I'll either get another ego stroke (*grin*) or some more insights as to the reason why things are done the way they are (ie, not the way I do 'em!). This is probably going to be long, please forgive me for going from newly subscribed to thinks-he-can-write-a-howto overnight! =) I am bucking a trend, I am starting to realize. Big time! The assumption seems to be that any given page will build itself, it will suck in standard_html_header and standard_html_footer, and compose itself of whatever else in between those things. DTML Document is the base unit of a page. Partially because I was planning at the time to build an over-simplified front end for our system, I wanted people to be able to upload simple, stupid chunks of "content" html and not have to do things like put <dtml-var standard_html_header> at the top and ..._footer at the bottom. Any lame wysiwyg editor that had save-to-ftp could then push up a 'body file' into the right folder, and I could get writers writing without learning zope. I also started to really groove on the idea of Object Oriented precepts for my pages, and having to explicitly "#include" peices like the common stuff offended those sensibilities. I wanted "objects" that had both "data" and "code" as its members, in a nice little bundle. So, I made the decision that my atomic unit of what constitutes a "page" on my server is a Folder object. This lets me collect everything specific to a page, images that are only used there, methods that are only used there, etc, in a tidy little bundle. So here's my scheme: I think of /index_html, a DTML Method, as if it were a member function of an object. It might as well be named "render_this_folder_as_a_page." So, it looks like (oversimplifying:) <dtml-with images> <dtml-with "PARENTS[0]"> <dtml-var standard_html_header> <table><tr><td> <dtml-var menu> </td><td> <dtml-var body> </td></tr></table> <dtml-var stnadard_html_footer> </dtml-with> </dtml-with> So, now, in each folder I just put a dtml method called body. When you visit /about, index_html gets acquired, but since it's a dtml method, the /about folder remains the first place to look for other stuff, so body gets located in /about. If I want to override the menu code, I also stick another object in there called menu, but by default my toplevel menu code works for all the subfolders. In some perverse sense, sub-pages conceptually are sub-classes of higher up pages, which inherit some things (index_html for instance) things and override things (/body, nearly always, and sometimes other things). If I repeitively built $header + $menu + some content + footer over and over again in page after page, I couldn't radically redesign my site (for instance, pulling in body and sticking an advertisement between every 3rd paragraph) without touching every page. But in the model that I use, the one true index_html method is free to suck body in, do crazy post-processing to it, and then send that out. And, of course, index_html itself can be overridden for sub-trees of the site, if need be. And, I can also come up with different renderers, I suppose. Untested might be the idea that I could put /alt_renderer as a DTML Method at the top level, then visit /about/alt_renderer and invoke that method in the /about context. So by separating content from presentation, I can plug my content into lots of things simultaneously. Presumably. The only thing that has bummed me out about this strategy is that I feel like that every time I use a 3rd party product I end up working up hill: it usually expects to be able to write out a DTML Method or Document that says <dtml-var standard_html_header> app-specific-logic-here <dtml-var standard_html_footer> and have gotten it all. Adding a "Search Interface" is a typical example of this. When I can, I hack around this and migrate "app-specific-logic-here" into SomeFolderName/body. But for products which manufacture pages on an ongoing basis, e.g. FlexFaq/Knowledgebase, this is less of an option, and points more towards me hacking the package code itself. I don't honestly expect that what I invented in the middle of the night 7 days before the VistaSource launch to revolutionize how everyone builds pages (like I said, I actually suspect that these hacks that I invented have some major drawback that you guys will help clue me into, though, hehehe, I haven't been dissauded by the search drawback..), but perhaps someone will have suggestions on how I can make my style "play nicer" with all these products, too. Sorry so long. If this was illustrative to anyone for seeing how unbelievably, scream it down the halls, wake your mom up in the middle of the night to tell her, very very cool Zope is, then it was worth it. =) Because Zope is quite simply the coolest damn thing I have ever worked on, bar none. I would love to bump into Jim Fulton at a show sometime, because I think I like the way his mind works!! =) jim hoping to git educated. =) -- Jim Hebert http://www.cosource.com/ jim@cosource.com The cooperative market for open source software "Well actually I was considering opening a market in flying pigs. Mostly because it would be more practical...." -- Alan Cox
Jim Hebert wrote:
Uh oh, careful, I'm encouragable and you'll really have a monster on your hands. ;-)
<ego stroke> I like the way you think, lots of good will come of it.. ;-) </ego stroke>
I am bucking a trend, I am starting to realize. Big time! The assumption seems to be that any given page will build itself, it will suck in standard_html_header and standard_html_footer, and compose itself of whatever else in between those things. DTML Document is the base unit of a page.
I think it's a trend worth bucking, as you point out, this trend can be out of line with the whole acquisition - inheritence objecty thing that Zope does so well...
front end for our system, I wanted people to be able to upload simple, stupid chunks of "content" html and not have to do things like put <dtml-var standard_html_header> at the top and ..._footer at the bottom. Any lame wysiwyg editor that had save-to-ftp could then push up a 'body file' into the right folder, and I could get writers writing without learning zope.
Totally agree with this :-))) [snip excellent possible solution]
And, I can also come up with different renderers, I suppose. Untested might be the idea that I could put /alt_renderer as a DTML Method at the top level, then visit /about/alt_renderer and invoke that method in the /about context. So by separating content from presentation, I can plug my content into lots of things simultaneously. Presumably.
This would be really useful for things like WAP and AvantGo... [snip sucky products] Well, you either have to re-develop the products or live with them :/
I don't honestly expect that what I invented in the middle of the night 7 days before the VistaSource launch to revolutionize how everyone builds pages
With any luck, you may be surprised ;-)
perhaps someone will have suggestions on how I can make my style "play nicer" with all these products, too.
I have a slightly different take on the problem from back when I used to use mason. Autohandlers solve parts of this... An autohandler is a bit of code which would get executed during URL traversal. it's main use is to render a wrapper around a page, for example: ...do stuff... process and render the rest of the URL (called mc_auto_next in Mason) ...do mroe stuff... So your standard_ stuff apears in the autohandler and is _automatically_ wrapped around the eventual object. How far would this go to doing what you were talking about? Not far enough might be the answer... I'm really interested in the stuff you talked about so please email more of it to me directly if you don't think it's list-related enough.... hope to hear from you soon, Chris
Jim Hebert wrote:
OK, I am just going to go ahead and spill the rest of what swirled around in my head about zope when I threw up this vistasource.com site, in the hopes that I'll either get another ego stroke (*grin*) or some more insights as to the reason why things are done the way they are (ie, not the way I do 'em!). This is probably going to be long, please forgive me for going from newly subscribed to thinks-he-can-write-a-howto overnight! =)
Ha ha! I like your enthusiasm, Jim.
I am bucking a trend, I am starting to realize. Big time! The assumption seems to be that any given page will build itself, it will suck in standard_html_header and standard_html_footer, and compose itself of whatever else in between those things. DTML Document is the base unit of a page.
Partially because I was planning at the time to build an over-simplified front end for our system, I wanted people to be able to upload simple, stupid chunks of "content" html and not have to do things like put <dtml-var standard_html_header> at the top and ..._footer at the bottom. Any lame wysiwyg editor that had save-to-ftp could then push up a 'body file' into the right folder, and I could get writers writing without learning zope.
It's a great idea but I've had some thoughts on this myself. I think the approach I would take is to create a ZClass. Content authors would create instances of this ZClass and would not have to use standard-html-header nor any other DTML if they don't want to. The ZClass would perform a simple transformation of the content before presenting it on the Web, such as adding standard_html_header/footer and including the title and date.
I also started to really groove on the idea of Object Oriented precepts for my pages, and having to explicitly "#include" peices like the common stuff offended those sensibilities. I wanted "objects" that had both "data" and "code" as its members, in a nice little bundle.
So, I made the decision that my atomic unit of what constitutes a "page" on my server is a Folder object. This lets me collect everything specific to a page, images that are only used there, methods that are only used there, etc, in a tidy little bundle. So here's my scheme:
I think of /index_html, a DTML Method, as if it were a member function of an object. It might as well be named "render_this_folder_as_a_page." So, it looks like (oversimplifying:)
<dtml-with images> <dtml-with "PARENTS[0]"> <dtml-var standard_html_header> <table><tr><td> <dtml-var menu> </td><td> <dtml-var body> </td></tr></table> <dtml-var stnadard_html_footer> </dtml-with> </dtml-with>
So, now, in each folder I just put a dtml method called body. When you visit /about, index_html gets acquired, but since it's a dtml method, the /about folder remains the first place to look for other stuff, so body gets located in /about. If I want to override the menu code, I also stick another object in there called menu, but by default my toplevel menu code works for all the subfolders. In some perverse sense, sub-pages conceptually are sub-classes of higher up pages, which inherit some things (index_html for instance) things and override things (/body, nearly always, and sometimes other things).
I think you'll have more flexibility if you make ZClasses a major part of your solution. When the time comes, you'll be able to make fundamental changes more easily. Have you learned about property sheets yet? They are the key to success with ZClasses.
If I repeitively built $header + $menu + some content + footer over and over again in page after page, I couldn't radically redesign my site (for instance, pulling in body and sticking an advertisement between every 3rd paragraph) without touching every page. But in the model that I use, the one true index_html method is free to suck body in, do crazy post-processing to it, and then send that out.
And, of course, index_html itself can be overridden for sub-trees of the site, if need be.
And, I can also come up with different renderers, I suppose. Untested might be the idea that I could put /alt_renderer as a DTML Method at the top level, then visit /about/alt_renderer and invoke that method in the /about context. So by separating content from presentation, I can plug my content into lots of things simultaneously. Presumably.
Also remember you can play tricks with acquisition. If you have a "default" style and a "lowres" style, you can set up your directories like this: /home /lowres /content "lowres" and "content" are both children of "home". The default style elements are in home. When the user browses to /home/content/index_html, they get the default style. When the user visits /home/lowres/content/index_html, they get the lowres style.
The only thing that has bummed me out about this strategy is that I feel like that every time I use a 3rd party product I end up working up hill: it usually expects to be able to write out a DTML Method or Document that says
<dtml-var standard_html_header> app-specific-logic-here <dtml-var standard_html_footer>
and have gotten it all. Adding a "Search Interface" is a typical example of this. When I can, I hack around this and migrate "app-specific-logic-here" into SomeFolderName/body. But for products which manufacture pages on an ongoing basis, e.g. FlexFaq/Knowledgebase, this is less of an option, and points more towards me hacking the package code itself.
I don't honestly expect that what I invented in the middle of the night 7 days before the VistaSource launch to revolutionize how everyone builds pages (like I said, I actually suspect that these hacks that I invented have some major drawback that you guys will help clue me into, though, hehehe, I haven't been dissauded by the search drawback..), but perhaps someone will have suggestions on how I can make my style "play nicer" with all these products, too.
Sorry so long. If this was illustrative to anyone for seeing how unbelievably, scream it down the halls, wake your mom up in the middle of the night to tell her, very very cool Zope is, then it was worth it. =) Because Zope is quite simply the coolest damn thing I have ever worked on, bar none. I would love to bump into Jim Fulton at a show sometime, because I think I like the way his mind works!! =)
Jim and the rest of the Zope community have created a lot of mechanisms in Zope and it's not easy to grasp all of them. But learning each concept is a fun experience. And they all tie together. Zope is like a collection of Legos (TM): you're given a bunch of blocks and some instructions on how to build some specific models, but encouraged to explore putting them together in new ways. Have you heard of the Lego Machine Gun? :-) Shane
On Fri, 30 Jun 2000, Shane Hathaway wrote:
Also remember you can play tricks with acquisition. If you have a "default" style and a "lowres" style, you can set up your directories like this:
/home /lowres /content
"lowres" and "content" are both children of "home". The default style elements are in home. When the user browses to /home/content/index_html, they get the default style. When the user visits /home/lowres/content/index_html, they get the lowres style.
This is, actually, not quite right. Given the following hierarchy: /home header footer /content index_html /lowres header footer and a request of /home/content/index_html, we have the following acquisition path (assuming index_html is a DTML Method): /home/content = (content of home) /home/content/index_html = (index_html of (content of home)) Assuming index_html contains: <dtml-var header> Content. <dtml-var footer> when index_html asks for header, the acquisition path is searched from left to right; the content folder is searched first, followed by the home folder, where header is found. Now, with a request of /home/lowres/content/index_html, we have: /home/lowres = (lowres of home) /home/lowres/content = ((content of home) of (lowres of home)) /home/lowres/content/index_html = (index_html of ((content of home) of (lowres of home))) Therefore, when index_html looks for header, the content folder is searched, then the home folder, then the lowres folder, then the home folder. Unfortunately, for our example, the header is found in the search of the home folder, and we never make it to the lowres folder. If, instead, we structure the request as /home/content/lowres/index_html, we have: /home/content = (content of home) /home/content/lowres = ((lowres of home) of (content of home)) /home/content/lowres/index_html = (index_html of ((lowres of home) of (content of home))) When index_html looks for header, we search lowres, then home, then content, then home. The header is picked up from lowres, which is what we want. Hope this makes sense. Acquisition is not one of the things I have become good at explaining, yet. The slides from Jim's Acquisition Algebra talk is about the best source of information on this subject.
Shane
--Jeff --- Jeff K. Hoffman 704.849.0731 x108 Chief Technology Officer mailto:jeff.hoffman@goingv.com Going Virtual, L.L.C. http://www.goingv.com/
"Jeff K. Hoffman" wrote:
Therefore, when index_html looks for header, the content folder is searched, then the home folder, then the lowres folder, then the home folder. Unfortunately, for our example, the header is found in the search of the home folder, and we never make it to the lowres folder.
Oops--thanks for pointing that out. I sometimes wonder, however, why it was set up this way. Except for speed concerns, I see no reason why, if we set up the algorithm a different way, it couldn't search from right to left. A simple approach would be like this: def findattr(obj, name): while (obj is not None): base = getattr(obj, 'aq_base', obj) if hasattr(base, name): return getattr(obj, name) obj = getattr(obj, 'aq_parent', None) raise AttributeError, name
Hope this makes sense. Acquisition is not one of the things I have become good at explaining, yet. The slides from Jim's Acquisition Algebra talk is about the best source of information on this subject.
Of course, Jim would probably look at my example and want to hit me. He likes things to be optimized. :-) Shane
On Fri, 30 Jun 2000, Shane Hathaway wrote:
It's a great idea but I've had some thoughts on this myself. I think the approach I would take is to create a ZClass. Content authors would
Oooh, I like that idea a lot. Solves lots of problems, most notably the hackery I currently do with the searching stuff: The search results come up with urls like http://www.vistasource.com/body, which ain't right, so I do a bunch of munging to make the urls right. Also sounds like work, but hey, I suppose it's about time I earn that salary... =)
fundamental changes more easily. Have you learned about property sheets yet? They are the key to success with ZClasses.
Nope, where shall I go to read the fine manual on those?
visits /home/lowres/content/index_html, they get the lowres style.
(I understand this now, modulo the other post from Jeff.) Yeah, this is the part of acquisition that I _get_, but just shy away from for some reason. I need to get over that, because this is probably one of the coolest things about acquisition.
Zope is like a collection of Legos (TM): you're given a bunch of blocks and some instructions on how to build some specific models, but encouraged to explore putting them together in new ways. Have you heard of the Lego Machine Gun? :-)
Yeah, funny you should mention it. I was just looking at the web page for it like 2 weeks ago. And I like the analogy. =) Thanks so much, I hope others on the list are profiting from this exchange as much as I am! jim -- Jim Hebert http://www.cosource.com/ jim@cosource.com The cooperative market for open source software "Well actually I was considering opening a market in flying pigs. Mostly because it would be more practical...." -- Alan Cox
Jim Hebert wrote:
fundamental changes more easily. Have you learned about property sheets yet? They are the key to success with ZClasses.
Nope, where shall I go to read the fine manual on those?
I'm not sure, but let me just give you enough info to get started. ZClasses have a "property sheets" tab where you can add sheets. Group relevant properties together. Then go to the ZClass "Views" tab and add your property sheets to the list of views of your objects available through the management interface. Voila--not only do your class instances have configurable properties with defaults, but the management interface lets you set them. And the effort required was minimal.
Yeah, this is the part of acquisition that I _get_, but just shy away from for some reason. I need to get over that, because this is probably one of the coolest things about acquisition.
I also avoid it because its behavior is not completely obvious, thus even if I understand it, someone else who has to maintain my work later may shoot him/herself in the foot with the bullet I've provided!
Thanks so much, I hope others on the list are profiting from this exchange as much as I am!
Thanks for a nice Friday discussion. Shane
participants (7)
-
Chris Withers -
Hamish Lawson -
Jeff K. Hoffman -
Jim Hebert -
Jim Hebert -
Jim Hebert -
Shane Hathaway