Daisy documentation
 PreviousHomeNext 
5.5 NavigationBook Index5.5.3 Implementation notes

5.5.2 Description of the navigation XML format

5.5.2.1 The empty navigation tree

The simplest possible navigation tree description is the empty one:

<d:navigationTree xmlns:d="http://outerx.org/daisy/1.0#navigationspec">
</d:navigationTree>

5.5.2.2 Document node

Adding document nodes to it is easy:

<d:navigationTree xmlns:d="http://outerx.org/daisy/1.0#navigationspec">
  <d:doc id="26"/>  
  <d:doc id="32">
    <d:doc id="15"/>  
  </d:doc>
</d:navigationTree>

As shown, the nodes can be nested.

By default , the navigation tree will display the name of the document as the label of a node. However, sometimes you might want to change that, for example if the name is too long. Also, when editing the navigation tree description as a source document, it will quickly become difficult to figure out what node stands for what. Therefore, you can add an attribute called "label" to the d:doc elements:

<d:navigationTree xmlns:d="http://outerx.org/daisy/1.0#navigationspec">
  <d:doc id="26" label="Introduction"/>  
  <d:doc id="32" label="Hot Stuff">
    <d:doc id="15" label="Fire"/>
  </d:doc>
</d:navigationTree>

By default the ID of a document node is the document ID, but you can assign a custom ID by specifying it in an attribute called nodeId. The custom ID should not start with a digit and not contain whitespace.

To link to a document on another branch or in another language, add a branch and/or language attribute on the d:doc element. The value of the attribute can be a branch/language name or ID. By default, documents are assumed to be on the same branch and in the same language as the navigation tree document itself.

5.5.2.2.1 Visibility

The d:doc node supports a visibility attribute. By default, nodes are visible. The visibility attribute allows to specify that a node should only become visible when it is active or should never be visible at all. Non-visible nodes are useful to have the navigation tree opened up to a certain point, without displaying a too-deeply nested hierarchy or a large amount of sibling nodes. In the Daisy Wiki, where the navigation tree controls the URL space, this can additionally be useful to control the URL path.

The syntax is:

<d:doc id="..." visibility="always|hidden|when-active"/>

5.5.2.3 Link node

To insert a link to an external location (a non-Daisy document), use the link element:

<d:navigationTree xmlns:d="http://outerx.org/daisy/1.0#navigationspec">
  <d:doc id="26" label="Introduction"/>  
  <d:doc id="32" label="Hot Stuff">
    <d:doc id="15" label="Fire"/>
  </d:doc>
  <d:link url="http://outerthought.org" label="Outerthought"/>
</d:navigationTree>

The attributes url and label are both required. The link element supports an optional id attribute.

5.5.2.3.1 Visibility

It is possible to hide link nodes depending on whether the user has read access to some other document (a guarding document). The syntax for specifying this document is:

<d:link url="http://www.daisycms.org" label="Daisy CMS"
        inheritAclDocId="78-DSY" inheritAclBranch="main" inheritAclLanguage="default"/>

As usual, specifying the branch and language is optional.

For the inheritAclDocId, one can use the special value "this" to refer to the Daisy document in which the navigation tree itself is stored. In this case, the value of the inheritAclBranch and inheritAclLanguage attributes, if present, is not used.

5.5.2.4 Group node

If you want to group a number of items below a common title, use the group element. The group element can optionally have an attribute called id to specify a custom id for the node (otherwise, the id is automatically generated, something like g1, g2, etc).

<d:navigationTree xmlns:d="http://outerx.org/daisy/1.0#navigationspec">
  <d:group label="Some title">
    <d:doc id="26" label="Introduction"/>  
    <d:doc id="32" label="Hot Stuff">
      <d:doc id="15" label="Fire"/>
    </d:doc>
  </d:group>
  <d:link url="http://outerthought.org" label="Outerthought"/>
</d:navigationTree>

The group node also supports the visibility attribute, see the document node for more information on this. 

5.5.2.5 Import node

To import another navigation tree, use the import element:

<d:navigationTree xmlns:d="http://outerx.org/daisy/1.0#navigationspec">
  <d:group label="Some title">
    <d:doc id="26" label="Introduction"/>  
    <d:doc id="32" label="Hot Stuff">
      <d:doc id="15" label="Fire"/>
    </d:doc>
    <d:import docId="81"/>
  </d:group>
  <d:link url="http://outerthought.org" label="Outerthought"/>
</d:navigationTree>

The docId attribute on the d:import element is of course the id of the navigation document to be imported.

5.5.2.6 Query node

It is possible to dynamically insert nodes by including a query, for example:

<d:navigationTree xmlns:d="http://outerx.org/daisy/1.0#navigationspec">
  <d:doc id="26" label="Introduction"/>  
  <d:doc id="32" label="Hot Stuff">
    <d:doc id="15" label="Fire"/>
    <d:query q="select name where $somefield='hot'"/>
  </d:doc>
</d:navigationTree>

The selected value, in this example "name", will be used as the node label.

Since the query is embedded in an XML file, don't forget that you might need to escape certain characters, e.g. < should be entered as &lt;

