Julian Wraith

Menu Close

Tag: day software

Product Camp Amsterdam

But the place which you have selected for your camp, though never so rough and grim, begins at once to have its attractions, and becomes a very centre of civilization to you: “Home is home, be it never so homely.”  ~Henry David Thoreau

Yesterday I attended Product Camp Amsterdam and had a great time. From where I live, I had to get up early but it was worth it. Being a little early as usual, it gave me chance to take in the magical Amsterdam morning. Arriving and being greeted with free t-shirts (yes, I am simple to please) and name badges, the early morning challenges began. Two problems, 1) how do you decide your first and second choice of sessions that you want to see when everything looks interesting and 2) how does the selection process _really_ work? No one could really answer the last one and someone who thought he knew, decided that he did not know by the end of our questions. In the end, I just stuck my pink & green post-its on what I thought might work for me. In the end, it worked!

The first session was Martin van Mierloo on the Lessons Learned Towards a Formal Roadmap Process at GX. GX is a Web Content Management company just down the road from where I live, so close even that I have been known to stalk them. I enjoyed the session very much and it was nice to see SDL Tridion, Day, Hippo and GX discuss the pitfalls and differences in their Roadmaps. I am not a product manager so I cannot say everything about SDL Tridion’s Roadmap process, I just have the basics, but I was interested to know from a consulting perspective how GX’s customers react to a new release once per three months. Clearly the changes are small by comparison to say Day or SDL Tridion and it makes it easier to keep up to date with the latest releases. I would be curious to know other companies release cycles and how that affects their customer’s product stability.

After this session, lunch was served (great lunch!) and a chance to chat to a few people. I chatted allot to an employee from Hewlett-Packard who is involved in the project I am working on. Interesting chat and hard to explain the coincidence of meeting randomly…

After Lunch it was off to the nest session. Jaco van Wilgenburgh: THE User Does Not Exist – Personas and Scenarios to the Rescue? I enjoyed the session very much and it led to a number of discussions about the differences between role, actor and persona – which takes too long to explain here but there is some interesting information on this page. I believe that such a process can help all parts of an organisation understand better who they are building their products for. Whilst Jaco did not mention it, I think the consulting side can also benefit by understanding the people they encounter better and how they fit into the scenario a product is designed to help.

I hope very much that 2010 will see another Product Camp in Amsterdam. It was a great day with many interesting people. Thanks to Mark Schiefelbein and the sponsors for making the day possible.

SDL Tridion and JCR: A marriage made on Java

I have been quiet on my blog for sometime which I never like because I often feel the urge to type and to rant. However, I have been channeling my mental efforts into looking at the combination of SDL Tridion R5.3 and a JCR repository.

The Content Repository API for Java (JSR-170) is a Java API specification that allows for uniform access to content repositories. Content Management Systems incorporate JCRs to store their content and metadata and a number of vendors are using a JCR as part of their offering. So, I have decided to look at how SDL Tridion could connect to such a repository.

Looking at the architecture and the most likely place where you would integrate a JCR, I looked at the Content Delivery side of SDL Tridion R5 (R5.3 SP1 to be exact). R5 uses a distributed content delivery model –where the CMS and Websites are typically on separate systems – and this is a typical place where customers integrate other 3rd party products in to the Content Delivery environment. Typically these integrations include things like search but rarely how content is stored. R5 has two basic options for storing content; a database or a file system and these cover pretty much any requirement you could have. The Broker is the layer which abstracts this from the presentation layer (typically a website). In addition to being able to present content to a webpage, the Broker is also responsible for storing the content in the Content Data Store which is normally a database or file system.



At the bare facts the Broker is a Java API and as such we can modify for our own means. Typically you would extend the functionality but you can also replace functionality the existing with your own. In this case I intend to replace the storage mechanism to use a JCR instead of the standard file system or database. To make a complete change, I would have to create 10-15 extensions to extend all the functionality of Content Delivery, in this case I will not do that but I will simply create one extension.


So why would you want to do this? There are three basic use cases for this:

  1. You have chosen a JCR as a content repository for your website, maybe inherited from another CMS
  2. You are publishing content to a single JCR from multiple CMS systems
  3. You are an SDL Tridion Consultant with too much private time on your hands

To implement my new storage classes for the Broker I am going to publish blog posts from my R5 environment to a JCR. The aim of this, is to prove this in as simple a way as possible. I am not an expert Java programmer nor am I an expert in the JCR API or the JCR implementation which I will use and as such I will trample in the face of best practices and laugh in the direction of standards. But seriously, the perfect implementation is not the point, making it work so that someone else can take the experience forward to something better is the idea.

The Content Management part

In R5 all content is defined by a Schema. A blog post schema would normally include content fields like title, body, date & time and then also metadata fields such as author, trackbacks, categories, keywords etc. My schema will include just two content fields, Title and Body. From this I want to publish a XML Dynamic Component Template.

So my schema looks as follows:


So I have a simple schema and I can now create some components against these schemas. I created four components that I will test with and just to be neat and tidy I put them in their own folder:


Any time you include content Components on some sort of presentation (static or dynamic page) you will need to combine the Component with a Component Template (CT) to create what is known as a Component Presentation (CP). The CP is a combination of the template and the content and more than one CT can be used to create different CPs from the same content. A typical usage would be on a news site where the component, our news item, would be represented as both a front page teaser and the full article. Both the front page teaser and the main article could have a different CT but the same Component.

My CT will just output some XML:

<?xml version="1.0"?>
<blogpost>
<title>First Post!</title>
<body>Welcome to my blog, I hope I can write lots of interesting things</body>
</blogpost>

And my CT code will look like:

<?xml version="1.0"?>
<blogpost>
     <title>[% WriteOut Component.Fields(1).value(1) %]</title>
     <body>[% WriteOut Component.Fields(2).value(1) %]</body>
</blogpost>

In this code I have paid no attention to how you would really work with XML so if I were to put, for example, un-encoded HTML characters in my content (e.g. &) then the whole thing will go belly up, so normally a template would be a little more robustly coded.

So now I can publish XML to my website as a Dynamic Component Presentation (DCP) and it is currently residing on the file system (the default option).The resulting XML DCP can now be used on my website.

Where to put the content?

I already indicated that I am going to publish the content to a JCR. The challenge and interest here was that I know nothing about how to use a JCR. Knowing that Day has their freely available JCR implementation, CRX, I downloaded it with the documentation. The documentation is pretty good and some time with a Diet Coke and a print out of the setup and developers guides meant I already had a good idea of what to do.

Installation was really easy and within a few minutes (plus some time to get a license key) it was up and running. With CRX you get management tools that enable you to browse and administer the repository so I set about defining the Node Types that I need to define my content. An explanation on how you define Node Types and their properties is best left to the documentation suffice to say that I will need a BlogPost Node Type to be able to store any content in the JCR.

Now, if I were to implement full storage for content from R5 then maybe I would need to model the Broker storage model in the JCR. Looking at this, this would be possible. The fully dynamic Broker is a relational database (file system is not as flexible as a database) and as such I can imagine that this would be possible. For the time being though, we are going to store some content in the repository which means I will create a Node Type that is similar to my Schema. In there I will place my content.

For organization purposes I created a BlogPosts Node in the JCR and it is within that Node that I will save my content. My Node Type, called BlogPost, is defined with the fields:

  • Title
  • Body
  • TCMURI
  • XML


Once I have done that I can then create multiple BlogPost nodes in my node BlogPosts.

Making them work together

For this I am going to make a custom storage binding. Effectively I am going to rewrite how _all_ XML DCPs are stored. Once content is published, the Deployer will deploy the content and in the process request the Broker to store the content. My class will be the one called to store the content.
To do this, my class will implement XMLComponentPresentationHome and as such will implement the following methods:

  • Create
  • Remove
  • Update
  • GetComponentPresentation

Hopefully these are all clear as to what they do, however, it should be noted that GetComponentPresentation is needed even when you do not plan to get DCPs from the JCR via the Broker – i.e. you are retrieving them via another method. The method is needed to decide whether or not you need to create a new Node or update an already published one. Without implementing this method fully you will always create a new component.

Storing my DCP

Opening a session to the JCR is the first thing I need to do. This is done on the first call to the class and is performed over RMI. RMI was the most logical choice for me and it did not take much to get CRX to work with RMI. However, you can choose from JNDI, HTTP or WebDAV rather than RMI if you wish.

To do this we create a repository object:

System.setProperty("java.rmi.server.useCodebaseOnly", "true");
ClientRepositoryFactory factory = new ClientRepositoryFactory();
Repository repository = null;
repository = (Repository) factory.getRepository(url);

Login and get the session:

SimpleCredentials creds = new SimpleCredentials("admin", "admin".toCharArray());
session = repository.login(creds, "crx.default");

Get the blogPosts node where we will store our data:

root = session.getRootNode();
blogPosts = root.getNode("BlogPosts");

From there I can store my content. I will need to load my content as a DOM, get the values and create a new node from those values.

OK, get the XML content and extract the values:

content = cp.getContent();
Document doc = stringToDom(content);
doc.getDocumentElement().normalize();
nodeList = doc.getElementsByTagName("title");
title = nodeList.item(0).getTextContent();
nodeList = doc.getElementsByTagName("body");
body = nodeList.item(0).getTextContent();

Then add the new node:

javax.jcr.Node blogpost = blogPosts.addNode(title, "BlogPost");
blogpost.setProperty("title", title);
blogpost.setProperty("body", body);
blogpost.setProperty("tcmuri", "tcm:" + publicationId + "-" + componentId);
blogpost.setProperty("xml", content);
session.save();

Now you may notice I am storing two other values with this content. I am storing “tcmuri” and a field called “xml”. The TCM URI is the unique URI of every item in SDL Tridion. I will need this later to work out whether or not a specific piece of content already exists in the JCR. I chose not to store the node with this as the title, to keep the JCR repository human friendly. The XML field is a copy of the complete XML content which I have stored in this example so that my GetComponentPresentation method works without having to parse the data back into an XML string so I can later parse it with an XSLT on my website. I therefore have both options when using the data again.

Now that content goes into my JCR, I need to see if I can update or remove it. The GetComponentPresentation method will need to be implemented. To get a DCP I will need to find it in the JCR and return a CP object.

OK, so open a workspace and a query manager and then use an XPath to find my item based upon the TCM URI that I am wanting up get:

Workspace workspace = session.getWorkspace();
QueryManager qm = workspace.getQueryManager();
Query query = qm.createQuery("//BlogPosts/*[@tcmuri='tcm:" + publicationId + "-" + componentId + "']", Query.XPATH);
QueryResult queryResult = query.execute();

Then, select the first node (I can only ever have one published) and return a CP object:

NodeIterator nodes = queryResult.getNodes();
Node n = nodes.nextNode();
Node blogpost = blogPosts.getNode(n.getName().toString());
Property content = blogpost.getProperty("xml");
return new XMLComponentPresentationImpl(publicationId, componentId, componentTemplateId, content.getValue().toString());

Now it can be decided whether or not my DCP already exists in the JCR and if it does exist I update it in more or less the same way as I did when I created it, only I start with an existing node.

To remove, I once again retrieve the existing node and then remove it:

QueryResult queryResult = findJcrComponent(publicationId, componentId);
NodeIterator nodes = queryResult.getNodes();
Node n = nodes.nextNode();
Node blogpost = blogPosts.getNode(n.getName().toString());
blogpost.remove();

I can now publish, re-publish and un-publish my XML content from the database. It would only be one small step further to use the content on my website.

Conclusion

It is clear I have implemented a far from perfect integration; I just built something to see what would happen. It was never really going to be a problem to integrate SDL Tridion and a JCR; it was just something that has never been done. Both have the correct integration points to make any integration possible so it is certainly possible to do pretty much anything you can imagine.

Whilst doing this it became clear that under certain circumstances you should either extend or override the functionality of the Broker.  These cases would be general to any extension of deployment of SDL Tridion’s Broker storage functionality and not just to the JCR

Case 1: Publishing all XML DCPs to the JCR

This means over riding the existing Broker functionality to move every XML DCP to the JCR. The issue I have most here is that I did not solve the problem that multiple types of XML DCPs have different XML structures and if you would like use the values from the XML (rather than storing the entire XML) then you will need to work out how to scale the parsing of the XML so that new XML structures are able to be stored in the JCR. Of course, storing the entire XML string will mean that you do not need to do anything special but you will may also want to consider storing any associated metadata too.

Case 2: Publishing some XML DCPs to the JCR and others in the standard Broker storage

Here you would extend the storage rather than replace. Catch those you want to place into the JCR and then allow the parent classes to continue processing all the others as normal. Again you might need to make the processing of the XML scalable but there is a reduced need to do so. Typically, if you are publishing only some DCPs to the JCR then you know which DCPs and therefore it can be a little more hardcoded.

Case 3: Storing the XML DCPs in both the standard Broker storage and in the JCR

If you want to store in two places, then extend the Content Deployer. It is one stage before the Broker and allows you to deploy the DCPs into an additional location. The code would be the same, just in a different class. Processing the XML also has the same challenges as before.

Case 4: Replacing the Content Data Store with the JCR

I would like to see this, even if just for fun. However, the task is not necessarily so easy. The Broker data model is not massive but there are a large number of classes to override and develop on so it would take a reasonable amount of time to deliver and I am not sure on the overall benefits to fit an existing proprietary data model into a JCR.

In addition to the above I learnt that I can still program Java, it was a bit of a shock that it all went so easily but I was helped greatly by the good documentation from both SDL Tridion and Day. I am sure there are also better ways to do this but this one worked for this experiment.

