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">
@@ -164,7 +164,7 @@
tal:condition="nocall:target">
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)