Sunday, March 27, 2011

Rants on Tridion implementations

Those of you who know me, and work/worked with me, know that my job is not always an easy or necessarily happy one. In a nutshell, I tend to tell customers that "if you see me walk into your project, it means you're in trouble".

So, if you're about to start implementing Tridion, and you don't want to see me walk into your project to fix it, here's a few things to remember:

Before you try to do XYZ with Tridion, try to do it without Tridion. Seriously, if you don't know what the expected output of a page is, how do you expect to write a template that "does" it?

If you think you know WCM and therefore learning Tridion is a non-issue, think again. Then re-think. And a year later re-evaluate what you know about WCM. If there is one thing I can tell about Tridion and the other WCM packages available, is that Tridion IS different - and customers buy the software for those EXACT reasons that make it different. If you're planning to implement Tridion just like you would [insert random WCM package here], then why don't you go implement [random WCM package] instead? Many times I've heard things like "We're not planning to use BluePrinting", "why can't I just create pages" and "feature XYZ should be out of the box" (this last one is my favourite, since everyone wants XYZ done differently, but out of the box anyway). The higher-up people that made the decision to buy Tridion were likely triggered to do it based on Blueprinting, Component-based content and the extensibility points offered - not because they thought the implementation team likes those concepts.

Stop being a language zealot. So what if you need to understand Java for deployer extensions? And so what if you need to use c# for Event Systems? It's not as if programmers care about that? You should care functionality and complete API, not what language. If language _really_ is an issue for you, then write your own mediator, there's even a sample for that in the documentation.

Make sure you understand that you will always need 2 types of people in your development team: Web designers and programmers. Web designers will not do a good job writing templates, and programmers are typically bad web designers. It is one of the best features of the product that both teams can work together by focusing on different template building blocks. So use it.

Think before you do anything. This should be a no-brainer, right? Some examples...
Everyone wants to implement SmartTarget, but it is OH-SO-RARE that people actually know what they want to do with it. Developers don't get it, they think they could have done everything themselves through code (missing the point that this is exactly what SmartTarget is about).
Audience Segmentation? You need to know the _current_ audience before you start segmenting it.

And I could go on ranting, but enough negativity for today. Here's how I tell people to learn Tridion.
  1. Get yourself a development environment to play with.
  2. Find your way into the Tridion Developer Forum (via Customer Support).
  3. Get yourself enrolled into a Technical Training. Really. It will open your eyes and save you a lot of time.
  4. Read the template implementation guide. I am not kidding, RTFM can do miracles for you.
  5. Now implement a simple, one-page site. Make sure all content is translatable via blueprinting, and editable via SiteEdit.
  6. Once that's working, implement the multiple language versions of that site.
I tend to tell people to start with something really simple (crawling before walking). Like the Google home page, for instance.

OK, enough ranting for the day, happy thoughts and enjoy implementing Tridion. It is an amazing piece of software, and once you get it, you will think differently about WCM systems.

Sunday, February 13, 2011

Tutorials and Copyright...

I'm having a bit of a conundrum here. I wrote a few quite extensive Tutorials on Tridion 2011 which I want to make public via Tridion World but I can't understand if I'm infringing copyright or not.

Let me explain: In these tutorials there are very detailed, step-by-step instructions with loads of screenshots. My goal here is to make sure I don't ever again get basic questions like "what do I need to install for Tridion to use an Oracle database back end?" or "What are the Windows 2008 R2 Roles I must install?".

Of course, having Tridion screenshots is NOT copyright infringement, because I work for the copyright owner and I would be distributing it via the copyright's owner website. I am allowed to create those screenshots and empowered to distribute them via Tridion World (but I am not allowed to distribute it via my own website, even though many other people do that and we don't seem to care much about it).

The way I see it, I can't really distribute the Oracle Client installation screenshots, or Windows 2008 install, or the SQL Server 2008 R2 installation screenshots.
And if I remove those screenshots, the tutorials are not as detailed as I need them to be.

Anyone out there with suggestions? Should I contact the 3rd parties (Oracle and Microsoft mostly) and ask for their approvals?

I'll figure it out...

Update: found some info on Screenshot copyright in general and Microsoft guidelines for screenshots, and it looks like I'm in the clear, since I do not modify any of the screenshot content, do clearly identify it as being from an Oracle or Microsoft product and don't do anything evil with it.

So, new tutorials to show up soon in Tridion World

Saturday, November 13, 2010

Tridion Content Delivery and Caching

I recently had to assist a customer increasing the performance of their (Tridion-powered) site. The initial claim was that Tridion caching was not performing as expected and their database was being hit too many times.

