[Zope] How to pass values from python script back to calling dtml-method ???
Duncan Booth
duncan@rcp.co.uk
Mon, 26 Mar 2001 10:25:32 +0100
> Greeting, people !
Greetings back, but please could you try not to post HTML to the
mailing list.
> I may seem completely ignorant, but Zope namespaces are driving me
> wild for the last couple of days :-( I need to solve a pretty simple
> task: I have a dtml-method which calls a Python script. When that
> python script is through, it has a variable (say, returnValue="return
> value"). How can I access this variable in calling dtml method ?
> Please help !!!!!
If you want to return a single value, just return it and use dtml-var to
insert it into your document at one location, or dtml-let to save the
value for use in several places.
DTML:
<dtml-var myscript>
PythonScript myscript:
return "return value"
If you want to return multiple values, then return a namespace
object and use dtml-with to make the values available for use. The
example below shows the technique I prefer, which is to make all
python scripts return a namespace.
For example, the following code is taken from a simple shopping
basket system. basketSummary displays a one line summary of
the basket contents:
<dtml-comment>
This method returns an HTML segment that displays a summary
of the contents of the current shopping basket.
</dtml-comment>
<dtml-with "logic.basketContents()">
<p class="small">Shopping Basket: <dtml-var numlines> lines,
<dtml-var numitems> items, Total Value: <dtml-var totalvalue
fmt="$%1.2f">
</p>
</dtml-with>
The python script basketContents, kept in the logic folder, retrieves
the current contents of the basket and looks like this:
if not context.REQUEST.has_key('SESSION'):
context.Session(REQUEST=context.REQUEST)
basket = context.REQUEST.SESSION.get('basket', None) or []
customer = container.customerData()
# Return the basket contents.
contents = []
totalvalue, items = 0.0, 0
for c, d, u, q, p in basket:
contents.append(namespace(code=c, description=d, unitprice=u,
quantity=q, price=p)[0])
totalvalue, items = totalvalue + p, items + q
shipping = 4.95
total = totalvalue + shipping
vars = namespace(contents=contents, totalvalue=totalvalue,
shipping=shipping, total=total, numlines=len(contents), numitems=items,
customer=customer[0])
return vars
Notice that for the summary display we are just interested in the
totals. The code that does the full display can get at the individual
lines using dtml-in:
<dtml-with "logic.basketContents()">
<dtml-in contents>
<dtml-var description> <dtml-var unitprice> etc.
</dtml-in contents>
</dtml-with>
Note that the namespace function actually returns a tuple
containing the namespace as the first (only) element. This is fine
when returning the final result, but for building a list of namespaces
you have to remove the extra tuple wrapping, hence the [0] in the
append call (and also the customer[0] since customer was the
result of another call to namespace).
--
Duncan Booth duncan@rcp.co.uk