[Zope] String to object ID

Chris McDonough chrism@digicool.com
Sun, 05 Dec 1999 04:01:19 -0500


Goodrichs wrote:
> 
> We don't count here until I'm sure I am explaining it correctly ;^)

Thank god.  :-)

> 
> The line;
> <dtml-with "_.namespace(imagename='images.hd' + section)">
> 
> is where we are building a string that will match the name (or id) of the
> target image we want to display. The folder has a property called section
> that has a value of 'mysection'. We are concat'n the value of this property
> onto the end of the string 'images.hd' which we use to denote a top level
> image. So the target image we want to display in the folder 'mysection'
> would be called 'hdmysection', in the top level directory named 'images'
> 
> We want to display the image 'images.hdmydirectory'. If I use this tag;
> 
>  <dtml-var "images.hdmysection">
> 
> it works, the image displays. But... if I concatenate two strings (as in
> the above example) and try to use the result to call the image. Zope
> objects because Zope knows I'm using strings and not an object reference.
> 
> Are you familar with Frontier? We have used Frontier extensively to build
> large websites. One of the truly great things about Frontier was I could
> place any image anywhere in a website by using this code;
> 
> {imgref ("myimagename")}
> 
> and the path to that image would be built on the fly and the html inserted
> into the page. When I need to choose an image based on the location of the
> page being rendered I could build the image name on the fly like so;
> 
> {imgref ({imagename = "ThisPageTitle()" + "ThisPageId()")})}
> 
> The inside macro would expand first creating the correct image name, then
> the outer macro would expand and insert an image tag pointing to the
> correct image.
> 
> ThisPageTitle = "mypage"
> andThisPageId = "myid"
> 
> {imagename = pageTitle() + pageId())} returns "mypagemyid"
> which then will execute the macro {imgref ("mypagemyid")} and return the
> correct image tag.
> 
> SO..........   my question is this, "How do I use a string I have
> constructed on the fly, to reference a Zope path to an object, and tell
> Zope to insert that object into the web page."
> 
> Are you with me?

Yes...

One more time, with feeling.

OK, this is an ugly, ugly hack.  There is undoubtedly a better way to do
this.  It's also untested.

<dtml-call "REQUEST.set('myvar', 'a.space.separated.string')">
<dtml-call "REQUEST.set('mylist', _.string.split(myvar,'.')">
<dtml-call "REQUEST.set('baseobjectstring', mylist[0])">
<dtml-call "REQUEST.set('baseobject', _.getitem(baseobject, 0)">
<dtml-call "REQUEST.set('myurl', baseobject.absolute_url())">
<dtml-in mylist>
    <dtml-if sequence-start>
    <dtml-else>
    <dtml-call "REQUEST.set('myurl', myurl+'/'+_['sequence-item']">
    </dtml-if>
</dtml-in>

<IMG SRC="<dtml-var myurl>">

Get the idea?  What I'm trying to do here is get away from objects and
build a string using the URL path instead.  First we build a list of
(potential) object names using string.split from a dot-separated string
and put it in mylist.  Then we get a handle on the "base" object via
getitem (it'll be first in the mylist list).  Then we get that object's
"absolute url".  (This is gonna fail if there is no such object, you'll
want to wrap it in a try).  We go through the items in mylist in the in
loop (skipping the first one by using if sequence-start, that's the base
object).  Then we cycle through the rest of the mylist list, appending a
slash and the next object name.  And so on until we get to the end of
the list.  The result should be, (assuming the "a" object has an
absolute url of http://mysite.com/a):

<IMG SRC="http://mysite.com/a/space/separated/string">

You could also probably replace the line that appends the sequence-item
to myurl with an .append method, I'm too lazy.

You wanna design your site around string representations of objects. 
Well, who am I to say no?!