SEO: show informative URLs (with title) when global option 'useInformativeURLs' is set

This commit is contained in:
Helmut Merz 2011-12-05 10:44:34 +01:00
parent c963f05964
commit a86c8afcfa
5 changed files with 26 additions and 38 deletions

View file

@ -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

View file

@ -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):
@ -465,10 +464,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 +493,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 +897,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 <base .../> 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

View file

@ -141,7 +141,7 @@
tal:condition="nocall:target">
<div tal:repeat="related item/resources">
<a href="#"
tal:attributes="href string:${view/url}/.target${related/uniqueId};
tal:attributes="href python:view.getUrlForTarget(related);
title related/description"
tal:content="related/title">Resource Title</a>
</div>
@ -164,7 +164,7 @@
tal:condition="nocall:target">
<div tal:repeat="related item/children">
<a href="#"
tal:attributes="href string:${view/url}/.${related/uniqueId};
tal:attributes="href python:view.getUrlForTarget(related);
title related/description"
tal:content="related/title">Concept Title</a>
</div>

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2006 Helmut Merz helmutm@cy55.de
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -18,10 +18,9 @@
"""
Utilities.
$Id$
"""
import re
from zope.app import zapi
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.app.publisher.browser.menu import BrowserMenu
@ -65,3 +64,9 @@ def html_quote(text, character_entities=((u'&', u'&amp;'), (u'<', u'&lt;' ),
for re, name in character_entities:
text = text.replace(re, name)
return text
pattern = re.compile(r'[ /\?\+%]')
def normalizeForUrl(text):
return pattern.sub('-', text)

View file

@ -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)