You are here: Q and A / TECHNICAL: How it works / Customizing liveSTORYBOARD CMS

How liveSTORYBOARD web CMS works, customization

How customizable is liveSTORYBOARD CMS? Do I have to be an experienced XML/XSLT developer to customize the CMS?

liveSTORYBOARD CMS is very flexible and almost anything can be customized. In most cases, clients modify CSS and XHTML.

You don't have to have a any previous experience with XML/XSL to get started. It would help if you'd like to take things completely into your own hands and modify liveSTORYBOARD CMS extensively on your own. If that's the case - not to worry - we help you in two ways:

  • liveSTORYBOARD CMS comes with defaults for everything you need - from XML to XSLT to CSS, so you can use these defaults to extend (as opposed to creating them from scratch), as well as learn, if you are new to these technologies.

  • We are here to help - our team often gets hired to help customize more complex projects. Get in touch if you are interested in our consulting services or simply to ask more questions.

Below are brief descriptions of key components of liveSTORYBOARD CMS used to customize projects. The project's XML content and configuration are used in XSL(T) 1.0 transformations and indexed so that search can be finely tuned.

Configuration

Transformations use a site configuration file ($PROJECT_HOME/lsb/site.xml) as the main source. Other configuration files are used for group permissioning, GUI configuration, structure, metadata, etc., but we don't want to bore you with the details here.

The site configuration can be defined as a virtual file system. It breifly describes metadata used for several transformation scenarios (more metadata is stored in a separate file, see the metadata section below). The schema for the site.xml can be found at $LSB_DEFAULT/schemas/site_config.xsd. An example site.xml looks like:

<site xmlns="http://livestoryboard.com/schemas/lsb" id="site_root" status="editorial" generate="1" label="Home" name="DEMO" index_page="site_ind" snailtrail="1" xsl="default"> <page id="site_ind" status="editorial" generate="1" onnav="1" label="Welcome to this website" name="Welcome.html"/> <page id="p1" status="editorial" generate="1" label="New page 1" name="one.html" atom="1"/> <topic id="t1" status="editorial" generate="1" onnav="1" label="Topic 1" name="topic1" snailtrail="1" pager="1" atom="1" xsl="topics"> <content id="c1" status="editorial" generate="1" onnav="1" label="Article 1" name="article1.html" xsl="default"/> <content id="c2" status="editorial" generate="1" onnav="1" label="callout 1" name="c2.html"/> </topic> <folder id="f1" status="editorial" generate="1" onnav="1" label="Sailing" name="Sailing" index_page="p2" snailtrail="1"> <page id="p2" status="editorial" generate="1" onnav="1" label="Sailing Page" name="sailing.html"/> <page id="p3" status="editorial" generate="1" onnav="1" label="Sailing page 2" name="sailing2.html"/> </folder> <content id="c3" status="editorial" onnav="1" label="breaking news" name="c3.html"/> </site>

There are five elements in site.xml:

  • Site - the root element for a project website. It can contain an index_page attribute which tells the page that should be used as the site's index page. It also includes an xsl attribute which indicates a named template to provide a wrapper or decorator (see the XSL section below). Those descendants that do not have an xsl attribute will fallback to the value of the ancestor that has one. The site element can contain folder, page, topic and content elements.

  • Folder - is similar to the site element. @snailtrail indicates that snailtrails (or breadcrumbs) should show on its child pages and/or content pieces. @pager means a paging navigation should show on its child pages and/or content pieces. The folder element can contain folder, page, topic and content elements.

  • Page - is usually used as a container for multiple content pieces (assigned to regions in the metadata file). It has no child elements.

  • Topic - is a hierarchical way to organize topics and content pieces. It can be used to simply organize content pieces or generated to provide a structured view of the topic and/or content. Its children include topics and content.

  • Content - can be generated as an XHTML page (or ATOM, RSS, print friendly HTML, text,...) and/or assigned to pages, folders and site, which are generated. When assigned to folders or the site it cascades down to its children or descendants depending on the XSL. The content element has no children.

Attributes with a value of "1" are used as a stylesheet trigger. For example, add a snailtrail to all pages in a folder or not. A value of "0" or removing an attribute turns attribute-driven options off.

Metadata

Each element in the site.xml configuration file uses its localName and ID as a pointer to a metadata file that further defines the node ($PROJECT_HOME/lsb/metadata/{$nodeName}/{$ID}.xml). The schema for metadata is found at $LSB_DEFAULT/schemas/metadata_config.xsd.

