<?xml version='1.0' encoding='utf-8'?>
<?xml-stylesheet href="/style/browser.xsl" type="text/xsl"?>
<essay xmlns="http://docbook.org/ns/docbook"
       xmlns:xlink="http://www.w3.org/1999/xlink"
       xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
       xmlns:dc='http://purl.org/dc/elements/1.1/'
       xmlns:dcterms="http://purl.org/dc/terms/"
       xmlns:gal='http://norman.walsh.name/rdf/gallery#'
       xmlns:foaf="http://xmlns.com/foaf/0.1/"
       xml:lang="en"
       version='5.0'>
<info>
<title>NYMUG Summary</title>
<volumenum>12</volumenum>
<issuenum>41</issuenum>
<pubdate>2009-11-12T11:16:03-05:00</pubdate>
<author><personname>
<firstname>Norman</firstname><surname>Walsh</surname>
</personname></author>
<copyright><year>2009</year><holder>Norman Walsh</holder></copyright>
<abstract>
<para>Last night, I spoke at the inaugural New York Mark Logic User Group
meeting. I think it was a crowd pleaser, or at least, the punchline at the
end was.</para>
</abstract>
</info>

<para xml:id='p1'>The real purpose of a user group is to bring together
<emphasis>users</emphasis> (and prospective users). There was
much lively discussion after my presentation, which I won't attempt to
recapitulate here. The next NYMUG meeting will (most likely) be sometime
in January, so please plan to come. I'll post more concrete details here
when they're available, and we'll send them to
the
<link xlink:href="http://developer.marklogic.com/mailman/listinfo/nymug">mailing
list</link>, of course.</para>

<para xml:id='p2'>My biggest problem in preparing for speaking events is figuring
out what to talk about, and then figuring out how to stretch that
topic to fit in the time allotted.</para>

<para xml:id='p3'>When I was suggested as the speaker for our inaugural New York
meeting, I had to figure out what to talk about. I quickly thought of
a topic, but never imagined that it'd be possible. To my delight and
surprise, when I shopped the idea around engineering and marketing,
there was universal support for the idea. So after I picked my jaw up
off the floor, I had to turn my attention to stretching the
topic.</para>

<para xml:id='p4'>The topic I had in mind would easily fit on a couple of slides.
That would make for a pretty short talk. At a user group meeting,
maybe that wouldn't be all bad, but I felt I needed to say a bit more.
I stretched things out by talking about three new and cool features
that I thought some folks might not have seen or used yet.</para>

<section xml:id="https">
<title>Support for https: and URI rewriting</title>

<para xml:id='p5'>Support for <systemitem class="protocol">https:</systemitem>
is pretty self-explanatory. Lots of
sites have private information (user profiles and passwords, for example) that
<emphasis>should not</emphasis> (many would say “must not”) be sent
over an insecure communications channel. Furthermore, most users have been trained
to look for a secure connection before sending credit card or other financial
information over the web.</para>

<para xml:id='p6'>Support for URI rewriting allows application authors to make cleaner
interfaces. I'm a fan of clean URI interfaces. Call me picky, but
 think it's a lot better to
expose the 4th slide in your presentation as
<uri>http://example.com/slides/nymug/4</uri> than as
<uri>http://example.com/slides.xqy?deck=nymug.xml&amp;foil=4&amp;format=html</uri>.
</para>

<para xml:id='p7'>Until recently, if you wanted to do this with a web site built on top
of MarkLogic Server, you had to put up a proxy of some sort (often an
Apache web server) to provide <systemitem class="protocol">https:</systemitem>
support and URI rewriting.
</para>

<para xml:id='p8'>Starting with MarkLogic Server V4.1, this is no longer necessary.
MarkLogic server now supports https (with your own certificate or a generated,
self-signed one) out of the box. The server also supports URI rewriting by
allowing you to designate an arbitrary query module to rewrite URIs.
Here's the example I used in the presentation:</para>

<programlisting xml:space="preserve">xquery version "1.0-ml";

declare variable $url as xs:string
        := xdmp:get-request-url();

if (matches($url, "^/slides/([^/]+)/([0-9]+)$"))
then
  replace($url,
          "^/slides/([^/]+)/([0-9]+)$",
          "/slides.xqy?deck=$1.xml&amp;amp;foil=$2")
else
  $url</programlisting>

<para xml:id='p9'>It's an incomplete, toy example taken from the real code I used
on the server behind my presentation, but it gives you a flavor for
how it works. Your module starts with the URL that that was used (and
access to the headers and other parts of the request), performs any
sort of computation that you'd like, and returns the new URI. The new
URI then goes into the server and is processed normally.</para>

<para xml:id='p10'>There may still be good reasons to put a proxy in front of MarkLogic
Server (load balancing, etc.), but you no longer have to just to satisfy
requests for these
two common and simple features.</para>

</section>
<section xml:id="toolkits">
<title>Office Toolkits</title>

