The hdsTree Class

The Dissemino tree class hdsTree holds groups of related articles and is commonly used to support hierarchical documents and discussion forums. It is also the server-side component of a nav-tree and was designed with this purpose in mind. Nav-trees are usually operated with AJAX calls (Asynchronous JavaScript and XML). The assumed operational setting is of a host page that is vertically split into two panes, one for the nav-tree, the other for displaying the currently selected article.

Articles may only result in partial HTML. There is no page header, no HTML body tag and no facility to automatically include JavaScript as there is with the hdsPage class. Articles are dependent on a host page to display. Other than this however, articles can contain much the same range of visual entities as pages and importantly, can include a form. Without forms, the hdsTree and navtree approach could be used to present hierarchical documents such as technical manuals (including this one). With forms however, the use can be extended to creating and editing of complex data objects spread across multiple forms and perhaps more importantly, Internet disscussion forums.

The hdsTree class is implemented as a 1:many map m_ItemsByParent and a 1:1 map m_ItemsByName. m_ItemsByParent maps the article parent id to articles, facilitating article hierarchy without requiring each article to have child, sibling or parent pointers. m_ItemsByName maps article names to articles and so facilitates direct article lookup.

Public and Private Trees

A hdsTree instance can either be public or private. A public tree is vested with the Dissemino application and is runtime persistent while a private tree must be attached to a user session and can only persist while the session persists. A public tree is availble to all users, subject to the normal resource access rules. A private tree is specific to the user and only accessible by the user. Private trees are used to create and edit complex data objects that either require or would benefit from being spread across multiple forms - such as a detailed user profile. In this scenario, the navtree articles contain the forms.

All hdsTree instances are created in the configs by <xtreeDcl> tags. To be public, the <xtreeDcl> tag must be a direct subtag of the <disseminoWebsite> project tag. It must not lay within the definition of a page or article or any other entity. All private trees are declared using executive commands and so the <xtreeDcl> will be part of a page or form-handler <procdata> block (see article 4.9).

Articles are added to both public and private trees by a hdsTree member function that is invoked by the <xtreeItem> tag with arguments as follows:-

1) parId Parent node id. This can be NULL in which case the article is placed at the root of the tree.
2) nodeId The id of the article being added.
3) link The URL that will be requested under AJAX to bring the article into the host page.
4) hdln The article title as it will appear in the navtree.

Blank headings (visible tree items with a title but no associated article), are added by the <xtreeHead> tag, which will have the same arguments as <xtreeItem> minus the link.

Navtree Manifestation

The navtree in the host page is implemented using JavaScript which is automaticly generated along with the HTML when the page is requested. Selection of articles does not alter the JavaScript capability, it is all supplied at the outset.

The host page nav-tree JavaScript is as is common, supplied in two parts. In the first part, page header five functions are supplied as follows:-

1) tog Toggles tree item state between expanded and contracted. 2) loadArticle Performs the asynchronous fetch upon selection. 3) addArticle Adds an article to the navtree 4) delArticle Deletes an item from the navtree 5) makeTree This translates navtree content encoded in an array into navtree HTML.

These functions are part of the Dissemino 'standard scripts' regime, under which groups of one or more JavaScript functions are included in the HTML <head> tag on the basis of flag settings. The functions themselves are simply fixed strings, declared in hzDsmScript.cpp and with the prefix "_dsmScript_" in their name. The above five functions are included when the member m_bScriptFlags of the host page, has the INC_SCRIPT_NAVTREE bit set. This is set by the presence of <xtreeCtl> tags in the page definition.

The second part of the nav-tree JavaScript is the content of the tree itself. This takes the form of a HTML <script> block with the navtree content encoded in an array, followed by a call to the makeTree function. This does not appear within the HTML <head> tag but in the HTML boby, in place of the <xtreeCtl> tag that directs its inclusion. The <xtreeCtl> tag has attribute show="navtree". The navtree content array is exported by the hdsTree::ExportDataScript() function.

Note that as the tree content array is set up as part of the host page HTML generation, any form action which adds or deletes articles to or from the server tree must be matched by calls to either addArticle() or delArticle() in the browser. These calls must be incorporated into the form validation JavaScript functions which are not supplied as standard.

