diff -u -x .svn -x '*~' -x '*.pyc' -N -r CMFEditions/CHANGES.txt CMFEditions_URL/CHANGES.txt
--- CMFEditions/CHANGES.txt	2006-06-25 08:09:28.000000000 +0900
+++ CMFEditions_URL/CHANGES.txt	2006-08-06 06:50:21.000000000 +0900
@@ -5,6 +5,58 @@
 This file contains change information for the CMFEditions releases.
 
 
+CMFEditions branches/version-urls
+---------------------------------
+
+Versions and diffs can now be accessed by bare URLs (no query string),
+which allows Squid or Apache to cache these pages without any special
+adjustments or workarounds.
+
+In the URL, version parameters are appended to the appropriate
+template ID as element which start with the single character 'v',
+optionally followed by one or more digits corresponding to the version
+number to be accessed.  An element without a number stands for the
+current version.  In two-element suffixes, the order of elements is
+irrelevant.
+
+Here are a few examples:
+
+  http://mysite.org/myobject/versions_history_form/v1 --
+    (Version 1)
+  
+  http://mysite.org/myobject/version_diff/v1/v2 --
+    (Changes from version 1 to version 2)
+  
+  http://mysite.org/myobject/version_diff/v1/v --
+    (Changes from version 1 to the current version)
+
+  http://mysite.org/myobject/version_diff/v/v1 --
+    (Same as above)
+
+The query-string URLs are still valid, but links generated by the
+templates versions_history_form and version_diff now supply the bare
+URL form, which can be treated as equivalent to the old form.
+
+The new behavior is produced using Five to designate versioned objects
+as "local sites" upon save, and by affixing a special marker interface
+to them.  (The first causes Five to issue a BeforeTraverseEvent notice
+against the object when it is traversed. The second helps discriminate
+versioned objects from other, "real" local sites that might exist
+further up the hierarchy.) An event handler responds to the notice,
+and refashions the URL in the same way that this is done in a Zope 2
+access rule.  Unlike an access rule, however, the event handler
+responds only to objects marked with the IVersionedObject interface,
+and requires no special procedures for installation; it just works.
+
+(As currently implemented, only the top-level object of a folderish
+hierarchy is marked when a version is saved.  If you have set up for
+recursive versioning, and content down the tree is later copied out of
+the hierarchy to another location, version URLs may not be enabled for
+the moved object until a fresh version of it is saved.  Not sure if
+this going to be a problem or not.)
+
+
+
 Upcoming CMFEditions 1.0rc1 (unreleased)
 -------------------------------
 
diff -u -x .svn -x '*~' -x '*.pyc' -N -r CMFEditions/configure.zcml CMFEditions_URL/configure.zcml
--- CMFEditions/configure.zcml	1970-01-01 09:00:00.000000000 +0900
+++ CMFEditions_URL/configure.zcml	2006-08-06 05:57:02.000000000 +0900
@@ -0,0 +1,15 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:browser="http://namespaces.zope.org/browser"
+    xmlns:five="http://namespaces.zope.org/five">
+
+    <five:localsite
+        class="Products.Archetypes.BaseObject.BaseObject" />
+
+    <subscriber
+        for="Products.CMFEditions.interfaces.IVersionedObject
+	     zope.app.publication.interfaces.IBeforeTraverseEvent"
+	handler="Products.CMFEditions.h.convertURL"
+     />
+		       
+</configure>
diff -u -x .svn -x '*~' -x '*.pyc' -N -r CMFEditions/CopyModifyMergeRepositoryTool.py CMFEditions_URL/CopyModifyMergeRepositoryTool.py
--- CMFEditions/CopyModifyMergeRepositoryTool.py	2006-06-25 07:38:42.000000000 +0900
+++ CMFEditions_URL/CopyModifyMergeRepositoryTool.py	2006-08-06 05:57:02.000000000 +0900
@@ -67,6 +67,10 @@
 except ImportError:
     WRONG_AT=True
 
