<?xml version="1.0" encoding="UTF-8"?>
<book><bookinfo><productname>eXist-db – Open Source Native XML Database</productname><title>Getting Started with Web Application Development</title><date>October 2012</date></bookinfo><chapter><title>Getting Started with Web Application Development</title><para>Being much more than just an XML database, eXist-db provides a complete platform for
            the development of rich web applications based on XML and related technologies (XQuery,
            XForms, XSLT, XHTML...).</para><para>Key components of this platform are:</para><itemizedlist><listitem><para>a standardized packaging format for modular applications, allowing deployment
                    into any eXist-db instance</para></listitem><listitem><para>a set of tools to create application packages, integrated into our XQuery IDE,
                    eXide</para></listitem><listitem><para>an <ulink url="templating.xml">HTML templating framework</ulink> for a clean
                    separation of HTML page content and application logic</para></listitem><listitem><para>a tight integration with XForms for fast form development</para></listitem><listitem><para>a clean approach for the deployment of RESTful services based on XQuery code
                    annotations (RESTXQ)</para></listitem></itemizedlist><para>This tutorial will demonstrate how to quickly prototype an application based on above
            components. Certainly there are many other ways to integrate eXist-db into your own
            application. This guide describes only one of the many possible approaches. However, we
            have found that taking the first steps is the most difficult part for new users, so we
            tried to make it as simple as possible.</para><section><title>The Packaging</title><para>eXist-db 2.0 builds on the concept of self-contained, modular applications which
                can be deployed into any database instance using a standardized packaging format.
                Applications live inside the database, so application code, HTML views, associated
                services and data all reside in the same place - though maybe in different root
                collections. This makes it easy to e.g. backup an application into the file system,
                pass it to someone else for installation in his own db, or even publish it to
                eXist-db's public repository. The documentation, the dashboard, eXide and the eXist
                XQuery Features Demo are examples of application packages.</para><para>The packaging format is compliant with the EXPath packaging proposal, though it
                extends it considerably. For distribution, an application is packed into a .xar
                archive, which is basically a ZIP archive. The .xar archive contains all the
                application code required by the application, and optionally sample or full data,
                along with a set of descriptors. The descriptors describe the application and
                control the installation process. As an absolute minimum, an application package
                    <emphasis>must</emphasis> contain two descriptor files:
                    <filename>expath-pkg.xml</filename> and <filename>repo.xml</filename>. You can
                read more about those files in the <ulink url="repo.xml">package repository documentation</ulink>, but knowledge
                about these is not required for the following sections, since eXide will create the
                proper descriptors for you automatically.</para></section><section><title>Starting a New Application</title><para>To start a new application, open <ulink url="{eXide}/index.html">eXide</ulink> by
                clicking the link or by going via the dashboard or the system tray menu of
                eXist-db.</para><procedure><step><para>From the main menu, select
                            <guimenuitem>Application</guimenuitem>/<guimenuitem>New
                            Application</guimenuitem>. The Deployment Editor dialog should pop up.
                        If you are not logged in as an admin user yet, you'll first be required to
                        do so.</para></step><step><para>Fill out the form by choosing a template, a target collection, a name, an
                        abbreviation and a title for the application. All other form fields and
                        pages are optional, so you can ignore them for now.</para><figure><title>Deployment Editor Dialog</title><mediaobject><imageobject><imagedata fileref="resources/new-application-screen.png" scale="75%"/></imageobject></mediaobject></figure><para>The important fields are:</para><variablelist><varlistentry><term>Template</term><listitem><para>The template used to generate the new application. Right now
                                    three templates are available: the "eXist-db Design" template is
                                    based on the standard eXist-db page layout and design. The
                                    "Plain" template creates a basic page layout without eXist-db
                                    specific stuff. Both templates use the Bootstrap CSS library for
                                    styling and the HTML templating XQuery module to achieve a clean
                                    separation of concerns. The "Empty Package" creates an empty
                                    package with just the descriptors in it.</para></listitem></varlistentry><varlistentry><term>Type of the package</term><listitem><para>The main distinction between "library" and "application" is: a
                                    "library" does not have an HTML view and will thus not appear
                                    with a clickable icon in the dashboard. Selecting "library" here
                                    does only make sense in combination with the "Empty Package"
                                    template.</para></listitem></varlistentry><varlistentry><term>Target collection</term><listitem><para>This is the collection where your app will be installed by
                                    default. Please note that this can be changed by the package
                                    manager during install. It is just a recommendation, not a
                                    requirement.</para></listitem></varlistentry><varlistentry><term>Name</term><listitem><para>A unique identifier for the application. The EXPath proposal
                                    recommends to use a URI here to avoid name collisions so we have
                                    made this is requirement.</para></listitem></varlistentry><varlistentry><term>Abbreviation</term><listitem><para>A short abbreviation for the application. Among other things,
                                    it will be used as the file name for the final .xar package and
                                    for the name of the collection into which the application
                                    installs. It is thus best to choose a simple abbreviation
                                    without spaces or punctuation characters.</para></listitem></varlistentry><varlistentry><term>Title</term><listitem><para>A short description of the application, which will be
                                    displayed to the user, e.g. in the dashboard.</para></listitem></varlistentry></variablelist></step><step><para>Click on <guimenuitem>Done</guimenuitem> when you have completed the form.
                        eXide will now generate a collection hierarchy for the application based on
                        the template you had selected. Once this has completed, the
                            <guimenuitem>Open Document</guimenuitem> dialog will pop up to indicate
                        that you can start editing files.</para><para>In the following, we assume that the app has been called "Tutorial" and
                        its abbreviation is "tutorial".</para><figure><title>Open Document Dialog after generating application </title><mediaobject><imageobject><imagedata fileref="resources/new-application-completed.png"/></imageobject></mediaobject></figure></step><step><figure float="1" floatstyle=""><title>Run Dialog</title><mediaobject><imageobject><imagedata fileref="resources/new-application-run.png"/></imageobject></mediaobject></figure><para>To test if the application has been generated properly, select the
                            <filename>index.html</filename> page of the new app in the open dialog
                        and load it into eXide. With <filename>index.html</filename> open, select
                            <guimenuitem>Application</guimenuitem>/<guimenuitem>Run App
                        </guimenuitem> from the menu. A small dialog box will pop up, showing you a
                        link to the application.</para><para>Click on the link to run the application in a separate browser tab. </para><figure><title>The Default Start Page of the Application</title><mediaobject><imageobject><imagedata fileref="resources/new-application-home.png"/></imageobject></mediaobject></figure><para>All the items in the <guimenuitem>Application</guimenuitem> menu apply to
                        the active app, which is the application to which the file currently open in
                        the editor belongs. You can check which app is active by looking at the
                        "Current app:" status label at the top right of the eXide window.</para></step></procedure></section><section><title>Understanding the Default Application Structure</title><para>As you can see, eXide has created an application skeleton for you which works out
                of the box. All resources of the application reside below the target collection
                    (<filename>/db/tutorial</filename>).</para><para>The generated collection hierarchy follows a certain structure, which is usually
                the same for all apps which ship with eXist-db. The most important collections and
                files are described below:</para><variablelist><varlistentry><term>/modules/</term><listitem><para>Contains XQuery modules. Most of the actual application code should go
                            here.</para></listitem></varlistentry><varlistentry><term>/resources/</term><listitem><para>Secondary resources like CSS files, images or JavaScript.</para></listitem></varlistentry><varlistentry><term>/templates/</term><listitem><para>Page templates containing all the repeating parts of the site's HTML
                            layout, i.e. all the stuff which applies to every HTML view of the
                            application.</para></listitem></varlistentry><varlistentry><term>collection.xconf</term><listitem><para>A template file for the index configuration that should apply to this
                            application. This file will be copied into the correct system collection
                            when the application is installed, thereby automatically indexing any
                            data that is installed.</para></listitem></varlistentry><varlistentry><term>controller.xql</term><listitem><para>The URL rewriting controller which handles the URL space of the
                            application. You will rarely need to change this for simple
                            applications.</para></listitem></varlistentry><varlistentry><term>expath-pkg.xml and repo.xml</term><listitem><para>These are the package descriptor files for the application that
                            contain the information you entered via the Deployment Editor. You don't
                            need to edit these files directly. Instead, open the Deployment Editor
                            to change any of the descriptor properties.</para></listitem></varlistentry><varlistentry><term>index.html</term><listitem><para>The default start page of the application.</para></listitem></varlistentry><varlistentry><term>pre-install.xql</term><listitem><para>An XQuery script which will be run by the package manager
                                <emphasis>before</emphasis> installing the app. By default, the
                            script only ensures that the index configurations in collection.xconf
                            are properly copied into the corresponding system collection before the
                            app is installed.</para><para>In addition to <guimenuitem>pre-install.xql</guimenuitem>, you may
                            also define a <guimenuitem>post-install.xql</guimenuitem> script via the
                            Deployment Editor. As the name says, this script will run after the app
                            has been deployed into the database and is most often used to copy
                            resources or run initialization tasks required by the app. </para></listitem></varlistentry></variablelist><para>You are not required to keep this structure. Feel free to restructure the app as
                you like it and remove some of its parts. However, you have to preserve the two
                descriptor files <filename>expath-pkg.xml</filename> and
                    <filename>repo.xml</filename>.</para></section><section><title>The HTML Templating Framework </title><para>The generated application code uses the <ulink url="templating.xml">HTML
                    Templating Framework</ulink> to connect HTML views with the application logic.
                The goal of the HTML templating framework in eXist-db is a clean separation of
                concerns. Generating web pages directly in XQuery is quick and dirty, but this makes
                maintenance difficult and it is usually bad for code sharing and for team work. If
                you look at the <filename>index.html</filename> page, you'll see it is just an HTML
                div defining the actual content body. The rest of the page is dragged in from the
                page template residing in <filename>templates/page.html</filename>.</para><para>The <filename>controller.xql</filename> is configured to call the HTML templating
                for every URL ending with <option>.html</option>. The processing flow for an
                arbitrary <filename>.html</filename> file is shown below:</para><figure><title>Processing Flow</title><mediaobject><imageobject><imagedata fileref="resources/Templating.png"/></imageobject></mediaobject></figure><para>The input for the templating is always a plain HTML file. The module scans the
                HTML view for elements with class attributes, following a simple convention. It
                tries to translate the class attributes into XQuery function calls. By using class
                attributes, the HTML remains sufficiently clean and does not get messed up with
                application code. A web designer could take the HTML files and work on them without
                being bothered by the extra class names. </para><para>If you look at <filename>index.html</filename>, the class attribute on the outer
                div contains a call to a templating function:</para><synopsis language="html">&lt;div class="templates:surround?with=templates/page.html&amp;amp;at=content"&gt;</synopsis><para><code>templates:surround</code> is one of the default templating functions provided
                by the module. It loads <filename>templates/page.html</filename> and inserts the
                current div from  <filename>index.html</filename> into the element with the id
                "content" in <filename>templates/page.html</filename>. A detailed description of
                    <code>templates:surround</code> can be found in the HTML templating module
                documentation.</para><para>In the generated application template, you can add your own templating functions
                to the XQuery module <filename>modules/app.xql</filename>, which is included by
                default (you can also add your own modules though: just import them in
                    <filename>modules/view.xql</filename>). 
                 </para></section><section><title>Example: "Hello World!"</title><para> For illustration, let's implement the
                traditional "Hello World!" example: </para><procedure><step><para>Create a new HTML view, <filename>hello.html</filename>, in eXide and add
                        the following content. To create the file, choose
                            <guimenuitem>File</guimenuitem> / <guimenuitem>New</guimenuitem> from
                        the menu. Make sure you set the <option>file type</option> to HTML (see the
                        drop down box at the top right in eXide).</para><programlisting language="xml">&lt;div class="templates:surround?with=templates/page.html&amp;amp;at=content"&gt;
    &lt;form action=""&gt;
        &lt;label for="name"&gt;Enter your name:&lt;/label&gt;
        &lt;input name="name"/&gt;
    &lt;/form&gt;
    &lt;p class="app:helloworld"&gt;&lt;/p&gt;
