Unpublish a Sitecore item

Any regular Sitecore users knows there are many ways to publish an item. However it’s not always obvious how to “unpublish” an item. Its actually quite straight forward.

1. Navigate to the item you want to unpublish using the Content Editor. From the Publish ribbon select the Change button:

In change dialog, make the item unpublishable by deselecting the Publishable checkbox:

The content editor will display are warning informing you what’s about to happen.

The final step to actually publish the item and it will disappear from the front-end but remain in the master database. This may sound strange, but as the item is already published we need to publish again to remove it from the web database.

Sitecore Habitat Installation Issues

I’ve recently attempted to setup a Sitecore Habitat solution by following instructions from the GitHub site.

This was not as straight forward as I’d hoped. The following are some issues I had to resolve along the way.

Web Forms For Marketers

Ensure this is installed correctly and working. Although I had installed the module and it appear to be successful, when I checked System/Modules/Web Forms for Marketers items were missing. The problem didn’t become apparent until Unicorn tried to sync items relating to WFFM.

I also discovered although it’s not mentioned in the Habitat documentation MongoDB is required for WFFM to work correctly with Habitat.

NodeJS

After installing NodeJS I ran npm install from the root of the Habitat repository as instructed. However this kept failing while trying to install node-sass with a 404 error. Running npm install node-sass to manually install the package before running npm install resolved the issue for me.

Editing repository files

Make sure any files you’ve been editing are not open by another application

Unicorn Sync

Although the sync process should work fine through Visual Studio Task Runner. I found it more successful to run it through a command prompt using gulp.\

Gulp

Even after a success npm install I received a gulp command not found error when running gulp from a command prompt. Running npm install –global gulp-cli in the repository root resolved the problem.

 

Sitecore items not visible on website

Sometimes you may find an item appears in both the master and web database’s. But when you navigate to that item on the live website site either a 404 returned, or in the case of a component it’s not visible.

This could be because the item has publishing restrictions in place. There’s a few places to check:

  1. Log into Sitecore.
  2. Open the Content Editor.
  3. Select the View tab and ensure Standard Values is checked.
  4. Navigate to the offending item using the content tree and select it.
  5. Using the right panel scroll down to the Publishing section.
  6. Check the dates are either empty or valid for displaying the item as of today.
  7. At the bottom of the Publishing section there is a Never Publish checkbox, make sure this is unchecked.

If workflow is in place it might be worth checking the Workflow selection for this item. The state field will highlight where in the workflow this item is. However if the item is’t approved it shouldn’t show in the web database.

If the above doesn’t help its worth republishing the item or its parent..

Sitecore generating Overlapping onDeckSearchers=x warnings in Solr logs

I’ve recently had an issue where every 10 minuets or so a entry would appear in the Solr logs. This was only an issue for the analytics core. After reading various articles and try different Solr configurations I failed to resolve the problem.

However after a chat with Sitecore Support the issue was resolved by a quick change to our Sitecore environment. Our production environment consists of four separate Sitecore instances, two delivery, one authoring and one processing server. By default Sitecore uses a Timed Index Refresh Strategy to update Solr’s analytics core. By having four environments pointing to the same Solr instance, the analytics core was being updated four times simultaneously.

When a processing server is being used only that should update the analytics core. In an environment without a processing server it would the possibility of authoring server.

To resolve the issue the processing server was left with the default Timed Index Refresh Strategy. Automatic updating of the analytics was disabled on the remaining three environments by changing the strategy to manual.

The strategies are set in the Sitecore.ContentSearch.Solr.Index.Analytics.config file. The default is:


<strategies hint="list:AddStrategy">
   <timed type="Sitecore.ContentSearch.Maintenance.Strategies.TimedIndexRefreshStrategy, Sitecore.ContentSearch">
      <param desc="interval">00:01:00</param>
   </timed>
</strategies>

To use a manual strategy remove the above from the config file and add:


<strategies hint="list:AddStrategy">
   <strategy ref="contentSearch/indexConfigurations/indexUpdateStrategies/manual" />
</strategies>

Rather than updating the config file a better solution would be creating a patch file. This way if the config file is replaced during an upgrade the config change will still be applied.

OctoPack NuGet versioning order

NuGet packages have version numbers. When you use OctoPack, the NuGet package version number will come from (in order of priority):

  1. The command line, if you pass /p:OctoPackPackageVersion= as an MSBuild parameter when building your project.
  2. If the [assembly: FileVersion] is the same as the assembly: AssemblyInformationalVersion, then we’ll use the [assembly: AssemblyVersion] attribute in your AssemblyInfo.cs file
  3. Otherwise we take the [assembly: AssemblyInformationalVersion].

Querying the Sitecore Reporting Database (xDB) Directly

While Sitecore provides comprehensive analytics from the main dashboard, there may be a requirement to interrogate the analytics data directly in your code. To do this we need to make use of Sitecore’s ReportDataProviderBase and ReportDataQuery classes. These provide access to the reporting database using the parameters set in the Sitecore.Analytics.Reporting.config.

Sitecore stores all it’s queries in items based in the ReportQuery template. As of Sitecore 8.1 these can be found at the following location Master/Web > sitecore > system > Settings > Report Queries.

First create a new ReportQuery item by duplicating an existing one. Open your new item and update the Query field with your own SQL query. Once complete save and publish taking note of the item ID.