+from Products.Five.site.browser import LocalSiteView
+from zope.interface import directlyProvides
+from interfaces import IVersionedObject
+
 VERSIONABLE_CONTENT_TYPES = []
 VERSION_POLICY_MAPPING = {}
 VERSION_POLICY_DEFS = {}
@@ -279,6 +283,18 @@
                             self._prepareSysMetadata(comment),
                             autoapply=self.autoapply)
 
+        siteview = LocalSiteView(obj,obj.REQUEST)
+        if not siteview.isSite():
+            #
+            # Set up to issue IBeforeTraverseEvent
+            #
+            siteview.makeSite()
+            #
+            # Slap an interface on the object, so we can
+            # discriminate it from other local sites
+            #
+            directlyProvides(obj, IVersionedObject)
+
     # -------------------------------------------------------------------
     # methods implementing IPurgeSupport
     # -------------------------------------------------------------------
diff -u -x .svn -x '*~' -x '*.pyc' -N -r CMFEditions/h.py CMFEditions_URL/h.py
--- CMFEditions/h.py	1970-01-01 09:00:00.000000000 +0900
+++ CMFEditions_URL/h.py	2006-08-06 06:34:17.000000000 +0900
@@ -0,0 +1,64 @@
+# URL rewrite for CMFEditions
+
+import zLOG
+
+def convertURL (obj, event):
+    stack = event.request.get('TraversalRequestNameStack',[])
+
+    if not stack:
+        return
+    elif len(stack) == 2 and stack[1] == 'versions_history_form':
+        setVersions(obj,stack)
+        stack.pop(0)
+    elif len(stack) == 3 and stack[2] == 'version_diff':
+        setVersions(obj,stack)
+        stack.pop(1)
+        stack.pop(0)
+    else:
+        return
+
+def setVersions (obj,stack):
+    version = []
+    for s in stack[:-1]:
+        if not s.startswith('v'):
+            return
+        else:
+            n = s[1:]
+            if n == '':
+                val = -1
+            elif n.isdigit():
+                val = n
+            else:
+                return
+        version.append(val)
+
+    if not version:
+        return
+
+    zLOG.LOG('CMFEditions',100,'OK!')
+    
+    for pos in range(len(version)-1,-1,-1):
+        if version[pos] == -1:
+            version[pos] = 'current'
+
+    if len(version) == 1:
+        zLOG.LOG('CMFEditions',100,'Length of one!')
+    
+        if version[0] == 'current':
+            return
+        obj.REQUEST.set('version_id',str(version[0]))
+
+    elif len(version) == 2:
+        zLOG.LOG('CMFEditions',100,'Length of two!')
+
+        version.sort()
+        if version[0] == 'current':
+            return
+        obj.REQUEST.set('version_id1',version[1])
+        obj.REQUEST.set('version_id2',version[0])
+
+    else:
+        #
+        # This can't happen
+        #
+        raise
diff -u -x .svn -x '*~' -x '*.pyc' -N -r CMFEditions/interfaces/__init__.py CMFEditions_URL/interfaces/__init__.py
--- CMFEditions/interfaces/__init__.py	2006-06-13 18:32:44.000000000 +0900
+++ CMFEditions_URL/interfaces/__init__.py	2006-08-06 05:57:02.000000000 +0900
@@ -1 +1,5 @@
- 
\ No newline at end of file
+from zope.interface.interface import Interface as ZInterface
+
+class IVersionedObject(ZInterface):
+    """Object marked as having saved versions
+    """
diff -u -x .svn -x '*~' -x '*.pyc' -N -r CMFEditions/skins/CMFEditions/version_diff.pt CMFEditions_URL/skins/CMFEditions/version_diff.pt
--- CMFEditions/skins/CMFEditions/version_diff.pt	2006-06-25 07:38:42.000000000 +0900
+++ CMFEditions_URL/skins/CMFEditions/version_diff.pt	2006-08-06 05:57:02.000000000 +0900
@@ -18,7 +18,7 @@
        tal:define="id1 request/version_id1|options/version_id1|string:current;
                    id2 request/version_id2|options/version_id2;
                    diffs python:here.getVersionDiff(id1,id2);