I have used Tridion cache in all my projects, and especially when coupled with Dynamic Component Presentations I see drastic performance improvements. I don't remember ever having performance issues related to this, so I was a bit astonished as to the claim.

A quick overview of the code for this "static" site quickly revealed the reason why cache was not performing as desired - and I'll get to this in a second.

The Tridion content delivery cache uses a fairly complex dependency algorithm and something we call the "Cache Channel Service" to notify all delivery nodes when a given item has been published/republished/unpublished and therefore invalidate its cached version. When all is operating normally you will NEVER get an out-of-date page, even on a large (100+ servers) delivery environment. (You can read more details about the Cache Channel Service on this article at SDLTridionWorld).

However, what very often developers seem to not understand is what is cached, and what is a "dynamic" page in the context of Tridion. So let's do some definitions here.

Tridion Dynamic Page.
We call a page "Dynamic" not when it responds to a user's behavior, preferences or profile. We consider a page as dynamic if the system doesn't necessarily "know" what components will be displayed at the time the page was published. A good example of such a page is a "press release index" page, where the component presentations displayed are dynamically retrieved from the Content Broker at run time.

A page that includes ASCX controls to perform taxonomy lookups and determine which component presentations to display is not what we would call static - even if the page contains no logic to interact with the user's profile (which raises some more questions about why the taxonomy queries are being performed, but that's an issue for another day).

Tridion Object Cache
As the name implies, the Tridion object cache contains all the recently used Tridion objects loaded by your application - this typically includes Page Metadata, Component Metadata, Component Presentations, Dynamic Links, Keywords, Taxonomy objects, etc.

It allows us to minimize the number of times a given object is loaded from the content repository (file system or database) by storing a cached version of it - which gets invalidated only when 1) it is republished/unpublished or 2) the cache runs out of usable memory (configurable setting, by default set to 16 MB).

OK, so what does "object" cache mean?
It means that queries to the content broker (for instance "all press releases sorted by last published") will result on a set of objects being received by your application - and all those objects will probably be in memory already. So when you call ComponentPresentation.GetContent() you  will have an average wait time of 0 milliseconds or thereabouts.

However, your query results are not cached. In context of:
  • How cache invalidation occurs;
  • What we consider dynamic;
  • How often your content may be updated,
it makes sense that database query results don't get cached - otherwise any publishing action would invalidate all query result caching, and on a site that is updated thousands of times a day, this would result in more cache invalidation messages than anything else.

We could automatically make the results cached for a duration of, let's say, 5 minutes - but then you don't get the latest results, etc.

So Tridion (as we expect) took the "hands-off" approach of letting you control the cache through your application.

OK, so back at the issue at hand. I'm trying to ensure that the page I currently load, which may display up to 10 Component Presentations based on keywords attached to these components, improves its average load time from 1 second to as quick as possible. Since all these queries are going to the database, even if database cache is performing correctly, you will have to cope with additional db connections, network latency and what-not - multiplied by 10-12 queries per page, and here's a recipe for "slowness".

This site doesn't get updated very often, and has a very high number of average sessions, so I decided to test it with a 5 minute ASP.NET cache object for all my queries. Each individual query will be cached for a maximum of 5 minutes, which is an acceptable value for content editors/publishers.

What did I find?
Average load time went from 800 milliseconds to 17 milliseconds with an extremely simple change to my code.

For many reasons, I will not post the code as is currently being used at the customer, but here's the basics of it.
A wrapper method was created for Query (Tridion.ContentDelivery.DynamicContent.Query) which takes 2 parameters: the query object and a unique (per query) cache key. This cache key is nothing more than the string concatenation of the query parameters.

private String[] ExecuteTridionQuery(Query query, 
      String CacheKey)
{
  String[] results;
  if (Cache.Get(CacheKey) != null)
   results = (String[])Cache.Get(CacheKey);
  else
  {
  results = query.ExecuteQuery();
  Cache.Add(CacheKey, results, null, 
    DateTime.Now.AddMinutes(5), 
    System.Web.Caching.Cache.NoSlidingExpiration, 
    System.Web.Caching.CacheItemPriority.Normal, null);
  }
  return results;
}

And voilà, instant 60x boost to your "static" page.

N

Monday, October 25, 2010

#upintheair

I get frequently asked "where I've been lately", and been finding it really hard to tell people where I've been, simply because it mostly feels like I only briefly "was" anywhere, never really got to be there - but I do remember going there and coming back.

So, here's a list of where I've been to this year for work, that I can refer people to if I don't feel like telling them... :)

  • San José, CA (
  • Laguna Beach, CA
  • Newport, CA
  • San Francisco, CA
  • Oakland, CA
  • San Ramon, CA
  • Las Vegas, NV
  • Washington, DC
  • Phoenix, AZ
  • Columbus, OH
  • Amsterdam, The Netherlands
  • Helsinki, Finland
  • Lisbon, Portugal

Friday, October 08, 2010

MVP Nomination stats

Got ten nominations in less than a week, so it's looking pretty good for the 2011 MVP awards.

With still nearly 3 months to go (nominations are valid if received before January 1st 2011) I'm hoping to have many more candidates! See how you can nominate someone for an MVP award here.

An interesting fact is that 85% of people nominating others are based in the Netherlands, the UK has not nominated anyone yet, and only one person in the USA has nominated someone.

There's clearly something wrong with those numbers, last time I checked the US had overtaken the Netherlands and the UK in number of visits to the forum and SDLTridionWorld, however the community is still very much based in and around Amsterdam.

A second interesting fact - which I hadn't noticed until someone mentioned it in the MVP summit last week - is that we have several (4) MVPs based in the Netherlands, but none of them is dutch. Actually, we don't have any dutch MVPs, which is quite odd if you look at the company's history. Maybe it will change this year?

Well, keep 'em coming, there is no maximum number of MVPs, all you need to do is to be valuable to the community, and share your knowledge.

Thursday, October 07, 2010

MVP Summit 2010, Fortaleza do Guincho, Portugal

Judging from all the activity on twitter, one would think that the MVPs locked themselves in a room and did nothing else but code.

Indeed, I think we got something very useful off the ground with the Hello World GUI extension sample, and the Content Interaction extension (aka MVP Fondue Kit), but what I really liked the most was the opportunity to spend some time with the Tridion MVPs and pick their brain about the Tridion community, what to improve, what to expect from 2011, the whole MVP nomination process, etc.

And, of course, the location!
Surrounded by the cliffs of Guincho and the imposing Serra de Sintra, the scenery has to be one of the prettiest I've seen.

I'm obviously biased, having lived for 11 years pretty close to this location, but I had never stayed in the Fortaleza do Guincho hotel before, and I must say it was quite a good choice for the event, as we couldn't have asked for more.

So, rather than bore you with more details about what the MVP did or didn't while in Portugal, I'll just leave you with a couple more pictures...




Monday, July 26, 2010

Phoenix, Arizona

Just added one more city to my list of "places I've been to for work". It's 101 degrees outside, at 9:36 PM (that's 38 degrees celsius).

Pretty long week ahead, being involved in a rather large Proof of Concept for an amazing reference if we get the deal.

Time will tell, I hope to announce this company as a customer soon. Now I think I'm going to pass out in bed.

Amazing how you can fly for 5 hours and 1) never leave the same country and 2) land in a place that feels just like the place you left from - except for the temperature, that is.

Thursday, July 22, 2010

This is cool... Tridion 2011 from my iPhone

After all the talk about Tridion on the iPad I thought that if it runs on the iPad, it should run on the iPhone, right?

Right indeed.

Not that I think it's a very useful client, but it does work...

N

Wednesday, July 21, 2010

Preparing for 2011 MVPs

Last year we launched the SDL Tridion MVP program, and being the first time it took a rather "Career Achievement" look to it, and (perhaps unfortunately) many of the nominations (over 60%) were for SDL employees.

No matter what people think of it, we decided to create an independent Selection Panel that would select who deserved the MVP title, and awarded it to those that did make an exceptional job of assisting people in the community.

In preparation for the 2010 MVPs I can confirm that we will keep the independent selection panel (with a couple of adjustments as to the members of the panel to adapt to people's changes in careers), but this year we will not allow for SDL employees to be nominated.

This means that great Tridion resources like Jeremy, Julian, Jeff and Peter will not be 2011 MVPs (and, of course, yours truly).

Now that this is out of the way, here's the 2nd part of my message for today...

Why would you want to be an MVP? 

Granted, being the first time we were doing it, there was a lot of guess work as to what people would want. First - and perhaps foremost - you get to have your name in a rather exclusive list of Tridion professionals. I know of at least 2 people that got contacted for work directly from being on that list, and there's probably more.

Second, you get a shiny award to show off to your friends (who already considered you a geek beforehand, and will now have confirmation of your uber-geek status worldwide).

Third, you get access to a MVP-only Linked-In group of very dubious benefit at the moment.

Fourth, you get to spend a "work" weekend with all your fellow MVPs on a nice sunny location, 1-star Michelin restaurant, and breakfast by the beach (aha!).

Fifth, and professionally the most important, you get access to anything related to Tridion. You want to participate in "internal-only" bootcamps? No problem. You want some version of some software? No problem. Want to play around with Tridion 2011 Beta? No problem. Want to escalate an issue with Customer Support? No problem (well, depending on the issue). Need access to a license, information on some upcoming product, you-name-it? No problem.

So, question for the day: What are you doing now that makes you a great candidate for the MVP award next January?

N

Thursday, May 13, 2010

MVP

I was asked to provide a picture of me with my shiny MVP award... so here goes :)

Saturday, April 10, 2010

Outputting a keyword hierarchy in XML

With Tridion 2009 we saw the introduction of hierarchical keywords - aka Taxonomy, aka Intelligent Navigation - and with it a whole new world of possibilities for content classification.

However, in some cases, you really don't want all the intelligence around it and would much rather have just an "old style" xml hierarchy. If you tried this yourself, you probably figured out by now that the keyword hierarchy doesn't look so... hierarchical when viewed through the API. Not at all.

It looks rather flat.

I had to write a template recently with some information about every keyword in the hierarchy (including its metadata) for a site navigation, and keeping the keyword "parent/child'' relationships.

Here's how can you do it.

Category Navigation = engine.GetObject(NAVIGATION_CATEGORY) as Category;
using (MemoryStream ms = new MemoryStream())
{
    XmlTextWriter w = new XmlTextWriter(ms, new System.Text.UTF8Encoding(false));
    w.Indentation = 4;
    w.Formatting = Formatting.Indented;

    w.WriteStartDocument();
    w.WriteStartElement("Navigation");
    log.Debug("/Navigation created");

    Filter filter = new Filter();
    filter.Conditions.Add("Recursive", false);
    foreach (XmlNode RootChildren in Navigation.GetListKeywords(filter).SelectNodes("//*[@IsRoot='true']"))
    {
        Keyword RootKeyword = engine.GetObject(RootChildren.Attributes["ID"].Value) as Keyword;
        log.Debug("Generating XML for keyword " + RootKeyword.Title);
        w.WriteStartElement("Item");
        w.WriteAttributeString("ID", RootKeyword.Id);
        w.WriteAttributeString("Title", RootKeyword.Title);
        if (RootKeyword.Metadata != null)
        {
            WriteKeywordMeta(RootKeyword, w);
        }
        WriteChildrenXml(RootKeyword.Id.ToString(), w);
        w.WriteEndElement();
    }
    w.WriteEndElement();
    w.WriteEndDocument();
    w.Flush();
    w.Close();

    package.PushItem(Package.OutputName, package.CreateStringItem(ContentType.Xml, Encoding.UTF8.GetString(ms.ToArray())));
}

And the recursive "WriteChildrenXml" method would look more or less like this:

private void WriteChildrenXml(String RootKeywordId, XmlWriter writer)
{
    Keyword ParentKeyword = _engine.GetObject(RootKeywordId) as Keyword;
    Filter filter = new Filter();
    filter.Conditions.Add("Recursive", false);

    foreach (Keyword ChildKeyword in ParentKeyword.GetChildKeywords(filter))
    {
        writer.WriteStartElement("Item");
        writer.WriteAttributeString("ID", ChildKeyword.Id);
        writer.WriteAttributeString("Title", ChildKeyword.Title);
        if (ChildKeyword.Metadata != null)
        {
            WriteKeywordMeta(ChildKeyword, writer);
        }
        WriteChildrenXml(ChildKeyword.Id.ToString(), writer);
        writer.WriteEndElement();
    }
}
Nuno

Wednesday, February 24, 2010

SDL Tridion MVP Awards - online now

It's official, it's out there, and here's the location statistics:

Excluding SDL:
Netherlands: 2
UK: 2
US: 1

Including SDL:
Netherlands: 4
UK: 3
US: 3

Check it out, you may know someone from that list: http://www.sdltridionworld.com/community/mvp_award/mvp-award-2010.aspx

PS - Before people start shouting that giving the award to SDL employees is wrong, I think it's worth re-reading the MVP Program rules at http://www.sdltridionworld.com/community/mvp_award/index.aspx, specifically the part about the MVP Selection Panel. This panel is NOT controlled by SDL and most of the nominations received were for internal SDL people (and many didn't get the award).
PPS - If you use the forum, you will certainly know that the SDL MVPs really do deserve it.