Author: jmorliaguet Date: Wed Jun 28 00:40:48 2006 New Revision: 3531 Modified: cpsskins/branches/paris-sprint-2006/locations/README.txt cpsskins/branches/paris-sprint-2006/locations/location.py cpsskins/branches/paris-sprint-2006/standard/negotiation/page.py cpsskins/branches/paris-sprint-2006/storage/locations.py cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/negotiation_section.pt cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/views.py
Log: - added support for method names in locations: /sections/url.html will match only /sections/url.html while /sections/ will match /sections/url.html, /sections/urlB.html, /sections/ ... Modified: cpsskins/branches/paris-sprint-2006/locations/README.txt ============================================================================== --- cpsskins/branches/paris-sprint-2006/locations/README.txt (original) +++ cpsskins/branches/paris-sprint-2006/locations/README.txt Wed Jun 28 00:40:48 2006 @@ -88,24 +88,24 @@ All location information will be looked up from a given context which can considered as the sublocation of a nearest location. -For instance in the context of folder1/folder2/folder3, among the following +For instance in the context of folder1/folder2/folder3/, among the following locations: - - folder1 + - /folder1/ - - folder1/folder2 + - /folder1/folder2/ the former is the nearest location, because the location context is contained in it and because it is contained in all other locations. We can sort locations as: - folder1 > folder1/folder2 > folder1/folder2/folder3 + /folder1/ > /folder1/folder2/ > /folder1/folder2/folder3/ (with '>' meaning 'contains') the rules associated with the location 'folder1' will shadow the rules -of associated with 'folder1/folder2' +of associated with '/folder1/folder2/' If no nearest locations can be found in a given context then no rules will be applied, and the context will contain no local information. @@ -125,13 +125,13 @@ >>> from cpsskins.locations import Location - >>> l1 = Location(title=u'folder 1', path=u'/f1', data=u'd1') + >>> l1 = Location(path=u'/f1/', data=u'd1') >>> l1 - <Location 'folder 1' at /f1> + <Location at /f1/> - >>> l2 = Location(title=u'folder 1/2', path=u'/f1/f2', data=u'd1/2') + >>> l2 = Location(path=u'/f1/f2/', data=u'd1/2') >>> l2 - <Location 'folder 1/2' at /f1/f2> + <Location at /f1/f2/> to get the location's data, we call the location: @@ -154,8 +154,8 @@ if two locations have a same path, they are equal: - >>> lA = Location(title=u'A', path=u'/f1/f2', data=u'A') - >>> lB = Location(title=u'B', path=u'/f1/f2', data=u'B') + >>> lA = Location(path=u'/f1/f2/', data=u'A') + >>> lB = Location(path=u'/f1/f2/', data=u'B') >>> lA == lB True @@ -172,8 +172,8 @@ >>> from pprint import pprint >>> pprint(dict(locations)) - {(u'', u'', u'f1'): <Location 'folder 1' at /f1>, - (u'', u'', u'f1', u'f2'): <Location 'folder 1/2' at /f1/f2>} + {(u'', u'', u'', u'f1'): <Location at /f1/>, + (u'', u'', u'', u'f1', u'f2'): <Location at /f1/f2/>} we can obtain the list of locations with: @@ -183,20 +183,20 @@ now we want to find the location of '/f1/f2/f3': - >>> locations.find(u'/f1/f2/f3') - <Location 'folder 1/2' at /f1/f2> + >>> locations.find(u'/f1/f2/f3/') + <Location at /f1/f2/> -or get the location of '/f1/f2' +or get the location of '/f1/f2/' - >>> locations.find(u'/f1/f2') - <Location 'folder 1/2' at /f1/f2> + >>> locations.find(u'/f1/f2/') + <Location at /f1/f2/> or '/f1': - >>> locations.find(u'/f1') - <Location 'folder 1' at /f1> + >>> locations.find(u'/f1/') + <Location at /f1/> - >>> locations.find(u'/f2') is None + >>> locations.find(u'/f2/') is None True scopes @@ -210,93 +210,94 @@ By specifying a scope we can restrict the paths covered by a location, for instance: - >>> l3 = Location(title=u'C', path=u'/f1/f3', data=u'C', scope=(0, 1)) + >>> l3 = Location(path=u'/f1/f3/', data=u'C', scope=(0, 1)) >>> locations.add(l3) >>> l3 - <Location 'C' at /f1/f3> + <Location at /f1/f3/> means that the 'l3' location has a scope covering /f1/f3 and all immediate sublocation paths (/f1/f3/...) but not (/f1/f3/.../...) - >>> locations.find(u'/f1/f3') - <Location 'C' at /f1/f3> + >>> locations.find(u'/f1/f3/') + <Location at /f1/f3/> - >>> locations.find(u'/f1/f3/f4') - <Location 'C' at /f1/f3> + >>> locations.find(u'/f1/f3/f4/') + <Location at /f1/f3/> - >>> locations.find(u'/f1/f3/f4/f5') - <Location 'folder 1' at /f1> + >>> locations.find(u'/f1/f3/f4/f5/') + <Location at /f1/> -l4 has a scope covering '/f1/f4' and sublocations of level 1 and 2: +l4 has a scope covering '/f1/f4/' and sublocations of level 1 and 2: - >>> l4 = Location(title=u'D', path=u'/f1/f4', data=u'D', scope=(0, 2)) + >>> l4 = Location(path=u'/f1/f4/', data=u'D', scope=(0, 2)) >>> locations.add(l4) - >>> locations.find(u'/f1/f4') - <Location 'D' at /f1/f4> + >>> locations.find(u'/f1/f4/') + <Location at /f1/f4/> - >>> locations.find(u'/f1/f4/f5') - <Location 'D' at /f1/f4> + >>> locations.find(u'/f1/f4/f5/') + <Location at /f1/f4/> - >>> locations.find(u'/f1/f4/f5/f6') - <Location 'D' at /f1/f4> + >>> locations.find(u'/f1/f4/f5/f6/') + <Location at /f1/f4/> - >>> locations.find(u'/f1/f4/f5/f6/f7') - <Location 'folder 1' at /f1> + >>> locations.find(u'/f1/f4/f5/f6/f7/') + <Location at /f1/> - >>> locations.find(u'/f1/f4/f5/f6/f7/f8') - <Location 'folder 1' at /f1> + >>> locations.find(u'/f1/f4/f5/f6/f7/f8/') + <Location at /f1/> l5 has a scope covering the '/f1/f5' location's immediate sublocations only: - >>> l5 = Location(title=u'E', path=u'/f1/f5', data=u'E', scope=(1, 1)) + >>> l5 = Location(path=u'/f1/f5/', data=u'E', scope=(1, 1)) >>> locations.add(l5) - >>> locations.find(u'/f1/f5') - <Location 'folder 1' at /f1> + >>> locations.find(u'/f1/f5/') + <Location at /f1/> - >>> locations.find(u'/f1/f5/f6') - <Location 'E' at /f1/f5> + >>> locations.find(u'/f1/f5/f6/') + <Location at /f1/f5/> -l6 has a scope covering the '/f1/f6' location's sublocations of level 2 or +l6 has a scope covering the '/f1/f6/' location's sublocations of level 2 or more: - >>> l6 = Location(title=u'F', path=u'/f1/f6', data=u'F', scope=(2, 0)) + >>> l6 = Location(path=u'/f1/f6/', data=u'F', scope=(2, 0)) >>> locations.add(l6) - >>> locations.find(u'/f1/f6') - <Location 'folder 1' at /f1> + >>> locations.find(u'/f1/f6/') + <Location at /f1/> - >>> locations.find(u'/f1/f6/f7') - <Location 'folder 1' at /f1> + >>> locations.find(u'/f1/f6/f7/') + <Location at /f1/> - >>> locations.find(u'/f1/f6/f7/f8') - <Location 'F' at /f1/f6> + >>> locations.find(u'/f1/f6/f7/f8/') + <Location at /f1/f6/> - >>> locations.find(u'/f1/f6/f7/f8/f9') - <Location 'F' at /f1/f6> + >>> locations.find(u'/f1/f6/f7/f8/f9/') + <Location at /f1/f6/> + + >>> locations.find(u'/f1/f6/f7/f8/f9/f10/') + <Location at /f1/f6/> - >>> locations.find(u'/f1/f6/f7/f8/f9/f10') - <Location 'F' at /f1/f6> namespaces .......... Namespaces can be created by specifying a location root: - >>> l7 = Location(title=u'G', path=u'/f1', data=u'G', root=u'pages') + >>> l7 = Location(path=u'/f1/', data=u'G', root=u'pages') >>> locations.add(l7) - >>> locations.find(u'/f1', root=u'pages') - <Location 'G' at /f1 for 'pages'> + >>> locations.find(u'/f1/', root=u'pages') + <Location at /f1/ for 'pages'> - >>> l8 = Location(title=u'H', path=u'/f1', data=u'H', root=u'engines') + >>> l8 = Location(path=u'/f1/', data=u'H', root=u'engines') >>> locations.add(l8) - >>> locations.find(u'/f1', root=u'engines') - <Location 'H' at /f1 for 'engines'> + >>> locations.find(u'/f1/', root=u'engines') + <Location at /f1/ for 'engines'> we get the list of roots with: @@ -318,13 +319,40 @@ >>> locations.getAllPaths() # doctest: +NORMALIZE_WHITESPACE [(u'', u'f1'), (u'', u'f1', u'f6'), (u'', u'f1', u'f2'), - (u'', u'f1', u'f3'), (u'', u'f1', u'f4'), (u'', u'f1', u'f5')] + (u'', u'f1', u'f3'), (u'', u'f1', u'f4'), + (u'', u'f1', u'f5')] + +view names +........... + +View or method names can be included in paths: + +if a location has a /f10/ path, all locations such as /f10/_____ will +match the location: + + >>> l10 = Location(path=u'/f10/', data=u'any') + >>> locations.add(l10) + + >>> locations.find(u'/f10/edit.html') + <Location at /f10/> + + >>> locations.find(u'/f10/view.html') + <Location at /f10/> + +but if we add a location where the method name is explicitly specified we +get that location instead: + + >>> l10b = Location(path=u'/f10/edit.html', data=u'edit') + >>> locations.add(l10b) + + >>> locations.find(u'/f10/edit.html') + <Location at /f10/edit.html> -finally we remove the locations: + >>> locations.find(u'/f10/view.html') + <Location at /f10/> - >>> locations.remove(l1) -or we purge the entire storage: +we purge the entire storage: >>> locations.purge() Modified: cpsskins/branches/paris-sprint-2006/locations/location.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/locations/location.py (original) +++ cpsskins/branches/paris-sprint-2006/locations/location.py Wed Jun 28 00:40:48 2006 @@ -28,10 +28,10 @@ implements(ILocation) def __init__(self, path=u'', data=u'', scope=(0, 0), root=u''): + self.path = path self.data = data self.scope = scope self.root = root - self.path = path def __repr__(self): path = self.path @@ -61,13 +61,16 @@ return other > self def __eq__(self, other): - return self._path_tuple == other._path_tuple + return (self._path_tuple, self._method) == (other._path_tuple, + other._method) def getPath(self): - return u'/'.join(self._path_tuple) + return u'/'.join(self._path_tuple + (self._method,)) def setPath(self, path): - self._path_tuple = tuple(path.split(u'/')) + parts = path.split(u'/') + self._path_tuple = tuple(parts[:-1]) + self._method = parts[-1] path = property(getPath, setPath) Modified: cpsskins/branches/paris-sprint-2006/standard/negotiation/page.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/standard/negotiation/page.py (original) +++ cpsskins/branches/paris-sprint-2006/standard/negotiation/page.py Wed Jun 28 00:40:48 2006 @@ -90,7 +90,8 @@ def __call__(self): context = self.context nearest_site = IPhysicallyLocatable(context).getNearestSite() - path = getPath(context)[len(getPath(nearest_site)):] + path_info = self.request['PATH_INFO'] + path = path_info[len(getPath(nearest_site)):] location = self.manager.getLocation(path, root=u'pages') if location is not None: page_name = location() Modified: cpsskins/branches/paris-sprint-2006/storage/locations.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/storage/locations.py (original) +++ cpsskins/branches/paris-sprint-2006/storage/locations.py Wed Jun 28 00:40:48 2006 @@ -61,7 +61,7 @@ implements(ILocationStorage) def add(self, location, name=u''): - key = (location.root,) + location._path_tuple + key = (location.root, location._method) + location._path_tuple if key in self: del self[key] self[key] = location @@ -72,21 +72,25 @@ if not isinstance(locations, (list, tuple)): locations = [locations] for location in locations: - key = (location.root,) + location._path_tuple - if key not in self: + if location not in list(self): continue - del self[key] + del self[location] def find(self, path, root=u''): if isinstance(path, basestring): path = tuple(path.split(u'/')) + path, method = path[:-1], path[-1] path_len = len(path) for i in range(path_len): p = path[0:path_len-i] - key = (root,) + p + # look for a path + method first + key = (root, method) + p if key not in self: - continue + # fall back to the path without method + key = (root, u'') + p + if key not in self: + continue l = self[key] start, end = l.scope if (start == 0 or i >= start) and (end == 0 or i <= end): @@ -104,13 +108,13 @@ for key in self: if key[0] != root: continue - paths.add(key[1:]) + paths.add(key[2:]) return list(paths) def getAllPaths(self): paths = Set() for key in self: - paths.add(key[1:]) + paths.add(key[2:]) return list(paths) def getLocations(self, root=u''): @@ -121,8 +125,8 @@ locations.append(value) return locations - def getLocation(self, root=u'', path=u''): + def getLocation(self, root=u'', path=u'', method=u''): path = tuple(path.split(u'/')) - key = (root, ) + path + key = (root, method) + path return self[key] Modified: cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/negotiation_section.pt ============================================================================== --- cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/negotiation_section.pt (original) +++ cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/negotiation_section.pt Wed Jun 28 00:40:48 2006 @@ -21,7 +21,7 @@ edit python: edited == location_path"> <tal:block condition="not:edit" tal:define="edit_url string:javascript:CPSSkins.getModelById('negotiation-section').setData({'form': {'section': '$section', 'edited': '${location/path}' }})"> - <td><a tal:attributes="href edit_url" tal:content="location_path" /></td> + <td><a tal:attributes="href edit_url" tal:content="location/displayed_path" /></td> <td><a tal:attributes="href edit_url" tal:content="location/scope" /></td> <td><a tal:attributes="href edit_url" tal:content="location/data" /></td> </tal:block> Modified: cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/views.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/views.py (original) +++ cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/views.py Wed Jun 28 00:40:48 2006 @@ -152,8 +152,14 @@ for location in locations.getLocations(root): scopes = scopes_factory(location) data_choices = data_choices_factory(location) - info[root][location.path] = { - 'path': location.path, + path = location.path + displayed_path = path + if (u'/' in path and path[-1:] != u'/') or (u'/' not in path): + meth = path.split(u'/')[-1] + displayed_path = u"%s<%s>" % (path[:-len(meth)], meth) + info[root][path] = { + 'path': path, + 'displayed_path': displayed_path, 'data': location.data, # FIXME: get the title 'scope': scopes.getTerm(location.scope).title, 'object': location, -- http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins