All content in zena (pages, images, documents, etc) is a sub-class of the main class ‘Node’. The following diagram shows the inheritance diagram for the base classes:
The arrows mean “is a”. So the Image is a Document (behaves like a document) and the Document is a Node.
This means that when searching for Documents, you will find images as well and when searching for Pages, you will find sections and projects together with simple pages.
To identify the classes inside SQLiss, we use the class path
kpath. This is defined as the first letter of all classes in the inheritance hierarchy. For example:
Node: N Document: ND Image: NDI TextDocument: NDT Project: NPP
You can use this attribute in filters to load documents without images for example:
<r:documents where='kpath not like "NDI%"'>...</r:documents>
For the techie amongst you, we store all the data for nodes and sub-classes in a single table called
nodes using single table inheritance.
Section and Project scoping
These two classes (and their sub-classes) can be used to scope data (e.g. “nodes in project”). This is an important feature to better organize your data. For example, if you are managing contracts with clients, it is a good idea to make the Contract class a sub-class of “Project” so that you can find every class of element belonging to a Contract without having to recurse through all childs, no matter how deeply hidden the node is inside the site’s and contract’s project page hierarchy.
This works because the “Project” class propagates “project_id” to all it’s descendants and “Section” propagates “section_id”.
Contract "xyz" (id = 34) <= Contract is a sub-class of Project +-- sub-page (project_id = 34) +-- other page (project_id = 34) +-- deep (project_id = 34) +-- sub-proj (project_id = 34, id = 45) <= sub-class of Project +-- deeper (project_id = 45)
You can then make direct queries for objects inside a given project. For example:
<!-- From any page, this shows the latest images in the same project as the current page. --> <ul do='images in project order by updated_at desc limit 5'> <li do='img' mode='std'/> </ul>
The difference to using the “in sub_nodes” scope scope is that “in project” will not return the nodes belonging to child projects.
Important attributes for
Attributes to secure access to the node (none can be directly used in zafu) :
site_id, rgroup_id, wgroup_id, dgroup_id, user_id
Attributes to locate the element in “space” and time :
sqlparent_id, position, project_id, section_id, created_at, updated_at, publish_from, max_status
max_status is the maximal status of the node’s versions (published if any is already published, etc).
The content itself is not stored in
nodes but in another table called
versions. The versions are used for each language of the site and to keep old redactions when new text is published. See unknown link for details.
Main zena tables.
The content of attatched documents is not stored in
versions, because it would be silly to make an exact copy of an image just because the text describing it changes or because the text is translated. Documents are stored in the filesystem and are referenced with the “attachments” table.
Attributes are stored inside the versions tables as a single Json encoded blob. This make dynamic properties very fast to access and display.
To model your site specific data, you can create your own classes which will be inserted inside this diagram. For example you might need a ‘List’ class for pages that should display nice lists of other pages:
Inheritance diagram for a virtual class.
In this example, the List objects will behave like pages. The kpath would be
NPL. See virtual classes for details.
Data Model Design
This is heavily related to Indexing and Searching.