[z3-checkins] r55607 - in z3/deliverance/sandboxes/paul/dvplone: etc lib var/themesets/nuplone var/themesets/plone

paul at codespeak.net paul at codespeak.net
Thu Jun 5 22:20:09 CEST 2008


Author: paul
Date: Thu Jun  5 22:20:08 2008
New Revision: 55607

Added:
   z3/deliverance/sandboxes/paul/dvplone/lib/mgmtui.xsl
   z3/deliverance/sandboxes/paul/dvplone/lib/tsm.py
   z3/deliverance/sandboxes/paul/dvplone/lib/utils.py
Removed:
   z3/deliverance/sandboxes/paul/dvplone/lib/theme1.html
Modified:
   z3/deliverance/sandboxes/paul/dvplone/etc/serve.ini
   z3/deliverance/sandboxes/paul/dvplone/lib/dvngfilter.py
   z3/deliverance/sandboxes/paul/dvplone/lib/dvplone.py
   z3/deliverance/sandboxes/paul/dvplone/lib/dvploneapp.py
   z3/deliverance/sandboxes/paul/dvplone/var/themesets/nuplone/contentcustom.xsl
   z3/deliverance/sandboxes/paul/dvplone/var/themesets/nuplone/themeset.xml
   z3/deliverance/sandboxes/paul/dvplone/var/themesets/nuplone/themesource-plain.html
   z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/contentcustom.xsl
   z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/themeset.xml
   z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/themesource-plain.html
   z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/themesource-tables.html
Log:
Theme selection via ++dvmanage++ now works

Modified: z3/deliverance/sandboxes/paul/dvplone/etc/serve.ini
==============================================================================
--- z3/deliverance/sandboxes/paul/dvplone/etc/serve.ini	(original)
+++ z3/deliverance/sandboxes/paul/dvplone/etc/serve.ini	Thu Jun  5 22:20:08 2008
@@ -1,3 +1,6 @@
+[DEFAULT]
+debug = True
+
 [server:main]
 use = egg:Paste#http
 

Modified: z3/deliverance/sandboxes/paul/dvplone/lib/dvngfilter.py
==============================================================================
--- z3/deliverance/sandboxes/paul/dvplone/lib/dvngfilter.py	(original)
+++ z3/deliverance/sandboxes/paul/dvplone/lib/dvngfilter.py	Thu Jun  5 22:20:08 2008
@@ -1,64 +1,128 @@
 """WSGI middleware to switch Deliverance themes"""
 
-from dvngcompiler import DVNG
 import os
 import lxml.html
 from lxml import etree
 from wsgifilter import Filter
+from webob import Request, Response
+import urllib
+from tsm import ThemesetManager
+
 
 TSHEADER = "X-DV-Themeset"
 
 class DVNGFilter(Filter):
 
-    default_themeid = "plone"
+    current_themeid = "nuplone"
+    moduledir = os.path.dirname(os.path.abspath(__file__))
+
+    def __init__(self, app, varthemesets, debug):
 
-    def __init__(self, app, varthemesets):
+        # app is the DVPlone instance, pretending to be Plone as the
+        # WSGI endpoint.
         self.app = app
 
-        # The directory for var/themesets holds the cached versions of
-        # compiled themesets.  Passed in from the .ini file.
-        self.varthemesets = varthemesets
-
-        # Cache the processors for themesets we have already loaded.
-        # Obviously we need a way to tell these things to update
-        self.cached_themesets = {}
-
-
-    def loadThemeset(self, themesetid):
-        """Load themesetid if not loaded, then return DVNG processor"""
-
-        # XXX This might be a terrible idea.  Need to make sure 
-        # that lxml/libxml2 caching of XSLT processors doesn't 
-        # vomit.  If so, we just reload the processor on each request.
-        processor = self.cached_themesets.get(themesetid, None)
-        if processor is None:
-            # Need to load, store, and return the themeset
-            fn = "%s/themeset.xml" % themesetid
-            fullfn = os.path.join(self.varthemesets, fn)
-            themesetfn = os.path.join(fullfn)
-            dvng = DVNG(themesetfn)
-            processor = etree.XSLT(dvng.xslt)
-            self.cached_themesets[themesetid] = processor
+        # The themeset manager handles the local storage of download
+        # themesets, browsing for new themesets, making/caching
+        # processor, etc.
+        self.tsm = ThemesetManager(varthemesets, debug)
 
