How do Sitecore commands work in the cms?

Under the hood the Sitecore api offers huge amounts of functionality. When you are using the cms environment, chances are you are triggering this functionality via sitecore commands.

Most buttons in the cms are tied into these commands so how do you pair up specific buttons to specific code?

There is an excellent Firefox plugin – Firebug, which is essential if you do a lot of web development. If you haven’t ever used this, download it now!

Once installed, run through the following steps:

  1. Fire-up your cms environment inFirefox (once firebug is installed)
  2. Activate firebug and select ‘inspect element’ – then click the button you are interested in
  3. Check the firebug window for the JavaScript attached to the button click – this should be wrapped in a sitecore form post JavaScript method eg javascript:return scForm.postEvent(this,event,’item:setdisplayname’)
  4. Open /app_config/commands.config and search for the command name. Examples of this are: item:setdisplayname, item:publish
  5. Find the assembly referenced in the commands file and fire up your favourite decompiler eg reflector or ilspy and search for eg <command name=”item:setdisplayname” type=”Sitecore.Shell.Framework.Commands.SetDisplayName,Sitecore.Kernel” />

You should now have a route into the source code for each button in the cms!

Sitecore packages

If you have ever developed with Sitecore, chances are you will have deployed content via Sitecore Packages.

A sitecore package is essentially a zip file containing the xml to be stored in the sitecore databases along with any files you choose to deploy. Some upgrades make use of *.update files – this is out the scope of this post.

When you install content from packages, items should have the same guid. If conflicts are found during an install you are presented with several options. One word of caution – if you choose overwrite, its pretty easy to blow away large chunks of the tree if you package only contains a few items.

If you want to see what is in a package you have a few options:

  1. Drill into the zip file with your favourite zip program – content items are nested by database and then path
  2. Load the package into the Sitecore Package Designer (I wish I knew about this one sooner!!!!!)

For the second option, there is a hidden button (why this is hidden I dont know!) in the package designer:

When you click ‘From Existing’ you are shown the contents of your data -> packages folder. If you have been sent the package, copy it to this folder.

Once the package is selected you should see items in the package designer as if you had created the package yourself. From here you can then save the xml definition as per normal.

Add item anywhere in the tree without setting any Sitecore insert options

Consider the following scenario: you setup a new Sitecore template (or branch) which you want to add anywhere in the tree without setting any sitecore insert options

The reason you may want to do this is you have several templates in place throughout the tree, if the insert options can’t be inherited then you would need to update a lot of standard values!

If you dont use the rule engine for this (see this post) you can still achieve the same solution.

In the following example, we want the user to be able to add a Generic Form anywhere under the home node of the site.

Which then needs patching into the uiGetMasters pipeline (/App_Config/Include):


After the talk at the Bristol Sitecore User Group yesterday, Raul demonstrated the rule engine for this kind of thing – the exact same problem can be solved without any code 🙂

You need to set yourself up a rule eg:

Note, one step remains – you need to select the root item.

API techniques – accessing items in the sitecore tree

Sitecore offers various methods for accessing items in the sitecore tree. The following shows some examples:

Typically we will store key item guids and key template guids in static classes so they can be used throughout the code.

From experience it is rare to use path to access items since an items path can change over time – essentially it is content rather than something fixed. An items guid should never change even when it is packaged up and distributed to multiple environments.

Its worth noting that once you have accessed an item, it may be it is null. Another scenario is that it doesnt have any versions – this can be caused by an item being published when it isnt in a final workflow state.
These are easy things to check:

Sitecore custom sublayout cache key

Out the box, sitecore offers several options for caching the output of sublayouts. Some of the options you have for this are things like ‘vary by querystring’ and ‘vary by data’. This post will demonstrate how to setup custom sublayout cache keys.

Behind the scenes Sitecore builds up a cache key by appending together information from the current request based on the parameters selected in the caching options. The result of this being the cache key is longer, the more permutations you select.

For typical builds, the out the box options cover all scenarios however what do you do if you need to customise this?

In a recent project we exploited * (or wildcard) items so we could accomodate data fed from an external api. This would map known url patterns to one node in the tree, allowing the presentation components on the page to be set in sitecore but the data in the body content be fed from and external system. The mvc routing dll solves the same problem in a similar fashion.

With the default cache options we ran into the issue that the cache key for each wildcard page would always be the same since the ‘vary by data’ option used the items id, rather than the dynamic url we were assigning. Essentially every page would share the cache key for the * node.

Solution
There are only two steps needed for this implementation:

  1. Create custom implementation of a sublayout
  2. Create custom sublayout factory

Custom sublayout

To use this on the front end, you would then embed in the markup using:

If you want sublayouts instantiated from Sitecore to make use of your new type, you need to update the sublayout renderingControl in the config:

And finally the new rendering type:

In the example above the new sublayout is used for wildcard items as well as items which match an MVCRoute – this is some new functionality currently being developed by Steven Pope @ Sitecore UK.

Sitecore and RegisterClientScriptInclude / RegisterClientScriptBlock / RegisterClientScriptResource

One of the common issues when using Sitecore HTML Caching is how to execute dynamic scripts based on code behind actions when the control front end is being cached.

The solution listed below defines the theory behind the approach rather than the concrete implementations.

Consider the following scenario:
You need to display the date to the user using javascript. To solve the issue, you decide to make use of either RegisterClientScriptBlock or RegisterStartupScript and register some javascript to write out alert(‘DateTime.Now’) [psuedo code].

This works fine during development since you are building your project a lot and the full use of caching isnt implemented. Down the line, you tune up / turn on caches and the date is only shown the first load after the caches are emptied 🙁

Do not fear, there is a solution to the issue and that is to make use of Sitecore Html Cache. Rather than calling asp.net RegisterClientScriptInclude(Block, Resource), setup your own methods (for the demo, these are exposed off SScriptManager):

In your master page, add another control (for the demo, known as SScriptManager).

When you register the script includes / blocks, store this information in the html cache remembering to build the cache key from current item, current language and script key.

During the Render/PreRender phase of the page lifecycle, the SScriptManager can then iterate through all keys in html cache and if the keys match the current page, relay on the script calls to the page.

Common mistakes when programming with Sitecore pt1

The aim of this post is to highlight some pitfalls I have run into in the past when working with the Sitecore API. Hopefully some ideas demonstrated here will help people avoid some common mistakes when programming with Sitecore.

Over time I’d like this list to grow so if anyone has any feedback or suggestions for more items, please let me know.

For each item I will highlight some examples of where I have seen the mistakes and how they can best be avoided.

  1. Direct database access
  2. Expensive content queries

1. Direct database access
There are several ways to get a reference to a Sitecore database. Note, these are defined within the config (<databases>). In the following example, the first 2 items get a specific database, the last the context database.

Why is this bad?
In larger Sitecore builds one of the common tasks is to run through the ideas stored in the following guides on the sdn: security hardening and configuring production environments.

One of key steps in these documents is that the content delivery site only has a reference to the web database. Typically you would have an independent content authoring environment which has references to core, master and web. In this setup, if your code has a direct reference to master, you will get an exception since master doesnt exist.

When might you want to do this?
It may be that in certain circumstances you do want to target a specific database. Consider an import routine. In this example you would want to ensure that new items are only added to master – note you would need to ensure the import routine is run from an environment which can access the master database.

2. Expensive content queries
Sitecore.Data.Items.ItemAxes exposes a set of methods which can be used to drill up and down through the content tree. Some examples of this are:

Within your sublayouts you could then call eg:

Why is this bad?
If your content tree contains thousands of content items and you call GetDescendants from the root node – you will effectively be loading every single item in the tree – I can guarantee the bigger the tree, the slower this will go!

When might you want to do this?
If you are comfortable that the result of a descendants call will expose a controlled set of nodes then you may find them more useful than querying direct children. An example of this is if folders are used in the structure you are querying.

Where might you make this mistake?
A typical place I have seen this implemented is building footer navigation. Consider the following: ‘A developer understands your template structure and sees there is a common base template for each page so adds a new checkbox ‘Show in footer navigation’. In the footer control they then start at the home node calling GetDescendants, checking each item for the new checkbox.

What can I do instead?
In the footer example, try to consider alternative solutions for defining which items should be shown in the footer. How about a configuration area of the content tree where the footer navigation is defined as its own node (and children if needed). Your descendants call could then target these specific items.

Other alternatives are using shallower axes for your queries for example: direct children or siblings.

Create a version of an item in all languages in the Sitecore client

This post aims to demonstrate how to add new versions for all languages if they dont exist in the cms.

When you click buttons within the Sitecore client, typically Sitecore commands are used to map these actions to c# code. This link is defined in /App_Config/Commands.config. Some sample entries here are:

If you want to add your own commands you can either edit this file or setup a patch file in /App_Config/Include. Note the patch file is the preferable option.

The code used for this example is:

This then needs to be added into the commands section of the config with the following patch file:

If you want this functionality available from a cms button, you need to wire up the button to the command. To do this, switch to the core database.

In this example we will add to the Language chunk of the ribbon (/sitecore/content/Applications/Content Editor/Ribbons/Chunks/Language). You need to create a new button and then setup the data section paying close attention to the Command field. This wants to be the same value as set in the patch file (item:addversiontoalllanguages).

Debugging Sitecore pipelines

A quick tip for checking data flowing through the Sitecore pipelines is to setup empty processors and then move them sequentially through the required pipeline.

An example for the pipeline:

Then add your debug point and dig into the args.

Some example usage for checking which site has been resolved:

Sitecore Gutters for updated presentation

Sitecore gutters are a great way of seeing quick summaries of content within the tree. Some existing gutter options include Locked Items, Workflow State, Missing Versions and more. These can be toggled by right clicking in the left column of the content editor.

Its easy to build custom gutters – in the example above we have a new item available – ‘Custom Presentation’. When this is active on an item it shows:

Behind the scenes there is very little code to achieve this:

Gutters then need to be added to the core database at ‘/sitecore/content/Applications/Content Editor/Gutters