Next create a method to run the query, below is a basic example:

        public void GetReportingData()
        {
            if (!String.IsNullOrEmpty(searchTerm))
            {
                using (var context = Index.CreateSearchContext())
                {
                    // By using the ReportDataProviderBase and ReportDataQuery Sitecore is instructed to use the Reporting (Analytics database)
                    // defined in the connectionStrings.config

                    // Create ReportDataProviderBase factory using connection info from Sitecore.Analytics.Reporting.config
                    var provider = (ReportDataProviderBase)Factory.CreateObject("reporting/dataProvider", false);

                    // Load SQL from Sitecore ReportQuery item
                    Item dataSourceItem = Context.Database.Items[ID.Parse("{id of ReportQuery item created above}")];
                    var dataSQLQuery = dataSourceItem.Fields["Query"].Value;
                    var query = new ReportDataQuery(dataSQLQuery);

                    // Run query using the FiltersFactory defined in the reporting node from the dataProvider node in the Sitecore.Analytics.Reporting.config
                    // in this case /sitecore/system/Settings/Analytics/Vendor Specific Filters/MSSQL
                    var response = provider.GetData("reporting", query, CachingPolicy.WithCacheDisabled);

                    // Populate list
                }
            }
            return list;
        }

Sitecore MVC Ajax POST to Controller

Using AJax to post to a controller using Sitecore MVC is a bit different to standard MVC. The following is example on how to do this. The main difference’s are the URL and data properties. With standard MVC the URL would be the controller name and Action i.e /MyController/MyAction and data would contain any variables which need passing into the action method. With Sitecore MVC we set the URL property to the current URL and pass the controller name and action in the data property.

First the controller action method, the controller is called MyController

[HttpPost]
public JsonResult MyAction(string myData)
{
   return Json(...)
}

Next the Javascript

$(function () {

    $(".my-action-invoker").click(function () {
    var my-data = $(this).find(".my-data").html();

    $.ajax({
        url: window.location.href,
        type: "POST",
        context: this,
        data: { scController: "MyController", scAction: "MyAction", myData: my-data },
        success: function (data) {
            // do stuff
        },
        error: function (data) {
            console.log("error", data);
        }
        });
    });
});

Managing Sitecore Config Files

Sitecore is a very configurable content management system. To simplify configuration management the final config file is created at runtime from a number of smaller config files. Theses are located under the/App_Config/include folder (Sitecore 7 or greater)

Sitecore applies the config files starting with those in the root of the include folder, followed by any sub folders in alphabetically order. So if you want to ensure custom config files are applied over any standard Sitecore one’s, create a folder which appears last and place your config files in there. Config files are also applied in alphabetical order so ensure the names reflect the processing order.

Adding a variable

  1. Create a config file with the appropriate name.
  2. Start the config file like :
    • <?xml version="1.0" encoding="utf-8" ?>
      <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
      
  3. Identify what setting you wish to add and where is should appear. The node is added using the patch keyword with the following options.
    • patch:before: Insert the element before the specified element.
    • patch:after: Insert the element after the specified element.
    • patch:instead: Replace the specified element.
    • patch:delete: Remove the specified element.
    • patch:attribute: Define or replace the specified attribute.

For example adding another site node

<sitecore>
  <sites>
    <site patch:before="*[@name='website']"
    name="XXXXX" virtualFolder="/site" physicalFolder="/site" 
    rootPath="/sitecore/content/newsite/" 
    contentStartItem="/sitecore/content/newsite/Home" 
    startItem="/home" language="en" contentLanguage="en"
    database="web" domain="extranet" disableClientData="false" 
    cacheHtml="true" htmlCacheSize="250MB" 
    cacheRenderingParameters="true" 
    renderingParametersCacheSize="100MB" allowDebug="true" 
    enablePreview="true" enableWebEdit="true" enableDebugger="true" 
    enableAnalytics="true" notFoundItem="/sitecore/content/newsite/Home"/>
  </sites>
</sitecore>

Replacing an attribute

While patch:attribute is available, we find set:value to be easier to parse. For that, you have to adjust the namespace at the top of the file to also include:

xmlns:set="http://www.sitecore.net/xmlconfig/set/"

After which, you can then edit with:

<sc.variable name="dataFolder"    set:value="E:\inetpub\sitecore.data" />

Create a Solr computed field in Sitecore for storing image url’s

The following is an example of a computed field class for indexing an image url. This assumes you have Sitecore items with an image field called Image.

using Sitecore.ContentSearch;
using Sitecore.ContentSearch.ComputedFields;
using Sitecore.Data.Items;

namespace SitecoreProject.Search.ComputedFields
{
    class CallToActionImageUrl : IComputedIndexField
    {
        public string FieldName { get; set; }
        public string ReturnType { get; set; }
        public object ComputeFieldValue(IIndexable indexable)
        {
            var scIndexable = indexable as SitecoreIndexableItem;
            if (scIndexable != null)
            {
                var item = (Item)scIndexable;

                if(item != null)
                {
                    if(item.Fields["Image"] != null)
                    {
                        Sitecore.Data.Fields.ImageField imgField = item.Fields["Image"];
                        if (imgField.MediaItem != null)
                        {
                            return Sitecore.Resources.Media.MediaManager.GetMediaUrl(imgField.MediaItem);
                        }
                    }
                }               
            }
            return null;
        }
    }
}

In addition to creating this class you also need to add following to the section of the Sitecore.ContentSearch.Solr.DefaultIndexConfiguration.config file. This will create a field in Solr called image_url.

<field fieldName="image_url" storageType="no">NorfolkSitecore.Search.ComputedFields.CallToActionImageAlt,NorfolkSitecore.Search</field>