Self-Signed Certs in One Command

As security becomes more critical to web based applications the need to test and develop locally with SSL is good practice. Outside of spending mountains of money generating local test environment official SSL Certificates, we can create what is called a ‘Self-Signed’ Certificate.

There are plenty of articles out there that walk through steps to creating a self-signed certificate, some more detailed than others. This post aims to serve two purposes. First, to provide me a future (easy to find) reference point. Secondly, provide helpful information to the fewest number of steps required for creating a self-signed certificate.

Sitecore Fundamentals Install

As a Sitecore developer first (and most of my current teams are Sitecore related) the usage of the Sitecore Fundamentals Install framework will already be on their machine. For those not into Sitecore development, the following additional quick steps will need to be ran.

Setup PowerShell to interact with the Sitecore MyGet feed

  1. Open a PowerShell command prompt, ensure you are running it as Admin
  2. Register the connection to MyGet feed, at the prompt enter
    Register-PSRepository -Name SitecoreGallery -SourceLocation https://sitecore.myget.org/f/sc-powershell/api/v2

    Sitecore Fundamentals - Register Sitecore Gallery

  3. Install the Sitecore Fundamentals module, at the prompt enter
    Install-Module SitecoreFundamentals
  4. PowerShell will ask if untrusted scripts can be ran, enter ‘A‘ and hit Enter.Sitecore Fundamentals -  Accept Untrusted Scripts
  5. Before performing any other steps, and each time before you use the module, you will want to perform a check and update of the module via
    Update-Module SitecoreFundamentals
  6. Confirming everything installed correctly is as easy as running the following command, at time of writing the current version is 1.1.0
    Get-Module SitecoreFundamentals -ListAvailable

    Sitecore Fundamentals - Available Versions

Setup SSL

  1. Ensure your site exists in IIS
  2. Open a PowerShell command prompt, ensure you are running it as Admin
  3. Run the following at the prompt
    Import-Module SitecoreFundamentals
  4. Run the following at the prompt, this will create the self-signed certificate and assign it to your site
    Add-WebFeatureSSL -HostName "ENTER THE HOSTNAME FOR SITE" -RootDnsName "DO_NOT_TRUST_TheCodeAttic"
  5. Enjoy developing securely!!!
Advertisements

Partial and Page Designs in SXA

As I continue the climb to a better Coffeehouse experience through Sitecore Experience Accelerator (SXA) the next level of building blocks we have are Partial Designs and Page Designs.

Unlike the renderings we covered in the previous post, partial designs and page designs are tightly integrated, where one cannot function without the other.

Partial Designs

The smaller and hence more re-useable block is the Partial Design. My first experiments with partial designs, I struggled to see how they differ from the idea of snippets. As both provide a way to apply x-number of renderings into a ‘reusable’ chunk. It turns out there are two major differences to keep in mind when determining which to build.

The first difference is that a snippet is a specific composite rendering that is to be placed in a single placeholder on a page. Whereas a partial design provides the entire page (or layout) to work from. The partial design is then overlay on the page instance’s layout, providing both content, renderings, and new placeholders (in the sense of rows and columns or containers.)

The second difference is that the actual content initially wired up in a snippet can be edited on from any page the snippet is used. (Which if not configured correctly can create instances of global changes unbeknownst to an editor.) Similarly, a change to a partial design will affect all references to the partial but can only be edited through the partial design and via a page that leverages it.

How you can apply a partial design is also another major differentiation from a snippet, in that partial designs are applied through the assignment to a Page Design and so cannot easily (if at all) be assigned by any content editor unlike a snippet which functions like any other rendering.

The final thing that helps to define partial designs it is ability to inherit from other partial designs allowing for very complex yet highly re-usable designs to be built.

When to Consider a Partial Design

Based on above brief introduction to Partial Designs, the question begs when to choose a partial design when planning and working within your site. You can use the partial designs to create the design elements of your pages quickly for a consistent style. For example, you can create parts of your page once, such as headers and footers, and then use them everywhere on your site.

Partial Designs allows for planning and creation of common (think heavily reused) collection of renderings and associated data for consistent appearance across your site. When constructing partial designs, it is important to allow it to focus on a single congruent element of a page, it is even possible to allow a partial design to have an open placeholder or two or three that page specific content could be placed as needed, while still maintaining a consistent page appearance.

Page Design

Page Designs are the bridge between all those thoughtfully created Partial Designs and actual page instances of your site. Page designs can be assigned zero or more partial designs, which overlay each other into a page.

Partial Designs add up to Page Design

One thing to take note of is that renderings cannot be added to a Page Design. Page Designs are purely a bridge to get Partial Designs onto a page instance. This bridge type feature can be thought of like a branch template from traditional Sitecore development, with the benefit of being more easily updated to affect all related pages.

The full bridge affect can be seen in the following diagram

Page Design Inheritance Hierarchy

Page Designs can be assigned ad-hoc as new instances of a basic page are created or can be assigned via Standard Values to templates which are then instantiated in the site.

References

Helix Project Creation Script

Creating Helix Solutions and Modules with PowerShell

Helix is a set of overall design principles and conventions for Sitecore development, put forth by Sitecore in hopes of providing the community a path toward standardized solution development. As noted in the official documentation:

Helix provide a set of guidelines for your Sitecore projects. The Habitat example provides you with a pre-built and tested set of common modules that you can use as an inspiration to your project. Both improve the efficiency of your projects, reduce costs and time to market. As more and more people and organisations adopt the Helix conventions and principles, it will become a Sitecore standard. This means that people who are familiar with the conventions or the Habitat example will be able to work more easily on other convention-based projects with minimal training. It will be easier for Sitecore Product Support to understand projects built using the conventions, enabling them to resolve issues more quickly. Sitecore will test its software using the conventions so any compatible project that has been implemented for a customer will be more reliable. And since Sitecore will test its software using the conventions, Sitecore will be able to provide better guidance on how to update and upgrade existing Sitecore projects when new versions and new products are released.

(“Why be interested at all in Helix or Habitat?“, http://helix.sitecore.net/introduction/what-is-helix.html#why-be-interested-at-all-in-helix-or-habitat, April 16, 2018)

Some Basic Principles

Before we can dig into the script and creating Helix based solutions and modules, I want to reference some basic principles from the Helix documentation.

A Module is a conceptual grouping of assets which relates to a business requirement. For example, when the company asks that their Sitecore solution contains website search, all assets, business logic and configuration relating to search belongs to the Search module.

In technical terms, project often refers to Visual Studio project, but conceptually can also to the process of implementing the business requirements into an implementation.

The layer concept in Helix supports the architecture by making the dependency flow completely clear everywhere in the solution, in Sitecore, in Visual Studio and even in the file system. Furthermore, the layers provide a structure that is extremely suitable for creating and maintaining solutions of any size and steers both new and experienced developers to producing more maintenance-friendly and clean code. Layers helps control the direction of dependencies the importance of which is described by the Stable Dependencies Principle or SDP, which is one of the cornerstone principles in Modular Architecture:

Helix - Dependencies Direction

File System and Solution Layout

In the Helix documentation, (and a review of the sample Habitat site) one will find a very specific recommended (if not expected) layout and naming of folders both in the Visual Studio Solution as well as the file system. The uniqueness of this ‘recommended’ layout makes the initial setup of a solution very time consuming and increasingly error prone when you start to deal with adding modules at the different layers. The following two images, taken from the Helix documentation show what the Visual Studio Solution and corresponding file system begin to look like.

Helix - Visual Studio Solution, from Sitecore           Helix - File System, from Sitecore

Helpful but difficult

My team enjoys the flexibility as well as cleanliness of a solution built on the Helix principles. What we find most difficult is the extra leg work required in making the file system as well as the Visual Studio Solution appropriate to meet the principles. Trying to solve this problem has led us to try several solutions available in the Sitecore Community, many function very nicely, but didn’t always meet the needs of my teams. So I setout to solve some of these issues, including :

  • No use of custom templates and files to ease setup across machines
  • Option for serialization project creation
  • Pre-loading basic NuGet packages for a module
  • New projects added into the solution by default

Helix Project Creator PowerShell Module

Enough with the intro stuff and into the meat of what you’ve come looking for…a script to ease your Helix headaches and focus on the fun of implementing solutions. TheCodeAttic.Helix.ProjectCreator can be pulled from GitHub at https://github.com/gillissm/TheCodeAttic.Helix.PowerShellProjectCreator.

Setup and Use the Simple Manual Process

The first thing you need to do is retrieve the script from the GitHub repository. As this is hosted on GitHub there are numerous ways you can go about getting things ready to use. In an attempt to make adaption as easy as possible I’ve simplified setup to the following four steps for you:

  1. Open PowerShell command prompt as Admin.
  2. Change the directory to a working/temporary location
  3. Enter the following command
    (Invoke-WebRequest -UseBasicParsing -Uri https://raw.githubusercontent.com/gillissm/TheCodeAttic.Helix.PowerShellProjectCreator/master/ProjectCreatorEasyInstall.ps1).Content | Out-File "ProjectCreatorEasyInstall.ps1"
  4. Then enter
    .\SELRES_09210478-5ac2-4be5-81ef-480eb16e800fSELRES_66c735a3-48ae-4ec2-9967-83d5f083a6f6SELRES_906c181e-dccb-4538-a6c3-1eb25a8f6853ProjectCreatorEasyInstallSELRES_906c181e-dccb-4538-a6c3-1eb25a8f6853SELRES_66c735a3-48ae-4ec2-9967-83d5f083a6f6SELRES_09210478-5ac2-4be5-81ef-480eb16e800f.ps1
  5. Now go implement some awesome Sitecore solutions!

Setup and Configure the Manual Way

As an alternate to the above, you can pull the script from the GitHub repository and load it into Package Manager Console each time you need it with the following steps:

  1. Download from the GitHub repository to your local system in the manner that suits your workflow the best.
  2. Each time you wish to leverage the module in Visual Studio you will need to enter the following in the Package Manager Console
    Import-Module "C:\MyFiles\TheCodeAttic.Helix.PowerShellProjectCreator.psm1"

    Helix - Open Package Manager Console

Manual Process – Full Setup

OR you could download and configure the module manually (this is what ProjectCreatorEasyInstall.ps1 does for you.)

  1. Go to C:\Users\\Documents\WindowsPowerShell\Modules
  2. Create a new folder called “TheCodeAttic.Helix.PowerShellProjectCreator”
  3. Download the GitHub repository into the above directory
  4. Go up a level in the file system, should be at C:\Users\\Documents\WindowsPowerShell\
  5. Open (or create) NuGet_profile.ps1
  6. Add the following
    Import-Module TheCodeAttic.Helix.PowerShellProjectCreator
  7. Each time you run Visual Studio the module will be available to use in the Package Console Manager

Using Helix Project Creation

Create a new Helix Solution

  1. Open Visual Studio as Admin
  2. Open the Package Manager Console
    Helix - Open Package Manager Console
  3. Create a new Helix based solution by running Invoke-VisualStudioSolution
    Invoke-VisualStudioSolution -SolutionPath 'C:\Code\Coffeehouse.Demo.SXA'  -SolutionName 'Coffeehouse.Demo.SXA'

    Helix - Open Package Manager Console

Add a new module to a solution

  1. Open Visual Studio as Admin
  2. Open your Solution
  3. Open the Package Manager Console
  4. ‘Wake-up’ the $dte object by running
    $dte.Solution.FullName
    Helix - Wake-up $dte
  5. Add new module by running Invoke-NewModule
    Invoke-NewModule -ModuleName 'Coffeehouse.Demo.SXA.Coupon' -Layer 'Feature' -UseGlass -UseTDS

    Helix - Executing Invoke-NewModule

    Helix - Invoke-NewModule output

    Helix - Invoke-NewModule output, continued

  6. Go write some Sitecore code!!!!

Proof is in the pudding, they say

After running the Invoke-NewModule command your solution explorer should now look like the following:

Helix - New Module in Solution Explorer

And your file system will have the this:

Helix - New Module in File Explorer

References

The Sitecore Community members are always out to help each other, and some other Helix project creation solutions that may fit your work stream better are:

One Fewer Edit Frame

Recently I had a client that wanted an ‘enhanced’ Experience Editor. This was summarized as fewer clicks for the editors to perform their authoring. What made this request a little more challenging than normal was some of the fields which required editing where of type checkbox, date, and multi-select.

The following findings were based on Sitecore Experience Platform 8.2 update 4 and have not been tested on Sitecore XP 9, but my suspicion is that it will continue to work.

The Challenge

As most Sitecore developers know these types of complex fields cannot traditionally be displayed directly in the Experience Editor, and we usually end up leveraging some form of an Edit Frame, either custom built or via the very handy BeginEditFrame command via Glass.Mapper.

BeginEditFrame is very helpful in providing otherwise non-access to complex field types but does create the problem of several additional clicks, in my example it creates 3 clicks.

Enhanced Editing with Edit Frame

To make the above happen the code required is straight forward

@using (BeginEditFrame(Model, "Edit Frame", z => z.StickyDate,
                    z=> z.HideContactName,
                    z=> z.NewsandAnnouncementCategory))
{
    Click To Launch the Edit Frame
}

Solution

After a little spelunking into how the Experience Editor, I discovered that fields upon edit trigger a JavaScript function Sitecore.WebEdit.setFieldValue(scItemUri, fieldId, newFieldValue);.

The parameters for this are pulled from the hidden span fields with a class of ‘scChromeDate’ each field gets assigned. It looks something like the following

Enhanced Editing inline

To make this work we need to render the following values onto the page to support the setFieldValue method.

  • current page’s ID scrubbed of all brackets and dashes, I find the following works well Sitecore.Data.ID.Encode(PageId)
  • current language of the page being edited
  • current version of the page
  • the field’s ID scrubbed of all brackets and dashes

To get access to these values, I include them in as data-* attributes on the HTML, thus my checkbox would have the following HTML. (Note: my model uses GlassMapper)

< input id="hidcontact" class="editcheckbox" checked="checked"
   type="checkbox" 
   data-fieldid="@Sitecore.Data.ID.Encode(Content.Models.ArticleConstants.HideContactNameFieldId)" 
   data-version="@Model.Version"
   data-language="@Model.Language.Name" 
   data-itemid="@Sitecore.Data.ID.Encode(Model.Id)" / >
< label for="hidcontact">Hide Contact Name< / label>

With the data available next we need to trigger the change or action associated with the item, in this sample for checkbox we want to handle the click event. So, the JavaScript would be something like this

 jQuery('.editcheckbox', namespace).click(function () {            
        var itemId = jQuery(this).attr('data-itemid');
        var itemLanguage = jQuery(this).attr('data-language');
        var itemVersion = jQuery(this).attr('data-version');
        var fieldId = jQuery(this).attr('data-fieldid');

        if (jQuery(this).prop('checked')) {
            SetNewFieldValue('1', itemId, 
                  itemLanguage, 
                  itemVersion, 
                  fieldId);
        }
        else {
            SetNewFieldValue('0', itemId,
                  itemLanguage,
                  itemVersion, 
                  fieldId);
        }
    });

In the above snippet, you will see that I make a call to SetNewFieldValue. This is a global function I wrote that facilitates the actual call to the Sitecore method. Having it as separate method allows the logic to be used across my site.

 function SetNewFieldValue(newFieldValue, itemId, itemLanguage, itemVersion, fieldId) {
  //Create the JS Item Uri Object...the last parameter is a revision, which we don't have easy access to so blank is passed in.
  var scItemUri = new Sitecore.ItemUri(itemId, itemLanguage, itemVersion, '');
  Sitecore.WebEdit.setFieldValue(scItemUri, fieldId, newFieldValue);
}

You may have noticed that setFieldValue has a parameter called scItemUri but we are not generating this value at render via something like Sitecore.Context.Item.Uri. That is because setFieldValue is expecting a JavaScript object, which we can create via the call to Sitecore.ItemUri.

This little bit of JavaScript then allows are edit experience to become

Enhanced Editing inline

Bonus – Information For the multi-select

At base of any multi-select type field is a simple pipe-delimited string of item GUIDs. This simplicity of data storage means we can leverage our SetNewFieldValue method, by simplify passing in a newly generated pipe-delimited string of selected items.

The following is useful for very small multi-select list, such as for taxonomy usage, but has the possibility of significantly effecting the performance of the Experience Editor, so be smart about how you apply the following.

To make this happen, within in the associated controller for the rendering we load up all the items normally associated to the pick list in some sort of Name-Value pair, collecting the name and ID of each item. As part of this you’ll also need to indicate what values are currently selected…my code looks like this and leverages a custom object for the name-value pair.

//C# Controller code
//Setup Category Lists
viewmodel.CategoriesListEditing = new List();
var allCategories = Sitecore.Context.Database
.SelectItems(Sitecore.Context.Site.RootPath + "/Content Taxonomy[@@templateid='{30D58A48-789D-49D2-BBEE-360E5DB10A68}']/*").ToList();
if (allCategories.Any())
{
   var hasCategories = viewmodel.NewsandAnnouncementCategory != null && viewmodel.NewsandAnnouncementCategory.Any();
   foreach (var cat in allCategories)
   {
      viewmodel.CategoriesListEditing.Add(new NameValuePairObject(
       cat.Fields[TaxonomyItemConstants.TaxonomyNameFieldId].Value,
       cat.ID.ToString(),
       !hasCategories?false: viewmodel.NewsandAnnouncementCategory.Any(cv => cv == cat.ID.ToGuid())));
   }
}

This is rendered out into a checkbox list, whenever a box is clicked this trigger the following method.


jQuery('.newscatcheckbox', namespace).click(function () {
    var itemId = jQuery(this).attr('data-itemid');
    var itemLanguage = jQuery(this).attr('data-language');
    var itemVersion = jQuery(this).attr('data-version');
    var fieldId = jQuery(this).attr('data-fieldid');

    var idList = "";
    //Get all checkboxes and determine if the item is selected
    jQuery('.newscatcheckbox', namespace).each(function (index) {
        if (jQuery(this).prop('checked')) {
            if (idList !== '') idList += '|';
            idList += jQuery(this).attr("id");
        }
    });
    SetNewFieldValue(idList, itemId, itemLanguage, itemVersion, fieldId);
});

Finished

That’s all it took to enhancing the Experience Editor one step further for your authors. Let me know if you try this out or have other suggestions that could be leveraged in enhancing the Experience Editor.

A Master Key to Your Content

Once in a while I find myself in a situation where workflow hasn’t been completed but users have begun content entry or cleanup. Normally these users also have not been setup as site admins, but with some level of custom accesses. This causes the editors to spend time dealing with locking and unlocking items for editing. At times they’ll not even realize and they locked the item, and you start to get a trail of items edited then forgotten.

What’s an admin to do?

Without too much work you can turn-on the gutter icon for ‘Locked Items’, then drill through the tree visual identifying and jotting down what’s locked and who.

Locked Items Gutter Setting

But that’s tedious (and a bit error prone). As with all cool administrative tasks in Sitecore we are best to turn our attention to Sitecore PowerShell Extensions (SPE) in the marketplace

The SPE ships with function that gives us the ability to see and react to locked items on our site.

Get-LockedChildItem

Step 1 – Import Function

By default the function Get-LockedChildItem is not callable. You must first ‘import’ it into your console or ISE session.

Import-Function Get-LockedChildItem

 Import-Function Get-LockedChildItem

If you don’t perform an import of the function, then you’ll receive a red error message like the following

Get-LockedChildItem : The term ‘Get-LockedChildItem’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

Step 2 – Get a Report

Before performing any sort of automation on our content tree, we should always produce a report that provides some context of what may get changed. In this case we want to get a listing of all items that are locked

Get-LockedChildItem -Recurse | Show-ListView

Here we are using the ‘Recurse’ flag to walk the entire tree. The collection of items locked are then piped to the very nice Show-ListView, allowing for easy review and export.

Get-LockedChildItem as a Report

We can also run the report for specific users via the -LockedBy parameter

Get-LockedChildItem -Recurse -LockedBy 'sitecore\editor' | Show-ListView

Step 3 – Time to Free the Content

Once we understand who has what locked we can start performing some mass freeing of content with the -Unlock parameter. To unlock everything, we run

Get-LockedChildItem -Recurse -Unlock

If we want to perform some hand picking of section of the site, we can either open the console to a certain node of the tree and run the above or define the start point with -Path parameter. This will unlock all the children of the item defined by path, even providing a nice output of what was unlocked.

Get-LockedChildItem -Recurse -Unlock -Path {85E0AF8C-ED9F-4CDA-BFB2-084015E17634}
#or
Get-LockedChildItem -Recurse -Unlock -Path /sitecore/content/Coffeehouse/Home/About-Us

Unlock for a path

Finally, if we want to unlock for a specific individual we can re-use the -LockedBy parameter,

Get-LockedChildItem -Recurse -Unlock -LockedBy 'sitecore\editor'

Not a Replacement for workflow (i.e. the Disclaimer)

Being able to execute unlocking of content on a mass scale is helpful, but this shouldn’t be the replacement for properly planned and built workflow on your site.

Load Test from the Cloud

Building a any application, but especially high traffic websites on Sitecore one of the final steps before launch is to tune ensure any caching mechanisms have been properly tuned to support the needs of the organization.

One of the difficulties my teams always have is finding a server or two or three with enough available horse power to pound on out site. Running from a simple local machine is good enough for about 2 minutes until it begins heating the entire office.

But this headache and a more reasonably temperature office exists. How did we achieve this utopian level? Through the cloud of course…Visual Studio Team Services to be specific, by the way it’s free to register and take advantage of even.

Visual Studio Team Services provides a number of different tools and services, many for free such as GIT repos, CI, team and task management. One of the services provided is the ability to run scaled load testing from the cloud. Depending on your needs, you have the opportunity to run four types of tests from VSTS, Visual Studio Test, HTTP Archive Based Test, URL Based Test, Apache jMeter Test.

Load Test Options

Two things I found great about the service is, A) I get a decent number of free testing units (called Virtual User Minutes) to perform my testing, and B) I don’t have to purchase a high level MSDN or Visual Studio license. Why? Because it supports my tool of choice Apache’s jMeter.

As easy as 1, 2, 3

I can build and even pre-test my jMeter test scenarios on my local or internal hardware to confirm it generates the proper simulated traffic. After this is as easy as 1,2,3,4..and maybe a 5th step.

  1. Login to Visual Studio Online
  2. Click over to the Load Test screen
  3. Create a new test of type jmeter from the selector
  4. Upload the jmx file representing you developed jMeter scenario
    Load Test Options
  5. Upload your jmx file that defines your test run. Note, that the name of the file is the name the test will be referenced in the other screens.
  6. Set yout number of agents, length of run, and region the test should run from.
  7. Click Run
    Load Test Setup
  8. Smile and sip your coffee as the data pours into convenient charts and table.

Not Accessible to the World, yet?

If your site is sitting behind a firewall and only has internal DNS, with some additional setup you can still leverage the power of the cloud to perform your test, Testing private/intranet applications using Cloud-based load testing.

Testing Sitecore

For testing Sitecore load check-out this pre-started jMeter test provided by Sitecore themselves https://kb.sitecore.net/articles/398589. One thing to note if you would also like to test out or populate out xAnalytics data you will want to disable robots detection via the following patch config. Robots detection needs disabled as the tester does not trigger page events as required by xAnalytics for identifying a ‘human’ user. (Just be sure to turn it back on before site launch.)

<! --  ANALYTICS ROBOTS IGNORE ROBOTS    
    Ignore requests and do not write information to the Analytics 
        database when the visitor       
        classification identifies the visitor as a robot.   
    Default: true
 -- >
<setting name="Analytics.Robots.IgnoreRobots">
    <patch:attribute name="value">false</patch:attribute>
</setting>

If data still isn’t properly collecting you may also need to tweak the robot’s timeout value to allow the session to run longer.

<! --  ANALYTICS ROBOTS SESSION TIMEOUT 
        The ASP.NET Session Timeout for auto detected robots.
        When the automatic robot detection identifies a session as 
        being a robot, the ASP.NET Session Timeout 
        is set to this value (in minutes).  
    Default: 1  
-- >
<setting name="Analytics.Robots.SessionTimeout">
    <patch:attribute name="value">5</patch:attribute>
</setting>

Its that simple, and now there is no longer any reason to avoid even basic site load tests for Sitecore or any other application.

During my exploration of leveraging this cloud based load testing I found the following links to be informative:

Planning for Cache in Sitecore

This is a follow-up to my Unofficial Sitecore Planning Checklist, where I try to consolidate as much information as I can find on Sitecore’s built in caching.

One of the easiest ways to improve a visitor’s perceived impression of any website visit is through a well-tuned cache. A cache which has been properly tuned will be able to server of requested content quicker, sometimes magnitudes faster than rebuilding the HTML for a page on each request.

