Archive for the 'RedDot CMS' Category

Open Text UK Web Solutions Community Day 2009 Review

Sunday, June 28th, 2009

Introduction

On Wednesday 17th June 2008 I attended the Open Text UK Web Solutions Community Day - completing my trifecta of RedDot CMS conferences for this year. Unlike my previous reviews, I won’t be going into as much detail - the contents of the presentations (powerpoint plus audio) are available (well, the powerpoints are so far) on the UK WCM Community Site. For those of you without access to this site, each presentation could probably merit its own article - so I’ll just stick to the highlights for now. At the moment, I just want to get this out before the release of Version 10 on June 30th… Leave comments for anything you would like in more detail.

The conference was held at the Madejski Stadium in Reading, just a short and convenient hop from my place of residence. The day was broken up into four tracks - technical, partner, customer and Obtree. I stuck to the technical track and will be going through the audio and powerpoints of the other tracks as time permits (well, except for the Obtree track that is!)

The day started with the obligatory welcome and introduction - the main points of interest being the above mentioned launch of the UK WCM Community site (a replacement for the previous RedDot Community site) and that all sessions would be available there as powerpoints and audio. The obvious advantages being less note taking required and less concerns about missing the content of the other tracks.

Enhanced Template Design

First up on the technical track, enhanced template design - which showed how to use Render Tags and Pre-Execute scripting to create enhanced and multi-functional templates - ie single templates that handle what you may have previously considered implementing multiple templates for. Examples included alternative page headlines, styling the first item in a list differently, laying content out in different column configurations, pulling content up from pages nested below, detecting whether a list or container contains pages, using a single template for page links, documents or external URLs, splitting a list into two or more columns and A-Z listings.

If you haven’t done anything like the examples above, and/or you are not sure how to, then I would imagine this session (and the code samples) would have been beneficial for you. If the above sounds easy to you - well the benefits would have been limited. One thing to note - due to the limited scope and the introductory nature of the session, there are a number of issues not touched upon in the code samples, including placeholder escaping and code efficiency (one, you will probably want to use functions, two beware large amounts of logic in list processing - you can easily start creating Pre-executing script in the size of megabytes). Oh - and the Render Tag examples, while not requiring Navigation Manager, do require version 7+.

Two of the more advanced items to come out of this session - while you can use RQL in your Pre-Executing script - you should limit it to read options only, as write options during the page build are unpredictable and may cause issues. Also, you can switch from Pre-Executing script to RDExecute for debugging - though be aware that this will be easier if you use only a single Pre-Execute tag pair, and that the error and line numbers returned are specific to the generated script…

Implementing Web 2.0 Tagging & Voting using Delivery Server Web Components

An introduction to tagging and voting and how Open Text delivers them in Delivery Server, you can probably skip straight to page 17 of the presentation for the technical overview. Interestingly, you don’t need a license for the Tagging and Voting Web Components - but you do need the Delivery Server “RMVT” module license. In fact, the Tagging and Voting Web Components use standard Delivery Server functionality - you could write them yourself (though I am not sure whether this would include the integration into Delivery Server?) - they exist to get you off the ground quickly.

Tags exist in their own project so that you may share them between projects. Tagging can be assigned to pages or components of pages, and from Delivery Server or Management Server. A blacklist of unacceptable tags (including regular expressions) and a white list of suggested tags can be maintained. Future functionality (when?) includes managing tags from Management Server and utilisation of the BIRT chart engine for graphical views.

Having not implemented tagging, voting or Delivery Server recently - its not immediately obvious to me how good the implementation is - it will be interesting to hear some feedback in this regard. One note brought up was that there is no magic in the voting system that stops multiple anonymous votes. You can however limit votes for logged in users. In the meantime, the community site is using these components - so keep an eye on it to see how these pan out (its a bit barren to really test these components at the moment)

Navigation Manager - The Next Steps

Continuing on from last year’s Community Day Navigation Manager session (which I missed), this session goes into what has been learnt in the last year in terms of lessons learnt and best practice. If, like me, you have been through these “lessons” personally, then probably the explanation of Navigation Manager caching was the most interesting part of the session. For those that are yet to experience the fun of Navigation Manager - take heed - I can personally vouch for most of this session!

Some specific comments on some of the dos and don’ts:

  • Use as few navigation areas as possible - 1 - 3 is okay, 7+ is not (on a single template that is)
  • Use RenderTags for generating breadcrumbs and sitemap - the placeholder functionality may be deprecated in the future.
  • Make use of detailed authorisations on navigation lists - restrict the users who can connect pages to the navigation system, reduce likelihood of connecting duplicate pages etc.

The only “Don’t” I would question is the “Do not use Pre-execute or RDExecute in the Navigation Templates.” - though I would certainly caution against it - especially if you are planning to execute RQL as well. I would suspect that this is more an issue with code efficiency (as mentioned in Enhanced Template Design above) - you need to be aware that your code size and complexity will be multiplied out by the number of navigation items rendered - which can easily increase you Pre-execute or RDExecute script size to unmanageable levels - especially if you have ignored some of the other best practices.

Code samples included recognising first and last links in a list, differences in Rendertag and page info element GUID representations and how to successfully compare them, for each loops (including counters), changing site colours and/or footers per section, global project values and the CurrentMasterPage rendertag.

Unfortunately I think this session did a better job of highlighting the restrictions, limitations, inconsistencies and hacks required to utilise Navigation Manager rather than showcasing the progress that has been made. My recommendation still holds - the most important best practice is to keep your site navigation as simple as possible!

I missed picking up the updated cheat sheet - and I haven’t seen a copy on the community site - yet.

Delivery Server and User Generated Content

A worked through example of an events management system using Delivery Server. As always - skip straight to the implementation for the “meat” of the presentation. I imagine this would make a good next step after the Delivery Server training.

Again, the example is bare bones due to the introductory nature and time constraints - but basically should give a good example of moving data in and out (ie CRUD operations) of Delivery Server - regardless of whether it is an events management system or even user generated. I don’t know if I would go as far as to tag Delivery Server as a rapid application development platform though (comments?) It should be noted that the session was Delivery Server focused, so there was no mention of integration with Management Server. Perhaps next Community Day (or perhaps here) an example of User Generated Content and integration with Management server would be useful (rather than replicating user and workflow management in Delivery Server)

Developing a Sharing Strategy

This session covered every (and I do mean every) sharing possibility in Management Server, from page instances sharing content classes to inter-project content sharing. For those who are no longer beginners I think you can safely skip to slide 10 - inter-project sharing techniques. The actual sharing strategy decision graph from slide 18 is probably the most helpful element - but it won’t be anything new to advanced practitioners.

Probably the only hole is that the session doesn’t specifically mention sharing of content classes via project or language variants - but these pretty much come under multi-sites - the decision is still whether the information architecture is shared or not. For language variant projects I have been on, I would suggest you want over 80% shared information architecture if you want to use language variants over master/child projects.

Version 10 Preview

The version 10 preview was not too different from the one I wrote about in the 4th European RedDot Usergroup Conference Review - Part 1 so I will only mention the differences here. This preview was running off of the servers back in Germany, rather than on a virtual server. Hence it was even closer to being the finished version. The obligatory apology for speed was changed from virtual server to network speed :) We thankfully didn’t have any long winded introductory powerpoint presentation though - so we got straight into the live demo.

The major drivers for the new version are usability and cross browser compatibility - the goal being to provide a “groundbreaking” step in Web Content Management. I guess we will all be the judge of that soon… Consequently, except for the PageBuilder improvement - don’t expect any developer enhancements this time around :( Instead, expect your users to have more convenient, faster, quicker, less clicks, less popups and more direct access to features, functionality and completing tasks (ie replacing all that RQL you have been writing…) I sense the Open Text sales team will be very excited - lets hope our users are (which will come down to stability and robustness of the final product in the wild I think) and us (who still have to develop for and support it).

The latest version of Telerik’s RAD Editor will be included - lets hope Open Text have integrated it more successfully (fully and bug free) this time - giving cross browser support, more options and pure XHTML code generation.

Search by page id directly in the search box. Management Server will remember recent searches and will show both the search results and a selected page - allowing users to update each page in the search results in turn without popups or having to re-search.

The changes are all in SmartEdit, so no SmartTree updates. Also, not all dialog boxes have been converted to the new look and feel - so expect some “flashbacks” occasionally. Other future items not yet implemented include combining tasks across projects.

I missed the recent webinar on Version 10 - so leave comments on anything  last minute I’ve missed.

Conclusions

While I can’t speak for the partner or client tracks (yet) - the technical track  was good, but not excellent. On the plus side, most of the presentations included real problems and solutions with code samples. On the minus side, most also included a lot of introductory waffle before getting to the technical meat of the session. All were limited by the time allocated and were necessarily simplistic in order to get the concepts across in the time frame. It is my experience that the real problems surface when trying to fill out the last 20%, not the first 80%.

The venue and catering were good. The main room (registration, lunch, partners, socialising) was pretty small, so there were a limited number of partner stands - but there were plenty of Web Solutions and partners floating about - including the Web Solutions support team. We got another Open Text branded netbook bag (similiar to the Content Day) with another pad, pen, pencil and partner parenphenalia (including a red dot stress ball from one of the partners).

In conclusion it was a good day - though I personally could have used the content of the presentations a year or so ago, better late than never! It was a good opportunity to catch up with past clients, Web Solutions consultants and RedDot Usergroup members in a much cosier setting than the Content Day. I would certainly recommend it over the Content Day if your dealings with Open Text are limited to their Web Solutions arm (and you can only get to one)

4th European RedDot Usergroup Conference Review - Part 1

Tuesday, June 16th, 2009

Paul and I attended the 4th European RedDot Usergroup Conference on Tuesday May 19th 2009, held at the National Archives, London. This was my first time at a RedDot Usergroup conference - so my aim was to get a feel for the RedDot Usergroup, learn a few things and contribute where I could. The RedDot Usergroup is a non-profit organisation, so the conference was no free lunch. Which means evaluating the value for money for the conference and also whether to join up for an annual membership.

Disclaimer: I am a contract Management Server (nee RedDot CMS) / web developer currently working for the Legal Services Commission in London. However, I was at the conference on my own time and dime. I also blog for the Unofficial RedDot CMS Blog, for whom I gave a promotional presentation, and volunteer at Friends of the Earth, UK. However, all my views are my own and in no way represent the views of any of my affiliations, except by coincidence or accident :)

Welcome

The conference got off to a bit of a late start, what with some of the organisers, Open Text, partners and clients flying in from Germany. Of course it was someone from the UK that was truly late - London traffic and all. The welcome included a brief introduction to the RedDot Usergroup as well as current activities. Apparently a name change to the Web Solutions Usergroup is being investigated.

Unofficial RedDot CMS Blog

This was an awesome and thankfully very short presentation given by yours truly. I can’t take credit for the powerpoint presentation - that was all Frederic’s work - but the spoken content was all me, for better or worse. Contrary to popular opinion at the conference, its not *my* blog - I am merely one of the eight contributing authors. Perhaps if the stats rise significantly due to my presentation I might be able to join the coveted inner circle :)

Open Text Artesia Digital Asset Management

This was my first look at Artesia, having missed the presentations at the Open Text Content Day UK. Or maybe I should rephrase that as my first glimpse. One of the issues I have with a lot of vendor and partner presentations is that from a technical point of view, the content is minimal. Between the marketing spiel and the high level nature of the presentations - well maybe I am just not the right audience. The reality for me is the coal face of actually making things work in real life. Still, there were a couple of interesting points to come out of this. With the current move away from documents towards video I have to agree with the presenter that it is a bit unfortunate that Open Text has the word text in its name. Perhaps Open Video or Open Media would be more appropriate looking forward? Oh, and general consensus amongst clients was that no one was happy with the inbuilt Asset Manager in Management Server :)

Coffee Break

Had a great conversation with Ulrich Weiss about performance issues with Navigation Manager and 700+ instances of the master page templates - before I realised he is on the RDUG management board and also an accomplished RedDot developer at Karlsruhe Institute of Technology - as would be proven in a later session.

Roadmap and Version 10 Preview / Live Demo

After another lengthy marketing spiel (including slides from the Open Text Content Day UK and the previous Artesia presentation - well I can’t say Open Text don’t know a thing or two about content reuse!) and some buzzword bingo worthy rhetoric (We care, provide a compelling user experience, agility and innovation) - finally got some information on the roadmap and my first view of version 10 - mostly in Powerpoint slides, but with some live demo.

Nothing is final with dates, but we can apparently expect version 10 to drop in June 2009 (hey - that’s now!), with a smaller service pack or upgrade codenamed “Falcon” in December 2009. The next major version after that (codenamed “Orca” - not a good sign) is scheduled for April 2010, and is likely to be a major update of the backend to .Net.

Version 10 would seem to include a new version of the PageBuilder written in .Net, which supposedly could increase PageBuilder performance by up to 70% (depending on project implementation / complexity) and an overhaul to the SmartEdit interface - slicker, with drag and drop. The PageBuilder enhancements also have multi-processor support - which should allow publishing and editing at the same time - yay! It will also be released as an upgrade to version 9 separate from version 10.

The new SmartEdit will work across Firefox, Safari and Chrome (and IE of course!). SmartTree is planned for all four browsers, but it is not certain yet (it may contain an IE only tree). The clipboard comes to the new version of SmartEdit, as well as a read only Navigation Manager tree to help navigate the site, drag and drop content classes, a right mouse button menu to replace the Action Menu and a number of other common information / actions are promoted in the interface - project switching, views (SmartEdit, redlining - though still no structural redlining, form view, preview and Delivery Server preview - though no preview by date - you will have to do that the old fashioned way for now) and the current page identifier.

Search and tasks have been improved. You can now access recent searches and also save customised searches for later. The results may be grouped by your choice of search criteria. The excessive clicks, pages and popups required for tasks has been simplified - replaced with a new home page, fully customisable iGoogle style with “widgets”. For example, a custom search showing recently modified content. Presentation can be customised by group, but you can still only see information relating to the current project.

Last bits - should support 64 bit, should run on VMWare, while RQL should still be supported you will need to test as their is no 100% guarantee. There are no changes to SmartTree.

Discussion centred around the upgrade from 9 to 10 - basically play it safe - ideally upgrade on a separate box and migrate across (with all the fun that this entails). If there are going to be upgrade problems, this is going to be it. Of course, you always have the option of staying on 9 and upgrading the PageBuilder only - which should garner significant performance improvements by itself. Also - no date on version 10 service pack 2 (the first “usable” version, as one of the members joked).

My thoughts? It looks promising - but the proof will be on the ground in real projects, not in presentational demos. It has certainly been a long time coming. While I think most of the interface improvements will be for the better (and remove some RQL plugin requirements) the question is - is it enough? That will become even more pertinent if the upgrade process turns into a nightmare. I will add one personal note on the user interface - the drag and drop content classes. From the demonstration (which wasn’t perfect) - you can drag the content class from a pop out menu on the right. Apparently this will only show those content classes that are available on the page. The red dots you can place that content class on will remain red (others will be greyed out). Does this seem backwards to anyone? Wouldn’t it be better to present the available content classes from a context menu on the red dot itself? Also, there doesn’t appear to be any visual representation of content classes - which would have been a nice addition too.

I still have plenty more to cover, but that is a post for another time (soon!). On Wednesday I am off to the UK Web Solutions Community Day 2009 in Reading - which should hopefully shed some more light on version 10.

Until next time,
Adrian

CMS Vendor Meme

Monday, May 11th, 2009

Note: This post also appears on the Unofficial RedDot CMS Blog - check it out for more RedDot related posts from RedDot developers across the globe and less of my personal stuff :)

Many moons ago now (26th February 2009), Kas Thomas - an analyst at CMS Watch - wrote an article “A reality checklist for vendors“. A month later (17th March 2009), Day - a CMS vendor - responded with “Introducing the ‘CMS Vendor Meme’” - scoring themselves against Kas’ criteria and challenging other CMS vendors to do the same. Open Text responded (”Open Text on the CMS Vendor Meme“) on the 20th March 2009.

You can get a great wrap up on Jon Mark’s blog “CMS Celebrity Deathmatch - The Aftermath” or by doing a Google search for articles tagged with meme identifier 9c56d0fcf93175d70e1c9b9d188167cf.

What seemed to be missing, however, is some client and developer feedback on specific CMS vendor responses - some “keep the bastards honest” if you will. So this is my belated effort with respects to the Open Text response from a humble developer. I hope the conversation stirs up some comments/feedback from other clients/developers and provides more value than just a number. Oh - and I will ignore the ludicrousness of a scoring system that gives even my non-existent CMS a 15/45!

Removing buzzwords and marketese, we can safely ignore the first four paragraphs of the Open Text response and get straight to the questions.

1. Our software comes with an installer program.
Open Text’s Response
: Yes
Open Text’s Score: 3 (Jon scored all of Open Text’s responses as Open Text didn’t)
Adrian’s Response: Yes, though I think I have only used it once for an upgrade.
Adrian Score: 3

2. Installing or uninstalling our software does not require a reboot of your machine.
Open Text’s Response: Sort of; the response is dependent on the underlying OS choice of the customer.
Open Text’s Score: 2
Adrian’s Response: Hmmm. Not sure. I have often seen the server rebooted after an upgrade, but I am not sure whether it is necessary. Certainly there doesn’t appear to be good tools for restarting the services - but I do think the install/upgrade does this for you… Assuming we are both talking about Management Server (aka RedDot CMS) I am not sure what OS choice they are referring to - unless it is for various flavours of Windows?
Adrian Score: 2 (happy to carry Open Text’s score)

3. You can choose your locale and language at install time, and never have to see English again after that.
Open Text’s Response: Yes, as a global company with sales and support offices in most major regions, we have invested in multi-lingual product and support, a key requirement to help enterprises that span multiple geographies and time zones.
Open Text’s Score: 3
Adrian’s Response: Again, I haven’t been directly involved in many installs - and then I only use English anyway - so I can’t confirm. It would have helped for Open Text to provide a screenshot of the appropriate install screen to back up their answer - much more than the wordy marketing response. Or maybe as a developer I just prefer a succint yes/no answer with actual proof?
Adrian Score: 3 (Erring on Open Text’s side minus confirmed experience)

4. Eval versions of the latest edition(s) of our software are always available for download from the company website.
Open Text’s Response: Yes, all our software is always available for download to our customers. The same is true for early beta version to those customers and partners that participate in beta programs.
Open Text’s Score: 3
Adrian’s Response: Although this is true, I don’t think it answers the spirit of the question - which is that this software should be available to non customers to evaluate - which as far as I am aware, it definately isn’t. In my experience, the whole procurement process of Management Server is very tightly controlled by Open Text and its sales team and is in no way “open” *until* you have signed on.
Adrian Score: 1

5. Our WCM software comes with a fully templated “sample web site” and sample workflows, which work out-of-the-box.
Open Text’s Response: Yes, we deliver a demo project with the software. But the demands of global business today require Web Solution products that provide integrations into any eco-system from SAP to Microsoft. Therefore we decided to also provide customer workshops targeted to meet increasingly complex requirements of our customers, e.g. web solutions for SAP or Web Solutions for Multi-Sites.
Open Text’s Score: 3
Adrian’s Response: Again, true - but I think the wordiness of the response hides the fact that the demo project is rather basic. You *need* the workshops because the demo project doesn’t show enough of the system for what you actually *want* to accomplish. Oh, and this is an extra cost thank you as well :) (for the workshops and training that is, not the demo project) Images would help here - or maybe not :)
Adrian Score: 3 (technically has, but very basic - no real world challenges)

6. We ship a tutorial.
Open Text’s Response: Yes
Open Text’s Score: 3
Adrian’s Response: I am not certain what tutorial Open Text is talking about here. The demo project? The context sensitive help? The additional cost training and workshops? Apart from the training and workshops, there is no step by step tutorial showing you how to setup your project, templates and authoring environment to my knowledge. The context sensitive help is probably as close as you get with the product - but it is hardly a tutorial. Images would again help here.
Adrian Score: 2 (because I am nice)

7. You can raise a support issue via a button, link, or menu command in our administrative interface.
Open Text’s Response: “Issues” require a dialogue, and we have built-in support systems and tools that enhance the dialogue but not a single button to “call” support. But the really interesting question here should be, “Do you provide enterprise-class, global service level agreement support?” We serve our customers 24/7 at Open Text.
Open Text’s Score: 1
Adrian’s Response: Yes there is no single button to call support. Funnily enough I have implemented one before (A “bug” red dot to submit an issue to Trac complete with all that information the users forget to provide like server, project and page id!). But still, there seems to be a bit of controversy around this question regardless of Open Text’s wordy answer. What they don’t mention is that you now have to go through two levels of support to get to someone who actually knows the product and standard response is 8 hours. (Ah the joys of being enterprisey - see I can use big words too!)
Adrian Score: 1

8. All help files and documentation for the product are laid down as part of the install.
Open Text’s Response: Yes, in fact we take it one step further and provide an online community called the Knowledge Centre for our customers and partners to get access to the latest and greatest information they need whenever they need it. This ranges from basic information like the documentation and software updates, to best practices and active community discussions with their peers.
Open Text’s Score: 2
Adrian’s Response: Another controversial question, especially with regards to maintaining up to date information. Open Text do provide substantial help files and documenation as part of the install. No, it isn’t everything - training/workshops plus the Knowledge Centre hold more. Haven’t witnessed/participated in any active community discussions with my peers though (through Open Text anyway)
Adrian Score: 2

9. We run our entire company website using the latest version of our own WCM products.
Open Text’s Response: Sort of. The Web Solutions site is running on the latest Web Solutions technology; but some areas of Open Text run on earlier versions. Our priority was to build a platform that allows us to design micro sites we have affectionately named iVillages–sites designed to quickly integrate the newest acquisitions, and adopt emerging social marketplace requirements in a fast and efficient manner.
Open Text’s Score: 2
Adrian’s Response: Can’t add much here. Certainly all of the previously RedDot sites are run in Management Server, and the community site (before it was subsumed into the Knowledge Centre) was run in Delivery Server.
Adrian Score: 2 (I concur)

10. Our salespeople understand how our products work.
Open Text’s Response: Yes, our Web Solutions specialist sales people certainly understand our web solutions products. Given that we offer the entire spectrum of ECM technologies; from WCM to Social Networking (did we forget to mention we have built our own, highly secure and enterprise-friendly social networking platform?) to Records Management (we would be interested to learn what the other vendors’ compliance and e-discovery capabilities are) to enterprise class Process Management … We have specialists and generalists in all these exciting fields.
Open Text’s Score: 3
Adrian’s Response: Well it seems Open Text aren’t the only vendor that believe this. Of course this is going to come down to individuals to some extent, but I can’t help but feeling the support and Web Solution consultants know a lot more about the products than the salespeople. This is the first of the “perception” issue questions.
Adrian Score: 2

11. Our software does what we say it does.
Open Text’s Response: Yes, and more importantly, our customers tell us it does what they ask of it and rely on it for.
Open Text’s Score: 3
Adrian’s Response: The second “perception” issue question, especially relevant as (according to Kas Thomas) it flys in the face of customer satisfaction research - the issue being it not doing what the customers thought it would do! I think Management Server suffers from this in spades. It is very good at ticking checkboxes. It is not very good at being flexible in how it achieves those ticks. Or put another way, so long as you implement the way Management Server wants you to, and you have few additional requirements, you shouldn’t have a problem. Try to get too smart or start considering square pegs in round holes and you will start on a sure and steady journey to implementation hell. Unfortunately, real life is not good at sticking to arbitrary constraints.
Adrian Score: 3 (but make sure it actually does what you want it to do!)

12. We don’t charge extra for our SDK.
Open Text’s Response: Yes, our solutions come with an API.
Open Text’s Score: 3
Adrian’s Response: Doesn’t really answer the question. I have had some fun with this in the past. The SDK seemed to be freely available to US customers, but is definately not freely available to UK customers (requires additional module purchase). Not sure if this has changed with the move to the Knowledge Centre - but doubt it. Regardless, it is certainly not free and posted on the public-facing company web site (not a password-protected extranet).
Adrian Score: 1

13. Our licensing model is simple enough for a 5-year-old to understand.
Open Text’s Response: Let’s say yes. We only had one 6 year old in our focus group, but when I checked with my colleague’s son, he verified in crayon: “one engine and as many wheels you want to add.”
Open Text’s Score: 3
Adrian’s Response: Don’t know, haven’t been involved on the licensing/pricing side. Seems to be a fairly closely guarded secret - certainly isn’t discoverable on their web sites.
Adrian Score: 3 (Err on side of Open Text pending more information)

