Re: [Zope-dev] PythonLibraries Product
Tres Seaver wrote: Evan Simpson wrote: Seb Bacon wrote: Could you provide a brief summary of why this is better than a folder of python scripts? Perhaps a use case which illustrates the problems of the current way of doing things? It isn't *better* than a Folder of Scripts, it's *different* :-) I have two weak use-cases, a longstanding I'm going to write that some day itch, and some aesthetic arguments. Actually, the restricted case is the one which has the real win; the free-floating library is pretty, but not semanticaally needed. An added argument: a ZPT with its own private library becomes, in effect, a Zope3 view component; adopting such beasts will ease migration to Zope3. Well, I'm completely convinced :-) I'm not quite sure about the metaphor for binding a library to a template yet, though. Could libraries be added to folders as first-class objects (you want to be able to share them between templates easily, no?) and bound to the templates using a tab on either them or the templates? Their icons would be overlaid with a visual indication of if they are bound or not. Or, could you bind them at run-time using a new tal directive? (not likely to be a popular suggestion, I know) seb ___ Zope-Dev maillist - [EMAIL PROTECTED] http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] PythonLibraries Product
On Wed, Sep 10, 2003 at 09:50:51PM -0400, Tres Seaver wrote: For the filesystem representation: what if we just have two files for templates with libraries: 'foo.html' and 'foo.html.py'? Tools will like that better than either of the approaches which try to preserve the twins as a single file: sounds fine. I would vote for having the bound library's names inserted into the 'template' TALES namespace, BTW. +1 -- Paul Winkler http://www.slinkp.com Look! Up in the sky! It's ALPHABET METROID WINO! (random hero from isometric.spaceninja.com) ___ Zope-Dev maillist - [EMAIL PROTECTED] http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] PythonLibraries Product
Tres Seaver writes: Actually, the restricted case is the one which has the real win; the free-floating library is pretty, but not semanticaally needed. An added argument: a ZPT with its own private library becomes, in effect, a Zope3 view component; adopting such beasts will ease migration to Zope3. And it keeps all the pieces easy to locate! +1 For the filesystem representation: what if we just have two files for templates with libraries: 'foo.html' and 'foo.html.py'? Tools will like that better than either of the approaches which try to preserve the twins as a single file: The current Zope 3 filesystem synchronization doesn't currently support writing multiple files for a single object; every object is expected to be either file-like or directory-like. There are a few ways to approach serialization of a view that contains both a template and Python code: - Serialize it as a directory containing two files. - Serialize it as a file containing the template, and make the Python code live as an extra, which would be written to a file in the metadata storage area (tedious to work with, but could be an otherwise normal .py file). - Change the filesystem serialization so that multiple files can be generated to represent a single object. I think this would require a substantial amount of work. -Fred -- Fred L. Drake, Jr. fred at zope.com PythonLabs at Zope Corporation ___ Zope-Dev maillist - [EMAIL PROTECTED] http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] PythonLibraries Product
--On Thursday, September 11, 2003 10:08:23 -0400 Fred L. Drake, Jr. [EMAIL PROTECTED] wrote: Tres Seaver writes: Actually, the restricted case is the one which has the real win; the free-floating library is pretty, but not semanticaally needed. An added argument: a ZPT with its own private library becomes, in effect, a Zope3 view component; adopting such beasts will ease migration to Zope3. And it keeps all the pieces easy to locate! +1 +1 There are a few ways to approach serialization of a view that contains both a template and Python code: - Serialize it as a directory containing two files. IMHO, this is the obvious and probably best choice. It's well in line with a sentiment in the the Linux file system world that the way to handle multi-piece files is to treat them as directories rather than introduce another layer of special mechanisms. The file sytem itself can them optimize their storage as part of a general small file optimization strategy. I don't think the objection to having to pack a ZPT and it's script(s) in a separate ZODB folder applies anywhere near as well to file system storage. Dan Pierson ___ Zope-Dev maillist - [EMAIL PROTECTED] http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] PythonLibraries Product
On Wed, 2003-09-10 at 23:46, Evan Simpson wrote: Tres Seaver wrote: Actually, the restricted case is the one which has the real win; the free-floating library is pretty, but not semanticaally needed. An added argument: a ZPT with its own private library becomes, in effect, a Zope3 view component; adopting such beasts will ease migration to Zope3. Agreed. For the filesystem representation: what if we just have two files for templates with libraries: 'foo.html' and 'foo.html.py'? Eh. I think filesytem representations should handle this sort of thing much more generally. Assuming that the Zope object's ID is 'foo.html', there should be a text file of that name (encoded with quote_plus, which makes no difference in this case), and a directory named 'foo.html,'. Inside of this directory, there would be a 'library.py' (in this particular case), along with files such as 'properties' and 'proxies'. Hmm, I'm thinking about this for the CMF. In CMF 1.3.x, a template which has a cache manager, or a title, puts those values in a simple 'name=value'-formatted file, with extension '.properties'. Permission mappings go in a separate file, with extension '.security'. So, the filesystem-based template 'foo_view' might have as many as three files associated with it: - 'foo_view.pt' - 'foo_view.pt.properties' - 'foo_view.pt.security' CMF 1.4 unified the two files into a single, '.ini'-formatted one: - 'foo_view.pt' - 'foo_view.pt.metadata' It feels more natural to me just to add another file: - 'foo_view.pt.py' This is especially nice for many CMF skin templates (those which contain forms), because I can probably *remove* the separate template which serves as the POST-target for the form! Instead, such templates will post *to themselves*, and use the bound library to do the validation / updates. In this case, we go from: - 'foo_edit_form.pt' - 'foo_edit.py' to: - 'foo_edit_form.pt' - 'foo_edit_form.pt.py' And there is yet another argument for the bound library: it shows how unnecessary, as well has how evil, that script tag hack is. Yep :-) Refactoring a one-off template-cum-library will be simple, too: Cool! I would vote for having the bound library's names inserted into the 'template' TALES namespace, BTW. Tricky -- right now, that's just the template object itself. I'd just introduce a builtin 'library' variable, and probably dump the function names into the global namespace as well. +1, then. Tres. -- === Tres Seaver[EMAIL PROTECTED] Zope Corporation Zope Dealers http://www.zope.com ___ Zope-Dev maillist - [EMAIL PROTECTED] http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] PythonLibraries Product
Tres Seaver wrote: Hmm, I'm thinking about this for the CMF. In CMF 1.3.x, a template which has a cache manager, or a title, puts those values in a simple 'name=value'-formatted file, with extension '.properties'. Permission mappings go in a separate file, with extension '.security'. I wish I had been more involved when these decisions were being made -- I dislike this scheme, because it is irregular and requires you to know what sort of object you're dealing with just to be able to tell which files go together. If it's always file + ','-dir, external tools can move, rename, delete, etc safely. Then there's the potential for name clashes. It's unlikely, but not *terribly* so, that a user would create a second object named 'foo_edit_form.pt.py'. Using quote_plus avoids filesystem character set issues, and makes the simple ',' postfix clash-proof. Oh, well. Cheers, Evan ___ Zope-Dev maillist - [EMAIL PROTECTED] http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] PythonLibraries Product
Evan Simpson wrote: Seb Bacon wrote: Could you provide a brief summary of why this is better than a folder of python scripts? Perhaps a use case which illustrates the problems of the current way of doing things? It isn't *better* than a Folder of Scripts, it's *different* :-) I have two weak use-cases, a longstanding I'm going to write that some day itch, and some aesthetic arguments. One of the more frequently stated complaints about ZPTs is that to properly remove non-presentation logic and ugly little Python expressions from a template, you either need a pile of little Scripts, or a single controller Script that precalculates everything and passes it to the template. I've settled, fairly happily, on the second solution. Both of these solutions suffer from the two or more objects to accomplish one task management problem. I usually combine the objects in a dedicated Folder, which is still a bit awkward, and doesn't solve everything. One drawback is that the individual components are all published, despite the fact that I only intend one of them to be web-addressable. It would be very handy to attach the Scripts directly to the template, but the straightforward way of doing that means making the template a container, and opens a whole can of worms. Instead, what if templates had a Library tab, and it worked with External Editor? It would actually be easier to *just* write this, and not have independent Library objects, but generalizing this capability feels right to me Actually, the restricted case is the one which has the real win; the free-floating library is pretty, but not semanticaally needed. An added argument: a ZPT with its own private library becomes, in effect, a Zope3 view component; adopting such beasts will ease migration to Zope3. For the filesystem representation: what if we just have two files for templates with libraries: 'foo.html' and 'foo.html.py'? Tools will like that better than either of the approaches which try to preserve the twins as a single file: - Embedding the Python code into an HTML/XML comment at the head or foot of the template in the .pt file will not let editors help with syntax highlighting. - In addition to messing up syntax highlighting, embedding the template as a triple-quoted string literal in the .py file feels *really* nasty (almost as nasty as Zope3's script tag). And there is yet another argument for the bound library: it shows how unnecessary, as well has how evil, that script tag hack is. Refactoring a one-off template-cum-library will be simple, too: once the refactored code is moved to a real module (even a persistent module in Zope3!), the library can just contain 'from realmodule import usefulFunction', and the template won't need to change. I would vote for having the bound library's names inserted into the 'template' TALES namespace, BTW. Tres. -- === Tres Seaver[EMAIL PROTECTED] Zope Corporation Zope Dealers http://www.zope.com ___ Zope-Dev maillist - [EMAIL PROTECTED] http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] PythonLibraries Product
Evan Simpson wrote at 2003-9-8 14:43 -0500: I'm thinking seriously about writing a Product to provide collections of Python functions defined by a single source text -- PythonLibraries. + 1 ... The Python Libraries Product provides support for collections of restricted Python code. A Python Library is similar to a Folder full of Python-based Scripts, except that the functions in the Library are more like ordinary Python functions than Scripts, and a single persistent global variable namespace is shared among the functions in the Library. Hopefully, these variables are used only for customization. I have been hit in the past, when I used compiled regular expressions as default parameters to an ExternalMethod. Apparently, because some objects (such as compiled regular expressions) cannot be stored (worse loaded) persistently. Dieter ___ Zope-Dev maillist - [EMAIL PROTECTED] http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )
[Zope-dev] PythonLibraries Product
I'm thinking seriously about writing a Product to provide collections of Python functions defined by a single source text -- PythonLibraries. This would *not* be the same as Zope 3's persistent modules, although it would provide some of the same benefits. Here's the README.txt: Python Libraries The Python Libraries Product provides support for collections of restricted Python code. A Python Library is similar to a Folder full of Python-based Scripts, except that the functions in the Library are more like ordinary Python functions than Scripts, and a single persistent global variable namespace is shared among the functions in the Library. A Library obeys the same security restrictions, and has access to the same set of modules, as a Script. Libraries are *not* very much like Python modules or packages, except in that they both are convenient places to keep groups of functions. You cannot import a Library, define Python classes in one, or use the 'print' statement outside of function definitions. When changes to a Library are saved, its source code is executed. This process, known as Library initialization, also occurs whenever the Library is loaded into memory from the ZODB. Global variables defined during initialization are divided into three groups, depending on the kind of value to which they refer: functions, simple data, and modules. There is one additional global variable, named 'Library', that is defined both during initialization and function evaluation, and which cannot be deleted or rebound. It refers to the Library object itself. Functions are made available to other Zope code as Library attributes. A function 'do_it' contained in the Library located at '/foo/myLib' may be called by a TALES expression such as here/foo/myLib/do_it or the Python expression context.foo.myLib.do_it(). Function names that conflict with methods of the Library object are syntax errors. A Library's functions are not published by default, which means that they cannot be accessed by URL through ZPublisher. There is a Library method 'pl_publish()' that can be used to explicitly publish a function. Simple data includes Python built-in types such as numbers, strings, lists, and dictionaries. Variables with simple data are persistent, and their value is retained even when the Library is changed or reloaded, although the execution of the code can remove or overwrite them. These variables are not visible to other Zope objects. Modules are imported Python modules. These are not visible to other Zope objects, and do not persist -- they are re-imported each time the Library is changed or loaded. Unlike Scripts, Libraries do not have a Bindings tab. In order to access context objects, such as the Library's container, the root Zope object, or the authenticated user, functions must use a global variable created by a call to the 'pl_bind()' method of the Library. This method takes two arguments: a variable name, and a TALES expression. The TALES expression will be evaluated the first time that the variable is used in each call to a Library function, and the value will be cached for subsequent uses within the same call. For example, examine the following snippet of Library code: Library.pl_bind('user', 'user') Library.pl_bind('thingy', 'here/thingy | nothing') def f(): if user.has_role('Authenticated') and thingy is not None: print user, thingy return printed When the function 'f' is called, the 'user' and 'thingy' variables will be evaluated in its first line, and the values will be reused in the second line, if the condition is true. If 'f' is called again, in the same request or not, the bound variables will be re-evaluated. Bound variables are not available during Library initialization, since they are unlikely to evaluate meaningfully when a Library is loaded from the ZODB. ___ Zope-Dev maillist - [EMAIL PROTECTED] http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )