Tag Archives: Sitecore

Result of the Danish Sitecore Developer Group survey

The survey is now closed and here are the results:

q9 q7Danish Sitecore Developer Groupq6 q5 q4 q3 q2 q1

 

Free text comments received:

  1. I liked the way that DSDG has been untill now
  2. thank you ūüôā
  3. Great questions
  4. I think meetup could be extended to other .NET CMS systems and related technologies. Why not grouping with Umbraco, EpiServer etc. to broaden our knowledge.
  5. great to have a SC community like DSDG
  6. Good to see that the group is thriving. It’s a struggle to get things up and running here in au – keep the community-run group.
  7. If anything, clearer expectations of meeting content would be really nice. It would allow me to better decide whether to go or not – especially if the meeting frequency would go up (which I’d prefer). So for example, if someone was really into a particular subject, then they could get together and I would know better up front what the subject was really about
  8. Only been to 1 meeting, but it was a very positive thing and like to come to more

How to add a button to the sitecore content editor to download data as a CSV file

In this blog I will explain how to add a button to the content editor and download data as an CSV file. For this example I will assume that we want to download the data for a given web form for marketers form as a CSV file.

Adding the button
the button

Contextual Ribbons

You may not have noticed but this is a contextual ribbon that is it is only shown when the item is based on the forms template, as it gives no meaning to have the download data as CSV added to all items.

First you need to swap to the core database, and navigate to the Contextual Ribbons item for the content editor i.e. /sitecore/content/Applications/Content Editor/Ribbons/Contextual Ribbons.

This is where all the ribbons that are only shown for specific item types are¬†placed; within this folder there is a forms toolbar, which contains a form strip, which contains a forms chunk, which in turn contains the ‚ÄúExport Data as CSV‚ÄĚ button item.

button item
The most important part of the button item is the click field, which defines the command name that will be raised when the button is clicked (I will explain how to hook this up in more detail later).

But how is a contextual ribbon associated with a given template – well that part is easy on the template item under the appearance section there is a ribbon field which can define a contextual ribbon or toolbar to be shown.

co0ntextual form

How to hook the button click up to the code that is to executed? 

We have to add a command item to the /app_config/commands.config file to bind the command name to the class that is going to provide the functionality.

<command name="forms:exportformdata" type="WFFM.SQLServer.SaveToDatabase.Infrastructure.Commands.ExportFormDataCommand, WFFM.SQLServer.SaveToDatabase" />

The class must inherit from the Sitecore Command class, and override the Execute function.

    internal class ExportFormDataCommand : Command
    {
        public override void Execute(CommandContext context)
        {
            Assert.ArgumentNotNull(context, "context");
            Assert.IsNotNull(context.Items, "context items are null");
            Assert.IsTrue(context.Items.Length > 0, "context items length is 0");

            Item contextItem = context.Items[0];
            Assert.IsNotNull(contextItem, "First context item is null");
            OpenNewWindow(contextItem.ID, contextItem.Name);
        }

        private void OpenNewWindow(ID id, string name)
        {
            Assert.ArgumentNotNull(id, "id");
            UrlString url = new UrlString(Constants.Url.ExportFromDataPage);
            url.Append(Constants.QueryString.Name.ItemId, HttpContext.Current.Server.UrlEncode(id.ToString()));
            url.Append(Constants.QueryString.Name.ItemName, HttpContext.Current.Server.UrlEncode(name));
            SheerResponse.Eval(string.Format("window.open('{0}');", url));
        }
    }

Its not very elegant, but the code generates a URL which points to a aspx page that will stream the data. The Eval method of the sheer response, allows me to execute JavaScript on the client which in this case opens a tab/window.

The aspx page doesn’t do that much it just sets the ContentType to “text/csv” and streams the data.¬†If you want to see the complete implementation, you can download it from github

Hope this was helpful, Alan

Sitecore 7.5 SQL Provider (WFFM 2.5) – Added a button to download data as CSV

As promised I have added the ability to download the form data as an Excel spreadsheet (CSV) .

I have created an include file /app_config/WFFM.SQLServer.SaveToDatabase.config to bind the command to the class that exports the CSV.

<command name="forms:exportformdata" type="WFFM.SQLServer.SaveToDatabase.Infrastructure.Commands.ExportFormDataCommand, WFFM.SQLServer.SaveToDatabase" />

