You are viewing a plain text version of this content. The canonical link for it is here.
Posted to docs@cocoon.apache.org by do...@cocoon.apache.org on 2005/01/13 23:42:29 UTC

[Cocoon Wiki] Updated: SimpleContentModel

   Date: 2005-01-13T14:42:29
   Editor: MarkLundquist
   Wiki: Cocoon Wiki
   Page: SimpleContentModel
   URL: http://wiki.apache.org/cocoon/SimpleContentModel

   correct, refine, make more complete

Change Log:

------------------------------------------------------------------------------
@@ -8,13 +8,31 @@
  * Co-location of additional page-specific resources
  * External redirects to a "trailing slash" form of the URL (yes, you '''do''' want this...)
 
-I'll explain the content model by way of examples, and discuss these additional aspects in context of the examples.  
+I'll explain the content model by way of examples, and discuss these additional aspects in context of the examples.    A sitemap fragment implementing all of this is given at the end of the article.  
 
 You can use this model as a starting point, and modify it according to your needs/tastes/etc.
 
 = The Content Model =
 
-OK, then... first of all, in this implementation all the source documents handled in this way live in a directory structure rooted at a directory named 'content' that is a subdirectory of the webapp context directory.
+OK, then... we start with two top-level directories:
+
+{{{
+webapp/
+    content/
+    static/
+}}}
+
+{{{content}}} is the root of a directory structure that contains the XML source documents.
+{{{static/}}} contains:
+ * static resources common to all or most pages, such as
+  * layout artwork, e.g. logos
+  * site-wide CSS stylesheet
+  * common external javascripts
+ * symbolic links into the {{{content/}}} directory structure (see below!)
+
+{{{static/}}} does '''not''' contain any page-specific resources (see below!)
+
+In production, I run Cocoon applications behind an Apache front-end using mod_proxy.  Apache is configured to serve directly URIs starting with {{{static/}}}, because it can serve static content so much faster than a servlet container could ever hope to do.  But for development on my laptop, I don't want to have to run Apache, so the sitemap includes matchers for serving these static resource with the correct MIME types, and then I can just point my browser at Cocoon instances running on localhost.
 
 == The simplest case ==
 
@@ -51,23 +69,39 @@
 content/path/to/dogs
    Bowser.page/
       source.xml       # the document to be transformed
+      static/
+         images/
+            bad_dog.jpg
+            favorite_bone.jpg
+            # etc..
+         style.css        # a page-specific stylesheet
+         client.js        # maybe there's some javascript specific to this page...
+         flash/
+            bowser_chasing_tail.swf
+}}}
+
+We then create the following directory structure and soft link in {{{webapp/static}}}:
 
-      # Everything else is ad hoc, whatever the page wants
-      # (i.e. the sitemap doesn't know/care about it)
-      #
-      images/
-         bad_dog.jpg
-         favorite_bone.jpg
-         # etc..
-      style.css        # if I had a page-specific external stylesheet
-      client.js        # maybe there's some javascript specific to this page...
-      flash/
-         bowser_chasing_tail.swf
+{{{
+webapp/static/
+   path/
+      to/
+         dogs/
+            Bowser      ----> .../content/path/to/dogs/Bowser/static
 }}}
+''[ToDo: provide an ant task that automates this]''
 
-''[To-Do: document how the page references these resources and how Cocoon or Apache serves them]''
+A reference to a page-specific resource looks like this in the HTML, e.g.
+
+{{{
+<img src="/static/path/to/dogs/Bowser/bad_dog.jpg" />
+}}}
 
-The implementation looks for {{{Bowser.page/source.xml}}} in {{{content/path/to/dogs}}} if the resource {{{Bowser.xml}}} (see "The simplest case" above) does not exist there.
+It would be quite undesirable to hard-code the site structure into our XML source document, so we'll add a template to our stylesheet that lets us just write that as {{{<img src="static/bad_dog.jpg">}}}; the template will rewrite that to the necessary URI in the generated HTML.  See the implementation notes at the end of this article for the XSLT template.
+
+The sitemap looks for {{{Bowser.page/source.xml}}} in {{{content/path/to/dogs}}} if the resource {{{Bowser.xml}}} (see "The simplest case" above) does not exist there.  So this is really a "drop-in" content model; the sitemap doesn't have to be told on a page-by-page basis which resources use the "site-specific assets" model and which have just the source document as their only asset.
+
+Note the the sub-structure of {{{.../Bowser/static}}} is completely ''ad hoc''; all that matters at this level is that references in the page match the directory structure.  The sitemap does not know or care about this per-page "static/" directory, and it certainly doesn't care how it's structured internally.
 
 == "Trailing slash" resources ==
 
@@ -106,20 +140,50 @@
        source.xml
        # etc.
    vet_story.xml            # URL: 'path/to/dogs/vet_story
-                            # this one has no page-specific resources
+                            #    (this one has no page-specific resources)
 }}}
 
 ...and of course this kind of structure can be nested in any arbitrary way.
 
 The resource "main.xml" or "main.page/source.xml" here sort of corrseponds to "index.html" or "index.php" or whatever you might be used to in the Apache Directory``Index directive (except that I always called mine "main.php", since it usually isn't really an "index", is it?)
 
-= The Sitemap =
+= Implementation =
 
-Now for the sitemap fragment that implements this.  Sorry, I use a default namespace in my sitemaps, so you'll have to add "map:" to everything unless you do the same.
+== The Sitemap ==
 
-OK, here it is:
+Sorry, I use a default namespace in my sitemaps, so you'll have to add "map:" to everything unless you do the same...
 
 {{{
+    <!--
+      ++  Static content
+      -->
+
+    <map:match pattern="static/**.css">
+       <map:read src="{0}" mime-type="text/css"/>
+    </map:match>
+    <map:match pattern="static/**.js">
+       <map:read src="{0}" mime-type="application/x-javascript"/>
+    </map:match>
+    <map:match pattern="static/**.gif">
+       <map:read src="{0}" mime-type="image/gif"/>
+    </map:match>
+    <map:match pattern="static/**.jpg">
+       <map:read src="{0}" mime-type="image/jpeg"/>
+    </map:match>
+    <map:match pattern="static/**.png">
+       <map:read src="{0}" mime-type="image/png"/>
+    </map:match>
+    <map:match pattern="static/**.tiff">
+       <map:read src="{0}" mime-type="image/tiff"/>
+    </map:match>
+    <map:match pattern="static/**.swf">
+       <map:read src="{0}" mime-type="application/x-shockwave-flash"/>
+    </map:match>
+
+    <!--
+      ++  HTML pages generated from source documents
+      -->
+
     <match pattern="content//**/">
       <redirect-to uri="content//{1}/main" />
     </match>
@@ -148,6 +212,30 @@
     </match>
 }}}
 
+== XSLT template to rewrite URIs for local resources ==
+
+Add this to your stylesheet to rewrite relative URIs that begin w/ "static/" (see the discussion of "Co-Located Resources" above).  The {{{path}}} parameter is passed in by the stylesheet (see above)
+
+{{{
+<xsl:param name="path" />
+
+<!--
+  ++ Static content
+ -->
+<xsl:template
+  match="@href[starts-with(., 'static/')] | @src[starts-with(., 'static/')]"
+>
+  <xsl:attribute name="{name()}">/static/<xsl:value-of
+                select="concat($path,'/',substring-after(., 'static/'))"
+              /></xsl:attribute>
+</xsl:template>
+}}}
+
+== Ant task to automate building directories and links in webapp/static ==
+
+TBD!
+
+----
 That's all there is to it!
 
 ----