Public hdsTree in Fixed Documents e.g. Online Technical Manual

To create a public fixed document, a public tree is first declared by an <xtreeDcl> tag and then the host page is created by an <xpage> tag. The <xpage> tag has two attrbutes: name to name the tree and page to state the URL of the host page. The host page URL must be unique among all URLs although the tree name need only be unique among all hdsTree instances. To be meaningful, at least one articles must be supplied with an <xtreeItem> subtag. These have attributes as follows:-

1) parent The parent node, if blank the tree item is a root (there can be multiple roots) 2) id The unique id of the node. Note the use of normal document paragraph numbering as the the naming convention 3) link The URL of an article. Note that if the tree item is only a heading, this will be blank 4) hdln Headline of the article 5) lang This is a booean switch to support or not support languages

<xtree name="mydoc" page="/mydoc"> <xtreeitem parent="" id="md.1" link="md.1" hdln="Section 1: Intro" lang="off"/> <xtreeitem parent="md.1" id="md.1.1" link="md.1.1" hdln="Section 1.1: Objectives" lang="off"/> <xtreeitem parent="" id="md.2" link="md.2" hdln="Section 2: Basic Principles" lang="off"/> </xtree>

Note in the above that section 1 and 2 have no parent while section 1.1 has section 1 as its parent. Articles without a parent each form a tree root.

Private hdsTree in a Complex Form e.g. User Profile

A user profile is a good example of an extensive and complex data class covering a wide range of subject matters, some of which will be generally applicable, others will only apply in specific cases. Generally applicable matters will be things such as account information, contact details and privacy settings. And then there will be everythig else, e.g. Resume and work experience, published papers, software or other project material, etc. You name it, as long as you can define the data classes, the forms to garner such data can be put in a hdsTree nav-tree.

The tree will be private and will be initialized in the <procdata> block of the user profile host page. As HDB data classes are not extensible, the user profile has a finite set of sub-class objects. In general, the nav-tree will hold articles which will each contain a form for creating and editing a particular sub-class object. The <procdata> block contains executive commands to add these articles to the tree.

As data is added, depending on the applicable sub-class, the tree can grow. If multiple instances of a given sub-class are not permitted, filling in the form creates the sub-class object but does not alter the tree. If the same article is selected again, the same form appears with the new data. If multiple sub-class instances are permitted, each new instance including the first, will add an article to the tree. The original article will always show the same blank form. The sub-class instances created by this will be entered in the tree directly under the original article.

Public hdsTree in a Forum

For a forum, the hdsTree will be public and dynamic. A few entries could be specified by <xtreeitem> tags to initiate discussion but this is not really the right apporach. A better reason for initial entries would be to list topics the forum would limit itself to. However, the best approach is to leave the tree blank in the configs, and have the administrator enter the topics via the web forum itself.

Consider an example in which a forum has topic categories at the top level, then topics, then for each topic, a series of user entries. The user entries would be posts, comments on posts and replies to both posts and comments. Of these entities, only topic categories and topics are manifest as tree items and so these are the only items the tree would store in its own right. The posts, comments and replies are ordinary data objects and so would normally be stored in a data object repository. The access rights are everyone can read posts, comments and replies, members can add topics and write posts, comments and replies, but only the administrator can add topic categories.

There is no user awareness built into the hdsTree class itself, so access to the hdsTree and thus the list of topics and categories of topics, is governed by the access settings of the host page. This is simple to arrange using <xdiv> tags, which specify which users can see the <xdiv> subtags. The button for adding topic categories is contained in an <xdiv> that requires the user to be the administrator, while the buttons for adding topics, posts, comments and replies are contained in an <xdiv> that requires the user to be a member.

The hdsTree class stores its data as a JSON, which is considered to be a binary data object. The JSON can be stored in a binary repository but more commonly the JSON is stored in a dedicated file. The only issue with a forum, indeed with any public and dynamic tree, is that updates from any of the users permitted to update tree items, need to be communicated to all concurrent users. There are the addArticle and delArticle JavaScript functions that can be instigated by add and delete buttons prior to submissions, but this mechanism only keeps the nav-tree of the user performing the updates in step. As things stand other users only see the changes when they refresh the host page of the tree. This matter is listed in the HadronZoo Errata.