Open¬†the content editor navigate to any form, select the “Forms” tab, and click on the “Export Data as CSV” (see below).

For more information about the module please refer to original blog post, or get the sitecore package from sitecore marketplace  or the source code from GitHub for the source.

CSV button

Sitecore Fast Query Syntax ‚Äď Can kill your SQL Server or website

Over the years I have worked on lots of websites that have performance issue caused by sitecore queries that iterate over too many items, usually searching through descendants.

In development where there are not too many items the query performs OK. The site goes live and they start to add content and soon there are 1000’s of items and the queries becomes slower and slower over time. A typical example is searching for the 10 latest news, articles, blog’s etc.

At this point a fix is made by changing the queries to use the ‚Äúfast:‚ÄĚ syntax. There are a lot of articles already explaining this in detail, so this is just a brief intro, the fast syntax translates the query directly into an SQL server database query, and therefore for some queries it can perform faster, use less memory and less CPU.

But a warning it bypasses all caching that sitecore provides and make a request directly to the database every time the query is executed; in development this tends to outperform the standard queries that would have to iterate over a lot of items.

In development you usually test the normal query against the fast syntax query to establish if it is quicker and if it’s quicker you use it and everybody is happy… but that is not the full story.

Let‚Äôs assume each page generates 10-20 queries that rely on fast syntax to retrieve their items. Therefore each page request generates 10-20 calls to the SQL database, I‚Äôve seen sites that generate 100‚Äôs of SQL request per page ūüė¶

In development this would typically not be an issue and or not noticed, as only one page at a time is requested, but in a production on a website with lots of requests it can kill the SQL database and or slow the site down as sitecore itself cannot retrieve items form the database, as the SQL server is busy with all the fast queries.

Therefore you have to be VERY VERY CAREFUL with the use of fast queries.

I would say in 97% of cases – if your queries slow and it is caused by iterating over to many items the correct solution is to use Sitecore search i.e. lucene, Solr, Coveo or another indexer to retrieve the items.

No images after upgrading to Sitecore 7.5

With the release of Sitecore 7.2 encode name replacements now applies to media URL‚Äôs, prior to 7.2 it only applied to content items, and therefore media URL’s with spaces used to be like the following:

/-media/some%20item%20with%20space/test-xx-yy.jpg

But with Sitecore 7.2, they can be as follows:

/-media/some-item-with-space/test-xx-yy.jpg

This change in fact caused all the images on the site I was upgrading to disappear, but first a quick introduction to Encoding name replacement.

It provides the ability to specify text replacements to use when the media manager generates the friendly URL for a media item. The element /sitecore/encodeNameReplacements in the web.config; contains a number of replace elements and each replace element defines what to find and replace.

<encodeNameReplacements>
      <replace mode="on" find="&amp;" replaceWith=",-a-," />
      <replace mode="on" find="?" replaceWith=",-q-," />
      <replace mode="on" find="/" replaceWith=",-s-," />
      <replace mode="on" find="*" replaceWith=",-w-," />
      <replace mode="on" find="." replaceWith=",-d-," />
      <replace mode="on" find=":" replaceWith=",-c-," />
</encodeNameReplacements>

Strangely enough replacing a space with a dash is not defined by default, but I have added it to almost every solution as %20 in URL’s kills SEO. Below is the element you need to add to achieve that spaces are replaced by dashes.

<replace mode="on" find=" " replaceWith="-" />

Nemesis and side effects

I have reported to Sitecore support a number of times that I thought that encode replacements should apply to media URL’s. So with 7.2 I got my wish and this is where nemesis strikes me as after upgrading to Sitecore 7.2 all the product images disappeared from the site.
The solution has over 50000 images which are synchronized from their PIM (Product Information Management) and name of media item had a space and a dash.
If you want to have spaces replaced with dashes the one restriction is that you can no longer have dashes in the items name. Because when Sitecore tries to resolve the URL it applies the reverse of any encode replacements i.e. sitecore replace all dashes with a space to find the item path.
For example assume that your media item has a space and a dash in its name.

/media library/cars/myCar 26-10-2013

The URL will be

/~media/cars/myCar-26-10-2013.jpg

But when Sitecore tries to resolve the URL to find the image it replaces all the dashes with spaces (i.e. the reverse of the encode name replacement) and then it can’t find the item at the following path.

/media library/cars/myCar 26 10 2013