<para xml:id='p11'>For reasons that will become clear later on (and not only because
I find “office applications” to be an inefficient, frustrating, pointless
time-suck), I wanted to present this presentation using ordinary web
technologies. (Specifically, HTML+CSS+JavaScript served up by MarkLogic
Server.)</para>

<para xml:id='p12'>At the same time, because I was going to talk about new server
features, I was required to present a disclaimer:</para>

<important xml:id="disclaimer">
<title>Disclaimer</title>
<para xml:id='p13'>All statements describing future releases, estimated release
dates and content are plans only, and Mark Logic is under no
obligation to develop, include or make available, commercially or
otherwise, any specific feature or functionality in any Mark Logic
product.</para>
<para xml:id='p14'>Information is provided for general understanding and
informational purposes only, and is subject to change at the sole
discretion of Mark Logic in response to changing customer
requirements, market conditions, delivery schedules and other
factors.</para>
</important>

<para xml:id='p15'>(A disclaimer that applies as much to this weblog essay as it
did to my presentation last night, I might add.)</para>

<para xml:id='p16'>Trouble is, this slide was sent to me in Powerpoint. To use it,
I'd have to switch to Powerpoint for the rest of my presentation (yuck!),
copy and paste the text (where's the fun in that?), or find some way
to incorporate the slide into my DocBook-based slide deck (now that
sounds interesting).</para>

<para xml:id='p17'>Luckily, one of our engineers, <personname><firstname>Pete</firstname>
<surname>Aven</surname></personname> has already done all the heavy lifting.
Pete's the primary developer of Mark Logic's open source toolkits for
Word, Excel, and Powerpoint. Each toolkit provides a pipeline for ingesting
office documents into MarkLogic server, an office plugin for using the
server from the application, and some XQuery code to work wtih the files
in the server.
</para>

<para xml:id='p18'>With that framework in place, it was pretty easy to write a little
bit of XQuery code that would extract a slide from a deck and transform
it into DocBook. (That's about 20 lines of code, nothing fancy, it extracts
paragraphs and bulleted lists from slides, no more, no less.)</para>

<para xml:id='p19'>The source for my final presentation looks like this:</para>

<programlisting><![CDATA[<slides xmlns="http://docbook.org.ns/docbook">
  <info>
    <title>Transforming XML Development <?lb?>with MarkLogic</title>
    …
  </info>
  <foilgroup>

    <foil>
      <title>NYMUG!</title>
      …
    </foil>

    <foil pptx="/pptx/disclaimer" foil="1"/>

    …
  </foilgroup>
</slides>]]></programlisting>

<para xml:id='p20'>a straightforward mixture of hand-authored slides and references to
slides from a couple of Powerpoint decks. For the presentation, I edited
a Powerpoint slide and ran it back through the process in real time, but that
doesn't translate very well to a weblog essay.</para>

</section>

<section xml:id="presentation">
<title>Presentation</title>

<para xml:id='p21'>That left just the last part of my talk, “the big reveal” as it were.
Having set this all up so that I can author in DocBook, even including
Powerpoint slides, serve it up over
<systemitem class="protocol">https:</systemitem>, and use nice looking URIs,
I still have to go the last mile and get the content into the browser.</para>

<para xml:id='p22'>A couple of obvious ways present themselves. I could serve it up as
XML with a stylesheet and let the browser do the work. Could do, but I didn't.
I could translate the DocBook markup into (X)HTML using XQuery in MarkLogic
Server. Could do, but I didn't.</para>

<para xml:id='p23'>What I really want, but haven't been able to do, is to transform the
DocBook in MarkLogic Server with XSLT. And
<tag class="starttag">cue</tag>drum roll<tag class="endtag">cue</tag>
… I can haz!
<tag class="starttag">cue</tag>cymbal crash<tag class="endtag">cue</tag></para>

<programlisting><![CDATA[let $doc := xdmp:document-get(concat($ROOT, $xml))/*
let $expanded := local:expand-powerpoint($doc)
let $map := map:map()
let $put := map:put($map, ...("dbp:foil")), $foil)
let $put := map:put($map, ...("dbp:deck")), $deck)
let $put := map:put($map, ...(xs:QName("dbp:format")),
                    $format)
return
  xdmp:xslt-invoke($xslt, $expanded, $map)]]></programlisting>

<para xml:id='p24'>Running an internal build, I can demonstrate support for XSLT
2.0 in MarkLogic Server. (Go back and read that disclaimer again now.)
</para>

<para xml:id='p25'>There was some rejoicing at the user group meeting, I hope there's
some rejoicing out there over the intertubes too. I'm certainly giddy with
delight over the prospects of high-performance XSLT processing in
MarkLogic Server V.future.</para>

<para xml:id='p26'>What more can I say. When you've done your best trick, it's time
to get off the stage.</para>

<para xml:id='p27'>Thanks again to
<personname><firstname>Steve</firstname><surname>Kotrch</surname></personname>
and Simon&#160;&amp;&#160;Schuster for hosting. Hope to see you all in
January!</para>
</section>
</essay>
