# Radiant replace Pages with Abstract Content Model

**URL:** <https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376>\
**Category:** Radiant CMS\
**Created:** [March 28, 2007, 8:46am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376 "2007-03-28T08:46:21Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 28, 2007, 8:46am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/1 "2007-03-28T08:46:21Z")

</div>

Hi all:

The following might violate the “no-fluff” mentality of Radiant, but I  
will give it a shot anyway. Chances are that somebody else has already  
worked on something similar.

Something I have missed in Radiant, since I have first used it  
(pre-0.5), is a uniform representation of content. I personally find the  
Page model clever, but rather strict as online content is rarely limited  
to pages, page parts and layouts. A content management system should be  
able to handle all kinds of content, not just pages. Various attempts  
have been made to “hack” support for other content types into Radiant  
and we ended up with assets management, strange page behaviours (e.g.  
search\_behaviour) and still no commenting system.

While for many the page model is perfectly fine and Extensions will  
solve all the other problems, I was dreaming of a uniform representation  
of all content independent of its type. So I hacked together a slightly  
modified version of Radiant (mental branch) which replaces the Page  
model with an abstract content model at the root and derives all other  
content types from this abstract model.

For now, I have modified the previous Page model to be a derived content  
class and added a very simple content class called Binary. Those two  
content classes alone already provide me with a very rudimentary assets  
management as their content is uniformly represented in Radiant using  
uniform URLs and the familiar tree based administration interface.  
Additional content classes can be easily added through extensions and  
integrate seamlessly with the existing administration interface avoiding  
extra tabs, proxy pages and non-uniform URLs.

At the moment the modifications are not ready for release, but if you  
want you can play with the online demo. The site contains further  
information on how the abstract content model works and provides some  
examples as well as demonstrates the admin interface:

Live Site  
URL: [http://init.ca:3000/](http://init.ca:3000/)

Administration Interface  
URL: [http://init.ca:3000/admin/](http://init.ca:3000/admin/)  
Username: admin  
Password: admin

I will actively maintain and further develop this approach and hopefully  
release some code and patches against stock Radiant soon. On the top of  
my list for content classes is also a Comment content class, which  
essentially will store comments as children of a page.

Comments, ideas and flames – all are welcome.

Cheers,  
Oliver

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 28, 2007, 9:11am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/2 "2007-03-28T09:11:23Z")

</div>

> search\_behaviour) and still no commenting system.  
> I had a similar play when I first started messing around with radiant -  
> I think it’s something that makes some sense from a model  
> point of view - a lot of the behaviour of page is really specific to  
> creating a general page, whereas specialized page behaviours  
> (such as redirection) don’t need breadcrumbs (not that I’ve really ever  
> gotten the point of those) and page parts.

In terms of interface, however I think creating dedicated interfaces for  
asset and comment management is a better way to go.

I do like the way that you’ve put the ‘add…’ combo box on the page  
tree - we definitely need something that lets you specify the  
page type before you start editing it so that you can get the interface  
appropriate for your specific page type rather than just the  
generic page editing interface. Not sure if yours is the way to go, but  
I like the fact that it’s a one-click solution.

Dan.

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 28, 2007, 9:26am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/3 "2007-03-28T09:26:25Z")

</div>

Hi Dan:

Daniel S. wrote:

> In terms of interface, however I think creating dedicated interfaces  
> for asset and comment management is a better way to go.

My plan for that is to provide content class filters for the tree, such  
that only objects of the specific class are displayed. This idea can  
also be extended to provide stored tree views that can be accessed. For  
example a view that only shows comments or assets. Another potential  
extension is to provide the option to limit the display to a specific  
subtree, e.g. “Show me all comments that are below this page.”

> I do like the way that you’ve put the ‘add…’ combo box on the page  
> tree - we definitely need something that lets you specify the page  
> type before you start editing it so that you can get the interface  
> appropriate for your specific page type rather than just the generic  
> page editing interface. Not sure if yours is the way to go, but I  
> like the fact that it’s a one-click solution.

I find it looks quite crowded as it is right now, though I currently  
can’t think of an alternative. Maybe some fancy Javascript with hovering  
pop-ups or so will do.

Thanks for the feedback.

Cheers,  
Oliver

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 29, 2007, 6:21am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/4 "2007-03-29T06:21:34Z")

</div>

Oliver, I like your thought process.

What you are running up against is the fact that the core of radiant  
does not model the true problem domain. And I continually read here  
were developers hit this wall.

One of the things that I love about radiant (and rails too, really) is  
that it focuses on the user. In my mind, the goal should always be to  
make the user’s life simpler - even if this means making the developer’s  
work more difficult.

So I agree with John’s and Dan’s objective to keep the interface simple  
and intuitive. Let’s not over-complicate the thing. No fluff.

But does the radiant back-end have to match the UI?

No matter what the radiant interface design, HTML and HTTP are what they  
are. The web specifies HTML pages, images, stylesheets, and more - all  
organized within directories. Yet the core of radiant, really, only  
addresses the page (or at least text) part of this spec.

The (wise) simplification of UI has lead to a over-simplification of the  
data model - to the point where the model doesn’t match enough of web  
reality.

So newcomers to radiant keep stubbing their toes when they try to use  
radiant in legitimate but unforeseen ways. Yes, sometimes this is  
genuine over-complication on the developer’s part but many problems  
would be trivial with a more consistent model. And radiant would grow  
more gracefully.

As I see it, radiant, should model, track and store all the key web  
elements (in a db or otherwise is only a technical issue) because they  
are needed to make a site (they are all part of the content being  
managed).

Once the true objects exist within radiant, nothing says that you then  
can’t adjust how and which elements are exposed (like showing only HTML  
pages in the admin interface) or to add metaphors that make our user’s  
jobs simpler (like page parts).

So, Oliver I like your thinking because you see the benefit to making  
radiant “aware” of all the fundamental web pieces.

Now, whether the UI should expose the creation of page types with a  
combo-box or how simple the admin page should look… that’s is a wholly  
separate issue.

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 30, 2007, 5:18am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/5 "2007-03-30T05:18:13Z")

</div>

As I read through my original reply, it sounds a bit soap-boxy now. I  
apologize if it came across that way - it was getting late.

> My concern with Oliver’s patch is that it over complicates the  
> model. I’m a little leary of creating a complex inheritance  
> heirarchy for Radiant.

My thoughts are not so much tied to whether the model should be  
abstracted to the point of “generic HTML element” from which everything  
inherits (though that could prove smart). Instead, my view is that in a  
content management system, the goal should be to manage content. This  
means managing pages, but also pictures, video, etc.

> Yes pages and images and redirects have URLs, but beyond that  
> they have very little in common. Sometimes things that look similar  
> are not similar at all.

A small business user or any user with basic needs still requires  
method(s) to manage all the parts. It seems counter productive to the  
simplicity of Radiant to say, “We’ll help you store and manage your  
pages. Oh, you need pictures too? Here’s an FTP client” It seems that  
even a no frills CMS tool should address all the content.

This isn’t to say it has to be live in v0.6 but is it even a future  
goal? Having extension developers slog through various ways to  
implement these ideas may be a great development plan but eventually, I  
think that Radiant should own this domain.

Even if it’s just to offer a basic storage architecture and give an API  
to developers to customize the UI so that they can match their special  
use cases (like store an image with each page vs. some centralized  
administration UI).

> I’m not ruling out what Oliver is suggesting, but I am having  
> difficulty seeing the true value.

Would it not strengthen the platform to tackle the storage and  
management issue for all content? I think that many of the  
extensions/customizations out there are continually reinventing these  
wheels because it is a core need of any CMS system.

Other values come to play where you can treat these different elements  
commonly:

- CRUD operations
- User permissions and levels
- Caching
- Rules for handling simultaneous edits

I can give technical arguments like this all day long but, really though

- when it comes down to it - I keep seeing extensions and developer  
requests for the same recurring needs. It just smells like there is a  
simpler, more developer friendly, DRY-er solution. And my mind keeps  
refactoring this problem space back into Radiant.

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 29, 2007, 4:54pm UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/6 "2007-03-29T16:54:14Z")

</div>

Chris P. wrote:

> What you are running up against is the fact that the core of radiant  
> does not model the true problem domain. And I continually read here  
> were developers hit this wall.
> 
> …
> 
> The (wise) simplification of UI has lead to a over-simplification of the  
> data model - to the point where the model doesn’t match enough of web  
> reality.

I’m not sure that I agree. My concern with Oliver’s patch (which has  
been suggested at least once before) is that it over complicates the  
model. I’m a little leary of creating a complex inheritance heirarchy  
for Radiant. Yes pages and images and redirects have URLs, but beyond  
that they have very little in common. Sometimes things that look similar  
are not similar at all. I’m not ruling out what Oliver is suggesting,  
but I am having difficulty seeing the true value.

–  
John L.  
[http://wiseheartdesign.com](http://wiseheartdesign.com)

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 30, 2007, 2:11pm UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/7 "2007-03-30T14:11:19Z")

</div>

What about also unifying Snippets and Layouts under a single abstract  
model?

In which case this is no longer true:

> Actually the commonality is:
> 
> - available through a url
> - updates the response

The commonality is simply “user editable content”

If Pages, Snippets, and Layouts all made use of the same underlying  
“content” model, then this would give additional flexibility to  
extension authors to write other kinds of “content” also using this  
model.

For example: “Spotlights”. I can imagine an extension for managing a  
collection of spotlights and setting up rotating spotlights, (And it  
could even do things like manage banner ads) But underneaeth it should  
use the same Model and the same R:tags that Sinppets, Layouts and Pages  
use. And that model should be called Content.

Jacob

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 31, 2007, 3:20am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/8 "2007-03-31T03:20:28Z")

</div>

John W. Long wrote:

> Chris P. wrote:
> 
> > What you are running up against is the fact that the core of radiant  
> > does not model the true problem domain. And I continually read here  
> > were developers hit this wall.
> > 
> > …
> > 
> > The (wise) simplification of UI has lead to a over-simplification of the  
> > data model - to the point where the model doesn’t match enough of web  
> > reality.

This is exactly what I am trying to address. The data model does not  
have to reflect the simplicity of the UI, as long as it does not  
affect the UI. Especially not, when it could make the software  
developer’s job easier.

> I’m not sure that I agree. My concern with Oliver’s patch (which has  
> been suggested at least once before) is that it over complicates the  
> model. I’m a little leary of creating a complex inheritance heirarchy  
> for Radiant.

I, as a software developer, personally find dealing with many  
different non-related classes more complicated than with an  
inheritance hierarchy that provides abstraction. Very much like I  
prefer using a uniform set of file manipulation tools to move, copy,  
rename, archive, find, categorize, etc. files on my file system,  
independent of what content they represent.

> Yes pages and images and redirects have URLs, but beyond  
> that they have very little in common.

While I would not throw redirects together with pages and images, as  
they do not really represent content, I think pages and images and  
other content types have a lot in common. They can be published,  
searched, tagged (as in labeled), commented, viewed, have authors and  
licenses. If I think harder I might come up with some more.

Cheers,  
Oliver

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 31, 2007, 3:31am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/9 "2007-03-31T03:31:29Z")

</div>

Daniel S. wrote:

> Maybe that ‘separate url lookup’ table that has been rattling round a little could come into play here. Pages and Assets and  
> Redirects are all ‘mappable’ things - they can handle a url.
> 
> class UrlMapping  
> belongs\_to :handler, :polymorphic =\> true  
> end
> 
> module UrlHandler  
> def self.included(base)  
> […]  
> #do whatever  
> end  
> end

This would perfectly address the problem of unifying URLs for all  
content, but an abstract content model can go even further and provide  
standard interfaces for searching/indexing, backup, tagging,  
commenting etc. Maybe the OO thinking of mine is old-fashioned and  
acts\_as\_searchable, acts\_as\_backupable, acts\_as\_taggable and  
acts\_as\_commentable are the hip things to these days.

Oliver

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 31, 2007, 3:40am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/10 "2007-03-31T03:40:30Z")

</div>

Jacob B. wrote:

> What about also unifying Snippets and Layouts under a single abstract  
> model?
> 
> In which case this is no longer true:
> 
> > Actually the commonality is:
> > 
> > - available through a url
> > - updates the response
> 
> The commonality is simply “user editable content”

Hmm, I do not really see snippets and layouts as content, but they  
certainly could be and you could even give them a URL. I mean you  
would give a CSS file a URL or images that are embedded in an article.  
Why not do the same for layouts and snippets. In fact when using  
server-side includes, that is exactly how you include layouts and  
snippets, via URLs.

> For example: “Spotlights”. I can imagine an extension for managing a  
> collection of spotlights and setting up rotating spotlights, (And it  
> could even do things like manage banner ads) But underneaeth it should  
> use the same Model and the same R:tags that Sinppets, Layouts and Pages  
> use. And that model should be called Content.

Spotlights? I assume you are not talking about the ones used in stage  
performance 😉

Cheers,  
Oliver

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 30, 2007, 6:13am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/11 "2007-03-30T06:13:49Z")

</div>

> I’m not sure that I agree. My concern with Oliver’s patch (which has  
> been suggested at least once before) is that it over complicates the  
> model. I’m a little leary of creating a complex inheritance heirarchy  
> for Radiant. Yes pages and images and redirects have URLs, but beyond  
> that they have very little in common. Sometimes things that  
> look similar  
> are not similar at all. I’m not ruling out what Oliver is suggesting,  
> but I am having difficulty seeing the true value.

Actually the commonality is:

- available through a url
- updates the response

There’d be a couple of advantages of unifying pages/images/redirects  
into the one model - most notably the fact that the  
SiteController could remain untouched when you add another of these ‘url  
handling’ objects (I pretty much had to do a copy/paste  
duplicate to serve up images in my asset extension). I definitely think  
they should be viewed differently in the admin interface,  
but I could be sold on unifying the model.

The Page object adds really only one extra thing to that mix:

- has many page parts

I’m not sure if those advantages are worth it, but the point that I do  
see is that we currently have the view that Pages must be  
made up of parts - I don’t think that’s necessarily true… but until  
the work in facets for changing the way that you can interact  
with a page through the editing interface is worked out properly, I  
don’t think it’s easy to see the need. Perhaps if there was a  
SimplePage above page that didn’t have page parts, that’d by all the  
seperation I would need.

Maybe that ‘separate url lookup’ table that has been rattling round a  
little could come into play here. Pages and Assets and  
Redirects are all ‘mappable’ things - they can handle a url.

class UrlMapping  
belongs\_to :handler, :polymorphic =\> true  
end

module UrlHandler  
def self.included(base)  
base.class\_eval {  
has\_one :url\_mapping  
before\_save :update\_mapping  
}  
end

def update\_mapping  
url\_mapping = UrlMapping.new(:path =\> url)  
end  
end

class Page  
include UrlHandler  
def handle(request, response)  
#do whatever  
end  
end

class Attachment  
include UrlHandler  
def update\_mapping  
#url can have a transform part (the %) (ie /page/thumbnail/slug)  
url\_mapping = UrlMapping.new(:path =\> “#{page.url}%#{slug}”  
end  
def handles\_url?(url)  
/#{Regexp.escape(page.url)}([^/]/)?#{Regexp.escape(slug)}"  
end  
def handle(request, response)  
#do whatever  
end  
end

(Not sure if that should be has\_one or has\_many, I’ll go with has\_one  
for now)

If the sitecontroller looked up pages using a reverse like lookup (not  
sure about the database compatability of that):

mappings = UrlMapping.find(:all, :conditions =\> [’? like path’,url])  
if(mapping = mappings.find {|m| m.handler.handles\_url?(url)})  
handler = mapping.handler  
handler.handle(request, response)  
end

Pages that would need to handle multiple url paths that are unknown at  
publish time could override the update\_mapping method to set  
a mapping like “/search/%” and would be able to handle  
“/search/monkeys/blah” or “/search/things/bump/night”.

Dan.

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 31, 2007, 4:21am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/12 "2007-03-31T04:21:08Z")

</div>

Oliver B. wrote:

> Hmm, I do not really see snippets and layouts as content, but they  
> certainly could be and you could even give them a URL.

Snippets, layouts, and things like radiant tags are not true web  
elements. Instead they are abstract concepts that correspond to how  
users go about building sites. Concepts like these should guide the user  
to work more effectively.

Frankly, it’s one of the things I like most about Radiant.

We need to be able to reference them somehow to build pages but I like  
the delineation to the user that “these are pages” and “these are only  
parts of pages.” Once you get outside developers, you can easily get  
into too much abstraction.

While I favor Radiant owning all content and, possibly, abstracting it  
(I’m from that same old OO school), I agree wholeheartedly that users  
fundamentally approach the different content types differently.

For instance the benefit of page parts is lost on me if the content type  
is an image. Of course an edit image page… hmmm that might be cool.

-Chris

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [March 31, 2007, 3:45pm UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/13 "2007-03-31T15:45:44Z")

</div>

Oliver,

Might I suggest you write up a proposal of sorts on wiki. We can all  
help you refine it, but let’s propose something concrete about the  
strucutre of the “abstract models” from which Pages, Layouts, Snippets,  
and “future content types” should be based.

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [April 26, 2007, 10:24am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/14 "2007-04-26T10:24:25Z")

</div>

Hi,

I’ve read with interest all above messages as I have the same concern  
about how a model should manage contents.

Simplicity is a key of Radiant, and should remains as this. Now,  
extensions open the way to many new features. Even keeping the interface  
user centric, it’s important to deal with the need of extending content  
types. The interface doesn’t need to relate the content abstraction, but  
it should exists to allow extensions to easily integrate new content  
types and, more important, to globally manage contents (as for a  
search).

It s a good practice to think the interface for users, as it’s a good  
practice to think the model for contents.

Why not making everything a content (pages, assets, snippets,…) but  
keeping the model simple? Is a wiki already exists about an Abstract  
Content Model ?

–  
Stephane

---

<div class="post-metadata">

**Author:** ![ol1barn3s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de053/32.png) [@ol1barn3s](https://www.ruby-forum.com/u/ol1barn3s)\
**Post date:** [April 26, 2007, 10:33am UTC](https://www.ruby-forum.com/t/radiant-replace-pages-with-abstract-content-model/90376/15 "2007-04-26T10:33:57Z")

</div>

PS: looking further with the example on init.ca, I don’t think Content  
should replace Page, and the interface should keep it’s way to manage  
‘separately’ objects (contents)
