OpenWGA 7.6 - OpenWGA Concepts and Features

Design and development » HDBModel framework

Navigating and querying the HDBModel hierarchy

When developing WebTML for your application you will need to know how to navigate in your document hierarchy. Either that you need to select child documents for a given parent content or your want to query your documents for special content classes or other custom conditions. HDBModel provides some strategies to accomplish this with the used WebTML tools for that purpose.

Using the HDBModel unique name and name parts

HDBModel automatically creates unique names for each content and storage created which represent the hierarchy position of the given document.

The unique name of a document consists of:

  • the HDBModel document ID of the current document
    • Which is the storage id, if the document is a storage
    • Or the content id (!= content key, struct key), if the document is a content. This is a custom id of every content that is automatically generated by default (as a random 32-char string), but may also be determined by the contents data via custom code
  • preceded with all the HDBModel document IDs of the documents up the hierarchy.
  • All single IDs in the unique name are divided by point characters ".". Also all IDs are lowercased automatically and "dangerous" characters inside them (like "." and "/") are replaced with underscores "_".

This gives the root storages a very simple, navigable, ID. The name of the "projects" storage from the example data (on page HDBModel framework) would simply be:

"projects"

When we assume that the content IDs of "project" documents equal their project title, then the unique name of the document "Project X" should be:

"projects.project x"

When we further assume the same for "document" contents then the document "Concept" should have the unique name:

"projects.project x.documents.concept"

How does this help you in navigating the hierarchy? At first you may use the unique names in WebTML context expressions using the "name:" expression. So you could navigate the WebTML context to the "projects" storage simply by:

<tml:range context="name:projects">

....

</tml:range>

On this context you could use a simple WebTML navigator to iterate through all project documents.

Another notable context expression for HDBModel navigation is the namepart expression  "np:". It lets you navigate to a document whose unique name consists of the name of the current context document plus some additional namepart.

As the unique names of all HDBModel documents consist of the name of their parent document plus their own document ID you can use this expression together with HDBModel document IDs navigate down from parent to child documents in a controlled manner.

Assume the WebTML context is positioned on the "Project X" content document and you want to navigate to its "bills" storage, so you can iterate over the bills contained there. You can do this simply by:

<tml:range context="np:bills">

...

</tml:range>

This will navigate to the document with unique name: "projects.project x.bills". The expression already assumes the dot "." character as divider between parts, so this does not need to get specified

The HDBModel uses the unique name of content documents which in current OpenWGA versions is not recommended for authoring use and normally not editable in OpenWGA content manager. For your own usage you can still utilize the unique names of pages as HDBModel does not use these.

The content class

As a special feature every HDBModel content has a content class. This is stored in an equally named metadata field which can be directly queries as such. For example in HQL:

content.contentclass = 'customer'

Or in Lucene queries:

CONTENTCLASS:customer

Contrary to contents all storages have a the same content class: "$hdbmodel-storage". However this of course can also be queried if ever needed.

Parent relations

When a HDBModel content is stored "below" some parent content then HDBModel will automatically create content relations  on it pointing to those parents (see Content documents for an explanation of content relations).

For each "parent content" (there may be multiple as the hierarchy goes deeper) a separate parent relation is created pointing to the given parent content. The name of a parent relation is:

"parent-<contentclass>"

Where <contentclass> stands for the content class of the parent content.

You can use these relations to query for documents that lie below the given parent content. For example: Querying for all "task" contents on "project X" would only need the following query, run under the WebTML context of this project document:

<tml:query type="hql">

  content.contentclass='task' AND content.relations['parent-project'].target = :content

</tml:query>

Explained:

  • The first term selects only task documents, obviously
  • The second term selects "content.relations['parent-project'].target", so a relation to a parent content of class "project"
  • The second term filters that this relation goes to :content, which is a default query parameter always filled with the current WebTML context document, which as we said should be "Project X"

You can also use these relations in WebTML context expressions to directly change from child to parent content with the "relation:" expression. So going from a task to its project is as easy as:


<tml:range context="relation:parent-project">