14. We have one price sheet for all customers.
Open Text’s Response: Yes, but keep in mind we do business in 45 countries across all industry verticals and particular bundling preferences for specific markets will mean differences. We are also unique in the technology space in that we provide end-to-end Enterprise Content Management infrastructures for entire governments. WCM being one element in this holistic information governance strategy. In such specialized cases we are happy to work with our customers to assess a suitable pricing structure for their complete web content requirements.
Open Text’s Score: 3
Adrian’s Response: Sounds like a lot of verbage for a yes answer! Or a very large single sheet! Again, it doesn’t appear to be publicly available, so its hard to confirm. I don’t have any experience to comment one way or the other.
Adrian Score: 3 (Err on side of Open Text pending more information)

15. Our top executives are on Skype, Twitter, or some similar channel, and: Feel free to contact them directly at any time.
Open Text’s Response: Many are, but not all. e.g. Daniel is (he runs web solutions): @danielkraft/www.myifridge.com/myifridge (skype), and most of the web & social networking team is @CherylMcKinnon/candyandaspirin.blogspot.com, @DaveChalmers1, @craighepburn. Maybe it is also worth mentioning that all of our people (including all executives) use internal social networking tools like communities, forums, wikis, IM or blogs based on our own technology…so we walk the talk.

Given our continued growth as a major ECM vendor, we have a healthy diversity among our executive management team that ranges from early adopter technology and marketing strategists to pure business management C-levels responsible for the bottom line. Given the current economy I am glad to have that diversity of experience, street-smarts and education steering the ship, even if they don’t all Twitter…yet.

Cuneyt Uysal, Product Marketing, Open Text Web Solutions/@cuneytuysal/www.cuneytuysal.com/cuneyt.uysal (skype)
Open Text’s Score: 3
Adrian’s Response: Can’t argue with the proof - not that I have ever tried to contact any of them directly. Interestingly, Daniel Kraft is no longer with the company.
Adrian Score: 3

FINAL SCORE
Open Text: 40
Adrian: 34

Conclusion
The scores mean very little - what with the validity of the questions, their particular interpretations and a simple 1 to 3 scoring mechanism. So don’t get hung up on the scores. Who knows what the other systems would score if scored by their clients and/or developers :) What is (hopefully) interesting is the conversation. As a customer and/or developer do you agree, disagree, don’t care or have more to add?

Regardless of our opinions, my hat goes off to Open Text for actually responding - it puts them a lot closer to “getting it” in my opinion than any scoring system. It is interesting that the only other ECM vendor to respond (Vignette) is being bought by Open Text - perhaps they have more in common moving forward than first thought. Now if only they could drop the buzzwords and marketese… (and release the API publicly!)

Web Development Tips For Web Solutions Management Server (previously RedDot CMS)

Monday, April 27th, 2009

Note: This post also appears on the Unofficial RedDot CMS Blog - check it out for more RedDot related posts from RedDot developers across the globe and less of my personal stuff :)

One(!) of my current projects is about to have some web development done prior to being built in Web Solutions Management Server (previously RedDot CMS) which has started me thinking about some of the lessons I have learnt through this process previously. Passing these tips on to whomever is doing the web development, whether it be yourself, a colleague or an outside agency should make your job a lot easier!

Tip 1 - Develop *outside* of the CMS

Web Solutions Management Server is *not* an IDE and you will only frustrate yourself trying to use it as one. Use your favourite tools and construct a plain HTML site first. Doing so provides numerous additional advantages:

  • You can use dedicated web development tools.
  • You can use dedicated version control software to track changes in the design.
  • Yuo can use diff tools to pinpoint changes to be made to the CMS implementation.
  • You can check display issues free from issues with the CMS implementation.
  • Iterating the design is much faster and less frustrating.

Obviously not an issue if you are using an agency unfamiliar with Web Solutions Management Server.

Tip 2 - Separate your CSS into files with and without images

Take your CSS file(s) and extract all of the background images into a single CSS file. Why? Because all of these will become image placeholders in the CMS. (In fact, anything that will become a placeholder should be in this file). Background image links will rarely change in the iterative process, but your CSS probably will - and this way you should be able to simply copy and paste over the other templates without worrying where the changes actually occurred or re-instating multitudes of image placeholders…

Tip 3 - Make sure you have examples of content permutations

You are building an author editable site, not a static brochure site right? So you should check the design for edge cases in the content:

  • Zero intances - what happens if there is no content in a particular area or areas?
  • One instance - we usually get this right, but it pays to check
  • Many instances - what happens with many instances?

Also, you should check that the order of the content doesn’t break anything or look wrong either. All of these issues will soon become apparent in your implementation. All are much more easily discovered and rectified before you start building in the CMS.

Tip 4 - Do a red dot version as well

Why buy one when you can buy two for twice the price? Incorporating the editing interface into a second version of your plain HTML site has a number of advantages:

  • It makes sure you have thought about the red dots up front and therefore determined to some extent the content classes that will need to be built.
  • It makes sure that there is space for the editing interface.
  • It prevents you from trying to design the red dot editing interface within the CMS (see Tip 1) which is bound to cause more CSS issues (see Tip 2)

Tip 5 - Surround content areas with DIV tags

By content areas I mean those that will later become text placeholders. This will allow you to style the content areas independently via class attributes on the DIV tags. You should probably style the DIV and P text the same, in case your P tags go missing. Make sure these content areas are styled based on the output of the Rich Text Editor or you will be fighting an uphill battle.

What tips do you have?

While it would be nice to be able to hold off implementation until all of the web development is complete, I have yet to see this happen. If nothing else, the implementation itself often leads to changes in the design. Rather than fighting change, here we at least try to minimise and control it.

Do you have any pre CMS build web development tips to share?

Open Text Content Day UK 2009 Review

Sunday, April 26th, 2009

Note: This post also appears on the Unofficial RedDot CMS Blog - check it out for more RedDot related posts from RedDot developers across the globe and less of my personal stuff :)

Introduction

I missed the UK Community Day last year (due to a clash with a holiday in Croatia) so this year I made a commitment to go to as many of the Web Solutions Management Server (previously RedDot CMS) conferences as possible (without leaving the UK that is.) Apart from keeping up-to-date and networking, I was also wanted to determine whether I would be coming back next year :)

So on Thursday, April 23rd 2009 I was at Twickenham Stadium for the Open Text Content Day UK 2009 - the first of three conferences I plan to attend this year (the other two being the 4th European RedDot Usergroup Conference and the UK Web Solutions Community Day 2009.)

The day was broken up into the initial keynote address(es) followed by six breakout sessions with choices from across eight tracks, interspersed with refreshments and lunch. To let you know where I am coming from, I am a Web Solutions Management Server developer - pretty much the coal face (development wise) of only one of a plethora of Open Text products. Consequently, I did not have high expectations for the day - I did not expect anything technical from the keynotes and out of 47 sessions, I think I had only managed to identify two that appeared Web Solutions Management Server specific.

Keynotes

I am usually quite wary of keynote addresses from large companies but I was not disappointed by Open Text. Open Text’s commitment this year to research, development and education is impressive. Their understanding of the Internet, past, present and particularly future (its social media, video and keyboard-less interfaces) was scarily more forward thinking than I would have expected - making me question whether I am even keeping up - or worse, slowly falling behind. Being classified as part of the “keyboard” generation left me wondering whether Steve Jobs is shaking his head at me because I am excited that I will finally have cut and paste on my iPhone soon… Open Text’s vision for their product suite was equally impressive - standing on their own to meet specific needs or working seamlessly together to solve any business requirement.

It is interesting that Open Text appears to get the speed at which ideas happen on the Internet and the necessity for safe and secure products to make the most of these ideas. How they plan to implement these products in a timely manner, however, was unclear. But this is all the strategic vision, and Open Text was open about the fact that they aren’t there yet. Obviously I can’t speak for all of their products - but in my opinion they have a long way to go with Web Solutions Management Server to bring it up to the quality, integration and vision presented in the keynotes. I will believe it when I see it - and I wish Open Text the best of luck with that.

Breakout Sessions

Obviously I couldn’t attend all of the breakout sessions - so perhaps Paul might add a bit about those sessions he went to that I didn’t - so here is a run down of what I attended (you can check the details on the agenda):

Rise of the ECM Architect (ECM Champion Track)
I went to this more out of personal interest than anything else. The panel format was useful in providing a rounded picture and discussion of the ECM Architect role as each panellist had something unique to share coming from different backgrounds and companies. It was a bit dry, and as a double session was let down a little by people leaving in the middle to go to a different session. I did think of a great feature for my own CMS aspirations in this session though.

ECM: Improve your ROI, by focusing on people and process, and not just Technology (Partner Track)
After this I realised that ECM = LiveLink, not Web Solutions Management Server and the Partner Track was basically an opportunity for Open Text partners to pitch themselves and their products and/or services. :) While interesting, I didn’t learn anything new.

Case Study - HM Treasury (Public Sector Track)
Did you know the HM Treasury uses Web Solutions Management Server? Unfortunately this was a very high level session. This was more disappointing as it ended up being the only Web Solutions Management Server session - as the other one was cancelled. Still there were some interesting points:

  • The task was simply a migration from an existing web site to Web Solutions Management Server, including all content (8k-10k pages) - completed within 12 weeks.
  • All content was transferred manually - basically they threw bodies at it.
  • The ability of Web Solutions Management Server to publish out via FTP to an independent web server was critical to ensure information was secure in the CMS prior to publication.
  • The challenge of training on the actual web site prior to go live - when the build is not yet complete. (Why do they even need training? Its not like people need training to use FaceBook or Twitter…)

Enterprise 2.0 - Enabling the Social Workplace (ECM Champion Track)
Although this session was focussed on social media for the enterprise, the example was the STA Travel site (which is a Web Solutions Management/Delivery Server site). However, again, this session was high level and didn’t go into any technical details.

What can you do to protect your Open Text investment while reducing cost? (Partner Track)
I soon realised this was another Partner presentation, and for products to assist with eDOCS - which I have no experience with. However, what I found interesting was what the products *did* - basically adding reporting and auditing functionality and synchronisation capabilities across multiple libraries to an Open Text product with limited inbuilt functionality - if the functionality existed at all. Sound familiar? How cool would it be to be able to install a Web Solutions Management Server plug-in that allowed you to:

  • Synchronise projects across servers (development and production for example) whereby the authorisations are also synchronised (by synchronising users and groups by name rather than guid)
  • Update content classes *including* element attributes?
  • Advanced reporting - Diff tool for content classes anyone?

Partner Exhibitors & Open Text Solution Pods

I didn’t make too much use of these other than to pick up some free education vouchers from AIIM and to visit the Open Text Web Solutions pod - which was manned by the sales team. The sales guy was very enthusiastic, even with the slowness of running all of his demos at the same time in individual virtual machines on an overworked laptop. I didn’t feel I could get much of a word in edgewise and so was left to amuse myself with the implementation issues I know all to well that he was happy to gloss either over or right past. I guess on the upside it keeps me in a job!

Venue & Catering

The venue and catering were fine. Paul and I took the train from Reading, with the only mishap being it stopping at Whitton, not Twickenham (or maybe in addition to?) which made the walk longer than we expected and our return journey problematic - but nothing to do with Open Text :)

Stuff

A small Open Text / Microsoft / SAP branded netbook bag (I think) containing a pad, advertising and various parenphenalia. Two biros (Open Text & Steria). CD (Open Text eLearning demonstration). USB key (PDFs of various books).

Conclusion

In all, much better than I had expected. I think it is important to weigh up the merits of attending versus how many Open Text products you actually use, however the day is free and I do think I will be making the effort again next year. Personally, I am looking forward to the UK Web Solutions Community Day 2009 which should be more focused on the Open Text product I do use.

OpenText Content Day UK 2009

Tuesday, April 21st, 2009

Adrian Mateljan

I will be attending the OpenText Content Day UK 2009 on Thursday at Twickenham Stadium. Any RedDotters that are going and read this blog or the Unofficial RedDot CMS Blog - well I hope to see you there!

The One True Container

Saturday, April 18th, 2009

Note: This post also appears on the Unofficial RedDot CMS Blog - check it out for more RedDot related posts from RedDot developers across the globe and less of my personal stuff :)

One Container to rule them all, One Container to find them,
One Container to bring them all and in the templates bind them
In the CMS of OpenTextRedDot where the Content lies

Prologue

Ok, first up - a warning and some history. This is a long post that I have been working on, off and on, since the end of last year. Don´t be scared, most of the time and the bulk of the post is in the examples - which I have only recently had access to a suitable server to build and test. With a bit of luck, future posts will be a lot more compact - as this article lays the context for a lot of other posts I have been meaning to write - both in providing what I hope you will find to be a ¨real¨ example site, as well as the base template ¨pattern¨ that a lot of my solutions build upon.

So this post is a story about base templates. What I´ve seen, what I use and what I consider to be the advantages and disadvantages of both. Interestingly though, this post came about not from developing new projects, but from refactoring existing ones - and therefore I hope brings value regardless of where you are currently at. What I am about to show you comes squarely under the category of “things I wish I had known before my first project”.

This post is split into three sections. The first introduces you to our example project with what I consider to be the ¨easiest to implement, hardest to maintain¨ method of base template creation - ¨copy and paste¨. The second section takes our example project and converts it to what seems to be the most common method - ¨header and footer¨. The final section will lead you through the steps to refactor any project to my preferred method - ¨include container¨. Along the way there are sure to be a few interesting tips as well.

On a final note before we begin proper - while the example project works and hopefully will help you in understanding the advantages and disadvantages of the various methods discussed - it is not complete (for one, it doesn´t contain any red dots) nor optimal (for example, we have a lot more work to do towards localisation). Feel free to note in the comments any issues you would like to see addressed in future articles (or write them yourself!) - but try to keep the implementation discussions to the topic of this article - thanks! Oh, and probably one thing this example unfortunately doesn´t lend itself well to is navigation manager examples - but we will cross that bridge when we come to it.

The Fellowship of the Ring - Copy and Paste

So - how do you create your base templates? I expect most RedDot developers´ first experience is the RedDot training itself, which tends to be rather simplistic (as they need to teach you the basics of the system) and results in what I call ¨copy and paste¨ base templates. Basically, the process is as follows:

  1. Cut and paste the HTML of the web site into the template editor.
  2. Replace all links, images, content etc with the appropriate placeholders.
  3. Add red dots.

I have unfortunately not yet come across a HTML site as simple as the training one to implement in RedDot. :) In order to create an example with real world complexity and not burden myself with permission issues (nor creating a web site as well as the RedDot implementation) I have based my example project on the Unofficial RedDot CMS Blog itself! Not an ideal web site for RedDot you might say, but that is also a good reason to use it - it will highlight more challenges for this and future articles.

Applying ¨copy and paste¨ to the Unofficial RedDot CMS Blog gives us a base template (for articles) like so:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head profile="http://gmpg.org/xfn/11">

    <title><%hdl_headline%> | Unofficial RedDot CMS blog</title>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta http-equiv="content-style-type" content="text/css">
    <meta http-equiv="imagetoolbar" content="no">
    <meta name="robots" content="index, nofollow, noodp">
    <meta http-equiv="expires" content="43200">
    <meta name="audience" content="all">
    <meta name="language" content="en">
    <meta http-equiv="content-language" content="en">

    <link rel="stylesheet" href="<%anc_css_style2%>" type="text/css" media="screen, projection">
    <!--[if lt IE 7]>
        <link rel="stylesheet" href="<%anc_css_ie%>" type="text/css" media="screen, projection">
    <![endif]-->

    <link rel="alternate" type="application/rss+xml" title="Unofficial RedDot CMS blog RSS Feed" href="<%anc_xml_rss%>">
    <link rel="alternate" type="application/atom+xml" title="Unofficial RedDot CMS blog Atom Feed" href="<%anc_xml_atom%>">
    <link rel="pingback" href="<%anc_pingback%>">
    <link rel="shortcut icon" href="<%img_favicon%>">
    <link rel="EditURI" type="application/rsd+xml" title="RSD" href="<%anc_xml_rsd%>">
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="<%anc_xml_wlwmanifest%>"> 

<!-- all in one seo pack 1.4.7.4 [245,327] -->
<meta name="description" content="<%stf_meta_description%>">
<meta name="keywords" content="<%stf_meta_keywords%>">
<!-- /all in one seo pack -->
    <!-- Added By Democracy Plugin. Version 2.0.1 -->
    <script type="text/javascript" src="<%anc_js_democracy%>"></script>
    <link rel="stylesheet" href="<%anc_css_basic%>" type="text/css">
    <link rel="stylesheet" href="<%anc_css_style1%>" type="text/css">
    <link href="<%anc_css_syntax_highlighter%>" type="text/css" rel="stylesheet">
    <link rel="stylesheet" type="text/css" media="screen" href="<%anc_css_sociable%>">
<!-- Protected by WP-SpamFree v2.0.0.1 :: JS BEGIN -->
<script type="text/javascript" src="<%anc_js_wp_spamfree%>"></script>
<!-- Protected by WP-SpamFree v2.0.0.1 :: JS END -->
</head><body>   <!--start body-->
    <div class="container">   <!--start container-->

        <div id="header" class="column span-14">

            <div id="logo" class="column first">

                <div class="title">
                    <div><a href="<%anc_home%>">Unofficial RedDot CMS blog</a></div>
                    <div class="desc">RedDot hints from developers, freelancers and fellow customers</div>
                </div>

            <!--<a href="<%anc_home%>" title="RedDot hints from developers, freelancers and fellow customers: Home" class="sitelogo"></a>-->

            </div>

            <div id="search_menu" class="column span-6 border_left last push-0">

                <div id="search" class="column first">
                    <h3 class="mast4">Search</h3>

                    <div id="search-form">
                        <form method="get" id="searchform" action="<%anc_search%>">

                        <div><label for="s" class="none">Search for:</label>
                        <input name="s" id="s" class="search_input" value="" type="text">

                        <label for="searchsubmit" class="none">Go</label>
                        <input id="searchsubmit" class="submit_input" value="Search" type="submit"></div>

                        </form>
                    </div>
                </div>

                <ul id="menu">
                    <li><span class="home"><a href="<%anc_home%>">Home</a></span></li>
<!--                    <li><span class="about"><a href="<%anc_about%>">About</a></span></li> -->
                    <li><span class="archives"><a href="<%anc_archives%>">Archives</a></span></li>
                    <li><span class="subscribe"><a href="<%anc_subscribe%>">Subscribe</a></span></li>
<!--                    <li><span class="contact"><a href="<%anc_contact%>">Contact</a></span></li> -->
                </ul>
            </div>

        </div>   <!--end header-->

        <div id="topbanner_single" class="column span-14">   <!-- start top banner -->
            <div class="pagetitle">
                // you’re reading...
            </div>
        </div>   <!-- end top banner -->

        <div id="post_content" class="column span-14">   <!-- start home_content -->

            <div class="column span-11 first">
                <h2 class="post_cat"><%stf_category%></h2>

                <h2 class="post_name" id="post-<%inf_pageId%>"><%hdl_headline%></h2>

                <div class="post_meta">
                    By <a href="<%anc_author%>" title="Posts by <%inf_originalAuthorFullName%>"><%inf_originalAuthorFullName%></a> <span class="dot">⋅</span> March 11, 2009<%inf_pageReleaseDate%> <span class="dot">⋅</span>   <a href="#comments">Post a comment</a>
                </div>

                <%txt_content%>

<div class="sociable">
<div class="sociable_tagline">
<h5>Share and Enjoy:</h5>
</div>
<ul>
    <li><a rel="nofollow" href="javascript:window.print();" title="Print this article!"><img src="<%img_printer%>" onclick="" title="Print this article!" alt="Print this article!" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="mailto:?subject=<%hdl_headline%>&amp;body=<%inf_pageUrl%>" title="E-mail this story to a friend!"><img src="<%img_emailLink%>" onclick="" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://digg.com/submit?phase=2&amp;url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://digg.com/submit?phase=2&amp;url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>');" title="Digg"><img src="<%img_digg%>" title="Digg" alt="Digg" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://reddit.com/submit?url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://reddit.com/submit?url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>');" title="Reddit"><img src="<%img_reddit%>" title="Reddit" alt="Reddit" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.stumbleupon.com/submit?url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.stumbleupon.com/submit?url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>');" title="StumbleUpon"><img src="<%img_stumbleupon%>" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=<%inf_pageUrl%>&amp;title=<%hdl_headline%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=<%inf_pageUrl%>&amp;title=<%hdl_headline%>');" title="Google"><img src="<%img_googleBookmark%>" title="Google" alt="Google" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://del.icio.us/post?url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://del.icio.us/post?url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>');" title="del.icio.us"><img src="<%img_delicious%>" title="del.icio.us" alt="del.icio.us" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.mister-wong.com/addurl/?bm_url=<%inf_pageUrl%>&amp;bm_description=<%hdl_headline%>&amp;plugin=soc" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.mister-wong.com/addurl/?bm_url=<%inf_pageUrl%>&amp;bm_description=<%hdl_headline%>&amp;plugin=soc');" title="MisterWong"><img src="<%img_misterWong%>" title="MisterWong" alt="MisterWong" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.facebook.com/share.php?u=<%inf_pageUrl%>&amp;t=<%hdl_headline%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.facebook.com/share.php?u=<%inf_pageUrl%>&amp;t=<%hdl_headline%>');" title="Facebook"><img src="<%img_facebook%>" title="Facebook" alt="Facebook" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.mixx.com/submit?page_url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.mixx.com/submit?page_url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>');" title="Mixx"><img src="<%img_mixx%>" title="Mixx" alt="Mixx" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.furl.net/storeIt.jsp?u=<%inf_pageUrl%>&amp;t=<%hdl_headline%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.furl.net/storeIt.jsp?u=<%inf_pageUrl%>&amp;t=<%hdl_headline%>');" title="Furl"><img src="<%img_furl%>" title="Furl" alt="Furl" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>&amp;source=Unofficial+RedDot+CMS+blog+RedDot+hints+from+developers%2C+freelancers+and+fellow+customers&amp;summary=<%stf_summary%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.linkedin.com/shareArticle?mini=true&amp;url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>&amp;source=Unofficial+RedDot+CMS+blog+RedDot+hints+from+developers%2C+freelancers+and+fellow+customers&amp;summary=<%stf_summary%>');" title="LinkedIn"><img src="<%img_linkedIn%>" title="LinkedIn" alt="LinkedIn" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/https://favorites.live.com/quickadd.aspx?marklet=1&amp;url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>');" title="Live"><img src="<%img_live%>" title="Live" alt="Live" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://ma.gnolia.com/bookmarklet/add?url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://ma.gnolia.com/bookmarklet/add?url=<%inf_pageUrl%>&amp;title=<%hdl_headline%>');" title="Ma.gnolia"><img src="<%img_magnolia%>" title="Ma.gnolia" alt="Ma.gnolia" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://twitter.com/home?status=<%inf_pageUrl%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://twitter.com/home?status=<%inf_pageUrl%>');" title="TwitThis"><img src="<%img_twitter%>" title="TwitThis" alt="TwitThis" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://technorati.com/faves?add=<%inf_pageUrl%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/faves?add=<%inf_pageUrl%>');" title="Technorati"><img src="<%img_technorati%>" title="Technorati" alt="Technorati" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.newsvine.com/_tools/seed&amp;save?u=<%inf_pageUrl%>&amp;h=<%hdl_headline%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.newsvine.com/_tools/seed&amp;save?u=<%inf_pageUrl%>&amp;h=<%hdl_headline%>');" title="NewsVine"><img src="<%img_newsVine%>" title="NewsVine" alt="NewsVine" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.tumblr.com/share?v=3&amp;u=<%inf_pageUrl%>&amp;t=<%hdl_headline%>&amp;s=" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.tumblr.com/share?v=3&amp;u=<%inf_pageUrl%>&amp;t=<%hdl_headline%>&amp;s=');" title="Tumblr"><img src="<%img_tumblr%>" title="Tumblr" alt="Tumblr" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://buzz.yahoo.com/submit/?submitUrl=<%inf_pageUrl%>&amp;submitHeadline=<%hdl_headline%>&amp;submitSummary=<%stf_summary%>&amp;submitCategory=science&amp;submitAssetType=text" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://buzz.yahoo.com/submit/?submitUrl=<%inf_pageUrl%>&amp;submitHeadline=<%hdl_headline%>&amp;submitSummary=<%stf_summary%>&amp;submitCategory=science&amp;submitAssetType=text');" title="Yahoo! Buzz"><img src="<%img_yahooBuzz%>" title="Yahoo! Buzz" alt="Yahoo! Buzz" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://yigg.de/neu?exturl=<%inf_pageUrl%>&amp;exttitle=<%hdl_headline%>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://yigg.de/neu?exturl=<%inf_pageUrl%>&amp;exttitle=<%hdl_headline%>');" title="Yigg"><img src="<%img_yigg%>" title="Yigg" alt="Yigg" class="sociable-hovers"></a></li>
</ul>
</div>

<h5>Related posts:</h5><ol><!IoRangeDynLink><li><a href="<%anc_related%>r" rel="bookmark" title="Permanent Link: <%hdl_headline%>"><%hdl_headline%></a></li><!/IoRangeDynLink></ol>
<h2 class="post_comm2">About the author:</h2>
<div id="authorinfo">
    <!IoRangeConditional><img src="<%img_author%>" alt="<%inf_originalAuthorFullName%>" title="<%inf_originalAuthorFullName%>"><!/IoRangeConditional>
    <%txt_aboutAuthor%>
</div>

                <div class="post_meta">
                    <img src="<%img_tags%>" class="posttag" alt="Print This Post" title="Print This Post" style="border: 0px none ;">Tags: <!IoRangeDynLink><a href="<%anc_tag%>" rel="tag"><%hdl_headline%></a>, <!/IoRangeDynLink></div>

                <div id="comments">   <!-- start comments -->

                    <div id="commenthead">

                        <h2 class="post_comm">Discussion</h2>

                            <h3 class="mast5">? comments for “<%hdl_headline%>”</h3>    

                    </div>

<!-- You can start editing here. -->

    <ol id="commentlist">
        <%con_comments%>
    </ol>

<div id="comment-form">
<h2 id="respond" class="post_comm2">Post a comment</h2>

<form action="<%anc_comments%>" method="post" id="commentform">

<fieldset>
    <p>
        <label for="author" class="com">Name *</label>
        <input class="comtext" name="author" id="author" value="" size="22" tabindex="1" type="text">
    </p>
    <p>
        <label for="email" class="com">E-mail *</label>
        <input class="comtext" name="email" id="email" value="" size="22" tabindex="2" type="text">
    </p>
    <p>
        <label for="url" class="com">Web site</label>
        <input class="comtext" name="url" id="url" value="" size="22" tabindex="3" type="text">
    </p>

<!--<p><small><strong>XHTML:</strong> You can use these tags: &lt;a href=&quot;&quot; title=&quot;&quot;&gt; &lt;abbr title=&quot;&quot;&gt; &lt;acronym title=&quot;&quot;&gt; &lt;b&gt; &lt;blockquote cite=&quot;&quot;&gt; &lt;cite&gt; &lt;code&gt; &lt;del datetime=&quot;&quot;&gt; &lt;em&gt; &lt;i&gt; &lt;q cite=&quot;&quot;&gt; &lt;strike&gt; &lt;strong&gt; </small></p>-->
    <p>
        <label for="comment" class="com">Comment</label>
        <textarea class="comtext" name="comment" id="comment" cols="100" rows="10" tabindex="4"></textarea>
    </p>

</fieldset>
<fieldset>
    <p>
        <input name="submit" id="submit" tabindex="5" class="comsubmit" value="Submit Comment" type="submit">
        <input name="comment_post_ID" value="74" type="hidden">
    </p>
<noscript><p><strong>Currently you have JavaScript disabled. In order
to post comments, please make sure JavaScript and Cookies are enabled,
and reload the page.</strong> <a
href="http://www.google.com/support/bin/answer.py?answer=23852"
rel="nofollow external" >Click here for instructions</a> on how to
enable JavaScript in your browser.</p></noscript>
</fieldset>
</form>
</div>

                </div>   <!-- end comments -->

            </div>

                            <div class="column span-3 last">

                    <div id="side_categories">

                        <h3 class="mast">Categories</h3>

                        <ul class="cat">
                                <%con_categories%>
                        </ul>
                    </div>

                    <div id="side_recent_comments">

                        <h3 class="mast">Recent Comments</h3>

                        <ul class="reccom">
                            <!IoRangeList><li><%inf_originalAuthorFullName%> on <a href="<%lst_recentComments%>" title="View all comments for <%hdl_headline%>"><%hdl_headline%></a></li><!/IoRangeList>
                        </ul>

                    </div>

                </div>

        </div>   <!-- start home_content -->

        <div id="footer" class="column span-14">

            <div class="column span-7 first">
                © 2009 Unofficial RedDot CMS blog. <a href="<%anc_subscribe%>"><img src="<%img_subscribe%>" alt="Entries (RSS)" style="margin: 2px 0pt 0pt 7px; vertical-align: top;"></a>
            </div>

            <div class="column span-7 last">
                <div class="push-0">
                    <a href="http://wordpress.org/" title="Powered by WordPress"><img src="<%img_wordPress%>" alt="Powered by WordPress"></a>
                    <a href="http://code.google.com/p/the-morning-after/" title="Design: The Masterplan"><img src="<%img_masterplan%>" alt="Theme by The Masterplan"></a>
                </div>
            </div>

        </div>

    </div>   <!--end container-->

    <!-- WordPress theme by Arun Kale / www.themasterplan.in | Download it at http://code.google.com/p/the-morning-after/ -->

    <!-- Google Analytics for WordPress | http://yoast.com/wordpress/google-analytics/ -->
    <script type="text/javascript">
        var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
        document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
    </script><script src="<%anc_js_googleAnalytics%>" type="text/javascript"></script>
    <script type="text/javascript">
        var pageTracker = _gat._getTracker("UA-5132063-1");
    </script>
    <script type="text/javascript">

        pageTracker._trackPageview();
    </script>
    <!-- End of Google Analytics code -->
    <script type="text/javascript" src="<%anc_js_syntaxHighlighterCore%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterCSharp%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterPhp%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterJScript%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterVB%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterSQL%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterXML%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterCSS%>"></script>
<script type="text/javascript">
dp.SyntaxHighlighter.ClipboardSwf = '<%swf_clipboard%>';
dp.SyntaxHighlighter.HighlightAll('code');
</script>
                <!-- Piwik code inserted by Piwik Analytics Wordpress plugin by Jules Stuifbergen http://blog.jongbelegen/piwik -->
                <script language="javascript" src="<%anc_js_piwik%>" type="text/javascript"></script>
                <script type="text/javascript">
                <!--
                piwik_action_name = document.title;
                            piwik_idsite = 1;
                piwik_url = '<%anc_piwik%>';
                piwik_log(piwik_action_name, piwik_idsite, piwik_url);
                //-->
                </script><img src="<%img_piwik%>" alt="Piwik" style="border: 0pt none ;">
<object>
                <noscript><p>Web analytics <img src="<%anc_piwik%>?idsite=1" style="border:0" alt="piwik"/></p>
                </noscript></object>
                <!-- /Piwik -->

<!--end body-->
</body></html>

Which in SmartTree looks like this:

SmartTree

SmartTree

The main advantages of this approach are both the speed (the sales team can create an example of your web site in RedDot very quickly this way) and simplicity of the implementation (hence why it is so good for training). The disadvantages, however, are numerous:

  • It promotes the use of multiple base templates with similar HTML code, resulting in any changes having to be meticulously applied to multiple base templates.
  • Adding a new link  that is common for all pages (ie CSS or Javascript files) requires you to update all instances of the content class. While RedDot provides a plugin to do this, by default it is limited to 1000 instances per content class - and this can only (easily) be raised to a maximum of 2000 due to the limitations of Redot’s search results.
  • Localisation of interface elements (eg Search, Next, Previous etc) - text and graphics - is at best as problematic as adding new links. (You can put defaults in, but only for one language! Otherwise you have to update every instance in your other language variants)
  • It promotes the use of excessive content and structural elements. At best this slows down SmartTree and makes it harder to find the elements you are actually interested in. At worst, SmartTree only shows a certain number of items (or at least, it did prior to version 9) and you can’t access elements beyond that. I wouldn’t be surprised if publishing is giving the page builder a heart attack either.

Handy Hint
The ¨Reference Link in Clipboard for All Content Class Instances¨and ¨Reference Page in Clipboard for All Content Class Instances¨ plugins provided by RedDotOpenText are hardcoded to work for the first 1000 instances per content class only. You should modify this to 2000.

The Two Towers - Header and Footer

What I have tended to see “in the wild” (and how my first project went) was what I call “header and footer” base templates. Basically the process is the same as for “copy and paste” above, with the following exception - common pieces of HTML code are identified and extracted into their own template and replaced in the base templates with a container element. Common examples of HTML code extracted in this way includes the page header and footer - hence the name - but there may be others as well. For example, in this case I have also extracted the ¨social¨ icon bar. Templates then tend to look like this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head profile="http://gmpg.org/xfn/11">

<!IoRangePreExecute><%
hdl_headline = "<%hdl_headline%>"
inf_pageUrl = "<%inf_pageUrl%>"
stf_summary = "<%stf_summary%>"
%><!/IoRangePreExecute>

    <title><%hdl_headline%> | Unofficial RedDot CMS blog</title>
<!-- all in one seo pack 1.4.7.4 [245,327] -->
<meta name="description" content="<%stf_meta_description%>">
<meta name="keywords" content="<%stf_meta_keywords%>">
<!-- /all in one seo pack -->

        <%con_header%>

        <div id="post_content" class="column span-14">   <!-- start home_content -->

            <div class="column span-11 first">
                <h2 class="post_cat"><%stf_category%></h2>

                <h2 class="post_name" id="post-<%inf_pageId%>"><%hdl_headline%></h2>

                <div class="post_meta">
                    By <a href="<%anc_author%>" title="Posts by <%inf_originalAuthorFullName%>"><%inf_originalAuthorFullName%></a> <span class="dot">⋅</span> March 11, 2009<%inf_pageReleaseDate%> <span class="dot">⋅</span>   <a href="#comments">Post a comment</a>
                </div>

                <%txt_content%>

                <%con_sociable%>

<h5>Related posts:</h5><ol><!IoRangeDynLink><li><a href="<%anc_related%>r" rel="bookmark" title="Permanent Link: <%hdl_headline%>"><%hdl_headline%></a></li><!/IoRangeDynLink></ol>
<h2 class="post_comm2">About the author:</h2>
<div id="authorinfo">
    <!IoRangeConditional><img src="<%img_author%>" alt="<%inf_originalAuthorFullName%>" title="<%inf_originalAuthorFullName%>"><!/IoRangeConditional>
    <%txt_aboutAuthor%>
</div>

                <div class="post_meta">
                    <img src="<%img_tags%>" class="posttag" alt="Print This Post" title="Print This Post" style="border: 0px none ;">Tags: <!IoRangeDynLink><a href="<%anc_tag%>" rel="tag"><%hdl_headline%></a>, <!/IoRangeDynLink></div>

                <div id="comments">   <!-- start comments -->

                    <div id="commenthead">

                        <h2 class="post_comm">Discussion</h2>

                            <h3 class="mast5">? comments for “<%hdl_headline%>”</h3>    

                    </div>

<!-- You can start editing here. -->

    <ol id="commentlist">
        <%con_comments%>
    </ol>

<%con_footer%>

Which in SmartTree look like this:

SmartTree

SmartTree

By giving up a bit of the speed and simplicity of implementation, we gain the following benefits:

  • Changes to the HTML code within the extracted templates only needs to be updated in one place.
  • Adding a new link or image that is common for all pages to the extracted templates requires only its single instance to be updated. Same for localisation. (Though adding a new link or image that is not common to all pages is trickier)
  • Reduced content and structural elements per base template - you effectively trade the elements in the extracted templates for new container elements in the base template.

If the implementation is particularly advanced, you may also see pre-executing code being used to help reduce duplication and/or pass values (like page GUIDs or ids) from the base template to the extracted templates. In this example we transfer the headline, page URL and summary to the sociable container for use in constructing the links. The ¨sociable¨ component template is shown below to show how these values are ¨transferred¨:

<div class="sociable">
<div class="sociable_tagline">
<h5>Share and Enjoy:</h5>
</div>
<ul>
<!IoRangePreExecute>
    <li><a rel="nofollow" href="javascript:window.print();" title="Print this article!"><img src="<%img_printer%>" onclick="" title="Print this article!" alt="Print this article!" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="mailto:?subject=<%= hdl_headline %>&amp;body=<%= inf_pageUrl %>" title="E-mail this story to a friend!"><img src="<%img_emailLink%>" onclick="" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://digg.com/submit?phase=2&amp;url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://digg.com/submit?phase=2&amp;url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>');" title="Digg"><img src="<%img_digg%>" title="Digg" alt="Digg" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://reddit.com/submit?url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://reddit.com/submit?url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>');" title="Reddit"><img src="<%img_reddit%>" title="Reddit" alt="Reddit" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.stumbleupon.com/submit?url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.stumbleupon.com/submit?url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>');" title="StumbleUpon"><img src="<%img_stumbleupon%>" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>');" title="Google"><img src="<%img_googleBookmark%>" title="Google" alt="Google" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://del.icio.us/post?url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://del.icio.us/post?url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>');" title="del.icio.us"><img src="<%img_delicious%>" title="del.icio.us" alt="del.icio.us" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.mister-wong.com/addurl/?bm_url=<%= inf_pageUrl %>&amp;bm_description=<%= hdl_headline %>&amp;plugin=soc" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.mister-wong.com/addurl/?bm_url=<%= inf_pageUrl %>&amp;bm_description=<%= hdl_headline %>&amp;plugin=soc');" title="MisterWong"><img src="<%img_misterWong%>" title="MisterWong" alt="MisterWong" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.facebook.com/share.php?u=<%= inf_pageUrl %>&amp;t=<%= hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.facebook.com/share.php?u=<%= inf_pageUrl %>&amp;t=<%= hdl_headline %>');" title="Facebook"><img src="<%img_facebook%>" title="Facebook" alt="Facebook" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.mixx.com/submit?page_url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.mixx.com/submit?page_url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>');" title="Mixx"><img src="<%img_mixx%>" title="Mixx" alt="Mixx" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.furl.net/storeIt.jsp?u=<%= inf_pageUrl %>&amp;t=<%= hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.furl.net/storeIt.jsp?u=<%= inf_pageUrl %>&amp;t=<%= hdl_headline %>');" title="Furl"><img src="<%img_furl%>" title="Furl" alt="Furl" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>&amp;source=Unofficial+RedDot+CMS+blog+RedDot+hints+from+developers%2C+freelancers+and+fellow+customers&amp;summary=<%= stf_summary %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.linkedin.com/shareArticle?mini=true&amp;url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>&amp;source=Unofficial+RedDot+CMS+blog+RedDot+hints+from+developers%2C+freelancers+and+fellow+customers&amp;summary=<%= stf_summary %>');" title="LinkedIn"><img src="<%img_linkedIn%>" title="LinkedIn" alt="LinkedIn" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/https://favorites.live.com/quickadd.aspx?marklet=1&amp;url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>');" title="Live"><img src="<%img_live%>" title="Live" alt="Live" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://ma.gnolia.com/bookmarklet/add?url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://ma.gnolia.com/bookmarklet/add?url=<%= inf_pageUrl %>&amp;title=<%= hdl_headline %>');" title="Ma.gnolia"><img src="<%img_magnolia%>" title="Ma.gnolia" alt="Ma.gnolia" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://twitter.com/home?status=<%= inf_pageUrl %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://twitter.com/home?status=<%= inf_pageUrl %>');" title="TwitThis"><img src="<%img_twitter%>" title="TwitThis" alt="TwitThis" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://technorati.com/faves?add=<%= inf_pageUrl %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/faves?add=<%= inf_pageUrl %>');" title="Technorati"><img src="<%img_technorati%>" title="Technorati" alt="Technorati" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.newsvine.com/_tools/seed&amp;save?u=<%= inf_pageUrl %>&amp;h=<%= hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.newsvine.com/_tools/seed&amp;save?u=<%= inf_pageUrl %>&amp;h=<%= hdl_headline %>');" title="NewsVine"><img src="<%img_newsVine%>" title="NewsVine" alt="NewsVine" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.tumblr.com/share?v=3&amp;u=<%= inf_pageUrl %>&amp;t=<%= hdl_headline %>&amp;s=" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.tumblr.com/share?v=3&amp;u=<%= inf_pageUrl %>&amp;t=<%= hdl_headline %>&amp;s=');" title="Tumblr"><img src="<%img_tumblr%>" title="Tumblr" alt="Tumblr" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://buzz.yahoo.com/submit/?submitUrl=<%= inf_pageUrl %>&amp;submitHeadline=<%= hdl_headline %>&amp;submitSummary=<%= stf_summary %>&amp;submitCategory=science&amp;submitAssetType=text" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://buzz.yahoo.com/submit/?submitUrl=<%= inf_pageUrl %>&amp;submitHeadline=<%= hdl_headline %>&amp;submitSummary=<%= stf_summary %>&amp;submitCategory=science&amp;submitAssetType=text');" title="Yahoo! Buzz"><img src="<%img_yahooBuzz%>" title="Yahoo! Buzz" alt="Yahoo! Buzz" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://yigg.de/neu?exturl=<%= inf_pageUrl %>&amp;exttitle=<%= hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://yigg.de/neu?exturl=<%= inf_pageUrl %>&amp;exttitle=<%= hdl_headline %>');" title="Yigg"><img src="<%img_yigg%>" title="Yigg" alt="Yigg" class="sociable-hovers"></a></li>
<!/IoRangePreExecute>
</ul>
</div>

Handy Hint
Even though pages placed inside containers look separate, they are compiled into a single page. This is important for pre-executing script, as code inside a container can make use of (for better or worse!) code in the parent page above the container.

Handy Hint
To get pre-executing script to work, you need to set two options:

  • Check ¨Allow active templates¨ and enter ¨Eligible suffixes¨ (eg asp) in General Settings (under Administer Project Settings in SmartTree)
  • Edit the Project Variant (under Administer Project Settings in SmartTree) and select the eligible suffix in ¨Select scripting for active templates¨.

But, while we reduce the negatives from the “copy and paste” method, we don’t eliminate them - there is still HTML code duplication (usually surrounding placeholders that change between pages - in our example - the doctype, html and head tags, the img_tags and corresponding text), there are still multiple anchors and containers in each base template that don’t change and are taking up space, and if we want to add a new common component - well we are back to our original disadvantages…

The Return of the King - Include Container

What is the solution? Taking the process that led us from “copy and paste” to “header and footer” to its logical conclusion - “one include container” to contain all common code. How do we do that? One step at a time. If you are starting out on a new project, this should save you a lot of pain in the future. But where it shines is how easily it can be added to an existing project - without interfering with the existing structure and therefore allowing you to refactor the above pain spots on your terms, as and when you need or want to.

Step 1: Add your “include container” to each base template.
Create a container placeholder at the very end of each template, after the closing HTML tag. I call mine “con_include” as I liken it to the concept of using include files. I’ve previously used “con_library” and “con_prexecute” because it will all be pre-executed. The name is unimportant - choose something that has meaning to you. Surround the container with RedDot Pre-executing script block tags. A container with nothing in it won’t render as anything - so far, perfectly safe.

Handy Hint
We place our ¨con_include¨ placeholder at the end of the template because we plan to move the DOCTYPE declaration into this common code and we don´t want to risk spaces or new lines appearing before it in the final output (as it may then not be recognised). We can use ASP functions, subroutines and classes that are defined later in the file.

Step 2: Create content classes to be included, and create and connect instances to the ¨con_include¨ placeholder.
You could do this with one single content class, but I find it easier break them up into logical groupings - again, think include files.

A ¨Utility¨ content class to hold general functions used across the site:

<%
Public Function IIf(bCond, vTrue, vFalse)
    If bCond Then
        IIf = vTrue
    Else
        IIf = vFalse
    End If
End Function

Public Function IsString(v)
    IsString = IIf(VarType(v) = vbString, True, False)
End Function
%>
<script language="jscript" runat="server">
function GetVar(sId) {
    var re = /\/\*(.*)\*\//;
    return re.exec(eval(sId + ".toString()"))[1];
}

function GetTime() {
    var d = new Date();
    return d.getTime()
}
</script>

A ¨Page¨ content class defining a Page class to hold the contents of placeholders that are to be used in the shared output but differ from page to page:

<%
Class cPage
    Private m_hdl_headline
    Private m_inf_pageUrl
    Private m_stf_summary
    Private m_stf_meta_description
    Private m_stf_meta_keywords

    Public Property Get hdl_headline
        hdl_headline = m_hdl_headline
    End Property

    Public Property Let hdl_headline(str)
        m_hdl_headline = str
    End Property

    Public Property Get inf_pageUrl
        inf_pageUrl = m_inf_pageUrl
    End Property

    Public Property Let inf_pageUrl(str)
        m_inf_pageUrl = str
    End Property

    Public Property Get stf_summary
        stf_summary = m_stf_summary
    End Property

    Public Property Let stf_summary(str)
        m_stf_summary = str
    End Property

    Public Property Get stf_meta_description
        stf_meta_description = m_stf_meta_description
    End Property

    Public Property Let stf_meta_description(str)
        m_stf_meta_description = str
    End Property

    Public Property Get stf_meta_keywords
        stf_meta_keywords = m_stf_meta_keywords
    End Property

    Public Property Let stf_meta_keywords(str)
        m_stf_meta_keywords = str
    End Property
End Class
%>

Handy Hint
I use ASP classes as a way to package variables, functions and subroutines to avoid polluting the global namespace and the associated issues this may lead to.

A ¨HTML¨ content class defining an HTML class to hold subroutines that will output the shared HTML:

<%
Class cHTML
    Public Sub header(oPage)
%><!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head profile="http://gmpg.org/xfn/11">
    <title><%= oPage.hdl_headline %> | Unofficial RedDot CMS blog</title>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta http-equiv="content-style-type" content="text/css">
    <meta http-equiv="imagetoolbar" content="no">
    <meta name="robots" content="index, nofollow, noodp">
    <meta http-equiv="expires" content="43200">
    <meta name="audience" content="all">
    <meta name="language" content="en">
    <meta http-equiv="content-language" content="en">

    <!-- all in one seo pack 1.4.7.4 [245,327] -->
    <meta name="description" content="<%= oPage.stf_meta_description %>">
    <meta name="keywords" content="<%= oPage.stf_meta_keywords %>">
    <!-- /all in one seo pack -->

    <link rel="stylesheet" href="<%anc_css_style2%>" type="text/css" media="screen, projection">
    <!--[if lt IE 7]>
        <link rel="stylesheet" href="<%anc_css_ie%>" type="text/css" media="screen, projection">
    <![endif]-->

    <link rel="alternate" type="application/rss+xml" title="Unofficial RedDot CMS blog RSS Feed" href="<%anc_xml_rss%>">
    <link rel="alternate" type="application/atom+xml" title="Unofficial RedDot CMS blog Atom Feed" href="<%anc_xml_atom%>">
    <link rel="pingback" href="<%anc_pingback%>">
    <link rel="shortcut icon" href="<%img_favicon%>">
    <link rel="EditURI" type="application/rsd+xml" title="RSD" href="<%anc_xml_rsd%>">
    <link rel="wlwmanifest" type="application/wlwmanifest+xml" href="<%anc_xml_wlwmanifest%>">
    <!-- Added By Democracy Plugin. Version 2.0.1 -->
    <script type="text/javascript" src="<%anc_js_democracy%>"></script>
    <link rel="stylesheet" href="<%anc_css_basic%>" type="text/css">
    <link rel="stylesheet" href="<%anc_css_style1%>" type="text/css">
    <link href="<%anc_css_syntax_highlighter%>" type="text/css" rel="stylesheet">
    <link rel="stylesheet" type="text/css" media="screen" href="<%anc_css_sociable%>">
    <!-- Protected by WP-SpamFree v2.0.0.1 :: JS BEGIN -->
    <script type="text/javascript" src="<%anc_js_wp_spamfree%>"></script>
    <!-- Protected by WP-SpamFree v2.0.0.1 :: JS END -->
