Search

An XQuery / TEI example - Punch 1914-1916 - revisited

Joe Wicentowski developed a very nice example of TEI processing using XQuery/exist-db which he has used in teaching. I've just resurrected my version. This was originally written to use with the eXist URL-rewriting architecture. I've used it here as another test of the approach to URL-rewriting I'm working on.

 Punch

Zipped Resources

It's all to easy to get Apache into infinite rewriting loops.  I found it useful to adopt the convention of a capitalised name for the application, uncapitalised for its collection:

   RewriteRule ^/Punch/(.*)$  /punch/xquery/content.xq?_path=${escape:$1} [QSA,P]

The general function in the URL library creates the Context object:

declare function url:parse-path($steps) {
     if (count($steps) = 0)
     then ()
     else if (count($steps) = 1)
     then element {$steps[1]} {()}
     else  (element {$steps[1]} {$steps[2]}, url:parse-path(subsequence($steps,3)))  
};

declare function url:path-to-sig($steps) {
     if (count($steps) = 0)
     then ()
     else if (count($steps) = 1)
     then $steps[1]
     else  ($steps[1],"*",url:path-to-sig(subsequence($steps,3)))  
};

declare function url:get-context() as element(context) { 
   let $path := request:get-parameter("_path",())
   let $path := if (ends-with($path,"/")) then substring($path, 1, string-length($path) - 1) else $path
   let $steps := tokenize($path,"/")
   let $signature := string-join(url:path-to-sig($steps),"/")
   return
     element context {
       for $param in request:get-parameter-names()
       let $value := request:get-parameter($param,())
       return element {$param} {$value},
       element _signature {$signature},
       url:parse-path($steps)
     }
};

which is used to guide the construction of the page body:

declare function phtml:page($context) as element(div) {
let $sig := $context/_signature
return
<div>
  {phtml:search-form($context/q)}
  {if (exists($context/q))
   then
      let $hits := punch:section-selection($context/q)
      return
        (phtml:breadcrumbs(()), phtml:hits-in-context($hits))
   else
   if ($sig = ("","issue"))
   then
        (phtml:breadcrumbs(()), phtml:corpus-toc())
   else
   if ($sig = "issue/*")
   then
      let $issue := punch:issue($context/issue)
      return
           (phtml:breadcrumbs($issue), phtml:issue-toc($issue))
   else if ($sig = "issue/*/section/*")
   then
      let $issue := punch:issue($context/issue)
      let $section := punch:section($issue,$context/section)
      return
            (phtml:breadcrumbs($section), phtml:section($section))
   else ()
   }
</div>
};

Further functions build parts of the page, eg to build the table of contents

declare function phtml:corpus-toc() as element(div){
   <div class="body"  id="corpus-toc">
       <ul>
            {
            for $issue in punch:all-issues()
            let $title := punch:issue-title($issue)
            let $issue-id := punch:issue-id($issue)
            order by $issue/@xml:id
            return
                <li>{$title}</li>
            }
        </ul>
   </div>
};

The main script builds the HTML, using ids in the returned page to distribute parts of the page around the web page:

import module namespace phtml = "http://kitwallace.me/punchhtml" at "../lib/punchhtml.xqm";
import module namespace url = "http://kitwallace.me/url" at "/db/lib/url.xqm";

declare option exist:serialize 'method=xhtml media-type=text/html indent=yes';

let $context := url:get-context()
let $page := phtml:page($context)
return
        <html>
            <head>
                <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
                <title>Punch, or the London Charivari</title>
                <link rel="stylesheet" href="/punch/css/blueprint/screen.css" type="text/css" media="screen, projection"/>
                <link rel="stylesheet" href="/punch/css/blueprint/print.css" type="text/css" media="print"/>
                <!--[if IE ]><link rel="stylesheet" href="/punch/css/blueprint/ie.css" type="text/css" media="screen, projection" /><![endif]-->
                <link rel="stylesheet" href="/punch/css/screen.css" type="text/css" media="screen"/>
            </head>
            <body>
                 <div class="container">
                    <div class="span-24 last">
                        <div class="span-16">
                            <div class="banner">
                                <img alt="Punch" width="358" height="114" src="/punch/data/images/banner.png"/>
                            </div>
                        </div>
                        <div class="span-8 last">
                            {$page/div[@id='search-form']}
                        </div>
                    </div>
                    <div class="span-24 last">
                        <hr/>
                    </div>
                    <div class="span-24 last">
                        <div class="inner">
                            {$page/div[@id='breadcrumbs']}
                        </div>
                    </div>
                    <div class="span-24 last">
                        <hr/>
                    </div>
                    <div class="span-24 last">
                        <div class="inner">
                            {$page/div[@class='body']}
                        </div>
                    </div>
                    <div class="span-24 last">
                        <div class="inner">
                            <div class="footer bordered">
                                <div id="footerlinks">
                                    TEI Consortium |
                                    TEI@Oxford 2010 |
                                    Kit Wallace |
                                    eXist
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </body>
        </html>