It’s a struggle for sure. I don’t know if it is for you, but it certainly is for me. Hard-coding can sometimes make things so much faster to code. It can make things a lot more readable in your code too. Who wouldn’t want to have this:
var services = Sitecore.Context.Database.SelectItems("sitecore/content/home/services/*");
instead of this:
var services = Sitecore.Context.Database.SelectItems("sitecore/content/home/*[@@templatename = 'Services Landing Page']/*[@@templatename = 'Service Detail Page']");
Just today, I was having this discussion with another Sitecore developer and he gave me a very strong argument that I had never considered. He was arguing for hard-coding paths in Sitecore queries but with one condition: you restrict what the Content Authors are allowed to do with those Items whose paths are hard-coded. Following the example above, with his approach, you would deny the Content Author the ability to rename, delete or move the Services Item. And the thinking here is that the top level Services Item in your tree (and, subsequently, in your query) is so important to the overall structure and IA of the site that you never want it deleted anyway, so, save yourself the future head-ache: prevent the Content Author from being able to rename, delete or move it. Of course, this requires your client to accept this requirement.
As we all know, not all clients would like this idea, and to be honest, if they simply deleted the Item, neither of my queries above would work anymore. And, if they moved the Item, let’s say, completely outside of Home, or, even deeper than Home, for example, sitecore/content/home/public/services, again, neither of my queries above would work.
So really, I guess it’s about supporting the ability a Content Author has of renaming an Item. And, although this feature may not be used that much, it is available so if you’re client wants that flexibility, you’ll need to really think about whether or not it would be OK to hard-code an Item name in your query versus querying for Items of a given template name.
One thing to note, I believe the first query where the Services Item name is hard-coded would be faster. Probably not that much, but faster, nonetheless.
One final remark. One thing that would make things easier if you’re going with the second approach I suggested where you are not hard-coding the Services Item name, but rather, are querying Sitecore using the Template name, is to use the Custom Item Generator written by Velir. This module makes it easy to create strongly typed C# classes for your Templates. If you are not using this module for your Sitecore development, you are probably losing on a lot of times saving. I don’t think I’ll ever be able to do a Sitecore implementation without the CIG.
The strongly typed C# classes CIG creates for you are usually the name of the template with the word Item at the end (unless the word Item is part of your template name). One really REALLY useful property in the C# CIG classes is the static TemplateID string. You can use this property to query Sitecore for Items by ID which is even better than template name. My example above would look something like this using a CIG class:
var homepage = Sitecore.Context.Database.GetItem("sitecore/content/home"); var servicesLandingPage = homepage.GetChildren().Where(i => i.TemplateID.ToString() == ServicesLandingPageItem.TemplateID).FirstOrDefault(); var services = servicesLandingPage.GetChildren().Where(i => i.TemplateID.ToString() == ServiceDetailPageItem.TemplateID);
I’d like to hear from you. What are your thoughts on this topic?