</head>
<bo<% ' %>dy>   <!--start body-->
    <div class="container">   <!--start container-->

        <div id="header" class="column span-14">

            <div id="logo" class="column first">

                <div class="title">
                    <div><a href="<%anc_home%>">Unofficial RedDot CMS blog</a></div>
                    <div class="desc">RedDot hints from developers, freelancers and fellow customers</div>
                </div>

            <!--<a href="<%anc_home%>" title="RedDot hints from developers, freelancers and fellow customers: Home" class="sitelogo"></a>-->

            </div>

            <div id="search_menu" class="column span-6 border_left last push-0">

                <div id="search" class="column first">
                    <h3 class="mast4">Search</h3>

                    <div id="search-form">
                        <form method="get" id="searchform" action="<%anc_search%>">

                        <div><label for="s" class="none">Search for:</label>
                        <input name="s" id="s" class="search_input" value="" type="text">

                        <label for="searchsubmit" class="none">Go</label>
                        <input id="searchsubmit" class="submit_input" value="Search" type="submit"></div>

                        </form>
                    </div>
                </div>
                <ul id="menu">
                    <li><span class="home"><a href="<%anc_home%>">Home</a></span></li>
<!--                    <li><span class="about"><a href="<%anc_about%>">About</a></span></li> -->
                    <li><span class="archives"><a href="<%anc_archives%>">Archives</a></span></li>
                    <li><span class="subscribe"><a href="<%anc_subscribe%>">Subscribe</a></span></li>
<!--                    <li><span class="contact"><a href="<%anc_contact%>">Contact</a></span></li> -->
                </ul>
            </div>

        </div>   <!--end header-->

        <div id="topbanner_single" class="column span-14">   <!-- start top banner -->
            <div class="pagetitle">
                // you’re reading...
            </div>
        </div>   <!-- end top banner -->
<%
    End Sub

    Public Sub footer
%>
<div id="comment-form">
<h2 id="respond" class="post_comm2">Post a comment</h2>
<form action="<%anc_comments%>" method="post" id="commentform">
<fieldset>
    <p>
        <label for="author" class="com">Name *</label>
        <input class="comtext" name="author" id="author" value="" size="22" tabindex="1" type="text">
    </p>
    <p>
        <label for="email" class="com">E-mail *</label>
        <input class="comtext" name="email" id="email" value="" size="22" tabindex="2" type="text">
    </p>
    <p>
        <label for="url" class="com">Web site</label>
        <input class="comtext" name="url" id="url" value="" size="22" tabindex="3" type="text">
    </p>
<!--<p><small><strong>XHTML:</strong> You can use these tags: &lt;a href=&quot;&quot; title=&quot;&quot;&gt; &lt;abbr title=&quot;&quot;&gt; &lt;acronym title=&quot;&quot;&gt; &lt;b&gt; &lt;blockquote cite=&quot;&quot;&gt; &lt;cite&gt; &lt;code&gt; &lt;del datetime=&quot;&quot;&gt; &lt;em&gt; &lt;i&gt; &lt;q cite=&quot;&quot;&gt; &lt;strike&gt; &lt;strong&gt; </small></p>-->
    <p>
        <label for="comment" class="com">Comment</label>
        <textarea class="comtext" name="comment" id="comment" cols="100" rows="10" tabindex="4"></textarea>
    </p>

</fieldset>
<fieldset>
    <p>
        <input name="submit" id="submit" tabindex="5" class="comsubmit" value="Submit Comment" type="submit">
        <input name="comment_post_ID" value="74" type="hidden">
    </p>
<noscript><p><strong>Currently you have JavaScript disabled. In order
to post comments, please make sure JavaScript and Cookies are enabled,
and reload the page.</strong> <a
href="http://www.google.com/support/bin/answer.py?answer=23852"
rel="nofollow external" >Click here for instructions</a> on how to
enable JavaScript in your browser.</p></noscript>
</fieldset>
</form>
</div>

                </div>   <!-- end comments -->

            </div>

                            <div class="column span-3 last">

                    <div id="side_categories">

                        <h3 class="mast">Categories</h3>

                        <ul class="cat">
                                <%con_categories%>
                        </ul>
                    </div>

                    <div id="side_recent_comments">

                        <h3 class="mast">Recent Comments</h3>

                        <ul class="reccom">
                            <!IoRangeList><li><%inf_originalAuthorFullName%> on <a href="<%lst_recentComments%>" title="View all comments for <%hdl_headline%>"><%hdl_headline%></a></li><!/IoRangeList>
                        </ul>

                    </div>

                </div>

        </div>   <!-- start home_content -->

        <div id="footer" class="column span-14">

            <div class="column span-7 first">
                © 2009 Unofficial RedDot CMS blog. <a href="<%anc_subscribe%>"><img src="<%img_subscribe%>" alt="Entries (RSS)" style="margin: 2px 0pt 0pt 7px; vertical-align: top;"></a>
            </div>

            <div class="column span-7 last">
                <div class="push-0">
                    <a href="http://wordpress.org/" title="Powered by WordPress"><img src="<%img_wordPress%>" alt="Powered by WordPress"></a>
                    <a href="http://code.google.com/p/the-morning-after/" title="Design: The Masterplan"><img src="<%img_masterplan%>" alt="Theme by The Masterplan"></a>
                </div>
            </div>

        </div>

    </div>   <!--end container-->

    <!-- WordPress theme by Arun Kale / www.themasterplan.in | Download it at http://code.google.com/p/the-morning-after/ -->

    <!-- Google Analytics for WordPress | http://yoast.com/wordpress/google-analytics/ -->
    <script type="text/javascript">
        var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
        document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
    </script><script src="<%anc_js_googleAnalytics%>" type="text/javascript"></script>
    <script type="text/javascript">
        var pageTracker = _gat._getTracker("UA-5132063-1");
    </script>
    <script type="text/javascript">

        pageTracker._trackPageview();
    </script>
    <!-- End of Google Analytics code -->
    <script type="text/javascript" src="<%anc_js_syntaxHighlighterCore%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterCSharp%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterPhp%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterJScript%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterVB%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterSQL%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterXML%>"></script>
<script type="text/javascript" src="<%anc_js_syntaxHighlighterCSS%>"></script>
<script type="text/javascript">
dp.SyntaxHighlighter.ClipboardSwf = '<%swf_clipboard%>';
dp.SyntaxHighlighter.HighlightAll('code');
</script>
                <!-- Piwik code inserted by Piwik Analytics Wordpress plugin by Jules Stuifbergen http://blog.jongbelegen/piwik -->
                <script language="javascript" src="<%anc_js_piwik%>" type="text/javascript"></script>
                <script type="text/javascript">
                <!--
                piwik_action_name = document.title;
                            piwik_idsite = 1;
                piwik_url = '<%anc_piwik%>';
                piwik_log(piwik_action_name, piwik_idsite, piwik_url);
                //-->
                </script><img src="<%img_piwik%>" alt="Piwik" style="border: 0pt none ;">
<object>
                <noscript><p>Web analytics <img src="<%anc_piwik%>?idsite=1" style="border:0" alt="piwik"/></p>
                </noscript></object>
                <!-- /Piwik -->

<!--end body-->
</bo<% ' %>dy></html>
<%
    End Sub

    Public Sub tags
%><img src="<%img_tags%>" class="posttag" alt="Print This Post" title="Print This Post" style="border: 0px none ;">Tags: <%
    End Sub

    Public Sub sociable(oPage)
%>
<div class="sociable">
<div class="sociable_tagline">
<h5>Share and Enjoy:</h5>
</div>
<ul>
    <li><a rel="nofollow" href="javascript:window.print();" title="Print this article!"><img src="<%img_printer%>" onclick="" title="Print this article!" alt="Print this article!" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="mailto:?subject=<%= oPage.hdl_headline %>&amp;body=<%= oPage.inf_pageUrl %>" title="E-mail this story to a friend!"><img src="<%img_emailLink%>" onclick="" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://digg.com/submit?phase=2&amp;url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://digg.com/submit?phase=2&amp;url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>');" title="Digg"><img src="<%img_digg%>" title="Digg" alt="Digg" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://reddit.com/submit?url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://reddit.com/submit?url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>');" title="Reddit"><img src="<%img_reddit%>" title="Reddit" alt="Reddit" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.stumbleupon.com/submit?url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.stumbleupon.com/submit?url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>');" title="StumbleUpon"><img src="<%img_stumbleupon%>" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>');" title="Google"><img src="<%img_googleBookmark%>" title="Google" alt="Google" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://del.icio.us/post?url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://del.icio.us/post?url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>');" title="del.icio.us"><img src="<%img_delicious%>" title="del.icio.us" alt="del.icio.us" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.mister-wong.com/addurl/?bm_url=<%= oPage.inf_pageUrl %>&amp;bm_description=<%= oPage.hdl_headline %>&amp;plugin=soc" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.mister-wong.com/addurl/?bm_url=<%= oPage.inf_pageUrl %>&amp;bm_description=<%= oPage.hdl_headline %>&amp;plugin=soc');" title="MisterWong"><img src="<%img_misterWong%>" title="MisterWong" alt="MisterWong" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.facebook.com/share.php?u=<%= oPage.inf_pageUrl %>&amp;t=<%= oPage.hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.facebook.com/share.php?u=<%= oPage.inf_pageUrl %>&amp;t=<%= oPage.hdl_headline %>');" title="Facebook"><img src="<%img_facebook%>" title="Facebook" alt="Facebook" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.mixx.com/submit?page_url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.mixx.com/submit?page_url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>');" title="Mixx"><img src="<%img_mixx%>" title="Mixx" alt="Mixx" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.furl.net/storeIt.jsp?u=<%= oPage.inf_pageUrl %>&amp;t=<%= oPage.hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.furl.net/storeIt.jsp?u=<%= oPage.inf_pageUrl %>&amp;t=<%= oPage.hdl_headline %>');" title="Furl"><img src="<%img_furl%>" title="Furl" alt="Furl" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>&amp;source=Unofficial+RedDot+CMS+blog+RedDot+hints+from+developers%2C+freelancers+and+fellow+customers&amp;summary=<%= oPage.stf_summary %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.linkedin.com/shareArticle?mini=true&amp;url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>&amp;source=Unofficial+RedDot+CMS+blog+RedDot+hints+from+developers%2C+freelancers+and+fellow+customers&amp;summary=<%= oPage.stf_summary %>');" title="LinkedIn"><img src="<%img_linkedIn%>" title="LinkedIn" alt="LinkedIn" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/https://favorites.live.com/quickadd.aspx?marklet=1&amp;url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>');" title="Live"><img src="<%img_live%>" title="Live" alt="Live" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://ma.gnolia.com/bookmarklet/add?url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://ma.gnolia.com/bookmarklet/add?url=<%= oPage.inf_pageUrl %>&amp;title=<%= oPage.hdl_headline %>');" title="Ma.gnolia"><img src="<%img_magnolia%>" title="Ma.gnolia" alt="Ma.gnolia" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://twitter.com/home?status=<%= oPage.inf_pageUrl %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://twitter.com/home?status=<%= oPage.inf_pageUrl %>');" title="TwitThis"><img src="<%img_twitter%>" title="TwitThis" alt="TwitThis" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://technorati.com/faves?add=<%= oPage.inf_pageUrl %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/faves?add=<%= oPage.inf_pageUrl %>');" title="Technorati"><img src="<%img_technorati%>" title="Technorati" alt="Technorati" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.newsvine.com/_tools/seed&amp;save?u=<%= oPage.inf_pageUrl %>&amp;h=<%= oPage.hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.newsvine.com/_tools/seed&amp;save?u=<%= oPage.inf_pageUrl %>&amp;h=<%= oPage.hdl_headline %>');" title="NewsVine"><img src="<%img_newsVine%>" title="NewsVine" alt="NewsVine" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://www.tumblr.com/share?v=3&amp;u=<%= oPage.inf_pageUrl %>&amp;t=<%= oPage.hdl_headline %>&amp;s=" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.tumblr.com/share?v=3&amp;u=<%= oPage.inf_pageUrl %>&amp;t=<%= oPage.hdl_headline %>&amp;s=');" title="Tumblr"><img src="<%img_tumblr%>" title="Tumblr" alt="Tumblr" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://buzz.yahoo.com/submit/?submitUrl=<%= oPage.inf_pageUrl %>&amp;submitHeadline=<%= oPage.hdl_headline %>&amp;submitSummary=<%= oPage.stf_summary %>&amp;submitCategory=science&amp;submitAssetType=text" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://buzz.yahoo.com/submit/?submitUrl=<%= oPage.inf_pageUrl %>&amp;submitHeadline=<%= oPage.hdl_headline %>&amp;submitSummary=<%= oPage.stf_summary %>&amp;submitCategory=science&amp;submitAssetType=text');" title="Yahoo! Buzz"><img src="<%img_yahooBuzz%>" title="Yahoo! Buzz" alt="Yahoo! Buzz" class="sociable-hovers"></a></li>
    <li><a rel="nofollow" target="_blank" href="http://yigg.de/neu?exturl=<%= oPage.inf_pageUrl %>&amp;exttitle=<%= oPage.hdl_headline %>" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://yigg.de/neu?exturl=<%= oPage.inf_pageUrl %>&amp;exttitle=<%= oPage.hdl_headline %>');" title="Yigg"><img src="<%img_yigg%>" title="Yigg" alt="Yigg" class="sociable-hovers"></a></li>
