Retrieving site information in Sitecore

Sitecore provides functions to get the root path and start item for the current context. So when working with multisite solutions you should always get a path relative to the Sitecore.Context.Site settings:

Response.Write("Current site: " + Sitecore.Context.Site.Name + "<br/>");
Response.Write("Database: " + Sitecore.Context.Site.Database.Name + "<br/>");
Response.Write("Content start path: " + Sitecore.Context.Site.ContentStartPath + "<br/>");
Response.Write("Home node: " + Sitecore.Context.Site.StartPath + "<br/>");
Response.Write("Language: " + Sitecore.Context.Language.GetDisplayName() + "<br/>");

The code above would give me the following output for the site at site1.mysite.com:

Current site: website_1
Database: web
Content start path: /sitecore/content/website1
Home node: /sitecore/content/website1/home
Language: English : English

Finding a Sitecore item by ID using a Solr query

By default the _group field contains the Sitecore ID for a specific item. To search for an item with an ID of {799539AB-3495-4D40-9B2F-A394A87960D6} use the following Solr query:

_template:”799539ab34954d409b2fa394a87960d6″

Please note the ID is not stored in the group field as a standard GUID. For the search to work hyphens need removing and converting to lower case.

However this will only work for an item with a single version and language. As Sitecore uses the same item for each piece of content, regardless of the number of versions or languages, the above query may return multiple results.

In this case we need to use the _uniqueid field to return the exact item representing a specific version and language. In this example we change the Solr query to:

_uniqueid:”sitecore://master/{799539ab-3495-4d40-9b2f-a394a87960d6}?lang=en&ver=1&ndx=sitecore_master_index”,

Dependency Inversion Principle, Inversion of Control and Dependency Injection

To understand Dependency injection (DI) we need understand two things. First Dependency Inversion Principle (DIP), second Inversion of Controls (IoC). We’ll start with DIP.

Dependency Inversion Principle

By conforming with the Dependency Inversion Principle guideline it allows use to write loosely coupled classes. The definition of DIP states:

1. High-level modules should not depend on low-level modules. Both should depend on abstractions.
2. Abstractions should not depend upon details. Details should depend upon abstractions.

The following is an example of a service which writes errors to a message log. The example consists of two classes, one writes messages to the error log, the other watches for errors being thrown by the system.

class WriteToErrorLog
{
	public void WriteEntry(string errorMessage)
	{
		// Write to error log here
	}
}

class SystemErrorWatcher
{
	// Handle for WriteToErrorLog to write error logs
	WriteToErrorLog writeToErrorLog = null;
	// This method will be called when the system encounters a problem
	public void Notify(string message)
	{
		if (writeToErrorLog == null)
		{
			writeToErrorLog = new WriteToErrorLog();
		}
		writeToErrorLog.WriteEntry(message);
	}
}

While this code is perfectly legit and deals with the job in hand, it violates DIP. The SystemErrorWatcher depends on the WriteToErrorLog class, which is concrete rather than an abstract class.

This wouldn’t necessarily be an issue if we stopped there. However we may want to introduce some extra functionality, such sending an email if a specific error occurs. We could create a SendEmail class who’s job is to send an emails. The handle could then be created in SystemErrorWatcher. But at any point in time we will only be using the WriteToErrorLog or SendEmail class.

DIP states we need to decouple a system so that higher level models such as the SystemErrorWatcher will depend on simple abstraction. This abstraction will be mapped to a concrete class which make things happen.

Inversion of Control

The IoC principle allows us to develop higher level modules which depend on abstractions rather than concrete classes.

So using IoC we amend the above example to decouple the SystemErrorWatcher class from the WriteToErrorLog class. To do this we need to create an interface which provides the abstraction to act upon notifications received from the SystemErrorWatcher.

public interface INofificationAction
{
	public void ActOnNotification(string message);
}

Next change the SystemErrorWatcher to use the above interface

class SystemErrorWatcher
{
           // Handle for WriteToErrorLog to write error logs
           INofificationAction doSomething = null;
           // This method will be called when the system encounters a problem
           public void Notify(string message)
           {
                  if (doSomething == null)
                  {
                         // We need to map the abstraction to the concrete class here
                  }
                   doSomething.ActOnNotification(message);
           }
}

To complete this change we now need to update the WriteToErrorLog class so it implements the new INofificationAction interface.

class WriteToErrorLog : INofificationAction
{
	public void ActOnNotification(string errorMessage)
	{
		// Write to error log here
	}
}

In addition to emails we may want to send an SMS. Now we’ve decoupled we can create two concrete classes, one for email the other SMS which both implement the INofificationAction interface.

class EmailSender : INofificationAction
{
	public void ActOnNotification(string message)
	{
		// Send email from here
	}
}
class SMSSender : INofificationAction
{
	public void ActOnNotification(string message)
	{
		// Send SMS from here
	}
}

By doing this the high level models are now dependent on lower level abstractions rather than concrete classes. This is exactly what dependency inversion principle states.