&lt;/div&gt;</programlisting><para>This creates a simple form and a paragraph which is connected to a
                        template function, <filename>app:helloworld</filename>, through its class
                        attribute.</para><para>Save the HTML view to the root collection of your application, e.g.
                            <filename>/db/apps/tutorial/hello.html</filename>.</para></step><step><para>Open <filename>modules/app.xql</filename> and add an XQuery function
                        matching the <code>app:helloworld</code> template
                        call:<programlisting language="xquery">declare function app:helloworld($node as node(), $model as map(*), $name as xs:string?) {
    if ($name) then
        &lt;p&gt;Hello {$name}!&lt;/p&gt;
    else
        ()
};</programlisting></para><para>A template function is a normal XQuery function known in the context of
                        the calling XQuery (<filename>modules/view.xql</filename>), which takes at
                        least two required parameters: $node and $model, though additional
                        parameters are allowed (see below). $node is the HTML element currently
                        being processed - in this case a <sgmltag>p</sgmltag> element. $model is an
                        XQuery map containing application data. We can ignore both parameters for
                        this simple example, but they must be present or the function won't be
                        recognized by the templating module. Please refer to the <ulink url="templating.xml">HTML templating documentation</ulink> to read more
                        about those parameters.</para><para>The third parameter, $name, is injected automatically by the templating
                        framework. For now it is sufficient to know that the templating library will
                        try to make a best guess about how to fill in any additional parameters. In
                        this case, an HTTP request parameter with the name "name" will be passed in
                        when the form is submitted. The parameter name matches the name of the
                        variable, so the templating framework will try to use it and the function
                        parameter will be set to the value of the request parameter. </para></step><step><para>Open <filename>hello.html</filename> in the web browser using the base URL
                        of your app, e.g.:</para><synopsis>http://localhost:8080/exist/apps/tutorial/hello.html</synopsis><para>Fill out the box with a name and press return.</para></step></procedure><para>The templating framework has many more features, so you may want to head over to
                its <ulink url="templating.xml">documentation</ulink> to read more about it.</para></section><section><title>Exporting the App</title><para>Once you have created the first pages of an application, it is usually a good idea
                to export it to a folder on disk. You could just click on
                    <guimenuitem>Application</guimenuitem>/<guimenuitem>Download app</guimenuitem>
                to retrieve a <filename>.xar</filename> archive of the application, but exporting
                the app to the file system has the advantage that you can continue working on the
                app and have eXide keep track of which files have been modified since the last export. You
                may also want to add your app to a source control system like subversion or git,
                and this is easier if you have a copy on the file system.</para><para>To create an export to a directory on the file system, click
                    <guimenuitem>Application</guimenuitem>/<guimenuitem>Synchronize</guimenuitem>.
                In the popup dialog, fill in the path to the desired <emphasis>Target
                    directory</emphasis>. If you are accessing eXist-db on a server, not the machine
                you are opening eXide in, this must point to a directory on the server running
                eXist-db, not your local file system. If you are running eXist from your own
                machine,  the two are the same. The <emphasis>Start time</emphasis> can be ignored
                for now. It may show the time of your last export if you call synchronize again on
                the same application.</para><figure><title>Synchronize Dialog</title><mediaobject><imageobject><imagedata fileref="resources/sync-dialog.png"/></imageobject></mediaobject></figure><para>Clicking on <guimenuitem>Synchronize</guimenuitem> will start the export and the
                names of the written resources should show up in the table at the bottom of the
                dialog.</para></section></chapter></book>