This article covers a Hippo CMS version 11. There's an updated version available that covers our most recent release.

Document Model

Documents and Folders

In the Hippo Repository, folders are in general of type hippostd:folder, which defines the types of documents and child folders that can be created with the FolderWorkflow.

Documents are represented by hippo:handle nodes. These nodes can have multiple children with sub-types of hippo:document. They are termed 'variants'. Documents with simple workflows, like images and assets, only have one such variant. But the more complex 'documentworkflow' workflow manages three such variants (see below).

Each folder node has a mix:referenceable mixin added to it. Document variants also get the mix:referenceable mixin by default, unless a version history is needed, in which case the mix:versionable mixin is used. Similarly, handles have the mix:referenceable mixin, reflecting the fact that their UUIDs can be used to reference the document.

A typical node structure in the repository therefore looks something like this:

+ restapi [hippostd:folder]
    - hippostd:foldertype:  new-document new-translated-folder
    - jcr:mixinTypes:  mix:referenceable
    + browser [hippostd:folder]
        - hippostd:foldertype:  new-document new-translated-folder
        - jcr:mixinTypes:  mix:referenceable
        + index [hippo:handle]
            - jcr:mixinTypes:  mix:referenceable
            + index [hippogogreen:simpledocument]
                - hippostd:state:  published
                - jcr:mixinTypes:  mix:referenceable
                - hippo:availability:  live
                - hippostd:holder:  admin
                - hippostd:stateSummary:  live
                - hippostdpubwf:createdBy:  admin
                - hippostdpubwf:creationDate:  2011-01-19T12:32:00.000Z
                - hippostdpubwf:lastModificationDate:  2011-01-25T16:41:00.000Z
                - hippostdpubwf:lastModifiedBy:  admin
                - hippostdpubwf:publicationDate:  2011-01-25T16:41:00.000Z
                - hippogogreen:summary:  REST API Browser of the Hippo Go Green services.
                - hippogogreen:title:  REST Browser
            + index [hippogogreen:simpledocument]
                - hippostd:state:  unpublished
                - jcr:mixinTypes:  mix:versionable
                - jcr:baseVersion: 241d527c-705d-4390-ac48-9e633374f538
                - jcr:isCheckedOut: false
                - jcr:predecessors:
                - jcr:versionHistory: 4801aaf0-6a52-4516-8d8e-16f28254bf1a
                - hippo:availability:  preview
                - hippostd:holder:  admin
                - hippostd:stateSummary:  live
                - hippostdpubwf:createdBy:  admin
                - hippostdpubwf:creationDate:  2011-01-19T12:32:00.000Z
                - hippostdpubwf:lastModificationDate:  2011-01-25T16:41:00.000Z
                - hippostdpubwf:lastModifiedBy:  admin
                - hippostdpubwf:publicationDate:  2011-01-25T16:41:00.000Z
                - hippogogreen:summary:  REST API Browser of the Hippo Go Green services.
                - hippogogreen:title:  REST Browser
            + index [hippogogreen:simpledocument]
                - hippostd:state:  draft
                - jcr:mixinTypes:  mix:referenceable
                - hippo:availability:
                - hippostd:stateSummary:  live
                - hippostdpubwf:createdBy:  admin
                - hippostdpubwf:creationDate:  2011-01-19T12:32:00.000Z
                - hippostdpubwf:lastModificationDate:  2011-01-25T16:41:00.000Z
                - hippostdpubwf:lastModifiedBy:  admin
                - hippostdpubwf:publicationDate:  2011-01-25T16:41:00.000Z
                - hippogogreen:summary:  REST API Browser of the Hippo Go Green services.
                - hippogogreen:title:  REST Browser

This structure describes two folders ('restapi' and 'browser') with one document ('index'). As you can see, all nodes are mix:referenceable, with the 'unpublished variant' being mix:versionable.

Document Workflow

The default workflow for publishable documents is the 'document workflow'. Besides operations like 'copy', 'move', 'rename' and 'delete', it defines all operations for editing, publication, workflow requests and scheduling, versioning and unlocking, tied to the hippo:handle (parent) node of publishable documents.

Editing workflow operations

The editing workflow operations takes care of 'locking' the document when a user presses 'edit' in the CMS. (or obtains an editable instance via the workflow API) The hippostd:holder property on the draft variant contains the user id of the user who is editing the document. If this property is absent, the document is not being edited. Document content is copied from the unpublished to the draft when editing commences. It is copied in the reverse direction when the changes are committed.

A separate workflow operation, unlock, enables adminstrators to remove the lock from a document.

Publication workflow operations

These workflow operations make use of three main states for a document to be in:

  • new
    the document is available for preview, but is not live. This is the state a document enters when first created, or when taken offline.
  • live
    the document is published and has not been modified since publication.
  • changed
    the document is published, but has been modified since publication

This state is stored in the hippostd:stateSummary property (see above). Operations like 'publish', 'take offline', 'edit' and 'commit' take the document through these states.

Requested and scheduled publication workflow operations

Apart from the main states (new, live & changed), there are a number of states that deal with requests for (de)publication. These requests take two different forms:

  • author request
    an author requested a (de)publication of a document, an action that needs to be reviewed by an editor.
  • scheduled job
    a job was scheduled to (de)publish a document at a particular time in the future.

