Contentment::Node - Node storage for Contentment


This package is primarily intended for documentation to the end user. Don't use this class directly. Rather use Contentment::Node::Revision and Contentment::Node::Collection instead.

Use the documentation here to get the big picture.


In several content management systems, it has become popular to store data into nodes. Each node represents one document (or a document series if the CMS provides revision control). Contentment actually allows for some flexibility by allowing the use of regular file system files along with database nodes, but the real power of Contentment is in the nodes.

To create a new type of Node, you need to subclass either the Contentment::Node::Revision class. Then, create additional schema items using the Oryx persistence system. Then, you need to implement the generator methods for your object. For example, if you chose to extend Contentment::Node to create a book review node type, you could do something like this:

  package MyBookReview;

  use strict;
  use warnings;

  use base qw( Contentment::Node::Revision );

  our $schema = {
      attributes => [{
          name => 'book_title',
          type => 'String',
          name => 'book_author',
          type => 'String',
          name => 'book_publisher',
          type => 'String',
          name => 'book_pubdate',
          type => 'DateTime',
          name => 'book_isbn',
          type => 'String',

  sub get_property {
      my $self = shift;
      local $_ = shift;

      /^title$/     && do { return $self->book_title }
      /^author$/    && do { return $self->book_author }
      /^publisher$/ && do { return $self->book_publisher }
      /^pubdate$/   && do { return $self->book_pubdate }
      /^isbn$/      && do { return $self->book_isbn }

  sub generated_kind { return 'text/html' }

  sub generate {
      # print out the HTML...


And that's pretty much it. This is now a functional node subclass.

Finally, you'll probably want to use your node class by instantiating a few. However, you should be aware of a few details before you continue. Read on.


Now, it wouldn't be much of a publishing system without the ability to keep old revisions around. The details of this work are found in Contentment::Node::Revision and Contentment::Node::Collection.

Basically, a node object is really a collection of revisions. In general, each time you make a change to a node, a new revision is created and selected as the current revision. The old revision exists in limbo where you can't see it anymore unless you explicitly ask to see it.


The real power of the Contentment revision system is with the revision-sets. When I said, "a new revision is created and selected as the current revision," what I really meant was that the new revision replaces the old revision in the current revision-set. When a user visits the web site, she will be assigned a revision-set containing the revisions visible to her. By default, this revision-set is named "HEAD".

When an editor edits a node, the new revision created replaces the old revision in his current revision set. He could also change the revision-set he's using so that his changes aren't a part of the main web site. Thus, a new revision-set could be cloned from the HEAD, modified until all the new pieces are just right, and, then, merged back into the HEAD.

To "delete" a node, you don't have to remove the data from the database, just remove it from the change set.


Each node object has the following information associated with it:


This is a username identifying the node's owner. This can help you if your node subclass needs to base security decisions on the node owner. The owner may be undef if ownership isn't significant or is unknown.


The date the node was created. This is set automatically.


The username of the current principal when the node was created. This is set automatically.



This handles the "Contentment::install" hook. It deploys the Contentment::Node, Contentment::Node::Revision, and Contentment::Node::Collection schemas.


Implements the "Contentment::VFS::simple" hook and adds a new set of paths under the "/node" directory.


Andrew Sterling Hanenkamp, <>


Copyright 2005 Andrew Sterling Hanenkamp <>. All Rights Reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.