tl;dr Putting config files in a folder under
/App_Config/Include causes them to be patched in last.
Following an answer by @Bruud on Stackflow a few months ago I found out that it is possible to organise patch config files much more neatly. It was also mentioned as a passing comment on one of the recent Google Hangout highlighting the changes in Sitecore 7.X.
I’ve just started working on a few project from existing vendors and noticed the common patch file naming convention to ensure custom changes are applied after the standard Sitecore configs in
It turns out that you can simply put your custom configs in a child folder and Sitecore will include them after any files in
So simple that I wondered why I hadn’t always been doing this!
Sitecore will patch the web.config with all config files within the App_Config/Include folder first and then recursively patch in from the config files in the other folders. From the Include File Patching Facilities document on SDN:
When Sitecore reads the include files, it traverses the file system recursively. Sitecore first enumerates all the *.config files in the /App_Config/Include folder and then recursively enumerates all the sub-folders. You should take this order into account when you create sub-folders in the /App_Config/Include folder.
As an added bonus, if you are using Sitecore 7 upwards then when you view your merged config (via
http://mysiteurl/sitecore/admin/showconfig.aspx or Sitecore Rocks) it now tells you where the patch has come from:
<event name="item:added"> <handler patch:source="MyCustomConfig.config" type="Sitecore.Data.Fields.ItemEventHandler, Sitecore.Kernel" method="OnItemAdded"/> <handler type="MyCustom.ItemEventHandler, MyCustom" method="OnItemAdded"/> <handler patch:source="Sitecore.EmailCampaign.config" type="Sitecore.Modules.EmailCampaign.Core.ItemEventHandler, Sitecore.EmailCampaign" method="OnItemAdded" /> </event>
You could put your configs in separate folders dependent on environment (e.g. dev, test, QA, UAT…) and excluding them using your build process. I prefer to use config transforms with SlowCheetah but use whatever meets your requirements.
You could also just set the hidden attribute of the file/folder since Sitecore makes a check and excludes config files which have the hidden attribute set – we’ve used this trick before when we were working directly out of the IIS folder and needed to exclude build configs. Some version controls systems strip away the hidden attribute when you check the file in, to get around this we ran post-build script to set the hidden flag again. Nowadays though, we are working in a separate folder and publishing into the IIS folder. Much simpler!
If you want to learn more about patching config files then read John West’s excellent blog post (which has further links)
Clean up your web.config
While you’re at it, you might as well extract out the AppSettings, Sitecore and Log4Net nodes into their own separate config files, working with a smaller and uncluttered config makes it much simpler to see what is going on, and upgrading Sitecore means just copying and pasting the entire Sitecore node from the updated config.
<connectionStrings configSource="App_Config\ConnectionStrings.config" /> <appSettings file="App_Config\AppSettings.Config"> <add key="EmailReminder.FromAddress" value="firstname.lastname@example.org" /> <add key="App.Key" value="1234567980" /> <add key="Custom.App.key" value="abcdefgh" /> </appSettings> <sitecore configSource="App_Config\Sitecore.config" /> <log4net configSource="App_Config\Log4net.config" /> <RequestReduce configSource="App_Config\RequestReduce.config" />
You can still use Winmerge or other file compare tools to see if anything else has changed in the config file (or look at the Sitecore upgrade notes), usually it is fairly minimal outside of the
sitecore node anyway.