Add a proper LastModified field to Sitecore

To track item changes Sitecore uses the “__Updated” field in the Statistics section. It’s a normal Datetime field i.e. it contains a date for every language and version. This is fine in most cases, but sometimes you need to track changes a bit further. For example when you change a shared field, you’re applying a change to all languages and versions. So how do you track those changes?

An image in the Media Library is a typical example of this problem. If you change the image, you’ve changed the item on all languages, but if you just add a translation to the “ALT” text, you’ve only changed that particular version.
Continue reading

A different way of using Sitecore

Developer meeting Gothenburg

Presenting a live demo of the solution

This week I’ve been speaking at the Sitecore developer meeting in Göteborg. My speech was a live demo of a quite different way of using Sitecore.

We at Stendahls have created an event solution where we’ve throwed away PowerPoint and uses a web browser instead for presentation. The audience each have an iPad mini as a second screen and the speakers controls everything from an iPad instead of using a clicker.

Charging iPads

Charging 120 iPads for the event

Everything is driven by Sitecore and SignalR and we had this setup for 120 iPads and about ten presentation screens. It worked extremely well and just imagine what you can do with DMS, ECM, Analytics and personalization when the audience are all logged in as a Sitecore user using a pin code from their badge. 🙂

At the developer meeting we also listened to some nice insights about Sitecore DMS by @SimeonArrr and some code examples in Sitecore 7 by @LarreCMS.

I hope I’ll be doing the same speech at the next Sitecore developer meeting in Malmö.

Sitecore Image Optimizer module

This is going to be a very short one – I’m really too busy right now to spend time on doing a proper blog post. I hope I’ll manage to do an update soon.

I’ve just spent two hours creating an image optimization module that’s just submitted to Sitecore Marketplace. It will run pngcrush, jpegtran, or whatever image compression utility you prefer on your images in media library.
Continue reading

A better Sitecore publishing dialog

2014-03-11 Update: The just released Sitecore 7.2 has implemented all these features into the product, so this blog post is only valid for 7.1 and below. Thank you Sitecore!

The Sitecore publishing dialog has some flaws that I finally got the chance to fix.

Original Publishing DialogHere is a screenshot of the original publishing dialog from one of our Sitecore setups. The most obvious error you’ll find in the standard dialog is that the list of languages is unsorted. Another strange thing is that the list of languages is filtered on read access for each language. So, if I have read access on the language item (not even LanguageRead), I may publish any items on that language. Eh? When will I ever need to publish items that I can’t edit in the first place? I think LanguageWrite is a more suitable permission.

Another thing that can become an issue, is that anyone can do a complete Re-publish of everything. This shouldn’t ever be done really, unless you have a corrupt database. With a growing database, a Re-publish can have great performance impact. I guess Republish access is only needed for Administrators in most setups.

Publishing targets is also an issue. Continue reading

Sitecore auto publishing agent

There are many reasons to do auto publishing i Sitecore. For example users that forgets to publish their changes, an auto publish will correct that. In a large scale setup, the problem could be the opposite. Too many CM users publishing their changes all the time, so that the CD servers cache gets cleared too often giving the site a bad performance. Then, remove the publish access from the authors and schedule an publish task like every few hours or so.

In an environment with limited languages, the Sitecore.Tasks.PublishAgent is really handy, but its main problem is that the list of languages that should be published is stored in the config files. I wanted to change that. Unfortunately the PublishAgent is almost a sealed class, so I ended up copying the main code of it and created a new class.
Continue reading

Sitecore 7 – Query items that inherits a template

Finally I’ve got a few hours to play with Sitcore 7 and its new LINQ interface to Solr/Lucene. Love it!

Computed index fields are really helpful to speed up things and make things easier. Some fields are enabled by default, but there are also a few pre-configured ones that are disabled by default in the DefaultIndexConfiguration.

One that caught my eye was the “_templates” field. It stores the collection of base templates of an item. It can for example be used for finding items of a specific type, or items that inherits this type. It’s disabled by default, so you have to enable it and rebuild the index.

I soon realised though that the “_templates” field just contains the list from Item.Template.BaseTemplates (plus Item.Template of course). I don’t know yet if this is by design – Sitecore 7 is stil just a preview.

If you need to query items that really inherits a template Continue reading

Database tuning for Sitecore Media Library

There seems to be tons of arguments whether you should store your Media Library files in the database or as files on disk. I usually prefer storing them in the database, since it’s usually easier to manage the data this way. The performance impact is virtually none anyway, since I always use a CDN. But I agree with many of the cons arguments about this as well, so I’ll leave that decision to you.

If you choose database storage, one thing worth considering, is moving the Blobs table into another file store, so that you can put the binaries on a cheaper disk volume. That is if you for example run your primary database on SSD disks, it’d work just fine having the blobs on conventional hard disks.
Continue reading

Dead Urls – Sitecore Module

We tend to spend quite some time on URL management in order to get them nice, SEO friendly in all sorts of ways, but I’ve noticed that most CMS I’ve been in contact with have overseen one of the areas that I think is one of the most important ones. That is proper handling of permanent redirect (301) of URL’s when they change.

The URL structure should of course reflect the site structure, have relevant keywords in it etc. When content authors work with the site, those URL’s may change. The old ones give a “404 Not Found”. Bad from a SEO perspective but it also means current visitors on the site will have downloaded html pages with broken links. My experience is that this escalates when having integrations to other systems that generates items.
Continue reading

Sitecore autoinstalling modules

This is a follow up on yesterdays post regarding autoinstalling NuGet packages into Sitecore.

On request, here is my prototype code on how I use WebActivator to automatically insert/update embedded items into a Sitecore installation. Please note that this is very much prototype code, and it’s really ugly too. But I hope you get the idea of how it works.
Continue reading

Sitecore, Hedgehog TDS, TeamCity and NuGet == true

I’ve been looking some time for a more streamlined development process when building Sitecore modules and share code between Sitecore projects. Separating code into modules is easy, but when you have dependencies on Sitecore items, things becomes a bit more complicated.

The package installation wizard in Sitecore is helpful, and it get’s better with update packages generated by Hedgehog TDS. But I think we can do better. With multiple developers, multiple installations (dev, test, QA, live environments etc), the update process becomes too time consuming and painful.

In addition, I want to be able to create generic modules that can be shared between different Sitecore projects, so I want the code to be built and tested on our build servers and deployed to our local NuGet server.

I’ve done a prototype of this, and I think it worked out quite nice, though there is still a lot of room for improvements.
Continue reading

A common problem with large scale web applications

When working on large scale web application, typically hosted on multiple content delivery servers, regardless if it’s due to high load or a requirement for redundancy, there are quite a few pitfalls to handle.

One of them is on-demand, content delivery web server generated content. My most common case are ordinary web images. Images are typically selected by content authors and they don’t know anything about pixels, bandwidth etc. The people responsible of that are the web developers. The allowed image size constraints should be specified in the aspx/ascx/cshtml files. This means that you utilize some sort of function to resize the image on request of that image and you cache the result, typically as a file on the content deliver web server.

Since you’re good internet citizen, you have version control of your generated images as part of the image URL and you use long time client caching. And since you need speed, you use a Content Delivery Network (CDN) as well. Here I assume you use the site as CDN origin, i.e the images aren’t uploaded to a CDN storage.

Now, using multiple content delivery servers behind a load balancer, this usually causes problems. Let’s say you update something that’ll change the image and its URL (the versioning part). During the publishing sequence of your CMS, you’ll have a state where some content delivery servers are updated and some are not. The time may be short, but it’ll be there (*).

Since we’re talking large scale here, you will now have a problem. A visitor to your newly published site will get an updated html page with the new image URL. The client browser will then load the new image, typically through the CDN, and that request eventually goes into the content delivery cluster. Where will it end up? Possibly (or probably if your load balancer considers backend latency) on a server that hasn’t got the new image yet. We’re still in the middle of a publishing process, right. So, depending on your implementation, you’ll serve an old image, generate a new image based on old data, or give a 404. All are bad.

To make things worse, it’ll probably get cached by your CDN, so now all visitors will get an incorrect image.
Continue reading

Amazon CloudFront+Sitecore bugfix

Serving your Sitecore Media items, on public sites, through a Content Delivery Network (CDN) is always good. I like using Amazon CloudFront since it’s really cheap and easy to set up. For large, high volume sites, I’d look at alternatives as well. But since there is no startup cost or fixed monthly fees etc using CloudFront, I think all small and mid size Sitecore setups should leverage from it.

There are quite many tutorials out there on how to configure Sitecore for CloudFront, so I won’t get into that here. Maybe I’ll post something later..

There are a few minor problems with CloudFront though. One is a nasty bug that spoils proper caching.
Continue reading

SEO Canonical URL’s in Sitecore

Sometimes you end up with pages on your site that’s accessible from several different URL’s. It might not be a big deal, but from an SEO perspective it’s bad. Each page should have only one URL, otherwise Google and other search engines may treat your pages as duplicate content, resulting in a lower page rank etc etc.

In ASP.NET, URL’s are mostly not case sensitive, but a URL is actually case sensitive (see w3.org). This means you may accidentally refer to a page using different casing and thereby have duplicate content on your site.
Continue reading

Using Combres in Sitecore 6.6

After lots of frustration getting Combres to work properly with Sitecore 6.6, I got very good help from the Sitecore support team and a solution worth sharing with the community.

The problem is that since the first release of Sitecore 6.6, you cannot register a route to a synchronous IHttpHandler. (In the developer preview of 6.6 and in previews versions you could.) Instead you get this quite confusing error:
Continue reading