The metadata files contain information, such as:

  • Creation and last modified dates in ISO-8601 format

  • Creator and last modifed by

  • Dublin Core metadata

  • Title and description - the default XSLs look first for DC equivalents, if not found they fallback to these. For example a page title looks first for dc:title, if not found the generic title is used, else the site.xml's label attribute. The XSL can utilize the multiple title/description storage options for the HTML title tag, an H1, navigation title.

  • Regions and content assignments - In liveSTORYBOARD CMS, content and components (any well-formed markup) can be easily reused and assigned to different defined regions. Regions can be columns or any part of a page. Content is normally assigned to a page, but can be assigned to folders and even the site. If assigned to the site or folder it cascades down to its children or descendants.

  • Extended properties - name/value pairs that can be used for additional site element metadata.

An example page metadata file can look like:

<md-page xmlns="http://livestoryboard.com/schemas/lsb" creator="Iva Koberg" created="2004-11-07T04:46:20" modified="2005-01-25T06:26:55" last_mod_by="Iva Koberg"> <regions> <region name="Region1"> <content ref="c1"/> <content ref="c2"/> </region> </regions> <title>The title</title> <dc xmlns:dc="http://purl.org/dc/elements/1.1/"> <dc:title>liveSTORYBOARD CMS Questions</dc:title> </dc> <extended_properties> <property name="foo">bar</property> </extended_properties> </md-page>

Content

Content pieces in liveSTORYBOARD CMS can be any well-formed markup. liveSTORYBOARD CMS provides a default XML Schema (basically XHTML minus structural elements (HTML, HEAD, BODY) and DIV and SPAN). DIV and SPAN type XHTML elements are replaced with more semantically meaningful elements in liveSTORYBOARD CMS (such as: important, fineprint, note, section, etc.). The default schema can be extended/restricted or disregarded. An example FAQ content type instance might look like this:

<faq> <question> <p>Why should we care about accessibility? </p> </question> <answer> <p>By following accessibility when building a web site, you will not only help the millions of web users with various disabilities, you will widen your site's audience and increase your potential customer base. Web site accessibility compliance is also required by law in many cases.</p> </answer> </faq>

We get asked why we don't just use DIVs with class="faq"? Because it is not possible to validate in XML Schema. RNG could be used, of course, but there is little editor support. Plus, we prefer to match by element rather than by class name.

XSLT

liveSTORYBOARD CMS uses a base set of XSL files as defaults or fallbacks. Any project can override/extend the default set or create new XSLTs from scratch. Defaults are provided for:

  • Top level navigation (tabs)

  • Second level navigation (a left/right nav)

  • Snailtrail or bread crumbs

  • Paging mechanisms (previous 1 2 3 next)

  • Table of contents

  • Folder or site level index pages

  • Site maps

  • and others...

A project only needs a layouts.xsl which defines the wrapper(s) (or decorators) templates. There, we xsl:import default/fallback XSLs and local overrides/extends. The liveSTORYBOARD CMS public website has xsl:imports for the following:

<xsl:import href="head.xsl"/> <xsl:import href="banner.xsl"/> <xsl:import href="top-level-nav.xsl"/> <xsl:import href="second-level-nav.xsl"/> <xsl:import href="topics.xsl"/> <xsl:import href="footer.xsl"/> <xsl:import href="components/indexer.xsl"/> <xsl:import href="components/siteindex.xsl"/> <xsl:import href="components/metadata.xsl"/> <xsl:import href="components/toc.xsl"/> <xsl:import href="components/pager.xsl"/> <xsl:import href="components/snailtrail.xsl"/> <xsl:import href="content.xsl"/> <xsl:import href="table.xsl"/> <!-- start: override very carefully --> <xsl:import href="global_definitions.xsl"/> <xsl:import href="metadata_nodesets.xsl"/> <xsl:import href="linking.xsl"/> <xsl:import href="aggregator.xsl"/> <xsl:import href="jsp.xsl"/> <xsl:import href="jspp.xsl"/> <!-- end: override very carefully --> <xsl:import href="extends.xsl"/>

We override a few of the defaults by naming a file the same as the default/fallback. You can also redefine one or two templates in a fallback, but still use the rest. Our URI Resolver first looks in the project's well-known directory structure. If it does not find the file, it falls back to the default.

The most interesting XSLs above are the global_defintions.xsl and metadata_nodesets.xsl. They hold several global variables and utility templates that are used throughout all the templates.

