[Zope] breadcrumb navigation and ZUBB

Erik Enge erik+list@esol.no
18 Feb 2001 23:17:01 +0100


[Ulrich Wisser]

| But with my code I get as forum title only
| the title I gave at its creation, when I
| call a method, e.g. search
| 
| http://domain/forum/search
| 
| will give
| 
| root : forum : forum

Does the «search» method have its own «title» attribute?  If not, it
is acquired from the «forum» object.
 
| Does anybody know how to do this correct or where this
| error is coming from?

I'll paste in two methods for you.  Be warned, they have made it into
life by evolving, so they are quite unfactored, rude and ugly.  I use
them in a Python Product, but you should be able to stuff them in a
Python Script, I think (I'm not quite sure if you're able to access
the _properties attribute from there though).

This first one returns the appropriate attribute to be rendered in the
navigation bar:

	def name_title_or_id(self):
		"Returns either job_title, firstname + surname, name, title, meta_type or id - in that order."
		if self.get_property('job_title') == 1:
			job_title=self.get_job_title()
		else:
			job_title=''
		
		if self.get_property('name') == 1:
			name=self.name
		else:
			name=''

		if self.get_property('firstname') == 1:
			firstname=self.firstname
			surname=self.surname
		else:
			firstname=''
			surname=''

		title=self.title
		if callable(title):
			title=title()

		id=self.id
		if callable(id):
			id=id()

		if (len(job_title) > 0 and self.meta_type != 'Candidate'):
			return job_title +' / '+str(self.id)
		elif len(firstname) > 0:
			return firstname +' '+ surname
		elif len(name) > 0:
			return name
		elif len(title) > 0:
			return title 
		else:
			return id

In the future I'll be smarter and add a navigation_title (or
something) attribute to all of my objects, so I don't have to do
this.  The «get_property» method looks like this:

	def get_property(self, prop_name):
		"Return true if self._properties contains prop_name."
		for x in range(len(self._properties)): 
			for key in self._properties[x].keys():
				if str(prop_name) == str(self._properties[x]['id']):
					return 1
		return 0

This is needed because I couldn't figure out how to «turn off»
acquisition.  Even though I theoretically know how to.

The actual navigation method looks like this:

	def navigation(self, object, REQUEST, navi_html=""):
		"Return some navigation HTML code."
		url = object.REQUEST.SERVER_URL
		jump_navi=' '
		do_not_show = []
		if object.meta_type in do_not_show:
			return self.navigation(object.getParentNode(), REQUEST, navi_html)
		try:
			for element in object.getPhysicalPath():
				url = url + str(element) + "/"
			if object.meta_type == self.meta_type:
				navi_html = '<b><a href="'+url+'index_html">'+str(object.name_title_or_id())+'</a></b> <font color="red"><b>»</b></font> ' + str(navi_html)
			else:
				navi_html = '<a href="'+url+'index_html">'+str(object.name_title_or_id())+'</a> <font color="red"><b>»</b></font> ' + str(navi_html)
			if object.meta_type == '':
				raise AttributeError
			else:
				return self.navigation(object.getParentNode(), REQUEST, navi_html)
			return self.navigation(object.getParentNode(), REQUEST, navi_html)
		except AttributeError:
			return '<table width="100%" cellpadding="0" cellspacing="0"><tr><td valign="center" align="left" bgcolor="lightyellow" width="90%">'+navi_html[:-9]+'</td><td valign="center" align="center" bgcolor="lightyellow" width="10%">'+jump_navi+'</td></tr></table>'


A couple of this that you need to be aware of:

First, the do_not_show list is a list of meta_types that you do not
want to display in the navigation bar (very useful).  Second the
        
        if object.meta_type = '':
                raise AttributeError

is good to use if you don't want to traverse all the way back to the
root object.  It stops when it hits the meta_type you list there.

This isn't refactored at all, so I'm sure you would be better off
understand this code, and then coding it all over again (if you do,
do send me the code :).

Hope this helps, and sorry about the ugly code. :)