The requests are persisted as separate nodes beneath the handle. Their presence can block some actions. It is e.g. not possible to edit a document with a pending request for publication present. Similarly, it is not possible to request or schedule an action when another request is already present.

Variants

There are three document variants supported in the workflow:

  • published
    this variant has hippo:availability='live' when the document has been published
  • unpublished
    this is the versionable variant and the central point through which all content changes flow.
  • draft
    this variant contains intermediate changes by editors.

When a user starts editing a document, the contents are copied from the unpublished variant to the draft. Likewise, when committing an editable instance, contents are copied back from draft to unpublished variants. To make it possible to track content changes over time, a version is created from the unpublished variant when a document is published.

Versions

The unpublished variant is versionable, with versions being created when the document is published or taken offline. The version history is a linear history of changes that were made to the document. The version history is a regular JCR version history.

Availability

The hippo:availability property is used to expose the right variant in the right context on the delivery tier, the HST. This happens by means of authorisation rules. The 'published' variant is shown on the 'live' site by virtue of its hippo:availability value 'live'. Using the same mechanism, the 'unpublished' variant is shown on the 'preview' site.

Roles

Three roles exist in the document workflow. The author can edit documents and request (de)publication. The editor can (de)publish changes, schedule them, and accept/deny requests by authors. Finally, the administrator can unlock documents; i.e. it becomes available for editing, when it was locked before by an author or editor.

Visual representation of the document workflow

The graph below shows the states and the allowed transitions. Requests and jobs have been overlayed, as the difference can be considered an attribute of the state.

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/connect/library/concepts/selection_152.png

Version History

The version history of the 'unpublished' is extended with a new version when a document is published or taken offline. (The latter in order to be able to restore changes that were made since publication)

Here is the history of the document shown above, after being published twice:

+ 13f1f162-14d1-4659-b050-8cb6ed99cecd [nt:versionHistory]
    - jcr:uuid:  4801aaf0-6a52-4516-8d8e-16f28254bf1a
    + 1.0 [nt:version]
        - jcr:created:  2013-12-03T16:19:40.597+01:00
        - jcr:uuid:  d717dc75-4f61-44b8-860d-c5bbfc2304cd
        + jcr:frozenNode [nt:frozenNode]
            - hippogogreen:summary:  REST API Browser of the Hippo Go Green services.
            - hippogogreen:title:  REST Browser
            - hippostd:state:  unpublished
            - hippostd:stateSummary:  live
            - hippostdpubwf:createdBy:  admin
            - hippostdpubwf:creationDate:  2011-01-19T12:32:00.000Z
            - hippostdpubwf:lastModificationDate:  2013-12-03T16:19:33.901+01:00
            - hippostdpubwf:lastModifiedBy:  admin
            - hippotranslation:id:  68b7a325-d9f9-46a3-8ee4-901dfdc79bb1
            - hippotranslation:locale:  en
            - jcr:frozenMixinTypes:  hippotranslation:translated mix:versionable
            - jcr:frozenPrimaryType:  hippogogreen:simpledocument
            - jcr:frozenUuid:  13f1f162-14d1-4659-b050-8cb6ed99cecd
            - jcr:uuid:  61fc9886-a98e-4b8c-9e89-f4a084492fbf
    + 1.1 [nt:version]
        - jcr:created:  2013-12-03T16:20:46.021+01:00
        - jcr:uuid:  241d527c-705d-4390-ac48-9e633374f538
        + jcr:frozenNode [nt:frozenNode]
            - hippogogreen:summary:  REST API Browser of the Hippo Go Green services
            - hippogogreen:title:  REST Browser
            - hippostd:state:  unpublished
            - hippostd:stateSummary:  live
            - hippostdpubwf:createdBy:  admin
            - hippostdpubwf:creationDate:  2011-01-19T12:32:00.000Z
            - hippostdpubwf:lastModificationDate:  2013-12-03T16:20:42.297+01:00
            - hippostdpubwf:lastModifiedBy:  admin
            - hippotranslation:id:  68b7a325-d9f9-46a3-8ee4-901dfdc79bb1
            - hippotranslation:locale:  en
            - jcr:frozenMixinTypes:  hippotranslation:translated mix:versionable
            - jcr:frozenPrimaryType:  hippogogreen:simpledocument
            - jcr:frozenUuid:  13f1f162-14d1-4659-b050-8cb6ed99cecd
            - jcr:uuid:  690207df-deb1-4349-ac8e-46848562d25e
    + jcr:rootVersion [nt:version]
        - jcr:created:  2013-12-03T16:19:36.617+01:00
        - jcr:uuid:  18cca37d-ddb9-4463-986b-ea648f1f991c
        + jcr:frozenNode [nt:frozenNode]
            - jcr:frozenMixinTypes:  hippotranslation:translated mix:versionable
            - jcr:frozenPrimaryType:  hippogogreen:simpledocument
            - jcr:frozenUuid:  13f1f162-14d1-4659-b050-8cb6ed99cecd
            - jcr:uuid:  320b44cb-d255-4c96-8ae5-9912743dda8d
    + jcr:versionLabels [nt:versionLabels]

This version history can be found by dereferencing the jcr:versionHistory property of the 'unpublished' variant.

Since the version history grows on every publication action, it may get quite big. Using an updater script, the history can be trimmed.