However we still have one piece of the puzzle missing, we never create the concrete type to make something happen. We could modify the class to look like this.

class SystemErrorWatcher
{
      // Handle for WriteToErrorLog to write error logs
      INofificationAction doSomething = null;
      // This method will be called when the system encounters a problem
      public void Notify(string message)
      {
            if (doSomething == null)
            {
                   // We need to map the abstraction to the concrete class here
                   writeToErrorLog = new WriteToErrorLog();
            }
            doSomething.ActOnNotification(message);
      }
}

But by doing this we’ve introduced another dependency. This is where Dependency injection comes in.

Dependency Injection

Dependency Injection is mainly used for injecting concrete implementations into a class which is using abstractions. This will allow us to reduce the coupling between classes and move the binding between interface and concrete class out of the dependent class.

DI come in three forms, Constructor Injection, Method Injection and Property Injection.

Constructor Injection

This allows use to pass in the concrete implementation to the dependent classes constructor. We then assign this the interface created with in this classes. By doing this we can pass in any concrete class which is implements the interface we need to bind to. In our example this will allow us to pass in WriteToErrorLog, EmailSender and SMSSender concrete classes as these all implement the INofificationAction interface.

class SystemErrorWatcher
{
      // Handle for WriteToErrorLog to write error logs
      INofificationAction doSomething = null;
      public SystemErrorWatcher(INofificationAction concreteImplementation)
      {
            doSomething = concreteImplementation
      }
      // This method will be called when the system encounters a problem
      public void Notify(string message)
      {
            doSomething.ActOnNotification(message);
      }
}

The calling class can now do

WriteToErrorLog writeToErrorLog = new WriteToErrorLog();
SystemErrorWatcher systemErrorWatcher = new SystemErrorWatcher(writeToErrorLog); 
systemErrorWatcher.Notify("Something has broken");

Now if we want to send an email instead of writing to the error log.

EmailSender emailSender = new EmailSender();
SystemErrorWatcher systemErrorWatcher = new SystemErrorWatcher(emailSender); 
systemErrorWatcher.Notify("Something has broken");

Method Injection

This is similar to Constructor Injection but this time we pass the concrete class to the method rather than constructor. We use this if we don’t want the dependent class to use the same concrete class for it’s entire lifetime.

class SystemErrorWatcher
{
      // Handle for WriteToErrorLog to write error logs
      INofificationAction doSomething = null;

      // This method will be called when the system encounters a problem
      public void Notify(INofificationAction concreteImplementation, string message)
      {
            this.doSomething = concreteImplementation
            doSomething.ActOnNotification(message);
      }
}

The calling class now becomes

WriteToErrorLog writeToErrorLog = new WriteToErrorLog();
SystemErrorWatcher systemErrorWatcher = new SystemErrorWatcher(); 
systemErrorWatcher.Notify(writeToErrorLog, "Something has broken");

Property Injection

If the responsibility of selection of the concrete class and invocation methods are in separate places, we need to use property injection.

Here was pass the concrete class via a setter that’s exposed by the dependent class. To do this the SystemErrorWatcher class will look like this.

class SystemErrorWatcher
{
      // Handle for WriteToErrorLog to write error logs
      INofificationAction doSomething = null;

      public INofificationAction DoSomething
      {
            get
            {
                  return action
            }
            set
            {
                  action = value
            }
      }

      // This method will be called when the system encounters a problem
      public void Notify(string message)
      {
            doSomething.ActOnNotification(message);
      }
}

The calling class

SystemErrorWatcher systemErrorWatcher = new SystemErrorWatcher();
systemErrorWatcher.DoSomething = new WriteToErrorLog();
systemErrorWatcher.Notify("Something has broken");

If we want to send an SMS.

SystemErrorWatcher systemErrorWatcher = new SystemErrorWatcher();
systemErrorWatcher.DoSomething = new SMSSender();
systemErrorWatcher.Notify("Something has broken");

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..

How to reset NVRAM on your Mac

Shut down your Mac, then turn it on and immediately hold down these four keys together:

Option, Command, P, and R.

Keep holding the keys for about 20 seconds, during which your Mac might appear to restart. (If you have a Mac that plays a startup sound when you turn it on, you can release the keys after the second startup sound.)

CSS and JS files not being served correctly by IIS

If you receive a warning that that CSS and/or JS files are being ignored due to incorrect mime type. It could be IIS is not serving static content. Another indication is a blank content type field for static content in the IE developer tools network tab.

To resolve the issue:

  1. Go to Control Panel > Programs and Features
  2. Click Turn Windows features on or off
  3. Expand World Wide Web Services > Common HTTP Features
  4. Tick Static Content
  5. Click OK

Another cause is CSS and JS mime types being incorrect registered on the IIS server.  To check open regedit, expand HKEY_CLASSES_ROOT, find .css and check/change the Content Type value to text/css. Repeat for .js where the Content Type value should be text/plain.