-        return processor
+        self.debug = debug
+
+
+    def getManageScreen(self, req):
+        """Return the HTML body for a Themeset Management screen"""
+
+        # There is a Themeset Management UI.  It runs outside of
+        # Plone, but is made to look like part of Plone via the
+        # miracle of Deliverance and WSGI.  Run outside of Plone, of
+        # course, because the goal is to apply consistent
+        # look-and-feel across applications.
+        mgmtuifn = os.path.join(self.moduledir, "mgmtui.xsl")
+        mgmtdoc = etree.ElementTree(file=mgmtuifn)
+        mgmtprocessor = etree.XSLT(mgmtdoc)
+
+        # If this was a POST (self-posting form), do the work before
+        # displaying the results
+        if req.method == "POST":
+            # We only look for certain actions.  It is all one big  
+            # form, so dispatch based on which button was clicked.
+            dispatch_names = {
+                'apply-local': self.applyLocal,
+                'reload-remote': self.reloadRemote,
+                }
+            for dn in dispatch_names.items():
+                if req.POST.get(dn[0], None) is not None:
+                    # Found the method to match the submit button
+                    dn[1](req)
+
+        # Get the webob Response ready
+        res = Response(content_type="text/html")
+        screenid = "'%s'" % req.path_info[13:]
+        params = {'screenid': screenid}
+
+        # Apply XSLT and assign result to WebOb Response
+        result = mgmtprocessor(self.tsm.asXML(), **params)
+        res.body = str(result)
+
+        return res
+
+    def applyLocal(self, req):
+        """Apply changes to local cached themesets"""
+
+        current = req.POST['current']
+        self.tsm.setCurrentThemesetId(current)
+
+
+    def reloadRemote(self, req):
+
+        self.tsm.reloadRemote()
 
 
-    def filter(self, environ, headers, data):
-        """Turn incoming HTML4 data into etree, apply XSLT"""
-        
-        # First find out which themeset to use
-        themesetid = environ.get(TSHEADER, None)
-        if themesetid is None:
-            themesetid = self.default_themeid
+
+    def __call__(self, environ, start_response):
+        """Called on the way into the application"""
+
+        req = Request(environ)
+        url = urllib.unquote(req.url)
+        if url.find("/++dvmanage++/") > -1:
+            res = self.getManageScreen(req)
+            res.body = self.handle_body(res.body, self.current_themeid)
+            return res(environ, start_response)
+
+        return super(DVNGFilter, self).__call__(environ, start_response)
+
+
+    def handle_body(self, data, themesetid):
+        """Run the transform, do all the work, return a string"""
 
         # Get the processor from cache, or force a load
-        processor = self.loadThemeset(themesetid)
+        processor = self.tsm.getProcessor(themesetid)
 
-        # Apply the processor to the HTML and return the themed
-        # result.
+        # Apply the processor to HTML and return themed result.
         htmldoc = lxml.html.document_fromstring(data)
         result = processor(htmldoc)
         response = str(result)
+
+        return response
+
+
+    def _getThemesetId(self, environ):
+        """Single place to determine which themeset to use"""
+
+        themesetid = environ.get(TSHEADER, None)
+        if themesetid is None:
+            themesetid = self.tsm.current_themesetid
+
+        return themesetid
+
+
+    def filter(self, environ, headers, data):
+        """Turn incoming HTML4 data into etree, apply XSLT"""
+        
+        # First find out which themeset to use
+        themesetid = self._getThemesetId(environ)
+        response = self.handle_body(data, themesetid)
         return response
 
 

Modified: z3/deliverance/sandboxes/paul/dvplone/lib/dvplone.py
==============================================================================
--- z3/deliverance/sandboxes/paul/dvplone/lib/dvplone.py	(original)
+++ z3/deliverance/sandboxes/paul/dvplone/lib/dvplone.py	Thu Jun  5 22:20:08 2008
@@ -3,12 +3,16 @@
 from dvngfilter import DVNGFilter
 from dvploneapp import DVPlone
 
+def asbool(arg):
+    return arg in (True, 'True', 'true', 'yes', '1', 'on', 1)
 
 def make_dvng(app, global_conf, varthemesets, **kw):
     """Choose which Deliverance theme should be used"""
 
-    return DVNGFilter(app, varthemesets)
+    debug = asbool(global_conf.get('debug', False))
+    return DVNGFilter(app, varthemesets, debug)
 
 def make_dvplone(global_config, document_root, **local_conf):
+    """Simulate a Plone application, including the handshake"""
 
     return DVPlone(document_root)

Modified: z3/deliverance/sandboxes/paul/dvplone/lib/dvploneapp.py
==============================================================================
--- z3/deliverance/sandboxes/paul/dvplone/lib/dvploneapp.py	(original)
+++ z3/deliverance/sandboxes/paul/dvplone/lib/dvploneapp.py	Thu Jun  5 22:20:08 2008
@@ -6,6 +6,8 @@
 class DVPlone(StaticURLParser):
 
     def __call__(self, environ, start_response):
-        print "IN DVPlone"
-        environ[TSHEADER] = "nuplone"
+        print "In DVPlone at URL", environ['PATH_INFO']
+         
+        # Perhaps the endpoint wants to override the decisionmaking
+        #environ[TSHEADER] = "nuplone"
         return super(DVPlone, self).__call__(environ, start_response)

Added: z3/deliverance/sandboxes/paul/dvplone/lib/mgmtui.xsl
==============================================================================
--- (empty file)
+++ z3/deliverance/sandboxes/paul/dvplone/lib/mgmtui.xsl	Thu Jun  5 22:20:08 2008
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+    <xsl:output method="html" indent="yes"/>
+    <xsl:variable name="dvmanage">/++dvmanage++</xsl:variable>
+    <xsl:param name="screenid">manage</xsl:param>
+    <xsl:template match="/">
+        <html>
+            <head>
+                <title>Some Title</title>
+                <meta name="dv.section" content="DVNG Articles"/>
+            </head>
+            <body>
+                <div id="content">
+                    <h1>Themeset Manager</h1>
+                    <p>This screen lets administrators manage the DVNG themesets for this site.</p>
+
+                    <form method="post" action="{$dvmanage}{$screenid}">
+                        <h3 style="margin-top: 3em">Currently Installed Themesets</h3>
+                        <table width="95%" border="1" cellpadding="6" cellspacing="0">
+                            <tr>
+                                <th>Theme Title</th>
+                                <th>ID</th>
+                                <th>Version</th>
+                                <th>Current</th>
+                                <th>Remove?</th>
+                            </tr>
+                            <xsl:for-each select="/tsm/local/theme">
+                                <tr>
+                                    <td>
+                                        <xsl:value-of select="@title"/>
+                                    </td>
+                                    <td align="center">
+                                        <xsl:value-of select="@id"/>
+                                    </td>
+                                    <td align="center">
+                                        <xsl:value-of select="@version"/>
+                                    </td>
+                                    <td align="center">
+                                        <input name="current" value="{@id}" type="radio" >
+                                            <xsl:if test="@current">
+                                                <xsl:attribute name="checked">checked</xsl:attribute>
+                                            </xsl:if>
+                                        </input>
+                                    </td>
+                                    <td align="center">
+                                        <input type="checkbox" name="remove"/>
+                                    </td>
+                                </tr>
+                            </xsl:for-each>
+                        </table>
+                        <p>
+                            <input name="apply-local" type="submit" value="Apply"/>
+                        </p>
+
+                        <div style="float:right">
+                            <input name="reload-remote" type="submit" value="Reload Listings"/>
+                        </div>
+                        <h3 style="margin-top:3em">All Known Themes</h3>
+                        <p>Based on the theme repositories listed in the <code>plone.conf</code>
+                            file, the following is a list of themes available for installation.</p>
+                        <table width="95%" border="1" cellpadding="6" cellspacing="0">
+                            <tr>
+                                <th>Site/Theme Title</th>
+                                <th>ID</th>
+                                <th>Version</th>
+                                <th>Date Modified</th>
+                                <th>Install</th>
+                            </tr>
+                            <xsl:for-each select="/tsm/publishers/publisher">
+                                <tr>
+                                    <td colspan="5"
+                                        style="font-size: x-large; background-color:silver">
+                                        <xsl:value-of select="@title"/>
+                                    </td>
+                                </tr>
+                                <xsl:for-each select="theme">
+                                    <tr style="font-size: small">
+                                        <td style="padding-left: 2em">
+                                            <xsl:value-of select="@title"/>
+                                        </td>
+                                        <td align="center">
+                                            <xsl:value-of select="@id"/>
+                                        </td>
+                                        <td align="center">
+                                            <xsl:value-of select="@version"/>
+                                        </td>
+                                        <td align="center">
+                                            <xsl:value-of select="@modified"/>
+                                        </td>
+                                        <td align="center">
+                                            <input type="checkbox" name="load" value="{@id}"/>
+                                        </td>
+                                    </tr>
+                                </xsl:for-each>
+                            </xsl:for-each>
+                        </table>
+                    </form>
+                </div>
+            </body>
+        </html>
+    </xsl:template>
+</xsl:stylesheet>