Sophisticated caching scenarios can be configured through third-party tools and applications, but even for the most highly trafficked site properly tuning Sitecore’s different cache options should provide the desired performance gains. As site cache is configured and tuned, be aware the need for vertical or horizontal scaling may become necessary. (For details on scaling Sitecore checkout Scalability)

Determine the cache limits required

The general practice for Sitecore caching tuning is to turn all cache limits off via the following simple cache patch config:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <settings>
      <setting name="Caching.DisableCacheSizeLimits">
    <patch:attribute name="value">true</patch:attribute>
    </settings>
  </sitecore>
</configuration>

With the cache limits now disabled, Sitecore will try to manage based on current traffic and available resources to cache as much as possible. By performing well structured load test or allowing the site to run in this manner, the team should monitor both server resource utilization as well as the Sitecore cache levels to determine areas that should be manually limited to maximize performance.

To monitor what Sitecore has cached you can use the Sitecore admin page, http://&lt; your domain >/Sitecore/admin/cache.aspx, or leverage the Sitecore Marketplace module Caching Manager, https://marketplace.sitecore.net/en/Modules/Caching_Manager.aspx.

Cache Manager Options

After data collection has occurred you are ready to begin to evaluate which caches need their limits adjusted from the default level. For more information on the different cache limits that can be set see Sitecore CMS 7.0 – 7.2 CMS Performance Tuning Guide.pdf and Sitecore CMS 6.6 or later Cache Configuration Reference.pdf.