</ul>
</div>
<%
    End Sub
End Class
%>

Handy Hint
RedDot treats the ¨body¨ HTML tag in a ¨special¨ way that will cause you no end of grief when used in a container page. Make sure you hide it (and its closing tag) from RedDot using the above technique (inserting an ASP comment in the middle - ie <bo<% ‘ %>dy> and </bo<% ‘ %>dy>) or another similiar technique.

A ¨RedDot¨ content class defining a RedDot class which acts a single point of initialisation and cleanup:

<%
Class cRedDot
    Private m_iStart ' start time in milliseconds

    Public Property Get iElapsedTime ' time elapsed from start in milliseconds
        iElapsedTime = GetTime() - m_iStart
    End Property

    Private Sub Class_Initialize
        m_iStart = GetTime()
        Set oHTML = New cHTML
        Set oPage = New cPage
    End Sub

    Private Sub Class_Terminate
        Set oPage = Nothing
        Set oHTML = Nothing
    End Sub
End Class

Dim oHTML, oPage
%>

Handy Hint
Keeping track of the elapsed time of the execution of our scripts for the entire page is good peace of mind when it comes to hunting down performance issues.

Step 3: Add your ¨con_include¨ container to the clipboard and ¨Reference Link for All Content Classes¨ for all base templates.
None of the above changes should have had any effect yet on your existing templates - we have simply added common code, but without actually executing any of it.

Step 4: Update our base template.
We can now update our base template to make use of our new functionality, and remove the duplicated HTML and those extra unnecessary placeholders:

<!IoRangePreExecute><%
Set oRedDot = New cRedDot ' performs all initialisation
oPage.hdl_headline = "<%hdl_headline%>"
oPage.inf_pageUrl = "<%inf_pageUrl%>"
oPage.stf_summary = "<%stf_summary%>"
oPage.stf_meta_description = "<%stf_meta_description%>"
oPage.stf_meta_keywords = "<%stf_meta_keywords%>"
oHTML.header oPage
%><!/IoRangePreExecute>

        <div id="post_content" class="column span-14">   <!-- start home_content -->

            <div class="column span-11 first">
                <h2 class="post_cat"><%stf_category%></h2>

                <h2 class="post_name" id="post-<%inf_pageId%>"><%hdl_headline%></h2>

                <div class="post_meta">
                    By <a href="<%anc_author%>" title="Posts by <%inf_originalAuthorFullName%>"><%inf_originalAuthorFullName%></a> <span class="dot">⋅</span> March 11, 2009<%inf_pageReleaseDate%> <span class="dot">⋅</span>   <a href="#comments">Post a comment</a>
                </div>

                <%txt_content%>

                <!IoRangePreExecute><% oHTML.sociable oPage %><!/IoRangePreExecute>

<h5>Related posts:</h5><ol><!IoRangeDynLink><li><a href="<%anc_related%>r" rel="bookmark" title="Permanent Link: <%hdl_headline%>"><%hdl_headline%></a></li><!/IoRangeDynLink></ol>
<h2 class="post_comm2">About the author:</h2>
<div id="authorinfo">
    <!IoRangeConditional><img src="<%img_author%>" alt="<%inf_originalAuthorFullName%>" title="<%inf_originalAuthorFullName%>"><!/IoRangeConditional>
    <%txt_aboutAuthor%>
</div>

                <div class="post_meta">
                    <!IoRangePreExecute><% oHTML.tags %><!/IoRangePreExecute><!IoRangeDynLink><a href="<%anc_tag%>" rel="tag"><%hdl_headline%></a>, <!/IoRangeDynLink></div>

                <div id="comments">   <!-- start comments -->

                    <div id="commenthead">

                        <h2 class="post_comm">Discussion</h2>

                            <h3 class="mast5">? comments for “<%hdl_headline%>”</h3>    

                    </div>

<!-- You can start editing here. -->

    <ol id="commentlist">
        <%con_comments%>
    </ol>

<!IoRangePreExecute><%
oHTML.footer
%><!-- <%= oRedDot.iElapsedTime %>ms --><%
Set oRedDot = Nothing ' performs all cleanup
%><%con_include%><!/IoRangePreExecute>

Our SmartTree now looks like this:

SmartTree

SmartTree

Epilogue

So, what do we have at the end of our journey?

  • A simplified SmartTree - we now only have one placeholder representing everything shared between base templates. The rest are specific to the page (as they should be).
  • A simplified template - we have eliminated most if not all of the HTML repetition from the template.
  • A single place to add shared content and functions - we should no longer need to use the ¨Reference Link/Page for All Content Classes¨ plugin, and therefore can breath a bit easier as our instances head over the 2000 mark.

Are we done? For this article, yes. But here are some things to think about for the future (feel free to add more!):

  • Reducing the number of anchor placeholders by using dynamic anchors or lists for CSS and Javascript.
  • Performance optimisations - specifically bringing the CSS and Javascript inline for SmartEdit and collapsing into single files for Publish.
  • Red dots! And for more fun - red dots in shared content!
  • Escaping of placeholders for use in shared content, especially text fields.
  • Handling of categories, tags, authors and social links.

Which methods of base page template construction have you seen and/or used? Do you have any hints or tips regarding base page template construction or even a completely different method that you want to share?

Catchya,
Adrian

Unhappy CMS

Thursday, December 11th, 2008
Unhappy CMS

Unhappy CMS

Sorry - I couldn’t resist… Seriously though, custom error pages are cool!

Escaping RedDot

Tuesday, December 9th, 2008

Note: This post also appears on the Unofficial RedDot CMS Blog - check it out for more RedDot related posts from RedDot developers across the globe and less of my personal stuff :)  More importantly - why not get even more out of it by suggesting a topic for post of the month?

In today’s episode, we will cover:

  • How to safely(ish) use the output of content elements in scripts within our RedDot templates.
  • How not to use the output of content elements in scripts within our RedDot templates.
  • Reinforce that Preview is not the same as Publish!

Nothing like a little frustration to spur a new blog post. It all began last week as I was adding some localisation to a RedDot 6.5 project. Everything was working beautifully in SmartEdit and Preview. Then I published and it all went so very wrong…

By wrong I mean there was an error in the pre-execute code. Ie on the published page, anything within pre-execute tags was blank, missing, gone. But preview worked! And preview and publish are the same, right?

Using a slow process of elimination (anyone know where the publish pre-execute temporary files are kept?) I eventually discovered the issue. Sadly, it was one that had bitten me before - and hence will be immortalised here so that you and I should not fall prey to it again. But first, some background…

Every now and then (okay, all of the time) I find the need to take the content of a placeholder and either use it elsewhere (outside of the template it is defined in) or manipulate it in some way. Part of (okay, all of) the charm of RedDot’s templating system is that you have a whole scripting engine at your disposal - ASP (VBScript and JScript) or you can setup PHP (or even ASPX I believe…) Assigning a placeholder to a variable is a piece of cake:

VBScript:

<!IoRangePreExecute>
<%
myVar = "<%myPlaceholder%>"
%>
<!/IoRangePreExecute>

PHP:

<!IoRangePreExecute>
<?php
$myVar = '<%myPlaceholder%>';
?>
<!/IoRangePreExecute>

Or is it? What happens when the content of myPlaceholder contains double quotation marks? Or worse, if you are using PHP, a dollar sign or an apostrophe? (depending on which form of assignment you are using) Unfortunately, RedDot doesn’t allow you to specify the escaping of placeholders, so here are a few tricks all RedDot developers should know:

VBScript: For this we rely on the fact we get JScript for free…

<!IoRangePreExecute>
<script language="jscript" runat="server">
function myPlaceholder() { /*<%myPlaceholder%>*/ }

function getVar(id) {
   var re = /\/\*(.*)\*\//;
   return re.exec(eval(id + ".toString()"))[1];
}
</script>
<%
myVar = getVar("myPlaceholder")
%>
<!/IoRangePreExecute>

Or, much more simply in PHP:

<!IoRangePreExecute>
<?php
$myVar = <<<EOD
<%myPlaceholder%>
EOD;
?>
<!/IoRangePreExecute>

If you don’t need to manipulate the value, ie you want to output it later or based on some criteria or even output a chunk of HTML and/or placeholders, you can surround it with a function or subroutine:

VBScript (won’t be broken by */ or anything else in the content):

<!IoRangePreExecute>
<%
Sub header()
%>
<div id="header"><h1><%myPlaceholder%></h1></div>
<%
End Sub
header()
%>
<!/IoRangePreExecute>

PHP (won’t be broken by EOD; or anything else in the content - or whatever you used with the <<< operator):

<!IoRangePreExecute>
<?php
function header() {
?>
<div id="header"><h1><%myPlaceholder%></h1></div>
<?php
}
header();
?>
<!/IoRangePreExecute>

I find the above particularly good for reducing the number of container placeholders in my base pages (to one - but that is another post). You can also do some neat tricks with the red dots themselves - but again, another post.

Ok - now for the caveat. When doing variable assignment above, using the VBScript/JScript method, you can’t use any form of string manipulation on variables containing links to RedDot assets. Specifically, you can’t perform any of the following actions:

  • Regular expression matching (ie our JScript example)
  • Any VBScript string function - InStr, Mid, Replace, Split etc

On any variable that contains any of the following placeholders:

  • Anchors (whether to RedDot pages or external URLs)
  • Images
  • Media
  • Text - where the text may contain any of the above.

The most annoying thing is that it will work in Preview, lulling you into a false sense of security. That last one (Text placeholders) was one that had caught me out before - because the Publish suddenly stopped working for no apparent reason (it was fine with all the samples prior to that that did not contain links or images…)

This time around, it was anchor and image placeholders that I had used in the JScript functions - once I removed these (I replaced them with the subroutine method - as I didn’t actually need to manipulate them) everything was fine again.

If you must manipulate dodgy placeholders, you have a couple of options:

  • Switch to PHP - the issue only seems to affect ASP (VBScript/JScript). I can’t speak for ASPX.
  • Perform your manipulations on the web server (save as .asp or any other scripting language you like - once it is on the web server, it is free of RedDot issues - well unless you are using LiveServer of course!)

Here endeth the lesson.

Navigation Manager and Index Pages

Thursday, September 18th, 2008

When considering converting or creating a RedDot CMS project to use Navigation Manager, one of the tradeoffs you will be forced to consider - if publication structure means anything to you - is how to create index pages.

Navigation Manager uses list elements to build your site structure - ie each page in the site structure contains a list element that contains the child pages. Publication packages are attached to list elements - which means all of the child pages are published into the same folder. The challenge? How do you get the parent page (which is most likely being published to a location dictated by the list element of its parent) to publish as the index page (ie index.html or equivalent) in the same folder as its child pages?

Previously, all of the solutions I had seen to this conundrum were hideously complex - to the extent that it was just easier to live without it. But a couple of weeks ago, Paul pointed me to an entry on the “Unofficial RedDot CMS Blog” - “Publishing page to subfolder” - which would seem to be both a simple *and* elegant solution. Basically, just modify the filename of the parent page to include the path!

Disclaimer: I currently do not have a Navigation Manager enabled project available to confirm this (Paul?) so both credit *and* responsibility remain with the original author, Michael :)