Deleted: /z3/deliverance/sandboxes/paul/dvplone/lib/theme1.html
==============================================================================
--- /z3/deliverance/sandboxes/paul/dvplone/lib/theme1.html	Thu Jun  5 22:20:08 2008
+++ (empty file)
@@ -1,11 +0,0 @@
-<html>
-    <head>
-        <title>Theme Page Title</title>
-    </head>
-    <body>
-        <h1 id="pageheading">Theme Page Heading</h1>
-        <div id="pagecontent">
-            <p>Some sample theme content.</p>
-        </div>
-    </body>
-</html>
\ No newline at end of file

Added: z3/deliverance/sandboxes/paul/dvplone/lib/tsm.py
==============================================================================
--- (empty file)
+++ z3/deliverance/sandboxes/paul/dvplone/lib/tsm.py	Thu Jun  5 22:20:08 2008
@@ -0,0 +1,111 @@
+"""Themeset Manager
+
+Manage storage, retrieval, and updates of themesets.
+
+"""
+from lxml import etree
+import os
+from dvngcompiler import DVNG
+
+
+class ThemesetManager:
+
+    default_themesetid = "plone"
+
+    def __init__(self, storage_dir, debug):
+        
+        # Should be the directory in "var" that contains
+        # all the themeset information
+        self.storage_dir = storage_dir
+        self.current_themesetid_fn = os.path.join(storage_dir, 
+                                                  "current_themesetid")
+
+        # Write the default to the file if one hasn't been customized
+        if self.current_themesetid is None:
+            self.setCurrentThemesetId(self.default_themesetid)
+
+        # Cache the processors for themesets we have already loaded.
+        # Obviously we need a way to tell these things to update
+        self.cached_themesets = {}
+
+        self.debug = debug
+
+    @property
+    def current_themesetid(self, newid=None):
+        v = open(self.current_themesetid_fn, "r").read()
+
+        return v
+
+    def setCurrentThemesetId(self, newid):
+        """Write newly-chosen themeset id to disk"""
+
+        f = open(self.current_themesetid_fn, "w")
+        f.write(newid)
+        f.close()
+
+    def reloadRemote(self):
+        """Go through each repository and re-fetch their listings"""
+
+        pass
+
+
+    def getProcessor(self, themesetid):
+        """Either return a cached processor, or load a processor"""
+
+        # XXX This might be a terrible idea.  Need to make sure 
+        # that lxml/libxml2 caching of XSLT processors doesn't 
+        # vomit.  If so, we just reload the processor on each request.
+        processor = self.cached_themesets.get(themesetid, None)
+        if processor is None or self.debug:
+            print "######## --- Reloading processor for", themesetid
+            # Need to load, store, and return the themeset
+            fn = "%s/themeset.xml" % themesetid
+            fullfn = os.path.join(self.storage_dir, fn)
+            themesetfn = os.path.join(fullfn)
+            dvng = DVNG(themesetfn)
+            processor = etree.XSLT(dvng.xslt)
+            self.cached_themesets[themesetid] = processor
+
+        return processor
+
+
+    def asXML(self):
+        """Give an XML representation of the themeset manager"""
+
+        ese = etree.SubElement
+        root = etree.Element("tsm")
+        local = ese(root, "local")
+        lthemes = (
+            ('plone', 'Plone', '3.1', '2008/03/03'),
+            ('nuplone', 'NuPlone', '3.0', '2007/11/23'),
+            )
+        for ts in lthemes:
+            theme = ese(local, "theme",
+                        id=ts[0],
+                        title=ts[1],
+                        version=ts[2],
+                        modified=ts[3],
+                        )
+            if ts[0] == self.current_themesetid:
+                theme.set("current", "current")
+
+        # Eventually, contact the themeset global site and get a list 
+        # of known themesets
+        publishers = ese(root, "publishers")
+        sites = ('plone.org', 'Theme Warehouse', 'Internal Project')
+        themes = (
+            ('elevatorplone', 'Plone for Elevators', '0.1', '2007/11/27'), 
+            ('kittyplone', 'Hello Kitty', '0.8', '2006/02/19'),
+            )
+        for p in sites:
+            publisher = ese(publishers, 'publisher', title=p)
+            for t in themes:
+                theme = ese(publisher, "theme",
+                            id=t[0], title=t[1], version=t[2],
+                            modified=t[3])            
+
+        return root
+
+if __name__ == "__main__":
+    tsm = ThemesetManager("../var/themesets")
+    print tsm.current_themeid(33)