Queries embedded in a navigation tree are executed while building the internal model of the navigation tree. This internal model is cached and shared for all users, it is only updated when relevant changes happen in the repository. So if queries contain items that can change on each execution (such as the result of a CurrentDate() call), these will not work as expected.

5.5.2.6.1 Selecting multiple values

If you select multiple values in the query, then group nodes will be created for the additional selected values, for example:

select documentType, $Category, name where true

With this query, group nodes will be created per value of documentType, within that per value of $Category, and then finally document nodes with the name as label.

5.5.2.6.2 Selecting link values

When selecting a link value (as not-last value), a document node will be created instead of a group node.

5.5.2.6.3 Selecting multi-value and hierchical values

It is allowed to select multi-value and/or hierarchical values. Selecting a hierarchical value will cause the creation of a navigation hierarchy corresponding to the hierarchical path. For multi-value values, nodes will be created for each of the values.

5.5.2.6.4 Re-sorting nodes

Inside the d:query element, you can insert d:column elements specifiying options for each selected value (= each column in the query result set). The number of d:column elements is not required to be equal to the number of selected values (if there are more columns than selected values, the additional columns are ignored). The syntax is:

<d:query ...>
  <d:column sortOrder="none|ascending|descending" visibility="..."/>
  ... more d:column elements ...
</d:query>

Both the sortOrder and the visibility attributes are optional.

Note that it is also possible to use the "order by" clause of the query to influence the sort order, however with multi-value values or hierarchical values with paths of varying length, it might be needed to have the nodes sorted after tree building. Specifying both an order by clause and sortOrder's on the d:column attributes is not useful, it will only cause extra time to build up the navigation tree.

5.5.2.6.5 Nesting nodes inside a query node

It is possible to nest any sort of node inside a query node, including query nodes themselves. The nested nodes will be executed once for each result in the query, and inserted at the deepest node created by the result set row. If there are any multivalue fields among the selected values in the query, this will be done multiple times.

Attributes of nested nodes can refer to the current result row and its selected values using ${...} syntax. Available are: ${documentId}, ${branchId}, ${languageId}, and each selected value can be accessed using ${1}, ${2}, ...

When query nodes are nested inside query nodes, ${../1} syntax can be used to refer to values from higher-level query nodes.

If the expressions are inside a "q" attribute of a query node, the value will be automatically formatted appropriately for use in queries. For example, correct date formatting or escaping of string literals. Quotes will be added automatically as necessary, so you can just do something like $MyStringField = ${3}.

If the expression is used in the url attribute a link node, the value will be automatically URL-encoded (using UTF-8).

In all other cases, a simple "toString" of the value is inserted.

When an expressions refers to a non existing value (e.g. ${5} when there are less than 5 selected values), the expression will be left untouched (e.g. the output will contain ${5})

If a selected value is multivalue or hierarchical (or both) it is currently not made available for retrieval in expressions.

To insert ${ literally, use the escape syntax \${.

5.5.2.6.6 useSelectValues attribute

If you want to select some values in a query to make them accessible to child nodes, but don't want these values to be used for constructing nodes in the tree, the useSelectValues attribute of the d:query element can be used. The value of this attribute is a number specifying how many of the selected values should be used (counting from the left). This value may be null, in which case the current query node itself will not add any nodes to the navigation tree (this only makes sense if the query node has child nodes).

5.5.2.6.7 Default visibility

The query element can have a visibility attribute to specify the default visibility, for cases where the visibility is not specified for individual columns.

5.5.2.6.8 Filter variants

The query element can have an optional attribute called filterVariants with value true or false. If true, the query results will be automatically limited to the branch and language of the navigation document.

5.5.2.6.9 Example: query-import navigation trees

If you want to dynamically import navigation trees using a query, you can use the following construct:

<d:query q="select id where documentType = 'Navigation' order by name" useSelectValues="0">
  <d:import docId="${documentId} branch="${branchId}" language="${languageId}"/>
</d:query>
5.5.2.6.10 Example: generating link nodes
<d:query q="select name where true" useSelectValues="0">
  <d:link label="Search on google for ${1}"
          href="http://www.google.com/search?q=${1}"
</d:query>

5.5.2.7 Separator node

A separator node is simply a separating line between two nodes in the navigation tree. Its syntax is:

<d:separator/>

Multiple sibling separator nodes, or separator nodes appearing as first or last node within their parent, are automatically hidden.

5.5.2.8 Associating a navigation tree with collections

If you want to automatically limit the result of queries in the navigation tree to documents contained by one ore more collections, you can add a collections element as first child of the navigationTree element:

<d:navigationTree xmlns:d="http://outerx.org/daisy/1.0#navigationspec">
  <d:collections>
    <d:collection name="MyCollection"/>
  </d:collections>
  <d:doc id="26" label="Introduction"/>  
  <d:doc id="32" label="Hot Stuff">
    <d:doc id="15" label="Fire"/>
    <d:query q="select name where $somefield='hot' order by name"/>
  </d:doc>
</d:navigationTree>

5.5.2.9 Node nesting

The doc, group, query, separator, link and import nodes can be combined and nested as you desire, with the exception that separator and import can't have child elements.

Any other elements besides the ones mentioned here are prohibited, as is text in between the nodes.

 PreviousHomeNext 
5.5 Navigation5.5.3 Implementation notes