-                   base_page_url string:${request/ACTUAL_URL}?version_id1=${id1}&amp;version_id2=${id2}">
+                   base_page_url string:${request/ACTUAL_URL}">
 
     <h1 tal:content="here/title_or_id" />
 
@@ -43,7 +43,7 @@
         <tal:html condition="inline">
             <br />
             <a href="#"
-               tal:attributes="href string:${base_page_url}&amp;no_inline:int=1">Show code differences</a>
+               tal:attributes="href string:${base_page_url}?no_inline:int=1">Show code differences</a>
             <br />
             <br />
             <div class="inline-diff"
@@ -57,7 +57,7 @@
                 <br />
             </tal:visual-only>
             <a href="#"
-               tal:attributes="href string:${base_page_url}&amp;no_inline:int=1&amp;show_unified:int=1">Unified diff format</a>
+               tal:attributes="href string:${base_page_url}?no_inline:int=1&amp;show_unified:int=1">Unified diff format</a>
             <pre tal:content="structure d/html_diff">[html diff]</pre>
         </tal:html>
         <tal:unified condition="python:unified and not html">
@@ -67,7 +67,7 @@
             <br />
             <a href="#"
                tal:condition="exists:d/html_diff"
-               tal:attributes="href string:${base_page_url}&amp;no_inline:int=1">Show side by side</a>
+               tal:attributes="href string:${base_page_url}?no_inline:int=1">Show side by side</a>
             <pre tal:content="d/unified_diff">[unified diff]</pre>
         </tal:unified>
         <tal:ndiff condition="python:ndiff and not (unified or html)">
diff -u -x .svn -x '*~' -x '*.pyc' -N -r CMFEditions/skins/CMFEditions/versions_history_form.pt CMFEditions_URL/skins/CMFEditions/versions_history_form.pt
--- CMFEditions/skins/CMFEditions/versions_history_form.pt	2006-06-25 07:38:42.000000000 +0900
+++ CMFEditions_URL/skins/CMFEditions/versions_history_form.pt	2006-08-06 06:41:07.000000000 +0900
@@ -59,12 +59,12 @@
                     <span tal:content="id">1</span>
                     <a href="#"
                        class="version-table-version"
-                       tal:attributes="href string:$here_url/versions_history_form?version_id=${id}"
+                       tal:attributes="href string:$here_url/${template/id}/v${id}"
                        tal:condition="python:version_id!=id"
                        i18n:translate="label_preview_version_link">(preview)</a>
                     <a href="#"
                        class="version-table-version"
-                       tal:attributes="href string:$here_url/versions_history_form?version_id=${id}#version_preview"
+                       tal:attributes="href string:$here_url/${template/id}/v${id}"
                        tal:condition="python:version_id==id"
                        i18n:translate="label_preview_version_below">(jump down)</a>
                   </td>
@@ -82,7 +82,7 @@
                         <li>
                             <a href=""
                                style="text-decoration: none"
-                               tal:attributes="href string:$here_url/version_diff?version_id1=current&version_id2=${id}">
+                               tal:attributes="href string:$here_url/version_diff/v/v${id}">
                             Diff to current
                             </a>
                         </li>
@@ -90,7 +90,7 @@
                             <a href=""
                                style="text-decoration: none"
                                tal:define="prev_ver python:str(int(id)-1)"
-                               tal:attributes="href string:$here_url/version_diff?version_id1=${id}&version_id2=${prev_ver}">
+                               tal:attributes="href string:$here_url/version_diff/v${id}/v${prev_ver}">
                             Diff from last
                             </a>
                         </li>

