sitecore

Sitecore Conditional configs: deploy just 1 package

by Chris van de Steeg. 2 Comments

When deploying Sitecore to your DTAP environment, you will always need a separate set of configuration files per environment.
One solution to accomplish is this, is to use web.config transforms with slowcheetah.
What I personally dislike about this approach, is that you have to create separate builds per environment.

That is why we at eFocus came up with a different approach: conditional configs.
With conditional configs, you create separate config files per environment, and then specify which config file applies to which environment by using filters inside config file itself. The current available filters are machinename and installpath (if you need any other filters, let me know, the current two work for all our environments).
Now you can create a deploy package for you entire sitecore folder, including all configs. The configs will only apply if the filter matches at sitecore startup.

The patch system works exactly like you are used to from the sitecore include configs.
You just have to place them in a separate folder named include-conditional.

Also, we have built in 2 extra config options: files having the name of the rootnode set to “connectionStrings”, will patch your web.config’s connectionstring section
and files with rootnode “mailSettings” will patch your mailsettings section of the web.config.

You enable the conditional configs by either installing the nuget package Efocus.Sitecore.ConditionalConfig or by downloading the source from https://github.com/efocus-nl/efocus.sitecore.conditionalconfigs and include it in your project.
You have to patch your sitecore’s web.config on only one place, you have to place

    

instead of

  

Sample of how your condtional configs in app_config/Include-condtional might look:

< ?xml version="1.0"?>

  
    
    

    
    
    
    
  

As you can see on the rootnode, it has a condition “machinename”. This is a regular-expression, matched against the computer name at sitecore startup.
The other option is, like noted above, to match the installpath:

< ?xml version="1.0" encoding="utf-8"?>

  
  
  

In this case, there are two conditions, they have to match BOTH

Well, that’s all there is to it. If you have an opinion or question, leave a comment

Sitecore MVC in a multisite environment: area’s

by Chris van de Steeg. 0 Comments

If you are creating a multisite environment using Sitecore & MVC (or any MVC site for that matter), chance is you have to do some weird naming in your controllers to avoid naming conflicts.

This is why Microsoft introduced area’s in their implementation of MVC (as did others before them)

Using them in Sitecore is actually pretty easy, thanks to (again) sitecore’s flexible pipilines.

First, we extend the Initialize pipeline with our own step:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <!-- Loader -->
      <initialize>
        <processor type="BoC.Sitecore.Pipelines.InitializeRoutes, Thieme.Framework" />
      </initialize>
    </pipelines>
  </sitecore>
</configuration>

Then add our class to the project:

using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Sitecore.Configuration;
using Sitecore.Mvc.Configuration;
using Sitecore.Pipelines;

namespace BoC.Sitecore.Pipelines
{
    public class InitializeRoutes
    {
        public virtual void Process(PipelineArgs args)
        {
            var scRoute = RouteTable.Routes[MvcSettings.SitecoreRouteName] as Route;
            var indx = RouteTable.Routes.IndexOf(scRoute);
            AreaRegistration.RegisterAllAreas();
            foreach (var info in Factory.GetSiteInfoList())
            {
                if (info.Properties["mvcArea"] != null)
                {
                    var newRoute = new Route(scRoute.Url, 
                        new RouteValueDictionary(scRoute.Defaults), 
                        new RouteValueDictionary(scRoute.Constraints), 
                        new RouteValueDictionary(scRoute.Constraints), 
                        scRoute.RouteHandler);
                    newRoute.DataTokens.Add("area", info.Properties["mvcArea"]);
                    newRoute.Constraints.Add("sc-issite", new IsCorrectSiteContraint(info.Name));

                    if (info.Properties["mvcNamespaces"] != null)
                    {
                        newRoute.DataTokens["Namespaces"] = info.Properties["mvcNamespaces"].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        newRoute.DataTokens["UseNamespaceFallback"] = false;
                    }

                    RouteTable.Routes.Insert(indx, newRoute);
                }

            }
        }

        public class IsCorrectSiteContraint : IRouteConstraint
        {
            private readonly string _siteId;

            public IsCorrectSiteContraint(string siteId)
            {
                _siteId = siteId;
            }

            public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
                RouteDirection routeDirection)
            {
                return global::Sitecore.Sites.SiteContext.Current.Name == _siteId;
            }
        }
    }
}

Now what this code does, is to add a route to the routecollection for every Sitecore-site configured. It uses a routeconstraint to validate if the route is applyable for the current request. If it is applyable the property ‘mvcArea’ of the configured website is set as the MVC area for that request. So, we will have to extend the <site> tag of the sitecore configuration with an mvcArea attribute, like so:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <sites>
      <site  mvcarea="Corporate" mvcnamespaces="Corporate.Framework.*,Website.Corporate.*" language="nl-NL" content="web" database="web" scheme="http" patch:before="site[@name='website']" name="Corporate" hostname="coporate.com" targethostname="coporate.com" virtualfolder="/" physicalfolder="/" rootpath="/sitecore/content/Corporate" startitem="Home" allowdebug="true" cachehtml="true" htmlcachesize="10MB" enablepreview="true" enablewebedit="true" enabledebugger="true" disableclientdata="false" />
    </sites>
  </sitecore>
</configuration>

As you can see, we also specify “mvcnamespaces”, although these are optional, it allows you to tell MVC where to look for your controllers.

It’s this easy. So now you’re ready to go and create your controllers & views in the correct manner. Don’t forget to place your views in the correct folder (in this case: areas\corporate\views\)

eFocus crawler based Lucene Websearch for Sitecore (open source!)

by Chris van de Steeg. 2 Comments

If you work with Sitecore 7, you probably know that Sitecore 7 has greatly improved the search capabilities. But still, there is no native way to search through your generated html. There are several paid solutions like the dtSearch module for sitecore, but still, they all feel not to deepily integrated with Sitecore.

At eFocus we created our custom Websearch module, which crawls your website (or any website) and then adds the html content to your Sitecore Lucene index. It’s a total integrated Sitecore solution, so configuring and using it is a piece of cake.

The project uses (a slightly modified version of) the awesome NCrawler for the crawling part.

Go checkout the module at the Sitecore Marketplace or take a look at the source on GitHub