Configuring HTML Cache of Components

The first level of caching to configure to is review each rendering that is created and set the appropriate HTML level caching on it.

Rendering Cache Option

To turn HTML cache on for the rendering, select the first option Cacheable. From here you can customize the how different variations of the control should be cached via the different ‘Vary By’ options. Finally, you can mark that all cache be cleared when the search index is updated via the ‘Clear on Index Update’ selection.

The following fuller description of each cache option is taken from Chapter 4: Output Caching in Sitecore CMS 7.0 or later Presentation Component Reference.pdf.

Clear on Index Update

The Clear on Index Update property controls whether or not a control clears its cache when an item that is associated with the control is updated in the index. This is useful for any control that uses the new Search API to populate its data sources. For example:

  • You have a control that returns all the products that are on special offer from the index.
  • The Clear on Index Update property for this control is set to True.
  • The price of each product is stored in the index.

If someone updates the price of one of the products on special offer, the Clear on Index Update property will the trigger the control to clear its cache because something has been updated in the index that is bound to the control.

VaryByData

The VaryByData property controls whether or not output caching varies based on the data source of the presentation component.

Set the VaryByData property:

  • To False for components that do not generate different output when used with different data sources.
  • To True for components that generate different output when used with different data sources.

VaryByDevice

The VaryByDevice property controls whether or not caching varies based on the name of the context device.

Set the VaryByDevice property:

  • To False for components that do not generate different output when used with different devices.
  • To True for components that generate different output when used with different devices.

VaryByLogin

The VaryByLogin property controls whether or not output caching varies based on whether or not the user has authenticated. For caching configuration involving the VaryByLogin property, the layout engine treats all anonymous users as a single authenticated user.

Set the VaryByLogin property:

  • To False for components that do not generate different output for authenticated than for unauthenticated visitors.
  • To True for components that generate different output for authenticated than for unauthenticated visitors.

VaryByParm

The VaryByParm property controls whether or not output caching varies based on rendering parameters passed to the presentation component. Solutions built with earlier versions of Sitecore may have used the token VaryByParam instead of VaryByParm. Update any instances of VaryByParam to VaryByParm.

Developers set the VaryByParm property:

  • To False for components that do not generate different output when passed different rendering parameters.
  • To True for components that generate different output when passed different parameters.

VaryByQueryString

The VaryByQueryString property controls whether or not output caching varies based on query string parameters passed in the URL. The VaryByParm property causes output caching to vary based on rendering parameter values passed by the developer. The VaryByQueryString property causes output caching to vary based on parameters passed in the URL query string.

Developers set the VaryByQueryString property:

  • To True for components that generate different output when supplied different query string parameters.
  • To False for components that do not generate different output when supplied different query string parameters.

VaryByUser

The VaryByUser property controls whether or not output caching varies by the domain and username of the context user.

Developers set the VaryByUser property:

  • To False for components that do not generate different output for different users.
  • To True for components that generate different output for different users, when the number of active users between publishing operations is relatively small. The VaryByUser treats all anonymous users as a single authenticated user.

To avoid excess memory consumption, avoid using the VaryByUser property except in solutions with relatively small numbers of users, or monitor cache utilization closely. The VaryByLogin property causes Sitecore to generate different output depending based on whether or not a user has authenticated, differentiating anonymous users from authenticated users. The VaryByUser property causes Sitecore to generate different output for each user

Other Caches

Sitecore contains a number of other caches that help to lower the number of calls required to the database for item information and indexes. These are best described in a post from the Sitecore Tactics blog entitled How Sitecore caching work.

Additional Helpful references

One Final Note

Starting in Sitecore 8.2, the Cache APIs where refactored, creating breaking changes to any custom cache providers used in previous versions. Be sure to check out the change list, https://doc.sitecore.net/sitecore_experience_platform/developing/developing_with_sitecore/cache_api_changes.