Let's move on to variables, the lifeblood of any programming language. DTML has them too - although, if you're used to the way variables work in other languages, DTML's interpretation can take some getting used to. More on that later - first, a simple example:
Hello. My name is <dtml-var myName>.
This code belongs to a DTML Document with the ID "Introduction". The <dtml-var> tag is used to insert the contents of a DTML variable - which, over here, is called "myName".
Here's what Zope says when I attempt to view this Document:
Why the barf? Because despite Zope's best efforts, it coldn't find a variable named "myName" anywhere - and so it had to generate the error above.
You can make the error go away with one minor addition to the code above - add a default value for the variable via the "missing" attribute, and Zope will be happy.
Hello. My name is <dtml-var myName missing="Neo">.
And this time, when you attempt to execute the DTML, here's what you'll see:
Obviously, you can't define values for variables in this manner for very long - it tends to negate the point of having a variable in the first place. And so, Zope comes with something very cool - the ability to automatically inherit, or "acquire", variable from the Zope namespace. This capability to automatically search for and acquire variables is one of the most interesting things about Zope - and also one of the most common pitfalls for newbies.
In order to obtain the value of a named variable, Zope will first look in the current folder, and then recursively iterate through the folders above the current folder until it finds the named variable. In the event that it doesn't, it will check a couple of other places (most notably the REQUEST namespace that is created when a form is submitted) and - if it still doesn't find the variable - die with the error message above.
Acquisition in the Zope framework is fairly important, and so fundamental that you've already encountered it once before in this tutorial (although, obviously, you didn't know it). Flip back a couple pages, and look at that first example, and its output again:
<h2><dtml-var title_or_id></h2><p>This is the <dtml-var id> Document.</p><dtml-var standard_html_footer>
Here's the output:
Wondering how that Zope logo got into the final output? Well, that's acquisition at work. You see, when Zope is first installed, it automagically creates a couple of objects in the root folder. They're named "standard_html_header" and "standard_html_footer" respectively, and - if you peek into them - you'll see that they contain the following code:
<!-- contents of standard_html_header --> <html><head><title><dtml-var
title_or_id></title></head><body bgcolor="#FFFFFF"> [/code]
[code] <!-- contents of standard_html_footer --><p><dtml-var ZopeAttributionButton></p></body></html>
Pay attention to the footer there - you'll see that it contains a reference to a Zope variable named "ZopeAttributionButton". This variable actually references the Zope logo; this logo gets attached to the bottom of every page that uses this standard footer.
What does this have to do with acquisition? When Zope finds a reference to "standard_dtml_footer", it searches through the folder hierarchy until it finds, or acquires, an object with that ID, and replaces the variable placeholder with the contents of that object. So, even though I've not defined those two variables in the folder containing the FirstStep object instance, Zope still possesses the intelligence to find them and use them within the DTML script.