Hi, I'm a Zope newbie, still in the process of reading the documentation and working on my first Zope project. I'm at the stage of organizing all my scripts and DTML documents in a folder hierarchy, but am unclear on how to design against the "fragility" issues discussed in the Zope book. Should I try to avoid a deep folder hierarchy and go with something more flat (but less well-organized?) Does anyone have any recommendations for me? Thanks! (see below for the excerpt from the Zope book) http://zope.org/Documentation/Books/ZopeBook/2_6Edition/ScriptingZope.stx Fragility Over-use of context acquisition can also lead to fragility. In object-oriented terms, context acquisition can lead to a site with low cohesion and tight coupling. This is generally regarded as a bad thing. More specifically, there are many simple actions by which an unwitting developer could break scripts that rely on context acquisition. These are more likely to occur than with container acquisition, because potentially every part of your site affects every other part, even in parallel folder branches. For example, if you write a script that calls another script by a long and torturous path, you are assuming that the folder tree is not going to change. A maintenance decision to reorganize the folder heirarchy could require an audit of scripts in every part of the site to determine whether the reorganization will break anything. Recall our Zoo example. There are several ways in which a zope maintainer could break the feed() script: Inserting another object with the name of the method This is a normal technique for customizing behavior in Zope, but context acquisition makes it more likely to happen by accident. Suppose that giraffe vaccination is controlled by a regularly scheduled script that calls Zoo/Vet/LargeAnimals/giraffe/feed. Suppose a content administrator doesn't know about this script and adds a DTML page called vaccinate in the giraffe folder, containing information about vaccinating giraffes. This new vaccinate object will be acquired before Zoo/Vet/vaccinate. Hopefully you will notice the problem before your giraffes get sick. Calling an inappropriate path if you visit Zoo/LargeAnimals/hippo/buildings/visitor_reception/feed, will the reception area be filled with hippo food? One would hope not. This might even be possible for someone who has no permissions on the reception object. Such URLs are actually not difficult to construct. For example, using relative URLs in standard_html_header can lead to some quite long combinations of paths. Thanks to Toby Dickenson for pointing out these fragility issues on the zope-dev mailing li
On Sun, 2003-11-16 at 09:44, Brad Allen wrote:
Hi, I'm a Zope newbie, still in the process of reading the documentation and working on my first Zope project. I'm at the stage of organizing all my scripts and DTML documents in a folder hierarchy, but am unclear on how to design against the "fragility" issues discussed in the Zope book. Should I try to avoid a deep folder hierarchy and go with something more flat (but less well-organized?) Does anyone have any recommendations for me?
The key here is discipline, especially if there is more than one person adding objects to the site. A shallow hierarchy might reduce the opportunity for accidental duplication of object IDs... but that approach does nothing to address "magic" names (the real problem here) and makes enforcing levels of access more difficult. Since levels of access are your primary defense against one user breaking another user's namespace, shallow won't help. IMO, the hierarchy should be at least as deep as the number of levels of access you want. You may want *more* hierarchy than that if your information architecture requires it... but no less. Some best practices: 1. Write things down. In particular, what "magic" names are provided by custom objects? 2. Design and enforce a security policy. 3. Reduce usage of objects as "global" variables. 4. Create a special naming scheme for "magic" names and objects that *are* used as variables. 5. Plan on doing some troubleshooting anyway. :-) HTH, Dylan
On Sun, Nov 16, 2003 at 10:38:56AM -0800, Dylan Reinhardt wrote:
On Sun, 2003-11-16 at 09:44, Brad Allen wrote:
Hi, I'm a Zope newbie, still in the process of reading the documentation and working on my first Zope project. I'm at the stage of organizing all my scripts and DTML documents in a folder hierarchy, but am unclear on how to design against the "fragility" issues discussed in the Zope book. Should I try to avoid a deep folder hierarchy and go with something more flat (but less well-organized?) Does anyone have any recommendations for me?
The key here is discipline, especially if there is more than one person adding objects to the site. (snip) Some best practices: 1. Write things down. In particular, what "magic" names are provided by custom objects? 2. Design and enforce a security policy. 3. Reduce usage of objects as "global" variables. 4. Create a special naming scheme for "magic" names and objects that *are* used as variables. 5. Plan on doing some troubleshooting anyway. :-)
Good advice. I would add one more: 6. When your application requirements have settled down a bit, refactor a group of scripts and magic-named objects into one or more Products with clear responsibilities and interfaces. As an example, in CMF it's common to implement new functionality with Scripts in the skins. This is fine for prototyping, but I'm finding it nice to convert the new functionality into a CMF Tool. p.s. I'm the guy that put the word "fragility" in that chapter :-) -- Paul Winkler http://www.slinkp.com Look! Up in the sky! It's ANTI RANDOM ENGINEER! (random hero from isometric.spaceninja.com)
Thanks, Paul and Dylan...but will I need a security policy if there's only one other developer that I work closely with? He works on the web pages and I work on the scripts. Eventually, we will have a security policy for one administrator who may use the Zope management interface. End users will never see the Zope management interface. I don't follow your use of the word "magic". My current Zope folder hierarchy looks something like this: appRoot bizlogic product [several nested subfolder levels in here containing scripts and Z SQL methods] distributor inventory arrival customer pages [hierarchy of DTML web pages which refer to scripts under bizlogic] There will be many web pages referring to specific paths to scripts to obtain results. Likewise, scripts under bizlogic will need to make reference to specific paths in the hierarchy of web pages. This structure seems like a perfect example of "fragility" because of the frequent need to bridge between two major branches. Does it makes senses to combine the "bizlogic" and "pages" branches? I'm accustomed to thinking in terms of keeping UI logic separate from business logic, so it goes against my instincts to merge the two.
On Sun, 2003-11-16 at 09:44, Brad Allen wrote:
Hi, I'm a Zope newbie, still in the process of reading the documentation and working on my first Zope project. I'm at the stage of organizing all my scripts and DTML documents in a folder hierarchy, but am unclear on how to design against the "fragility" issues discussed in the Zope book. Should I try to avoid a deep folder hierarchy and go with something more flat (but less well-organized?) Does anyone have any recommendations for me?
The key here is discipline, especially if there is more than one person adding objects to the site.
A shallow hierarchy might reduce the opportunity for accidental duplication of object IDs... but that approach does nothing to address "magic" names (the real problem here) and makes enforcing levels of access more difficult. Since levels of access are your primary defense against one user breaking another user's namespace, shallow won't help.
IMO, the hierarchy should be at least as deep as the number of levels of access you want. You may want *more* hierarchy than that if your information architecture requires it... but no less.
Some best practices: 1. Write things down. In particular, what "magic" names are provided by custom objects? 2. Design and enforce a security policy. 3. Reduce usage of objects as "global" variables. 4. Create a special naming scheme for "magic" names and objects that *are* used as variables. 5. Plan on doing some troubleshooting anyway. :-)
HTH,
Dylan
On Sun, Nov 16, 2003 at 10:38:01PM -0600, Brad Allen wrote:
Thanks, Paul and Dylan...but will I need a security policy if there's only one other developer that I work closely with? He works on the web pages and I work on the scripts. Eventually, we will have a security policy for one administrator who may use the Zope management interface. End users will never see the Zope management interface.
I don't follow your use of the word "magic".
I mean this: Asking for an object only by name and expecting to get the right object, no matter what folder you're in. Acquisition provides the "magic". It's very convenient when it works, and also easy to shoot yourself in the foot. -- Paul Winkler http://www.slinkp.com Look! Up in the sky! It's THE NEW SPOOK! (random hero from isometric.spaceninja.com)
At 12:38 AM 11/17/2003 -0500, Paul Winkler wrote:
On Sun, Nov 16, 2003 at 10:38:01PM -0600, Brad Allen wrote:
I don't follow your use of the word "magic".
I mean this: Asking for an object only by name and expecting to get the right object, no matter what folder you're in. Acquisition provides the "magic". It's very convenient when it works, and also easy to shoot yourself in the foot.
"Magic" words are a little deeper than that, as is the advice to be careful with them. The Zope book passage you quoted didn't quite go deep enough into the explanation for programming newbies, I think. The example used "magic" words for Python scripts like "feed" and "vaccinate"... horrible choices, actually. Why? Because they are common words and easy to use for something else, like the poor administrator of the website example in the Zope Book. If that script writer had instead used ps_vaccinate (ps_ for Python Script), and consistently used ps_ prefixes for all such scripts, it would (1) be unlikely that someone would accidentally step on this reserved (or "magic") script name, and (2) anyone could learn quickly that ps_anything is reserved. Such a naming style doesn't lead to pretty, interesting URLs like the examples in the Zope Book provide, but I personally NEVER build a website that depends on script names and acquisition in the URL. Well, not never, because I use Plone more now, and it does so in a number of places without my interference. But otherwise, never. As with any advice about coding styles and management of large websites, YMMV. Good luck. =Paul
On Sun, 2003-11-16 at 20:38, Brad Allen wrote:
Thanks, Paul and Dylan...but will I need a security policy if there's only one other developer that I work closely with? He works on the web pages and I work on the scripts. Eventually, we will have a security policy for one administrator who may use the Zope management interface. End users will never see the Zope management interface.
I don't follow your use of the word "magic".
Paul and I differ a bit on what we mean by magic, it seems. When you use a tag like <dtml-var my_thing> and the my_thing object gets rendered, I don't consider that magical. It's cool, to be sure... but it's pretty easy to figure out which object is resolving the name. Magical behavior comes about when objects resolve names other than their own IDs. As one very obvious example, Folder objects will resolve many standard names such as index_html, manage_main, manage, manage_workspace and others. This behavior is "magical" in the sense that it is not obvious in the ZMI that those names are resolved by folders... you just have to know about them from experience and/or reading the code. And it's possible that only a *careful* reading of the code may help, since objects can be programmed to resolve arbitrary names. The good news is that most of the built-in stuff doesn't seem to have any inherent problems with collision among magical names. But such problems can easily be created, especially if you start fooling around with Access Rules or other stuff that manipulates the traversal stack. And as you develop your own products, you will probably make use of your own magic. None of this is bad per se, but it is worth being careful.
My current Zope folder hierarchy looks something like this:
appRoot bizlogic product [several nested subfolder levels in here containing scripts and Z SQL methods] distributor inventory arrival customer pages [hierarchy of DTML web pages which refer to scripts under bizlogic]
This structure makes perfect sense, but fails to take advantage of much of what Zope is able to do for you. Structuring this way will take a lot longer to build and way more time to maintain. I'd shoot more for: approot/ distributor/ customer/ priv/ inventory/ arrival/ Where (I'm assuming) distributor, customer, inventory, and arrival represent different functional views of your data and/or different levels of access to data. Anything located in approot is accessible from all levels, anything located deeper in the hierarchy should be specific to the function the folder represents. To elaborate a bit, let's say you have a set of ZSQL methods that are broadly applicable. You would put those in the approot **and** mark them as only usable by some group you create at the approot level (i.e., not Anonymous and not Manager). Let's call that the "ViewSQL" group. Don't make any users members of this group. Now you can put "viewer" methods/templates at different levels of the hierarchy that function with the proxy role of ViewSQL. Users can only access your data through the interfaces provided and your folder structure makes it easy to present *only* the interfaces you want each class of user to have. Each interface is quite easy to craft, as it merely needs to know the correct name of the ZSQL method it relies on. Zope handles the rest. Designing *this* way provides a lot of flexibility, makes maintenance about as easy as it gets and *still* manages to be security-centered. This is Zope's sweet spot.
I'm accustomed to thinking in terms of keeping UI logic separate from business logic, so it goes against my instincts to merge the two.
An excellent instinct... but you'll do best to maintain that separation by which objects you use, not by where the objects are stored. Python (scripts and ext. methods) is your best available tool for logic. Templates (DTML or ZPT) should be used for presentation only. It may help to use a naming scheme for your Python scripts & ext methods. If you call all your scripts "zz_*" for example, you're quite unlikely to have accidental namespace conflicts and all your methods will sort together at the bottom of each Folder. Naming schemes for templates are less important, but may be a good idea for things that get called server-side, such as headers, footers and other pre-built stuff. With templates, it's far more common that "collisions" will be intentional. It's quite common (and handy) to have default versions of templates that are overridden by identically-named replacements located lower in the hierarchy. HTH, Dylan
On Mon, Nov 17, 2003 at 07:34:38AM -0800, Dylan Reinhardt wrote:
On Sun, 2003-11-16 at 20:38, Brad Allen wrote:
Thanks, Paul and Dylan...but will I need a security policy if there's only one other developer that I work closely with? He works on the web pages and I work on the scripts. Eventually, we will have a security policy for one administrator who may use the Zope management interface. End users will never see the Zope management interface.
I don't follow your use of the word "magic".
Paul and I differ a bit on what we mean by magic, it seems. When you use a tag like <dtml-var my_thing> and the my_thing object gets rendered, I don't consider that magical. It's cool, to be sure... but it's pretty easy to figure out which object is resolving the name.
Normally, yes, when you acquire only by containment. The examples in the Zope book were intended to argue against constructing complex URLs to acquire objects from a different branch of the tree. When you do that, it gets ugly quickly. Otherwise, I agree with your comments. Maybe we should expand that section for the next edition. The point about objects that provide their own name resolution mechanisms is well taken. Consider CMF. Names that are not found in the folder heirarchy are looked up by the skin tool. The skin tool resolves every name you ask for by searching through its own subfolders in an order determined by the skin path property for the current skin. The results are presented in a single flattened namespace. A skin might provide a dozen or so folders in which my_thing might be located, and the structure of the skin folder hierarchy is irrelevant to the search order. When you know how it works, finding out which "my_thing" is currently in use is not difficult but it is rather tedious. I got tired of it (especially after I made a mistake and customized the wrong template) so I wrote a script to do it for me :-) -- Paul Winkler http://www.slinkp.com Look! Up in the sky! It's BURGLAR MAYOR ODD LOOKING! (random hero from isometric.spaceninja.com)
participants (4)
-
Brad Allen -
Dylan Reinhardt -
Paul Howell -
Paul Winkler