Quick Guide to Zope
|
|
Executive Summary
Zope was originally a commercial, closed-source
product called Principia and offered by Zope Corporation,
formely Digital Creations. It was open-sourced in 1998. Zope is a mostly Python-based
web application development tool, with C bits for performance-critical parts.
At best of my knowledge, it's an open-source equivalent to ColdFusion or UserLand.
All objects (scripts, HTML templates, data, etc.) live in a database, which
is the single-file-based ZODB by default but that can be moved to a full-fledged
DBMS server. Scripts can be written with either Zope's own DTML language, Perl,
or Python. Extra modules are available, such as Zope's Content
Management Framework (CMF) or the Slashdot-like blogger Squishdot.
Why use Zope...
... in the absolute?
After playing with simpler Zope-like tools like CherryPy,
I finally figured why using Zope et al. is a better alternative to writing PHP
scripts on top of a regular web server like Apache: An application server is
aimed at making it easier to build web applications, and especially make it
possible to handle web pages as objects and methods.
For instance, while http://localhost/support/index would execute a stand-alone
PHP script located in eg. the docs/support/ section on the hard disk of a regular
web server, the same URL could execute the index() method of the Support class
under an application server. And locating common stuff in a Root class makes
it a snap to share properties and methods with classes located below in the
hierarchy... Definitely beats PHP scripts scattered around in a filesystem,
each page independent from the others.
Pros
|
Cons
|
- Acquisition
- Clear distinction between logic and presentation thanks
to ZPT and Python scripts
- Main language is Python, an excellent OOL
- ACLs
- Versioning (changes are not displayed until developers say
so)
- Easy access to content with through the web editing
- Access to RDBMS
- Choice between using ZServer (Zope's own web server) or
setting up Zope as a module to eg. Apache
- Plone is a very good CMS
(Content management system)
|
- Steep learning curve
- Development is quite different from regular Python or PHP
- Mostly Python-based, so performance could be an issue
- How resilient is Zope's HTTP server as compared to eg. Apache or AOLServer?
- Python scripts only allow a sub-set of capabilities : must use external
methods for other features
- In real life, data live in the ZODB, on the file system
(full-fledged Python scripts) and a DMBS
- ZODB being a single, binary file (data.fs)... what about stability and
data corruption?
- Search engine is barely usable
- Versioning not up to par with real source control software (what changed
between the two versions?)
- TTW editing (either text or image) not as good as full-fledged editor like UltraEdit.
Working through FTP is not as simple as editing files from a
file system (Update: You can use the Wing IDE for Python: "Using
Wing IDE with Zope", or Boa
Constructor)
- No dedicated client, so no easy WYSIWYG editing to add content
besides using the DHTML widget (IE only) and no support for disconnected
mode
- Much fewer developers than eg. PHP or Python in non-Zope environments
|
... over PHP + MySQL + templating engine?
After playing with PHP and frameworks (templating engines like UltraTemplate,
or the mini-ZOPE PHITE)... I finally understood the beauty of ZODB and in-context
acquisition:
- Templating engines like UltraTemplate are nice but... without acquisition,
all objects must be located in the local folder, or you must add relative
or absolute links. Besides being a pain, what happens if you move this folder
or the items it references?
- PHITE is a great introduction to Zope, because you'll soon see why locating
items in something like ZODB is a Good Idea(tm) : For instance, it's a pain
to have to add a prefix ("signature") and a number ("sort")
to all sub-directory names. Besides PHITE currently doesn't look deeper
than two levels for sub-directories
- imagine having only a single index.html (index_html) to handle access
to every sub-folder simply by locating this object in the root folder
- in-context acquisition : if, for instance, the single index.html contains
dynamic variables such as the familiar <dtml-var title_or_id>, their
content is replaced in the context of where the object was called (eg. if
a user ends up in http://www.acme.com/some/deep/sub/folder/), Zope will
search all the way back to the root folder, located index_html... but replace
variables in the context of that deep sub-folder
- since web documents are a mixture of heterogenous objects (HTML snippets,
images, Flash, etc.)... it makes more sense to save them in an object-oriented
database like ZODB than a relational
- Since ZODB is a single binary file, it's easy to back up : compact ZODB,
stop the server, copy the file swhere else, restart the server
- Content of ZODB can be viewed through a web browser : faster and easier
than a command-line interface
- Being objects, items in ZODB can have properties attached to them
- The default scripting language is Python, an excellent object-oriented
language
From: "Wankyu Choi"
- I don't consider myself an *ex*-PHP developer, but just wanted to share
my thoughts.
-
- I developed and still develop all those serious applications in PHP and
even wrote a couple of books on the language with Wrox. PHP has a lot to offer
in various aspects, and does have its own set of advantages over Python and
Zope.
-
- However, when it comes to that old theme of web developers, separating
presentation and logic, I cannot but admit that Zope beats PHP hands down (of
course, unless you DTMLify all of your Zope applications and gave them 'welcome-to-my-jungle'
looks^^) In a way, PHP encourages mixing presentation and logic. I feel for
that 'immediate convenience' for a number of occasions and came up with applications
that do all kinds of presentation and logic mix-ups.
-
- One good example is PHP NeoBoard vs. Zope NeoBoard. PHP NeoBoard
has been in heavy use since 1999. I stopped developing it in PHP once I realized
I could do it in less than two days in Zope. And I did. Ported (not even ported,
just borrowed concepts from) PHP NeoBoard to Zope in less than a few hours.
My jaw just dropped at that moment I saw a 'better' NeoBoard work after a few
hours of coding in Zope. It took me more than a few moths to get there in PHP.
Just compare the length of the code: Zope NeoBoard 1.1b has tons of more features
than PHP NB 3.0 does with far fewer lines of code.
-
- Guess it's not entirely fair to compare Zope and PHP in all aspects since
we should see Zope as a developing platform/application server not a language.
But as a web development platform, yes, I came to choose Zope over PHP.
All I developed for basic foundation on which to develop other applications
in PHP: Zope already got it. One good example: you don't have to seek a
template engine. Zope already has it. I have yet to find a better template engine
than ZPT. I still marvel at the elegance in its design. Just spend a couple
of hours with ZPT, you'll know what I mean.
-
- Another strong point of Zope is... It's based on Python: complete OOP
language. Rumor has it that even PHP5 wouldn't be 100% oop-ish. What's missing
in PHP in terms of object-orientedness, you get more than you need with Python
and Zope. Personally, I'd go for Python over even Java for OO-ness. Python simply
helps you (even forces you to) code in far cleaner and more extensible
way. In terms of OOP-ishness, two more points for Python and Zope.
-
- For the sake of fairness, however, Zope has a few drawbacks (and
ZPT for that matter).
-
- 1. 'THE' PHP community is hundreds of times bigger than that of
Zope. (Hundreds? Guess some Zopistas wouldn't agree.... that's sad but true.
For instance, in Korea, I can even count everyone that can do any serious stuff
in Zope with my two sets of fingers. PHP? Everywhere you look.) You'd know what
I mean by this. I had a real hard time figuring out how I go about doing the
same stuff in Zope as I did in PHP.
-
- Documentation/community support/etc, ammunitions that you desperately
need in this sometimes-very-very-cold opensource world, is far weaker than those
of PHP. (It might be a blessing in disguise since from the opposite
end, that means you'd be rarity with Zope expertise: huge demand and little
supply^^ To extend that Korean market anology, we have so many PHP developers
that we even hear 'PHP developer' jokes as American people do lawyer jokes;-)
-
- 2. It comes with its own object database, which is something really
new to PHP developers. I have yet to find a good and Zope-friendly way out of
it, as a matter of fact. I have tons and tons and tons of data that I'm still
wary of putting into ZODB. (Okay some Zopistas, here, would say, hey that'
not true! But yes it's true in my case. Suppose you have 100 giga bytes of data.
More than 50% of it should be dynamically loaded into and unloaded from memory.
All I got, as of now, is a single-file ZODB storage. Having a single 100-giga
byte file... I just can't take take. I do want a version-less file-based ZODB
storage, which, again, as of now, is non-existent. I'm looking towards Directory
storage, but it's still in beta. ZEO? Well, I don't have the hardware to go
with that option. I've been doing this; no problem with LAMP - Linux, Apache,
MySQL, PHP combo. But with Zope, it IS a problem now. What I really, desparately
want from ZOPE is a bit more leeway in selecting strorage options. Maybe...
ZOPE3/ZODB4 combo? )
-
- 3. Elegance (separating presentaton and logic: MVC model) sacrifices
performance: I found ZPT is way slower than DTML and mixed-up PHP code (but
you'd get into similar dilemma if you opt for any template engine in PHP since
that would take a whole lot more time to render, anyway.) I used to choose performance
over anything else, thus the mix-up of presentation and logic. I changed that
attitude. I got sick and tired of re-doing all the applications I developed
years ago, months ago, weeks ago, and even days ago: I can't immediately
figure out what I was doing in that block of code in PHP NeoBoard 3.0, for example.
I tried my own template engine with PHP NeoBoard 3.0, an attempt that miserably
failed. I did a message board, community club application, e-commercing application,
web-base mail application, etc: the works in PHP. I'm RE-doing them all in Zope.
Why? Thought it'd be better to redo them all from scratch than extending or
even modifying the mess.
-
- Zope and PHP are good tools in their own rights. One might be preferred
in some areas and the other in the others. Simply put, one can't beat the other
in all aspects.
- What comes on top of your priority list, that's what counts, IMHO.
Also read Switching
from PHP to Zope/Python by salimfadhley, and (French) Quel
choix, Zope ou LAMP (php3 et php4)? .
Architecture
Zope (Z Object Publishing Environment)
is an open-source alternative to UserLand,
ie. a web-based development environment. It is almost entirely written in Python,
and is used as an easy-to-use and powerful content management system. Content
is viewed through a regular Web client, and can be edited through XML-RPC, WebDAV,
or FTP, depending on what is available on the client host.
Zope comes with its
own web server, but it can also run applications and have those be called by
a remote web server through CGI. If your storage needs are not too important,
all objects can be saved in the Object Database (ZODB); Otherwise, Zope can
also outsource storage to an external DBMS server. Zope programs are written
in the DTML (Document Template Markup Language) scripting language, but can
also be written in other languages like Perl or Python, and can also include in-line HTML
content, just like PHP and other server-based languages. Contents can be handled
through a web interface. Zope also supports Undo to correct an error, and versioning
to keep different versions of a document. Zope keeps data, code, and layout
in one location.
A Zope applications is built from objects, of which there are three types:
Content, Logic, and Presentation. Objects are containted in Folders.
Support for disconnected mode is minimal: An object, eg. a Folder, can be
downloaded into the client host as an Export file, and imported into the user's
Zope server at home. Later, the user must export this object from his Zope server
into his laptop, Import this object into an empty folder on the Zope server
at work, delete the original folder, and move the new version in its place...
As for editing documents, users are expected to either type HTML text in
an edit box (which can be made easier by building documents in a WYSIWYG editor
like Namo WebEditor, or semi-WYSIWYG editor like Hippie98, and copy/pasting
the output into the edit box), or upload an HTML file into the right folder
in Zope. If the latter, only one file can be uploaded, which leaves the issue
of add-on files like images, style sheets, etc. By default, the FTP server that
comes with Zope is listening on port 8021. Zope supports versioning, but differences
between two versions of a document are displayed in HTML source, making it unusable
for longer documents.
Until clients catch up to the latest WebDAV standard and
understand the difference between the source of a document and its result, Zope
offers a special HTTP server you can enable with the -W command line option.
This server listens on a different port than your normal HTTP server and returns
different, special source content for WebDAV requests that come in on that port.
This is an advanced feature and is explained more in the Documentation Section
of Zope.org.
(From the Zope site)
Setup
Linux
Binary tarball
- Make a dir where you want Zope to live, and cd to it: mkdir /var/zope
; cd /var/zope
- untar the package there
- change the owner
of this directory to the user account under which Zope will run later (eg.
nobody:nobody): chown -R nobody.nobody /var/zope
- Switch to the ad hoc user: su - nobody ; cd /var/zope
- ./install -u nobody -g nobody
- Write down the manager login name and password
- ./start &
- netstat -tuplan, and check that a process is listening on port 8080
(It can take a minute until Zope is up and running, so be patient)
Source tarball
RPMs
As of Sept 8th, the RPMs available from Tau
Productions installed OK, but the server fails starting with "Startup
exception : error: (91, 'Protocol wrong type for socket')". In any case,
a standard RedHat 7.1 comes with Python, while Zope 2.4 needs Python2:
- rpm -Uvh python2-2.1.1-3.i386.rpm
- rpm -Uvh python2-devel-2.1.1-3.i386.rpm
- rpm -Uvh Zope-2.4.1-1.i386.rpm
- rpm -Uvh Zope-zserver-2.4.1-1.i386.rpm
NT
- Download and run the installer
- Run Drive:\Program Files\WebSite\start.bat
- Write down the admin login/password
Backing up Zope
Here's a backup procedure on Zope.org: http://mail.zope.org/pipermail/zodb-dev/2002-October/003418.html
Installing Zope products
"Products" are add-ons to enhance Zope. To install a new product,
copy its files under (Unix) /lib/python/Products or (NT) "c:\Program Files\WebSite\lib\python\..",
and restart Zope.
Removing Zope products
Head for the Control Panel | Products section, remove the products, and also
remove the ad hoc folders under $ZOPE/lib/python/Products (otherwise, they get
re-added the next time you run Zope)
Tips
Once you're done installing Zope, launch a web brower, aim at http://myzopesrv:8080/manage,
and log on as the admin account with the password given to you during install.
Important: If you are having problems with copy and paste, make sure that you have enabled
cookies in your browser. Zope uses cookies to keep track of the objects that
you cut and copy.
You can change the admin's password by running the zpasswd.py Python script.
To start the Zope HTTP server, run python z2.py. -z tells the script where
Zope is installed.
A startup script located in /etc/rc.d/init.d/ calls up other Zope scripts
and set required variables for z2.py
To export an object from a Zope server, and import it into another server:
- In the Zope Management Interface, select the object, and click on Export
- As explained, the file was saved in the sub-directory var/ as myobject.zexp
- On the target server, create a sub-directory import/ on the same level
as other main directories (eg. var/)
- Copy the myobject.zexp into import/
- In the ZMI, go to the location in the tree where you wish to import
the object, and click on Import/Export
- Fill the Import editbox with the exact file name without its pathname,
eg. simply myobject.zexp
To download the directory tree or part of it before uploading it to a remote
FTP site, you can use wget
with the following options:
- wget -k -l 0 -m -nH -np -r http://localhost:8080/mysite
Post-install customizing
Virtual servers
If you wish to host more than one site on a single server, whether it only
has one IP or has more than one address assigned to the network interface, you'll
need to set up virtual servers, ie. each site has its contents located in its
own sub-directory in ZODB.
The usual way is to install VHM (Virtual Host Monster; might already be part
of the Zope distribution if you downloaded a binary package), add the Apache
web server to act as front-end, and set up Apache and Zope so that requests
go through Apache and are redirected to Zope. The added bonus of using Apache
as a front-end are security, load, and manageability (Toby Dickenson says
: "A lot of problems go away if using Apache Squid or Pound").
Some deeper information on Virtual Host Monsters can be found here.
Please note that "SiteRoots", which also can be used to create virtual
roots in Zope are deprecated. Don't use them unless you really know why you
need them.
VHM redirects calls to a given folder,and, if you're not using a front-end
web server like Apache, can also handle the task of rewriting the URL. It will
only do this even the URL contains keywords like VirtualHostBase and/or VirtualHostRoot.
For instance "/VirtualHostBase/http/www.site-b.com" rewrites the URL
to "http://www.site-b.com"; Note
that if Zope is running on port 8080, the URL will keep this port number, ie.
the URL will be rewritten to "http://www.site-b.com:8080";
If you wish to use a different port, you must include it, ie. use "/VirtualHostBase/http/www.site-b.com:80".
If you include the keyword VirtualHostRoot somewhere in the URL, any part
before this keyword is removed, and Zope starts afresh. For instance, "/a/b/c/VirtualHostRoot/d"
will be reinterpreted as "/d", just like if folder "d" was
located at the root.
Needless to say, users don't need to know this, since VHM rewrites those
URLs dynamically when a request for a virtual site comes in.
Imagine Zope is installed at www.site-a.com, and you wish to add a second
site, www.site-b.com on this host:
- Go to the root folder, and add a Virtual Host Monster (VHM) object by
clicking on "Select type to add...". Any ID will do, eg. vhm
- In the root folder, create a folder that will host the document tree
for the virtual site, eg. /site-b
- Go into this folder, and create a DTML Method, with id = index_html
- In the root folder, select the VHM object, and click on its Mappings
tab
- Add the following : www.site-b.com/site-b
- Hit http://www.site-b.com : Zope
will happily serve /site-b/index_html . You're in business :-)
More information
Performance
To increase performance, run Zope as a proxy module through Apache instead
of CGI. Use ZEO to build clusters.
From: "Thomas B. Passin"
Subject: Re: [Zope] Re: Speeding up Zope startup
[Christopher Quinn]
No experience to speak of, but just having read the python tutorial, I see mention of its ability to write out .pyc files alongside the .py, and this compiled bytecode form yields faster startup times. If zope was installed for multi-users, the ownership probably does not allow for such files to be written, although this does not trouble python. So perhaps arranging for all .py files in the zope installation to be pre-compiled?
[Tom P]
It is not that. Python creates the .pyc files when they are non-existent or out of date, so after the first time Zope is run, the .pyc files will be exist. There was a thread awhile ago about this, and as I recall, people with very large database files - data.fs - had very slow startup times. So clean up and pack your database.
Search the archives to see if you can find that thread.
Hmm, you might want to check whether everything is okay with your data.fs. If something is wrong, Zope rebuilds some stuff. Recompile all your scripts, pack the database, see if that helps. I had a similar thing at one time and the only thing that seemed to help was starting over with a clean zope install and importing my old site.
From: Stephan =?ISO-8859-1?Q?G=F6ldi?= <goeldi@goeldi.com>
Am Fre, 2002-07-26 um 08.15 schrieb EvH:
> Is anyone else running Zope on a Windows workstation (P3) and witnessing a good 30-s delay until Zope is up and running? BTW, I installed Zope on one of my brother's PCs (a P2), and it's close to a minute...
It is not of interest, if it is a P2 or a P3. How many MHz? How many RAM? I have Zope running on a P166 with 64MB RAM for demonstration only (sic!) It starts the server in about 30 - 45 seconds. On our product servers (www.zopehosting.ch) restarting Zope takes about 5 seconds (Redhat, not micros~1.oft).We are speaking here of the starting of a server environment, not of micros~1.oft Word (which takes about the same time). So what is your problem?
From: "Barry Berenberg" <berenberg@higher-speed.net>
I'm running Zope 2.5.1 under Windows 2000 on a P3-500 machine. I start it manually as a service. The service seems to start quickly (it says it's started after 5 seconds or so), but it's another 30 seconds or so until I can access the server. I've watched the task manager while it's starting
up, and it's the python.exe process that is using up CPU time during the wait.I just assumed 30 seconds was the normal startup time. On a 667 MHz G4 Powerbook (OSX 10.1.5), the Zope server takes 20-25 seconds to start.
ZOPE as a desktop CMS
Since it's pretty common for individuals to have some spare hard-disk on
a mutualized server over at their ISP, but no way to install any software, we
can run ZOPE on the desktop, generate a static snapshot of a site, and upload
this output to the web server through FTP.
At this point, there are two venues:
- Using the JavaScript-based Epoz WYSIWYG widget for TTW (through-the-web,
ie. browser-based) editing, but, as of Dec 2003, you are restricted to Internet
Explorer or Mozilla (besides, browsers being so unstable, I hate not being
able to hit CTRL-S when writing an article, just in case the app GPFs)
- Use a dedicated app that can access Zope objects through the XMLRPC
procotol. wBloggar can connect to a bunch of blogging servers, so it might
not be that big a deal to write such app
Epoz
Epoz is a WYSIWYG editing widget
written in JavaScript, and (Dec 2003) is currently available
in two versions: 0.x is the original work of Maik
Jablonski and is still under development because dumping this code
base would break some apps, and the newer 1.x which is being rewritten by Guido
Wesdorp and friends. More infos at http://codespeak.net/issues/epoz
.
Here's how to install this widget:
- Go to Zope's Products sub-folder (C:\Program Files\zope\lib\python\Products\), untar
FileSystemSite,
followed by Epoz. Restart Zope
- At the root of a folder, add a "Epoz editor" object, and
give it an id (eg. "epoz"). This will create a folder with several
objects, such as JavaScript, etc. "Typically you want to use the editor
macro in your own Page Template. First, create an 'epoz editor' object at
the top of your folder hierarchy and give it an id, e.g. 'epoz'. Then, create
a page template and make use of the macros and slots documented in API.txt
using 'here/epoz/epozmacros/macros' as TALES path prefix (if you have named
the editor object 'epoz')."
Latest news (April 2004): "As of now, the in-browser WYSIWYG editor
formerly known as epozNG has a new name: Kupu!
Even though it was never the intention, the Epoz WYSIWYG editor development
had split in 2 branches, confusing both developers and users. Hopefully the
new name settles this confusion."
IEDocument
External Document
OODocument
CMF or Plone + OpenOffice
XMLRPC clients
How to set up and test
xmlrpc in Zope
XMLRPC File into ZOPE
Make XMLRPC Calls From
ZOPE
Creating XML Applications
With Zope
Internet Scripting:
Zope and XML-RPC
xmlrpc utility for Windows
A
Zope 3 story - augmenting other components
XML-RPC
HOWTO
Using Zope
as an XML-RPC Server
Advanced XML
Applications in Zope
Writing applications
DTML is the older templating format provided by Zope. A newer, prefered alternative
is ZPT (Zope Pages Templates.) ZPT consists of TAL (Template Attribute Language),
METAL (Macro Expansion Template Attribute Language), and TALES (Template Attribute
Language Expression Syntax.)
Advices given on the Zope mailing list is to read the following material:
Writing business apps with Zope
From: Paul Winkler <pw_lists@slinkp.com>
On Mon, Dec 09, 2002 at 09:50:22PM +0100, Frederic Faure wrote:
I'm back to playing with Zope, except this time I need it as a tool
to rewrite business apps (payroll, in this case.) I've read the New Riders
book along wit the online Zope Book. I understand that DTML is evil
and that new users should prefer ZPT.
I wouldn't say that DTML is evil... simple DTML is very nice, it's just that *abuse* of DTML is evil and it's always tempting
to add just "one more thing" instead of breaking it out into a script. And you can abuse ZPT pretty easily, too...
tal:define and tal:condition and tal:repeat give you plenty of rope. It's somewhat more explicit rope than some of the magic DTML stuff, and there's a lot less of it; but you can still hang yourself with it. :)
Anyway, is there a good document for newbies that come from procedural
languages like VB that would show them how to get up to speed?
The "Advanced Scripting" chapter in the online Zope book is a decent
introduction to this kind of thing, although it's a lot more nuts-and-bolts than best-practices. I said *introduction*...
it has little examples of forms that are processed by scripts that can call other scripts, etc.
Since you say "procedural languages", I suspect what you really need is to read this:
http://www.zope.org/Members/mcdonc/HowTos/gainenlightenment
Again, it isn't exactly what you asked for - it's heavy on rah-rah and contains no real "how do I..." stuff. But it will
get you in the right mind-frame.
I need to understand how to separate logic and presentation as cleanly as possible.
Object orientation will help you here. Remember what the Extreme Programming guys say: "Refactor mercilessly". When you see some logic in your presentation templates,
ask yourself, "What is the maximum amount of this logic that I can break out into a separate script?
what is the absolute minimal amount of logic that I can have in this template and still get the job done?"
For example, look at the code in a tal:condition="..." statement. Do you have to do a bunch of tal:defines
just to set up the condition? Do you have nested tal:conditions? Can you put all that stuff in one python script and in this template just have tal:condition="here/myscript"?
These are the kind of low-level questions you can ask yourself.
As far as architecture of your app... big topic. TOO big. "It depends."
From: Dylan Reinhardt <zope@dylanreinhardt.com>
I've written several business apps in Zope and would suggest one best practice right off the bat: acquire more experience with your tools.
Not to be discouraging, but you'll need more than passing familiarity with
your development environment before you take on programming any reasonably
important business system. Yes, payroll software can be done in Zope. Yes, it's even a good idea. But I would encourage you not
to make a payroll system your first major project... in *any* language or environment. Particularly not if you're operating under any kind of
deadline or expectation of useful results.
As for frameworks, Zope *is* a framework and a very powerful one at that. Virtually anything Zope doesn't already do can be done with Python
products.
Read a good book on programming with Python (O'Reilly's Learning Python 2nd
Ed. is my recommendation). Then read the Zope Developer's Guide (http://www.zope.org/Documentation/ZDG) at least three times. Develop
a product that exposes a basic interface and can return functional administration screens using either ZPT or DTML. Give yourself at least
a month or two to do all this.
At the point where you're weighing issues more technically nuanced than whether DTML is evil (it isn't), I think you'll probably find a lot of help
available for any ambitious projects you may be ready to take on.
From The Zope Book
- ZOPE means Z Object Publishing Environment
- Change the initial user's password by running zpasswd.py, and restarting
Zope
- Create new users by clicking on the acl_users folder in the Navigator (tree
on the left). User folders are always called acl_users
- To add users to a new folder, go to this folder, click on the product
add list (the combo box in the upper right-hand corner that says "Select
type to add..."), and select "User Folder"
- To create a new folder, select the Root node in the Navigator, and select
Folder in the "Select Type to Add..." combo. The ID field is actually
the URL for the folder.
- Make sure that you enabled cookies in your browser, as Zope uses them
to handle copy/pasting of objects. Enabling JavaScript is also recommended
- Any action can be undone through the Undo tab
- Various aspects of Zope can be set through the Control Panel object.
Once you have packed the database, actions that occurred until then can
no longer be undone
- To shutdown Zope, select the Control_Panel folder, and click on... Shutdown
- The database is located in Drive:\Program Files\WebSite\var\Data.fs
- Folders contain objects. Generally, Zope objects belong to one of three roles: Content (eg. HTML
file), Logic (scripts), Presentation (templates, built using Zope's DTML
markup language). Presentation logic is coded in DTML, and business logic
is coded in either Python or Perl. Both live as objects in the database.
Code used to be written in DTML Methods, but newer development is done in
Python or Perl scripts
- Content can be either access through a web browser or called by another
object, eg. <dtml-var standard_html_header>
- If your document contains mostly content and little code, use a DTML
Document object. If it contains mostly code, use a DTML Method. If it's
complex code, use a Python or Perl script object
- Two kinds of methods can be called by a script: DTML Methods (presentation
methods) and SQL Methods (database queries)
- Objects can be exported to another Zope system. To import an object,
put the file in the import/ sub-directory in the root directory, creating
it if necessary. By default, export files have the .zexp extension, and
are save in var/ (eg. c:\Program Files\WebSite\var\) . Files can
be exported either in binary format (default) or XML
- A new type of object called Page Templates were introduced in Zope 2.5:
They're HTML templates to create dynamic presentations. Templates can be
either created in Zope or imported from an external file
- One of the several types of documents that Zope can hold is the DTML
Document (Document Template Markup Language), which is typically used for
dynamically-rendered pages such as sidebars
- Third-party object types are usually called Products
- Documents can be uploaded to a Zope server through FTP, WebDAV, or the
HTTP PUT method. By default, Zope offers FTP access through port 8021. If
ran with the -W option, Zope listens to a port that is different from the
usual HTTP ports so that users can edit the actual source of a document
instead of its output
- Zope also supports random, binary files with the Files object type
- To add a link to an image, take advantage of "<dtml-var mypic.jpg>"
which will generate the <img src="mypic.jpg"> line dynamically.
Another possibility is to create an Image object, and refer it to it through
its ID, eg. <img src="logo"> or even <dtml-var logo>
- When uploading a picture, make sure you choose Image instead of File,
or your browser will display binary data instead of the actual picture
- Versions: To make changes on the content of the Zope server, you can
create a Version object, and any change made is kept private until you decide
to make them public. A Version object is essentially a list of changes to
be activated or discarded.
- To speed up rendering of complex pages, you can add either a Cache Manager
(internal to your Zope server), or an HTTP Accelerated Cache Manager (external
cache server, eg. Squid)
- All items in Zope are actually objects, ie. they contain both data and
methods. For instance, a Folder object offers an objectValue() method that
returns the objects that it contains
- An object can have multiple properties attached to it
- Starting with release 2.3, and in addition to DTML Method objects, Zope comes with two script objects to write
scripts in Perl or Python as part of the business logic of a site. DTML
Methods are mostly used as presentation templates. Script objects are to
be preferred to DTML Method objects to write more complex scripts.
- Here's an example of a DTML Method object called objectList:
-
- <ul>
- <dtml-in objectValues>
- <li><dtml-var
getId></li>
- </dtml-in>
- </ul>
- Another exemple of embedded tags in DTML Documents is <dtml-var id>
, which displays the document's Title section
- The different between a DTML Document and a DTML Method is a matter
of how much content and logic they include
- In addition to Script and DTML Method objects, you can use SQL Method
objects to create SQL queries
- All folders implement the objectValues() method which is part of an
interface common to all folders called ObjectManager
- Methods are accessible by any object in or below the level where there
are located, eg. if the objectList DTML Method above is located in the root
folder, the objectList() method can be called by any object in the entire
tree
- Session data are handled through Browser ID Manager, Transient Object
Container, and Session Data Manager
- Object versioning, eg. letting more than one user edit a document at
the same time, is handled with Version objects, which can also be used to
work on a new site layout without making it available until it's ready for
showtime. While in Version mode, any change made to Zope is kept for later
publishing; The way it works is that any object that you edit while in Version
mode is tagged with a special field that tells Zope to keep this change
private, so for instance, any object that you add to Zope while in Version
mode is kept invisible to other users. Changes are applied by switching
to Version mode, and clicking on the Save/Discard tab, followed by a click
on the Save button
- The Id of the default document must be a DTML Method object named index_html
(not index.html)
- ZCatalog: what is it for?
- Performance can be improved two objects: HTTP Accelerated Cache Manager
and (RAM) Cache Manager
- Virtual hosting is achieved through SiteRoot, SetAccessRule, and VirtualHostMonster
objects
- E-mails can be sent through a MailHost object
- Pages templates are similar to DTML documents, ie. they contain both
HTLM and code, but are cleaner than DTML documents (valid HTML so can be
worked on in HTML editors, cleaner separation of code and presentation);
Page Templates use the Template Attribute Language (TAL), eg. <title
tal:content="here/title">Page Title</title>; All TAL
statements consist of tag attributes whose name starts with tal: and all
TAL statements have values associated with them. The value of a TAL statement
is shown inside quotes; clicking on the Test tab means that Zope will render
the page, ie. interpret the embedded TAL statements, while clicking on the
"Browser HTML Source" will display the page as-is
- Starting with Zope 2.5, Pages Templates are to be prefered over DTML
- Besides "template/title", other examples of path expressions
are "request/URL" (URL of the current web request), "user/getUserName"
(authenticated user's login name), "container/objectIds" (list
of Ids of the objects in the same Folder as the template), etc. ; path expressions
always start with a variable name, and sub-properties are accessible through
an extra "/"
- For text to be dynamically replaced, you must use either a <b tal:replace="...">...</b>
or a <span tal:replace="...">...</span> sequence.
- If <title tal:replace="template/title"> = "http://localhost:8080/test/simple_page".
When using <title tal:content="template/title"> = "A
Simple Page"
- To display a list of objects in the current folder:
<tr tal:repeat="item
container/objectValues">
<td tal:content="repeat/item/number">#</td>
<td
tal:content="item/getId">Id</td>
<td tal:content="item/meta_type">Meta.Type</td>
<td
tal:content="item/title">Title</td>
</tr>
- You can leave empty information with a tal:condition tag:
<table
tal:condition="container/objectValues"
border="1"
width="100%">
<tr tal:repeat="item container/objectValues">
<td
tal:content="repeat/item/number">#</td>
<td tal:content="item/getId">Id</td>
<td
tal:content="item/meta_type">Meta-Type</td>
<td
tal:content="item/title">Title</td>
</tr>
</table>
- Cookies can read with <p tal:condition="request/cookies/verbose
| nothing">
- The icon that corresponds to an object type can be displayed with <img
src="/misc_/OFSP/Folder_icon.gif" tal:attributes="src item/icon">
- A list of objects of a given type located in the current folder can
be displayed with a Python script: return container.objectValues('File')
- You can work on Page Templates without leaving your editor through the
HTTP PUT method, FTP, or WebDAV
- You can view the raw source code of a Page Template by adding /source.html
or /source.xml to its URL, eg. http://localhost:8080/test/index_html/source.html
- In addition to HTML, Page Templates can be formated in XML:
<guestbook
xmlns:tal="http://xml.zope.org/namespaces/tal">
<entry
tal:repeat="entry python:here.objectValues('DTML Document')">
<comments
tal:content="entry/document_src">Comment goes here...</comments>
</entry>
</guestbook>
- For contents, File objects can only contain text that is less than 64K.
For richer objects, check out the Content Management Framework (CMF)
- Note: "index_htm" is a keyword used by Zope to provide a default
view of a folder
- Warning: When copy/pasting code from the Zope Book into Opera, the "-"
sign in DTML tags are replaced with ".", eg. <dtml-var standard_html_header>
becomes <dtml.var standard_html_header>
- "Acquisition" is Zope-speak for when Zope will look up the
hierarchy for an object if it cannot be found within the current folder,
eg. if you have no standard_html_header in the current folder, it will keep
looking in folders located above itself until it finds the ony in the Root
folder. Conversely, sub-folders will use a index_html object from upper-level
folders if none can be found in the sub-level
- To use CSS, just create a DTML Document that contains CSS infos, and
add a link to it in the standard-header document through <dtml-var my_style_sheet>
- To add a Files section to let users upload files along with a title
and description, add an index_html DTML Method with the following:
<dtml-var
standard_html_header>
<h1>File Library</h1>
<table
width=100% border=1>
<tr>
<th><a href="&dtml-URL0;?sort=name">File</a></th>
<th><a
href="&dtml-URL0;?sort=date">Last Modified</a></th>
</tr>
<dtml-if
expr="_.has_key('sort') and sort=='date'">
<dtml-in expr="objectValues('File')"
sort="bobobase_modification_time" reverse>
<tr>
<td><a
href="&dtml-absolute_url;"><dtml-var title_or_id></a></td>
<td><dtml-var
bobobase_modification_time fmt="aCommon"><td>
</tr>
</dtml-in>
<dtml-else>
<dtml-in
expr="objectValues('File')" sort="id">
<tr>
<td><a
href="&dtml-absolute_url;"><dtml-var title_or_id></a></td>
<td><dtml-var
bobobase_modification_time fmt="aCommon"><td>
</tr>
</dtml-in>
</dtml-if>
</table>
<dtml-var
standard_html_footer>
... and add File objects along with a "description"
string item in the Properties section for each file
- When creating an index_html DTML Document/Method that builds a
framed-page, you must include a HEAD section, or Zope will complain:
<HEAD>
<TITLE>Fred's
Xcellent Web Site</TITLE>
</HEAD>
<FRAMESET
framespacing="0" border="0" frameborder="0"
COLS="15%,*">
<FRAME
SRC="framecol.html" NAME="framecol" scrolling="auto">
<FRAME
SRC="framemain.html" NAME="framemain">
<noframes>
<p> </p>
</noframes>
</FRAMESET>
- Generally speaking, Zope seems picky about HTML formatting, so if things
don't work as planned, make sure you have HTML, HEAD, and BODY sections
- Make sure you understand the difference between <dtml-var "title">
and <dtml-var title>: The former runs a Python script (an alternative
is <dtml-var expr="title">); the latter looks for a document's
property called "title"
- Python modules can be accessed through _.<module>.<method>
- Note that a DTML Method object can have no property except Title and
ID
- Structured documents are written as regular DTML Document objects but
with some special formatting that allows a DTML Method to convert its content
into HTML on the fly. For since, create an index_html DTML Method object
to include the following instruction: <dtml-var Document fmt="structured-text">.
Next, create a DTML Document object with the following text:
Hello
This
is my *first* document. It includes:
* titles
* paragraphs
Finally,
call index_html, and watch Zope turn Document from structured text into
HTML
-
DTML Tags
- <dtml-var title_or_id>: Displays content of the Title property
of the container (NOT the document itself!)
- <dtml-var id>: Displays content of the Title property
- <dtml-var ZopeAttributionButton>: Displays the "Powered by
Zope" icon
- <dtml-var user_name missing="Anonymous User">: Uses
alternative content if a variable cannot be found by Zope
- <dtml-var expr="getName('this is a parameter')">: To
call a Method with a parameter
- <dtml-var expr="objectValues()">: To call a Python method,
remember to use parentheses
- Var tag attributes: html_quote (so HTML-specific characters are escaped),
missing, fmt (to format output, eg. <dtml-var adult_rate fmt=dollars-and-cents>
- &dtml-cockatiel is short for <dtml-var name="cockatiel"
html_quote>
- To test for the existence of a variable <dtml-if monkey_house>
<p>There <em>is</em> a monkey house Mom!</p> </dtml-if>
- To test for the value of a variable: <dtml-if expr="monkeys
> monkey_limit"> <p>There are too many monkeys!</p><dtml-else><p>The
monkeys are happy!</p></dtml-if>
- <dtml-if expr="monkeys > monkey_limit"> <p>There
are too many monkeys!</p> <dtml-elif expr="monkeys
< minimum_monkeys"><p>There aren't enough monkeys!</p><dtml-else><p>There
are just enough monkeys.</p></dtml-if>
- <dtml-if expr="name != 'neo'">
- To iterate through a list of items: <dtml-in todo_list><p><dtml-var
description></p></dtml-in>
- A generic way to iterate through items located in the current folder
(Note: The ObjectManager class is a class that contains other Zope objects;
it provides methods that allow you to find out about the objects it "manages".
The ObjectManager includes methods such as objectIds(), objectItems(), or
objectValues() ):
<ul>
<dtml-in expr="objectIds()">
<li><dtml-var
sequence-item></li>
</dtml-in>
</ul>
- To iterate through a list of specific objects in the current folder:
<ul><dtml-in expr="objectValues('DTML Document')"><li><a
href="&dtml-absolute_url;"><dtml-var title_or_id></a></li></dtml-in></ul>
- <dtml-if sequence-even>: To test if the current iteration is even
or odd
- <dtml-if sequence-item>: Current item in the iteration
- <dtml-if sequence-index>: Current number, starting from 0, of
iterations completed so far
- <dtml-if sequence-number>: Current number, starting from 1, of
iterations completed so far
- <dtml-if sequence-start>: True for the very first iteration
- <dtml-if sequence-end>: True for the very last iteration
- To display a list of items in the current folder:
<table cellpadding="5"
cellspacing="0" border="0">
<tr bgcolor="#CFCFCF">
<td><b>Type</b></td>
<td><b>Name</b></td>
<td><b>Size</b></td>
<td><b>Last
Modified</b></td>
</tr>
<dtml-in expr="objectValues()"
sort="id" >
<dtml-if sequence-even>
<tr bgcolor="#DCDCDC">
<dtml-else>
<tr>
</dtml-if>
<td><img
src="<dtml-var sequence-var-icon>" border="0"></td>
<td><ahref="&dtml-absolute_url;"><dtml-var
sequence-var-id></td>
<td><dtml-var sequence-var-get_size>
bytes</td>
<td><dtml-var sequence-var-bobobase_modification_time></td>
</tr>
</dtml-in>
</table>
- To display a Home link which will be hidden when the user hits a page
in the root folder, add the following to the standard-header section :
<dtml-if
expr="_.len(PARENTS) > 2">
<a href="..">Return
to parent</a><br>
</dtml-if>
- <dtml-var expr="2 + 2">
- <dtml-var expr="PARENTS[0].title_or_id()">: Displays
the title or id of the document's parent (PARENT is actually a table that
contains all the parents of an object)
- Formatting output: <dtml-var expr="123" fmt="%04d">
- Other attributes that can be used when displaying a variable: missing,
size, lower/upper/capitalize, html_quote (in case the variable includes
HTML-unfriendly characters that need to be converted such as <BR>),
etc. Example: <dtml-var title_or_id upper>
- To call a method that returns no HTML output, use eg. <dtml-call
expr="mymethod()">
- If a method returns a value instead of HTML, use eg.
<dtml-if
CONDITION>
<dtml-return "'YES'">
<dtml-else>
<dtml-return
"'NO'">
</dtml-if>
- If a DTML Document object "articles" has a property of type
"lines", its content can be displayed like this:
<dtml-in
articles>
<dtml-var sequence-item>
</dtml-in>
- If you need to only display specific items located in a "lines"
property: <dtml-in "['Balloon', 'Doll']"><dtml-var sequence-item><BR></dtml-in>
- If a list is saved in a "text" property, using a carriage
return between each line: <dtml-in _".string.split(articles, '\n')"><dtml-var
sequence-item><BR></dtml-in>
- In case a list is actually empty, make sure you test this to avoid having
Zope display an error:
<dtml-in "[]">
<dtml-var
sequence-item><BR>
<dtml-else>
<I>No
item</I>
</dtml-in>
- To display a list of objects contained in a folder called "myfolder":
<dtml-in "myfolder.objectIds()"><dtml-var sequence-item><BR></dtml-in>
- To restrict listing to specific objects: <dtml-in "myfolder.objectIds()">
- To display the Title property and their ID along with the actuel content
of objects: <dtml-in "myfolder.objectValues(['DTML Document'])"><dtml-var
title> <dtml-var id><BR><dtml-var sequence-item></dtml-in>
- Displaying objects in a table:
<dtml-in "myfolder.objectValue(['DTML
Document])">
<dtml-if sequence-start>
<TABLE>
</dtml-if>
<TR><TD><dtml-var
title</TD></TR>
<dtml-if sequence-stop>
</TABLE>
</dtml-if>
</dtml-in>
- To display a list of tuples, with key and value: <dtml-in "{'Key1':'Item1'}.items()"><dtml-var
sequence-item> <dtml-var sequence-key> </dtml-in>
- Another way to display ID + title: <dtml-in "myfolder.objectItems(['DTML
Document'])"><dtml-var sequence-key> <dtml-var sequence-item>
</dtml-in> Note: you could simply use <dtml-var id> instead
of <dtml-var sequence-key>
- To sort items: <dtml-in "{'Key1':'Item1'}.items()" sort=sequence-key>
- To tell Zope the number of items to display and from which index to
start: <dtml-in "myfolder.objectItems('[DTML Document]')" size="3"
start="2">, where Zope will display three items starting with
index 2. If only size="3" is given, Zope will display the first
three items
- To add "Previous" and "Next" buttons:
<dtml-in
"dummy.objectItems(['DTML Document'])" size="3" next
start="BEGINNING">
<FORM ACTION="<dtml-var
URL>">
<INPUT TYPE="HIDDEN" NAME="DEBUT"
VALUE="<dtml-var next-sequence-start-index>">
<INPUT
TYPE="SUBMIT" VALUE="Next">
</FORM>
</dtml-in>
<dtml-in
"dummy.objectItems(['DTML Document'])" size="3" previous
start="BEGINNING">
<FORM ACTION="<dtml-var
URL>">
<INPUT TYPE="HIDDEN" NAME="DEBUT"
VALUE="<dtml-var previous-sequence-start-index>">
<INPUT
TYPE="SUBMIT" VALUE="Previous">
</FORM>
</dtml-in>
<dtml-in
"dummy.objectItems(['DTML Document'])" size="3" start="BEGINNING">
<dtml-var
sequence-item>
</dtml-in>
- Here's how to build a folder tree and links to collapse/expand all branches:
<dtml-tree
branches="objectValues">
<img src="<dtml-var
icon>"> <dtml-var id>
</dtml-tree>
<a
href="<dtml-var URL>?expand_all=1">Expand All</a>
<a
href="<dtml-var URL>?collapse_all=1">Collapse All</a>
Windows client
Some projects are currently under way to offer a Windows dedicated client
as an alternative to Web-based access: Zope
Fat Client, gnope (GNOME Zope client),
and an example Python client from Amos ??.
The latter requires (obviously) Python,
the tarball of the client, the wxPython toolkit,
and the xmlrpclib module. More infos @ http://www.xml.com/lpt/a/2000/01/xmlrpc/index.html
. Python 2.x ships with Zope (eg. Drive:\Program Files\WebSite\bin\), but even
this path to the PATH variable didn't help: wxPython complained that no Python
2.1 was installed; Installing Python-2.2b1.exe didn't help either because wxPython
really wants Python 2.1.
Installing
the xmlrpclib modules is done by copying the .py files the archives contains
into Drive:\Program Files\WebSite\bin\lib\ . Once you're done,
just untar the archive of the client, open a DOS box, and run "python ZopeClient.py".
Squishdot
Once you have Zope installed, a quick and easy way to set up a news and discussion
portal ("weblog") is to install Squishdot:
- Untar the Squishdot tarball into its own sub-directory under /var/zope/lib/python/Products/
(Unix), or Drive:\Program Files\WebSite\lib\python\Products\ (NT)
- Restart Zope
- Aim your browser to http://localhost:8080/manage
- In the "Select type to add..." combobox, select SquishDot
Site
- Give it an ID (this will be part of the URL, eg. http://localhost:8080/mysquish/),
and a Title. Click on Add
- Connect to http://localhost:8080/mysquish/. To post a new article, click
on the Post Article link in the upper left-hand corner.
- To make changes to your Squishdot site, go back to its main page, and
click on the Admin link in the left-hand corner (or aim at http://localhost:8080/weblog/manage).
This brings you into the Zope administration screen. The interesting tabs
in the navigation bar (upper part of the screen) are Postings, Options,
and Properties
Programming Tips
Editing code from UltraEdit
- File | FTP | Open from FTP
- Create an account, eg. domain=localhost, name=root, password=test, FTP
Port=8021. Optionaly, you can fill the Initial Directory setting to be pointed
to a specific folder in ZODB once you're connected
- Click on Close to save this new account
- Back in the main dialog, click on Open to list the content of ZODB
- Double-click on a file to edit it. To avoid being prompted by UE whether
to convert from UNIX to DOS format, there is a setting in UE that tells
it to perform this conversion automatically: Advanced | Configuration |
General : "Auto convert Unix files"
Alternatively, you can set up Windows to map a drive letter
to point to an FTP server: Right-click on the desktop, New, Shortcut, ftp://root:test@localhost:8021/
To access APIs in Python
_.module.method, where "module" is string, math, random, whrandom.
Variables can be accessed through _.attribute, where "attribute" can
be things like chr(x), eg. <dtml-var expr="_.chr(65)">
To display a list of folders
Create a DTML Method object and add the following code to have Zope create
a list of folders in the current folder, each item appearing as a URL:
- <dtml-in "PARENTS[0].objectIds('Folder')">
- <a href="<dtml-var sequence-item url_quote>">&dtml-sequence-item;</a><br>
- </dtml-in>
To display a list of folders and their content
Method 1
Documents themselves must be of type DTML Document since that's what we're
looking for. So far, I haven't found a way to sort the H2 sections, don't
know why they appear in such and such order, and can't handle a tree with a
depth superior to 1 (ie. sub-folders in folders)
- <dtml-in expr="objectValues('Folder')" sort=sequence-item>
- <dtml-if sequence-item>
- <H2><dtml-var title_or_id></H2>
- <ul>
- <dtml-in "_['sequence-item'].objectValues('DTML Document')">
- <li><a href="&dtml-absolute_url;"><dtml-var
title_or_id></a></li>
- </dtml-in>
- </ul>
- </dtml-if>
- </dtml-in>
You can learn more about the ObjectManage class and its method objectValues
at http://www.zope.org/Documentation/ZopeBook/AppendixB.stx
???? I should've also said.. take care to make sure that all the objects in
which you might acquire standard_html_header have a document_title
method.. ??? you might also use:
<dtml-if
document_title>&dtml-document_title;<dtml-else>&dtml-title;</dtml-if>
or somesuch.
Yes. Do it the other way around. Instead of including things from the documents, make a template, and
include the content from it.
Make a DTML Method or a ZPT called index_html and put it in the root.
From that include the content (in dtml with a <dtml-var content>) and then
putall the content into dtml-methods called "content". Put one method in
each folder making each folder a document. This also makes it easier to create automatic navigation.
ps. For $850 you can skip all this fiddling, and use Easy Publisher
instead. You'll get templating and automatic navigation, news services and
more. ds
Check the documentation of the ObjectManager (methods: objectIds() or objectValues()). They are described in Appendix
B of the Zope Book.
Maybe you would prefer to leverage acquisition. You'd create a universal
DTML Method called "list_documents" in your root folder. This method simply
lists documents in the current folder. And then you would place the following
code in each folder:
<dtml-var standard_html_header>
<dtml-var list_documents>
<dtml-var standard_html_footer>
How to add a Home link when the home folder is not the Root folder?
Eg. http://localhost/dummy-root/
? Using <a href="/">Home</a> or <a href="..">Home</a>
are not good solutions.
How to display a document's Title and ID through a default standard_header
section?
Here's the standard_header section that I use:
<html><head><title><dtml-var
title></title><dtml-var style_sheet></head>
<body>
<table
border="0" width="100%">
<tr>
<td
width="70%"><h1><dtml-var document_title></h1></td>
<td><dtml-if
expr="_.len(PARENTS) > 2"><a href="..">Return
to parent</a></dtml-if></td>
<td
align="right"><img src="<dtml-var id>.png"></td>
</tr>
</table>
When adding this into the default index_html DTML Method object, I'd like
the above banner to display the document's Title and a picture whose filename
is eg. index_html.png.
Problem is, using <dtml-var document_title> displays "Standard
Html Header", while <dtml-var title> displays the title of the container
(eg. a sub-folder located under Root) instead of the document's own Title!
Solution: Use a DTML Document instead of a DTML Method... but doing so will
break some things such as <dtml-in expr="objectValues('Folder')">
sections... Catch22.
To display an icon for an article
... either an icon that matches the name of the article (eg. mydoc.html.png),
or a default icon if none exists for the article:
- <dtml-try>
- <dtml-let imageObject="_[getId()+'.png']">
- <img src="<dtml-var getId>.png" border=0>
- </dtml-let>
- <dtml-except>
- <img src="default_icon.png" border=0>
- </dtml-try>
Thanks to Adrian Hungate from the Zope Development mailing list for the tip.
Q&A
Are there any good Zope-based CMS?
What are ZClass and ZPatterns?
ZPatterns
Howto
How is the Zope Tutorial displayed when calling http://localhost:8080/?
The index_html object located in the root folder includes a reference to
zope_quick_start, which is located in the Zope directory on the filesystem,
eg. "C:\Program Files\Zope\lib\python\App\dtml\zope_quick_start.dtml"
Although Zope is listening on port 8021 and I can log on, Zope gets stuck
before listing files and directories
I cannot access the root document (www.acme.com/)
due to authorization failure
I fail inserting images into ZODB through the ZMI
Don't use quotes in the path to the image
I deleted a picture from the catalog, and added a new picture with the same
id/Title, but the old picture still show up!
Delete the Image object, pack the database, and add the Image object
When viewing the source code, Zope uses absolute URLs instead of relative.
How to force Zope to use relative URLs and external links?
<a href="http://localhost:8080/test/item1.html">Item1</a>
<tr><td align=right><a href="http://www.zope.org/Credits"
target="_top"><img src="http://localhost:8080/p_/ZopeButton"
width="115" height="50" border="0" alt="Powered
by Zope" /></a></td></tr>
Note: The latter is coded as <tr><td align=right><dtml-var
ZopeAttributionButton></td></tr> in the original DTML Document.
How to backup Zope?
If using ZODB, do I just need to back up all the files located in eg. "d:\Program
Files\WebSite\var\.."? Is it OK if I just move those files onto another
server?
How can I change the title of a folder?
Select the folder, and click on Properties.
When copy/pasting a large HTML file into a DTML Document object using Opera
5.12 as my browser, some of the content gets left out
Either try a more recent version of Opera, or use IExplorer.
DTML Document, DTML Method : Who needs both?
A DTML Document is a complete object in and of itself, while a DTML Method
is a component of its container. Consequently, <dtml-var title> in a DTML
Method object displays the title of its container.
Resources
Books
- The Zope Book
(or online The
Zope Book (2.6 Edition))
- Zope
- The Book
of Zope
- Zope Bible
- Zope Developer's
Handbook
- The Zope Developer's
Guide Releases
- (French) Zope
Avec quatre études de cas, Pierre-Julien Grizel, Eyrolles - 06/2001, ISBN: 2-212-09281-4 (chapitre 1,
4,
6,
9,
12,
14,
15)
- (French) Zope
- Premier site collaboratif avec Zope et le CMF, Kamon Ayeva, Olivier
Deckmyn, Pierre-Julien Grizel, Eyrolles - 10/2002 ISBN: 2-212-11163-0
- (French) Zope
de Olivier Deckmyn, Pierre-Julien Grizel
- Zope Bible, Scott Robertson, Michael Bernstein
- Zope , Jerry Spicklemire, Steve Spicklemire, Kevin Friedly, Kim Brand,
New Riders; ISBN: 0735711100
Reference Site
Various documents