There are a number of solutions

  • Write script to replace all dashes with a space in the media library
  • Create a custom media provider, which doesn’t execute the encode replacements.

Whist I try to avoid modifying standard sitecore behavior in this case I choose to override the GetMediaUrl of the MediaProvider, as it is not possible to change the image names due to the business requirements of the site.

Anyway I hope this helps anybody if there images disappear after upgrading to 7.5.

Is it time to change the item structure of sitecore?

I hope with this blog to start a discussion about how we structure non-content items within sitecore. It is not about Component based architecture, that is just to set the context.

Sitecore item structure has always been very type orientated, see below. Where the content is structured by type instead of its logical grouping (component) i.e. you have to store the templates under the template folder, sub layouts under the sub layout folder, etc.

by type

For many years I have used component¬†architecture¬†where the logical grouping is more important than type i.e.¬†Function before type.¬†Use “Agile design principle”, where functionality is logically grouped based on cohesion. Focus on re-usability, maintainability and releasable.

by comp

It provides a good way to model a websites, as a website typically consist of one or more pages types, where each page type contains a number of components. The image below helps identify typical components.

break down

Each component usually consists of a number of non-content items i.e. layouts, templates, renderings, media, settings, look up values, etc.

Whist the visual studio project for the component can group the related files (C# classes, sub-layouts, layouts, XSLT’s, images, etc.)  prior to Sitecore 7.x this is not possible for template, layout, etc. items, they have to be stored under their respective root item, which causes items being fragmented throughout the item structure.

To assists in locating items related to a component, we are forced to use folder naming conventions to help track where a components items are located:

  • Templates¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†/sitecore/templates/components/[COMPONENT NAME]/‚Ķ.
  • Sub-Layouts¬† ¬† ¬† ¬† ¬† ¬† ¬†/sitecore/layout/sublayouts/components/[COMPONENT NAME]/‚Ķ.
  • Renderings¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†/sitecore/layout/renderings/components/[COMPONENT NAME]/‚Ķ.
  • Layouts¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† /sitecore/layout/layouts/components/[COMPONENT NAME]/‚Ķ.
  • Media Library¬† ¬† ¬† ¬† ¬† /sitecore/media library/components/[COMPONENT NAME]/‚Ķ.
  • Data source items (i.e. drop down values for the component) ‚Äď usually specific to the implementation/component

SPEAK/ROCKS sets non-content items free!

Since the release of SPEAK and if you use Sitecore Rocks it is possible to store your template, layouts items etc. outside their respective root folder ūüôā

This is in fact the philosophy and best practices for SPEAK where each application must be self-contained and store all templates, layouts, data source items, etc. under the root application item.

The only exception to this, is the dictionary items which must be stored under the dictionary item, please Sitecore can you fix this ūüôā

This afore mention approach has the following advantages

  • Each component is self-contained an isolated from other components.
  • It is easier to maintain as all the items are grouped together and not spread out throughout the tree structure.
  • Easier to remove a component as you only have to delete a single¬†root item.
  • Easier to move a component from one website to another, as you only have to take the root and its children.

One issue it does not help with is if a component modifies the Sitecore client as that is defined in the core database.

So if we move to a SPEAK based structure for non-content items it could be as follows:

  • Templates¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†/sitecore/components/[COMPONENT NAME]/templates/‚Ķ.
  • Layouts¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† /sitecore/components/[COMPONENT NAME]/layouts/‚Ķ.
  • Sub Layouts ¬† ¬† ¬† ¬† ¬† ¬†/sitecore/components/[COMPONENT NAME]/sub layouts/‚Ķ.
  • Renderings¬† ¬† ¬† ¬† ¬† ¬† ¬† /sitecore/components/[COMPONENT NAME]/renderings/‚Ķ.
  • Media ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† /sitecore/components/[COMPONENT NAME]/media/‚Ķ
  • Data Source values /sitecore/components/[COMPONENT NAME]/data source/‚Ķ.
  • etc. ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† /sitecore/components/[COMPONENT NAME]/[…]/‚Ķ.

I have not had the opportunity to try this with a customer and the only issue holding me back is that it requires the use of Sitecore Rocks as the Sitecore client itself does not support templates/layout items outside of their folder.

I would love any feedback about the idea of moving templates, etc., out of their respective root folders for a web site, and not just for SPEAK applications.