diff --git a/browser/common.py b/browser/common.py index 8cc21ab..9ab6845 100644 --- a/browser/common.py +++ b/browser/common.py @@ -58,6 +58,7 @@ from cybertools.relation.interfaces import IRelationRegistry from cybertools.stateful.interfaces import IStateful from cybertools.text import mimetypes from cybertools.typology.interfaces import IType, ITypeManager +from loops.browser.util import normalizeForUrl from loops.common import adapted, baseObject from loops.config.base import DummyOptions from loops.i18n.browser import I18NView @@ -151,6 +152,11 @@ class BaseView(GenericView, I18NView): def name(self): return getName(self.context) + def makeTargetUrl(self, baseUrl, targetId, title=None): + if self.globalOptions('useInformativeURLs') and title: + return '%s/.%s-%s' % (baseUrl, targetId, normalizeForUrl(title)) + return '%s/.%s' % (baseUrl, targetId) + @Lazy def principalId(self): principal = self.request.principal diff --git a/browser/node.py b/browser/node.py index ace25aa..864b5aa 100644 --- a/browser/node.py +++ b/browser/node.py @@ -292,8 +292,7 @@ class NodeView(BaseView): def targetUrl(self): t = self.targetObjectView if t is not None: - #return '%s/.target%s' % (self.url, t.uniqueId) - return '%s/.%s' % (self.url, t.uniqueId) + return self.makeTargetUrl(self.url, t.uniqueId, t.title) return '' def renderTarget(self): @@ -445,18 +444,20 @@ class NodeView(BaseView): def targetRender(self): return u'
%s
' % self.targetView('download.html', 'show') - @Lazy - def virtualTarget(self): - obj = self.virtualTargetObject + def getViewForTarget(self, obj, setup=True): if obj is not None: basicView = component.getMultiAdapter((obj, self.request)) if obj == self.targetObject: basicView._viewName = self.context.viewName - #if self.context.nodeType != 'text': - basicView.setupController() + if setup: + basicView.setupController() if hasattr(basicView, 'view'): return basicView.view + @Lazy + def virtualTarget(self): + return self.getViewForTarget(self.virtualTargetObject) + @Lazy def targetId(self): target = self.virtualTargetObject @@ -465,10 +466,10 @@ class NodeView(BaseView): @Lazy def virtualTargetUrl(self): - targetId = self.targetId - if targetId is not None: - #return '%s/.target%s' % (self.url, targetId) - return '%s/.%s' % (self.url, targetId) + target = self.virtualTargetObject + if target is not None: + tv = BaseView(target, self.request) + return self.makeTargetUrl(self.url, tv.uniqueId, tv.title) else: return self.url @@ -494,12 +495,10 @@ class NodeView(BaseView): """ Return URL of given target view given as .XXX URL. """ if isinstance(target, BaseView): - #return '%s/.target%s' % (self.url, target.uniqueId) - return '%s/.%s' % (self.url, target.uniqueId) + return self.makeTargetUrl(self.url, target.uniqueId, target.title) else: - #return ('%s/.target%s' % - return ('%s/.%s' % - (self.url, util.getUidForObject(target))) + return self.makeTargetUrl(self.url, util.getUidForObject(target), + target.title) def getActions(self, category='object', target=None): actions = [] @@ -900,21 +899,6 @@ class NodeTraverser(ItemTraverser): return self.context.getLoopsRoot() if name.startswith('.'): name = self.cleanUpTraversalStack(request, name)[1:] - #traversalStack = request._traversal_stack - #while traversalStack and traversalStack[0].startswith('.target'): - # # skip obsolete target references in the url - # name = traversalStack.pop(0) - #traversedNames = request._traversed_names - #if traversedNames: - # lastTraversed = traversedNames[-1] - # if lastTraversed.startswith('.target') and lastTraversed != name: - # # let tag show the current object - # traversedNames[-1] = name - #if len(name) > len('.target'): - # uid = int(name[len('.target'):]) - # target = util.getObjectForUid(uid) - #else: - # target = self.context.target target = self.getTarget(name) if target is not None: # remember self.context in request diff --git a/browser/node_macros.pt b/browser/node_macros.pt index 2f7af3c..5470efe 100644 --- a/browser/node_macros.pt +++ b/browser/node_macros.pt @@ -141,7 +141,7 @@ tal:condition="nocall:target">
Resource Title
@@ -164,7 +164,7 @@ tal:condition="nocall:target">
Concept Title
diff --git a/browser/resource.py b/browser/resource.py index 251ca49..1a41178 100644 --- a/browser/resource.py +++ b/browser/resource.py @@ -18,8 +18,6 @@ """ View class for resource objects. - -$Id$ """ import urllib @@ -134,9 +132,6 @@ class ResourceView(BaseView): else: return self.template.macros['download'] - #def __init__(self, context, request): - # super(ResourceView, self).__init__(context, request) - def setupController(self): cont = self.controller if cont is None: @@ -157,6 +152,20 @@ class ResourceView(BaseView): subMacro=version_macros.macros['portlet_versions'], priority=25, info=self) + def breadcrumbs(self): + data = [] + if self.breadcrumbsParent is not None: + data.extend(self.breadcrumbsParent.breadcrumbs()) + if self.context != self.nodeView.targetObject: + data.append(dict(label=self.title, + url=self.nodeView.getUrlForTarget(self.context))) + return data + + @Lazy + def breadcrumbsParent(self): + for c in self.context.getConcepts([self.defaultPredicate]): + return self.nodeView.getViewForTarget(c, setup=False) + @Lazy def view(self): context = self.context diff --git a/browser/skin/lobo/body.pt b/browser/skin/lobo/body.pt index 7d22bca..cca73aa 100644 --- a/browser/skin/lobo/body.pt +++ b/browser/skin/lobo/body.pt @@ -27,14 +27,21 @@
-
- You are here: - - - > -
+ + + + + +
You are here: + + + > +
+
diff --git a/browser/util.py b/browser/util.py index 5cd9a15..1bf3288 100644 --- a/browser/util.py +++ b/browser/util.py @@ -18,10 +18,9 @@ """ Utilities. - -$Id$ """ +import re from zope.app.pagetemplate import ViewPageTemplateFile from zope.app.publisher.browser.menu import BrowserMenu from zope.app.publisher.interfaces.browser import IBrowserSubMenuItem @@ -65,3 +64,9 @@ def html_quote(text, character_entities=((u'&', u'&'), (u'<', u'<' ), for re, name in character_entities: text = text.replace(re, name) return text + + +pattern = re.compile(r'[ /\?\+%]') + +def normalizeForUrl(text): + return pattern.sub('-', text) diff --git a/layout/browser/base.py b/layout/browser/base.py index d34da23..a6494d2 100644 --- a/layout/browser/base.py +++ b/layout/browser/base.py @@ -22,8 +22,6 @@ Base classes for layout-based views. $Id$ """ -import re - from zope.app.security.interfaces import IUnauthenticatedPrincipal from zope import component from zope.cachedescriptors.property import Lazy @@ -34,6 +32,7 @@ from zope.traversing.browser import absoluteURL from cybertools.util import format from loops.common import adapted from loops.i18n.browser import LanguageInfo +from loops.browser.util import normalizeForUrl as normalize from loops import util @@ -167,11 +166,7 @@ class BaseView(object): def getKeywords(self): return self.context.title.split() - + def getMetaDescription(self): return self.context.title -pattern = re.compile(r'[ /\?\+%]') - -def normalize(text): - return pattern.sub('-', text)