Experience Sitecore! | March 2015

Experience Sitecore!

Martin Miles on Sitecore

The quickest acceess to Layout Details dialog of Presentaion Details

This post going to be a quicke one. One of the most frequent screens I have to deal with in Sitecore is Layout Details dialog of Presentation Details:

I thought once, why not just to have the link to it from item's Context Menu? Sounds good, but, foirst of all, what is context menu?

Context Menu is just a set of Sitecore items under /sitecore/content/Applications/Content Editor/Context Menues/Default folder within core database. Each child item (except dividers) is derived from Menu Item template. The most interesting field there is Message - its value stores is nothing but just a Sitecore command with a parameter of current item (as all that happens in item's context).

Just want to remind - Sitecore commands are defined at <web_root>\App_config\Commands.config file, you may freely use any of them that start with item: (but not limited to that).

So, the only thing we need to do is to create an item under /sitecore/content/Applications/Content Editor/Context Menues/Default folder, and set its message to item:setlayoutdetails and that's it. Also you may configure Display name and the Icon to be shown next to that label within context menu (something like Applications/32x32/document_gear.png)

As soon as you return to master database, you'll get new context menu shortcut working:

This trick works on all versions of Sitecore. For lazy guys - here's a package for download that will do exactly the same - create Set presentation item for you within core database.

Hope this helps!

Debugging and inspecting Sitecore libraries

Debugging requires symbol files to present within a bin directory along. You have Sitecore libraries, and they are not obfuscated, so you may decompile and inspect the original code using various tools like Reflector. But you need PDBs to be able to to debug those libraries, for example perform step Into, watch and modify locals, set breakpoints and similar actions.

How to generate PDB files from assembly? There is a great (and free!) tool from JetBrains called dotPeek. As soon as you download and install it, you will be able to generate PDB from any non-obfuscated assembly with it. To do that, first specify the location where PDB are kept:

Also allow to debug "not just my" code -this will allow debugger to step into methods that are stored in other referenced libraries, of course of you have their PDBs in symbols folder, as set on previous step.

Now with dotPeek we'll generate PDB under the same path previously set in Visual Studio where it will seek for symbols. Open library in dotPeek, right click its context menu and select Generate PDB, as on a screenshot below:

Remember path should be the same:

Congratulations! Now you can debug that DLL and get more understanding of how Sitecore works internally especially when sometimes you may need to override its functionally and implement your custom logic based on that.

Important! On the recent versions of Sitecore, especially Sitecore 9 or newer you may experience troubles with stepping in withing Sitecore.Kernel library. That happens due to that with time it has been more and more rewritten to rely on Sitecore.Abstractions so you will need to generate PDBs and de-optimize that one as well.

You are now able to debug the code, step into the functions and investigate the logic as the code runs. But you may not still get the entire experience as if you were debugging your own code - due to optimization. To overcome optimization you need to start Visual Studio as Administrator with setting a specific environment variable:
set COMPLUS_ZapDisable=1
cd /d "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE"
start devenv.exe
Next, for each DLL you are about to explicitly disable optimisation, you need to accompany with a *.ini file having the same name and the following instructions (example for Sitecore.Kernel.ini):
[.NET Framework Debugging Control] 
Finally, as ReSharper is your permanent friend, you'll find the most convenient way to inspect the code by using its Assembly Explorer:

Hope this helps!

How websites are resolved with Sitecore - the essentials

What actually happens when you type website URL in browser and how is your request factually served in sitecore. We are going to use www.site.com as the URL for our example. This is simplified version where only most important steps are covered.

First of all, as you hit this URL in browser's address bar, it retrieves IP address by the host name from DNS server. Then it creates request to IP address resolved with host name (www.site.com) in HTTP header. There may be multiple traffic managers / load balancers on the route to the server, but eventually request gets to that IP address to the specified port (as we use normal HTTP, then the port is default 80).

On the server computer there should be specific software running and listening to that port (80) otherwise request will fail. In our scenario, that is the Microsoft IIS web server. Below are two most important IS configuration screens:

On the first screenshot you see Site Bindings screen that binds exact website within current IIS instance to specific port and hostname (if set). There can be multiple website hosted within same IIS instance, so you we usually vary them by hostname / port combinations. The example above shows that all requests to port 80 with the hostname www.site.com would be served by current website. Second record shows that all requests to port 443 (which is default to HTTP) would be served by the same site as well.

The second screenshot assigns our website www.site.com to a folder on a disk drive which becomes a web root for our site.

Root of the website should have a configuration file called web.config, that may be split and overridden in subfolders and that itself overrides global web.config and machine.config files with default settings. Every sitecore-based website contains <sitecore> node in the configuration file, that is where all sitecore settings are defined, including <sites> node that specifies all the websites per current Sitecore instance.

Important to note that sites are determined by "first match" principle, so order is critical. If you look at our www.site.com record - you'll notice that it specifies hostname - all requests matching that name will be served by this site. Other setting set what database is used for particular site (name should match database name from connection string), what is starting sitecore tree node within that database - factual page item that is being returned. There are also html caching setting, sitecore domain name for the site, etc.

The rest of request to current Sitecore instance, that do no math our host name pattern will be served by site called "website", it does not have hostName specified, so it will serve everything else and return /sitecore/content/home item.

Let's assume the site has been published from master database to web database, as per configuration. Here's below how sitecore tree looks like in Sitecore Content Editor:

Our website's home item (selected) is called SiteCom and it will return the page with "www.site.com"in title. Let's see the browser:

Here we done. That is our www.site.com landing page loaded!

Advanced topic: How to host several sites within the same Sitecore instance without specifying a hostname, just on different ports