Added: z3/deliverance/sandboxes/paul/dvplone/lib/utils.py
==============================================================================
--- (empty file)
+++ z3/deliverance/sandboxes/paul/dvplone/lib/utils.py	Thu Jun  5 22:20:08 2008
@@ -0,0 +1,29 @@
+"""Standalone utility functions for DVNG middleware"""
+
+from lxml import etree
+
+def hasMarker(node_or_doc, marker, value=None):
+    """Return true or false if an HTML doc has a marker value"""
+
+    if value is None:
+        # Check for the existence of the marker, not the value
+        xpfmt = "head/meta[@name='%s' and @id='%s']'"
+        xp = xpfmt % ('marker', marker)
+    else:
+        # Confirm both the existence of the marker and a certain
+        # value
+        xpfmt = "head/meta[@name='%s' and @id='%s']/@content='%s'"
+        xp = xpfmt % ('marker', marker, value)
+        
+        # Both xpaths resolve to True or False
+    return node_or_doc.xpath(xp)
+
+
+def setMarker(self, node_or_doc, markerid, value=None):
+    """Change content HTML to have a certain /html/head/meta"""
+
+    head = node_or_doc.xpath("head")[0]
+    marker = etree.SubElement(head, "meta", name="marker",
+                              id=markerid, content=value)
+
+

Modified: z3/deliverance/sandboxes/paul/dvplone/var/themesets/nuplone/contentcustom.xsl
==============================================================================
--- z3/deliverance/sandboxes/paul/dvplone/var/themesets/nuplone/contentcustom.xsl	(original)
+++ z3/deliverance/sandboxes/paul/dvplone/var/themesets/nuplone/contentcustom.xsl	Thu Jun  5 22:20:08 2008
@@ -1,15 +1,36 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-  <xsl:template match="/">
-    <div>I overroad everything!</div>
-  </xsl:template>
   <xsl:template match="ul[@id='breadcrumbs']">
     <div id="breadcrumbs">
-      <strong>You are here: </strong> 
+      <strong>You are here: </strong>
       <xsl:for-each select="li/a">
-        <a href="{@href}"><xsl:value-of select="."/></a>
+        <a href="{@href}">
+          <xsl:value-of select="."/>
+        </a>
         <xsl:if test="position() != last()"> | </xsl:if>
       </xsl:for-each>
     </div>
   </xsl:template>
+  <!-- For the DVNG management screen, support looking up "markers"
+  in the HTML and inserting some HTML, for example, the Themeset 
+  Management UI. -->
+  <xsl:template match="div[@id='dv-manage']">
+    <xsl:variable name="marker" select="/html/head/object[@id='current-theme-list']"/>
+    <xsl:variable name="curr" select="$marker/*[@name='current-themeid']/@value"></xsl:variable>
+    <div id="dv-mgmtblurb">
+      <h4>Current Themeset: <xsl:value-of select="$marker/*[@name='current-themetitle']/@value"/></h4>
+      <form action="." method="post"> Change to: <select id="dv-newtheme" size="4">
+          <xsl:for-each select="$marker/param[@name='themeid']">
+            <option value="{@id}">
+              <xsl:if test="@id=$curr">
+                <xsl:attribute name="selected">selected</xsl:attribute>
+              </xsl:if>
+              <xsl:value-of select="@value"/>
+            </option>
+          </xsl:for-each>
+        </select>
+        <input value="Save" type="submit"/>
+      </form>
+    </div>
+  </xsl:template>
 </xsl:stylesheet>