Aggregator.xsl is a centralized location to pull in content (using the XSL document function), as indicated by the site config and appropriate metadata files.

Linking.xsl is another important XSL. Because we use the site.xml config file as the main source, page relative, internal links will always be valid by traversing the config hierarchy.

As mentioned previously, the wrappers (or decorators) are defined in the layouts.xsl, which might look like:

<!-- The params/variables you see here are defined in the global_definitions.xsl and metadata_nodesets.xsl --> <xsl:template match="/"> <html xmlns="http://www.w3.org/1999/xhtml"> <xsl:call-template name="head"/> <body class="{$lsb_folder_nodeset/@name}"> <xsl:if test="$context='0'"> <xsl:attribute name="onload"> <!-- necessary only if using the LSB web interface --> <xsl:text>cover();</xsl:text> </xsl:attribute> </xsl:if> <xsl:choose> <xsl:when test="$user.focus.layout='default'"> <xsl:call-template name="default"/> </xsl:when> <xsl:when test="$user.focus.layout='nonav'"> <xsl:call-template name="home"/> </xsl:when> <xsl:otherwise> <h1> <em>Template not found: <xsl:value-of select="$user.focus.layout"/></em> </h1> </xsl:otherwise> </xsl:choose> </body> </html> </xsl:template> <xsl:template name="home"> <div id="content-body"> <xsl:call-template name="banner"/> <xsl:call-template name="tabs"/> <div id="content-main"> <div id="content-wrap"> <h1> <xsl:value-of select="$focus_title"/> </h1> <xsl:apply-templates mode="load_regions" select="$lsb_folder_metadata/s:regions/s:region[@name='wideColumn']/*"/> <xsl:choose> <xsl:when test="not($lsb_focus_localName='content')"> <xsl:apply-templates mode="load_regions" select="$lsb_focus_metadata/s:regions/s:region[@name='wideColumn']/*"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates mode="load_regions" select="$lsb_focus_nodeset"/> </xsl:otherwise> </xsl:choose> </div> </div> <div id="content-sidebar"> <xsl:call-template name="searchform"/> <xsl:apply-templates mode="load_regions" select="$lsb_folder_metadata/s:regions/s:region[@name='narrowCol']/*"/> <xsl:apply-templates mode="load_regions" select="$lsb_focus_metadata/s:regions/s:region[@name='narrowCol']/*"/> </div> <xsl:call-template name="footer"/> </div> </xsl:template> <xsl:template name="default"> <div id="content-body"> <xsl:call-template name="banner"/> <xsl:call-template name="tabs"/> <div id="content-main"> <div id="content-wrap"> <xsl:if test="$lsb_folder_nodeset/@snailtrail='1'"> <xsl:call-template name="snailtrail"/> </xsl:if> <h1> <xsl:value-of select="$focus_title"/> </h1> <xsl:apply-templates mode="load_regions" select="$lsb_folder_metadata/s:regions/s:region[@name='wideColumn']/*"/> <xsl:choose> <xsl:when test="not($lsb_focus_localName='content')"> <xsl:apply-templates mode="load_regions" select="$lsb_focus_metadata/s:regions/s:region[@name='wideColumn']/*"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates mode="load_regions" select="$lsb_focus_nodeset"/> </xsl:otherwise> </xsl:choose> <xsl:if test="$lsb_folder_nodeset/@pager='1'"> <xsl:call-template name="pager"/> </xsl:if> </div> </div> <div id="content-sidebar"> <xsl:call-template name="searchform"/> <div id="nav-header"> <xsl:variable name="href"> <xsl:apply-templates select="$lsb_folder_nodeset" mode="get_page_href"/> </xsl:variable> <a href="{$href}"> <xsl:value-of select="$lsb_folder_nodeset/@label"/> </a> <xsl:text>:</xsl:text> </div> <xsl:call-template name="nav"/> <xsl:apply-templates mode="load_regions" select="$lsb_folder_metadata/s:regions/s:region[@name='narrowCol']/*"/> <xsl:apply-templates mode="load_regions" select="$lsb_focus_metadata/s:regions/s:region[@name='narrowCol']/*"/> </div> <xsl:call-template name="footer"/> </div> </xsl:template>

Have questions? Get in touch and we would be happy to cover further details or provide specific examples.

« prev1 2 3 4 5 6 7 8 9 10 11 12




Content Management by liveSTORYBOARD Web CMS Content Management by liveSTORYBOARD CMS | Site Updated: 01/25/2008