I think publishing content to a JCR makes allot of sense. Whether or not it makes real sense to move the entire Broker data model over to a JCR is up for debate. Why use a JCR when a database works just as well? Reality says you will probably only publish to a JCR when you are sharing the JCR with another application and therefore the Broker data model is not applicable as you will need to fit into an existing or common structure. I would like to see a project to create such an implementation for the community, maybe, with this post I encourage others to help with this. If you want to, then contact me via my contact page.

On a final thought, I would like to hear your opinion on the merits of this experiment and maybe other use cases that I have not thought of. Feel free to post comments in the provided space below.

Download the sources

SDL Tridion to JCR example

Vignette starts round two?

Twitter searches have indicated that Vignette maybe writing a new CMS Vendor Meme for Enterprise CMS Vendors. The tweet from @kirstenpetra reads:

“starting my meme for Enterprise CMS vendors … getting feedback from the gallery … send questions if you like”

I welcome this from Vignette and I would eagerly await a new set of questions. If this is indeed the case, hope the community would enjoy it as much as the last and hopefully the questions will be nice and well balanced. Whilst a large number of CMS vendors have the capability to serve both large and small organisations, the positioning of the vendor is usually to serving either enterprise or smaller organisations. In the case of the latter, the vendor needs to be more open to serve that market. It was a point that Vignette made clear when they posted their response to the last CMS Vendor Meme.

Now if there is a new Meme I can’t wait… and maybe this one will encourage others who did not respond to the last one to respond this time.

🙂

Meme ID 9c56d0fcf93175d70e1c9b9d188167cf suggested by Bertrand Delacrétaz. Find more related pages on Google.

CMS Vendors go head to head

A few weeks back CMS Watch’s Kas Thomas posted his “reality checklist” for CMS vendors. Each vendor should ask themselves 15 tough questions about their product. Now Day has put down the challenge to all other CMS vendors, the CMS Vendor meme, to answer the questions from the check list.

Now, next to Day the CMS vendors have been posting their scores. Currently the leaderboard looks like:

  1. 44/45 – e-Spirit ***
  2. 43/45 – Jahia
  3. 43/45 – Hippo CMS
  4. 42/45 – Magnolia
  5. 42/45 – EPiServer
  6. 42/45 – GX *
  7. 42/45 – Midgard
  8. 42/45 – Nuxeo **
  9. 41/45 – infopark
  10. 41/45 – KnowledgeTree
  11. 40.5/45 – Enano
  12. 40/45 – Day
  13. 40/45 – Alfresco
  14. 40/45 – GX
  15. 40/45 – CoreMedia
  16. 40/45 – Sitecore
  17. 40/45 – Alterian
  18. 40/45 – OpenText
  19. 40/45 – Ez Systems
  20. 38/45 – dotCMS
  21. 37/45 – Vignette
  22. 37/45 – Autonomy Interwoven
  23. 36/45 – Escenic
  24. 33/45 – Sense/Net
  • bold scores are where the vendor did not score themselves but it was subsequentally worked out by Jon Marks
  • * Score adjusted to reflect original scoring system
  • ** Vendor does not seem to be able to add up 🙂
  • *** Was 45, now 44

Many of the answers to the checklist are very tongue in cheek but many of the questions do not really go deep. Mostly the questions surround how available software is either to download, easy it is to install or how clear the pricing is. These are indeed important things but I do feel the list missing something more concrete. Only two of the questions (3 & 7), for instance, address something to do with content editing. Surely this is one of the most important areas to cover and thus deserves more attention?

Of course this list is not a complete check list, but it seems more tuned towards vendors such as Alfresco as most of these types of vendors will probably score highly. However, it is nice to see the vendors interacting together and at least, it seems, giving honest scores.

Update 19/03/2009: Adding the meme ID 9c56d0fcf93175d70e1c9b9d188167cf suggested by Bertrand Delacrétaz. Find more related pages on Google.

Update 19/03/2009: Added infopark

Update 19/03/2009: Added dotCMS and Midgard (no scores yet though)

Update 19/03/2009: Added Vignette (no score either)

Update 20/03/2009: Added Nuxe (finally a score!)

Update 20/03/2009: Updated Escenic’s score

Update 21/03/2009: Added Sitecore’s, EPiServer’s & OpenText’s scores

Update 22/03/2009: Added Autonomy Interwoven (no score)

Update 23/03/2009: Added Alterian & Hippo CMS

Update 25/03/2009: Updated scores according to Jon Marks blog

Update 27/03/2009: Added KnowledgeTree

Update 02/04/2009: Added Enano

Update 03/04/2009: Added Ez Systems

Update 09/04/2009: added e-Spirit & Sense/Net

Update 15/04/2009: Updated e-Spirit score

© 2017 Julian Wraith. All rights reserved.

Theme by Anders Norén.