There can never be enough CMS's in the world, but there aren't nearly enough written in Perl. I've always thought that Everydevel, the one that runs Perlmonks was one of the most interesting.

It got even more interesting when chromatic started to overhaul it. I continued some of this work, such as expanding the test suite and zapping any global variables I could find. Recently, nate encouraged me to fork the project. I set up a git repository for this purpose.

In this CMS every bit of content (and most of the stuff that isn't 'content') is a 'node'. Each node has a 'type' which is also a node, a 'nodetype'. These types could inherit one from the other. However, Everything implemented its own unique inheritance system and didn't use Perl's class system.

The disadvantages of this became apparent and one of the original developers, chromatic, changed it to make sure that a 'node' was blessed into an appropriate perl sub-class. It's what the troops (including me) had been asking for. But the old system had its advantages.

The major advantage of the old system was that new nodetypes could be created whenever the system administrator wanted and this could be done on a live system. chromatic wisely turned off this feature.

But I needed it and hacked a reimplementation using string evals. Of course, it means that when I create new nodetypes Apache had to be restarted so that the relevant packages can be created for all the apache children. This is a bit inconvenient, (ok, it's an ugly hack then, I admit it) but it works.

Now, though, we have data related to the creation of nodetype classes in two spots. One is in the database the other in .pm files in the file system. This would be OK, except that the engine is designed to be run on Apache and whilst static .pm files can be run and loaded at start up and shared amongst all the children dynamic data in the database causes problems.

This problem needs a resolution:

Step 1: Moose and Metadata

After some thought, I figured that "nodetype" nodes should be treated as meta-nodes, which contain class data. What perl object solution provides fantastic meta-class support? Moose, of course.

In fact, I'd been thinking of switching Everydevel to Moose for a while. Not because I need a way to create accessors (Class::Accessor does that fine), but because of its meta-class capabilities. Having easy access to meta-data should make various tasks, like interfacing with the database, easier.

But back to nodetype data. Nodetype data, which I've now classified as meta-data, is pulled in from the backend database, I figured I could store this as a class attribute, thanks to MooseX::ClassAttribute, which slots it into each class's meta class. That's great and it works, so long as we have one implementation of the CMS on the server. If we have more than one in different 'locations' or in different virtual hosts, then each db will overwrite the other's class data.

I've tried it and the results are as unpredictable as could be predicted.

It got me thinking whether what I really need are 'lexical classes'? After all, Moose allows the creation of on-the-fly anonymous classes that aren't truly lexical, but their package names are random and they are deleted when the meta class object goes out of scope. It could be interesting to play with that.

But it is probably over-complicating the problem.

I think the real problem is that the data are not what they seem. 'Nodetype' data were originally classes of which ordinary nodes were instances. But is it really class data?

The data include such things as:

I don't think that any of these are class data. They are specific to a specific implementation. For example, access data are specific to a frontend object, database table names are specific to a db schema and so on.

Step 2: Moose and Metadata to Make Other Classes

Better than to treat these data as metadata is to treat them as instance data for completely different classes. Classes that are assigned specific jobs. The meta data proffered by Moose::Meta::Class can be used to help construct these instances.

This will be better, because it will mean that I'll be able to accomplish another thing: instances won't have to carry around references to their type nodes, and other objects (e.g. a database handle) - which could create leaks. It should also allow more flexibility.


In reply to Moose, Metadata and the Everything CMS by Nomad

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.