Modified: z3/deliverance/sandboxes/paul/dvplone/var/themesets/nuplone/themeset.xml
==============================================================================
--- z3/deliverance/sandboxes/paul/dvplone/var/themesets/nuplone/themeset.xml	(original)
+++ z3/deliverance/sandboxes/paul/dvplone/var/themesets/nuplone/themeset.xml	Thu Jun  5 22:20:08 2008
@@ -1,6 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<?oxygen RNGSchema="themeset.rng" type="xml"?>
 <themeset xmlns="http://openplans.org/deliverance">
+  <properties>
+    <id>nuplone</id>
+    <title>NuPlone</title>
+    <version>3.0</version>
+    <modified>2007/10/29</modified>
+  </properties>
   <customizers theme="themecustom.xsl" content="contentcustom.xsl"/>
   <theme href="themesource-tables.html">
     <!-- A pretty theme with a sidebar -->

Modified: z3/deliverance/sandboxes/paul/dvplone/var/themesets/nuplone/themesource-plain.html
==============================================================================
--- z3/deliverance/sandboxes/paul/dvplone/var/themesets/nuplone/themesource-plain.html	(original)
+++ z3/deliverance/sandboxes/paul/dvplone/var/themesets/nuplone/themesource-plain.html	Thu Jun  5 22:20:08 2008
@@ -5,6 +5,7 @@
             body {margin: 3em;font-family:sans-serif;font-size:large}
             #banner {background-color: silver; text-align: center; height: 1.5em; padding:0.5em}
         </style>
+        <link rel="stylesheet" type="text/css" href="static/basic.css"/>
     </head>
     <body>
         <h1 id="banner">I AM NUPLONE, HEAR ME ROAR</h1>

Modified: z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/contentcustom.xsl
==============================================================================
--- z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/contentcustom.xsl	(original)
+++ z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/contentcustom.xsl	Thu Jun  5 22:20:08 2008
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-  <xsl:template match="/">
+  <xsl:template match="/foo">
     <div>I overroad everything!</div>
   </xsl:template>
   <xsl:template match="ul[@id='breadcrumbs']">

Modified: z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/themeset.xml
==============================================================================
--- z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/themeset.xml	(original)
+++ z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/themeset.xml	Thu Jun  5 22:20:08 2008
@@ -1,6 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<?oxygen RNGSchema="themeset.rng" type="xml"?>
 <themeset xmlns="http://openplans.org/deliverance">
+  <properties>
+    <id>plone</id>
+    <title>Plone</title>
+    <version>3.1</version>
+    <modified>2007/11/13</modified>
+  </properties>
   <customizers theme="themecustom.xsl" content="contentcustom.xsl"/>
   <theme href="themesource-tables.html">
     <!-- A pretty theme with a sidebar -->

Modified: z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/themesource-plain.html
==============================================================================
--- z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/themesource-plain.html	(original)
+++ z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/themesource-plain.html	Thu Jun  5 22:20:08 2008
@@ -3,6 +3,7 @@
         <title>Theme Page Title</title>
     </head>
     <body>
+        <h1 style="text-align: right">Plone, not NuPlone</h1>
         <h1 id="pageheading">Theme Page Heading</h1>
         <div id="pagecontent">
             <p>Some sample theme content.</p>

Modified: z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/themesource-tables.html
==============================================================================
--- z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/themesource-tables.html	(original)
+++ z3/deliverance/sandboxes/paul/dvplone/var/themesets/plone/themesource-tables.html	Thu Jun  5 22:20:08 2008
@@ -3,6 +3,7 @@
         <title>Second Theme Page Title</title>
     </head>
     <body>
+        <h1 style="text-align: right">Plone, not NuPlone</h1>
         <table border="0" height="300" cellpadding="20">
             <tr>
                 <td width="200" bgcolor="gray" valign="top">


More information about the z3-checkins mailing list