Sitecore 9 installation and configuration nuts & bolts.

Now in Sitecore 9 version we have very good out of the PowerShell based installation/provisioning framework.

Even other than installation framework we have some more rich features, but we will not cover these features in this article.

Following are the minimum Prerequisites:

  1. Windows 8.1, 10, Server 2012 R2
  2. SQL Server 2016 or greater
  3. .Net Framework 4.6.2
  4. IIS 8.5 or 10
  5. Java Runtime Enviroment (JRE)
  6. Microsoft Powershell 5.1+
  7. Web Platform Installer 5.0
  8. Web Administration Module(IIS) Default in IIS 8.5/10
  9. Web Deploy 3.6 for Hosting Servers
  10. URL Rewrite 2+
  11. Microsoft SQL Server Data-Tier Application Framework (17.1)
  12. Microsoft SQL Server Transact-SQL ScriptDom

Step 1 : Install web deploy 3.6 for hosting servers

1

Open IIS manager and click on “get new web platform components” in right hand panel.

Step 2 :  Solr server installation–

Easy way to install Solr we can use the PowerShell script provided by Kamsar.

https://gist.github.com/kamsar/ef8811bd458603f1e808

Step 3 :  Create installation folder–

To install Sitecore, we must create a folder on our local drive with all the installation files, provided by sitecore.

  • Please download the Sitecore installation files from Sitecore Dev portal – https://dev.sitecore.net/Downloads/Sitecore_Experience_Platform.aspx
  • Download the  Packages for XP Single (XP0) Instance configuration.
  • Copy your license file into the folder.
  • Extract the  ‘XP0 Configuration files rev.xxx.zip’ and copy all the config files into the install folder

2

Step 4 :  Enable Contained Database Authentication by opening up SQL Server as an Administrator and executing the following script query:

sp_configure ‘contained database authentication’, 1 GO RECONFIGURE  GO

Step 5 :  Install the Sitecore Installation Framework (SIF)–

We can download from Stecore Dev portal or we can install from Sitecore nuget repository also.

https://dev.sitecore.net/Downloads/Sitecore_Installation_Framework/1x/Sitecore_Installation_Framework_12.aspx

We will use the following commands to install the latest version of SIF:

Register-PSRepository -Name SitecoreGallery -SourceLocation https://sitecore.myget.org/F/sc-powershell/api/v2

Install-Module SitecoreInstallFramework

Update-Module SitecoreInstallFramework 

Install-Module SitecoreFundamentals.

Import-Module SitecoreFundamentals

 3

Step 6:-Create the installation PowerShell script  using SIFLess

Download the SifLess framework from here http://www.rockpapersitecore.com/2017/10/introducing-sif-less-for-easy-sitecore-9-installation/

Run the SIFLess application as administrator.

  • Select the Licence, config.sitecore/xconnect package from the folder location create in step -3.
  • In install prefix you can add text for sitename prefix.
  • Configure the solr/database setting
  • 4
  • Click on test button and if it is successful than click on the generate files button to create the final installation power shell script file.
  • Find the installation PowerShell script in Sifless folder and run the script to install the Sitecore 9.
  • 5

Sitecore installation script generated by Sif-Less :

Import-Module SitecoreInstallFramework
$prefix = “Sitecore9”
$PSScriptRoot = “D:\Sitecore\Sitecore9\SC-9-171219\XP0 Configuration files 9.0.1 rev. 171219”
$XConnectCollectionService = “Sitecore9.xconnect”
$sitecoreSiteName = “Sitecore9.sc”
$SolrUrl = “https://localhost:8983/solr”
$SolrRoot = “C:\Bitnami\solr-6.6.1-0”
$SolrService = “solrJetty”
$SqlServer = “LP-5CD6255WJW\SQLEXPRESS”
$SqlAdminUser = “sa”
$SqlAdminPassword=”test@2012″

#install client certificate for xconnect
$certParams = @{
Path = “$PSScriptRoot\xconnect-createcert.json”
CertificateName = “$prefix.xconnect_client”
}
Install-SitecoreConfiguration @certParams -Verbose
#install solr cores for xdb
$solrParams = @{
Path = “$PSScriptRoot\xconnect-solr.json”
SolrUrl = $SolrUrl
SolrRoot = $SolrRoot
SolrService = $SolrService
CorePrefix = $prefix
}
Install-SitecoreConfiguration @solrParams
#deploy xconnect instance
$xconnectParams = @{
Path = “$PSScriptRoot\xconnect-xp0.json”
Package = “D:\Sitecore\Sitecore9\SC-9-171219\Sitecore 9.0.1 rev. 171219 (OnPrem)_xp0xconnect.scwdp.zip”
LicenseFile = “D:\Sitecore\Sitecore9\SC-9-171219\license.xml”
Sitename = $XConnectCollectionService
XConnectCert = $certParams.CertificateName
SqlDbPrefix = $prefix
SqlServer = $SqlServer
SqlAdminUser = $SqlAdminUser
SqlAdminPassword = $SqlAdminPassword
SolrCorePrefix = $prefix
SolrURL = $SolrUrl
}
Install-SitecoreConfiguration @xconnectParams
#install solr cores for sitecore
$solrParams = @{
Path = “$PSScriptRoot\sitecore-solr.json”
SolrUrl = $SolrUrl
SolrRoot = $SolrRoot
SolrService = $SolrService
CorePrefix = $prefix
}
Install-SitecoreConfiguration @solrParams
#install sitecore instance
$sitecoreParams = @{
Path = “$PSScriptRoot\sitecore-XP0.json”
Package = “D:\Sitecore\Sitecore9\SC-9-171219\Sitecore 9.0.1 rev. 171219 (OnPrem)_single.scwdp.zip”
LicenseFile = “D:\Sitecore\Sitecore9\SC-9-171219\license.xml”
SqlDbPrefix = $prefix
SqlServer = $SqlServer
SqlAdminUser = $SqlAdminUser
SqlAdminPassword = $SqlAdminPassword
SolrCorePrefix = $prefix
SolrUrl = $SolrUrl
XConnectCert = $certParams.CertificateName
Sitename = $sitecoreSiteName
XConnectCollectionService = “https://$XConnectCollectionService”
}
Install-SitecoreConfiguration @sitecoreParams

PowerShell version Problem

As you see that showing the PowerShell 5.1 required as per sitecore prerequisite also. In my Laptop I have Window 10 Powershell version 5.0 and to install sitecore 9 with the powershell 5.0 I have made some changes in SIF config file.

Solution

Go to this location

C:\Program Files\WindowsPowerShell\Modules\SitecoreInstallFramework

6

Open the file “SitecoreInstallFrameworkpsd1” change the powershell version value 

Problem- Solr 6.6.1 Version BaseConfig file location: In Solr 6.6.1 version baseconfig file location is “apache-solr/server/solr” location

Solution: Change this parameter in Sitecore-solr and xconnect-solr json files

Solr.Server”:      “[joinpath(variable(‘Solr.FullRoot’), ‘apache-solr’,’server’, ‘solr’)]”,

 7

 

Website physical path parameter : If you want to use other than C:/inetpub/wwwroot path than change this parameter in “sitecore-XP0.json” file.

Site.PhysicalPath”: “[joinpath(environment(‘SystemDrive’), ‘inetpub’, ‘wwwroot’, parameter(‘SiteName’))]”

Problem:- After running the installation script it may be possible that we got some error like “ unable to execute becoz it is use by another process” or due to some configuration issue

To resolve this issue, we have to manually delete the given below db and stop these two web applications (Sitecore9.sc and sitecore9.xconnect) :

Note* In my Sitecore 9 installation I have repeat this steps 3 times and in fourth time its successfully installed the Sitecore 9 

USE master ; 

GO 

DROP DATABASE Sitecore9_MarketingAutomation, [Sitecre9_Processing.Pools], Sitecore9_ReferenceData, [Sitecore9_Xdb.Collection.Shard0], [Sitecore9_Xdb.Collection.Shard1], [Sitecore9_Xdb.Collection.ShardMapManager], Sitecore9_Core, Sitecore9_ExperienceForms, Sitecore9_Master, xp0_Reporting, Sitecore9_Web

Go.

Post-Installation step:

On the Start menu click Run. >>  In the Open box type cmd, and then click OK to open a Command Prompt window >>
At the command prompt, type sqlcmd. >>Than run below script.

:SETVAR DatabasePrefix sitecore9
:SETVAR UserName collectionuser
:SETVAR Password Test123
:SETVAR ShardMapManagerDatabaseNameSuffix _Xdb.Collection.ShardMapManager
:SETVAR Shard0DatabaseNameSuffix _Xdb.Collection.Shard0
:SETVAR Shard1DatabaseNameSuffix _Xdb.Collection.Shard1

GO

IF(SUSER_ID(‘$(UserName)’) IS NULL)
BEGIN
CREATE LOGIN [$(UserName)] WITH PASSWORD = ‘$(Password)’; END;
GO

USE [$(DatabasePrefix)$(ShardMapManagerDatabaseNameSuffix)]
IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N’$(UserName)’) BEGIN
CREATE USER [$(UserName)] FOR LOGIN [$(UserName)]
GRANT SELECT ON SCHEMA :: __ShardManagement TO [$(UserName)] GRANT EXECUTE ON SCHEMA :: __ShardManagement TO [$(UserName)] END;
GO

USE [$(DatabasePrefix)$(Shard0DatabaseNameSuffix)]

IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N’$(UserName)’) BEGIN
CREATE USER [$(UserName)] FOR LOGIN [$(UserName)]
EXEC [xdb_collection].[GrantLeastPrivilege] @UserName = ‘$(UserName)’ END;
GO

USE [$(DatabasePrefix)$(Shard1DatabaseNameSuffix)]

IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N’$(UserName)’) BEGIN
CREATE USER [$(UserName)] FOR LOGIN [$(UserName)]
EXEC [xdb_collection].[GrantLeastPrivilege] @UserName = ‘$(UserName)’ END;

GO

Finally Sitecore 9 Insatalled

9

Advertisements

How to configure the Multisite in Sitecore using only single Domain/hostname

As we know Sitecore provide the out of the box feature to implement multisite solution using same sitecore instance.

Same sitecore instance can have multiple sites information architecture as example we want to implement the solution with single domain for multiple partner site with multiple region.

Site Definition:

To run multiple site we have to add site definition in in Sitecore.config file for each site.

<site name=”ABC” inherits=”website” hostName=”My.local”

virtualFolder=”/partner/fi”

  physicalFolder=”/ partner/fi “

targetHostName=””

scheme=”https”

rootPath=”/sitecore/content/portals/fi/”

startItem=”/Home”

database=”web”

domain=” ”

  language=” fi-FI”

enableContextualLinks=”true”

enableItemLanguageFallback=”true”

/>

 

<site name=”XYZ” inherits=”website” hostName=” ”

virtualFolder=”/partner/se”

   physicalFolder=”/ partner/se “

targetHostName=””

scheme=”https”

rootPath=”/sitecore/content/portals/se/”

startItem=”/Home”

database=”web”

domain=” ”

  language=”sv-se”

enableContextualLinks=”true”

enableItemLanguageFallback=”true” />

 

To implement single domain needs to do some more configuration as given below.

  • Virtual Folder: The value assigned to this attribute is added after the host name definition and is used to resolve sites according to incoming URLs . As you can see the virtual folder value will match in site information architecture “/partner/fi/
  • Physical Folder: Same value should configure which we have assigned to virtual folder.
  • Hostname will only configure in one site definition only

Sitecore Information Architecture for two sites:

Multisite.JPG

As we know Sitecore by default add language after domain. So for this single domain implementation we have to set false AlwaysStripLanguage property this as given below.

<settings>

<setting name=”Languages.AlwaysStripLanguage”>

<patch:attribute name=”value”>false</patch:attribute>

</setting>

  • Set languageEmbedding=”never” in link manager configuration.
  • Set Linkmanager “SiteResolving” property true.

 

*Now when you hit the url https://my.local/partner/se  or https://my.local/partner/fi Sitecore automatically resolve the site on basis of virtual path.

ADFS integration with Sitecore 8.2 Website using Owin Framework

Overview: In this article we will see how the ADFS can integrate with Sitecore website for authentication and authorisation using the Owin middle ware framework and how to access the claims that are provided using the federated login.

We will use the Sitecore habitat framework and add one new ADFS feature.

Lifecycle of ADFS Request

The browser request page of his website and the ADFS enabled web server (https://abc.com), and it is redirected with form to provide user information. The ADFS enabled web server is a claim aware application. The ADFS enabled web server takes the security token that it receives from STS( Security Token Service) uses as a token. The Security Token Service publishes all the information that is necessary to validate its tokens. The security token holds the organisation claim information for the client. Once user is authenticated by the AD, the security token which contains claim information set it to authentication cookies.

The authentication cookie facilities Single Sign on(SSO). After the STS validates the client once, the authentication cookie is written to client. Further authentication takes place through the cookie rather than through repeated collection of the client credentials. The authentication cookie is a session cookie. The authentication cookie is signed but not encrypted, so the use of transport layer security and secure sockets layer ( TLS/SSL) in ADFS is mandatory.

Prerequisite for ADFS integration:

  • Add Ownin Nuget Package to ADFs feature.
  • Change the authentication mode none in web.config
  • Sitecore 8.2 version and Owin framework 3.0 .0.1 both used the “System.IdentityModel.Tokens.Jwt” dll and have some version compatibility issue. So please add following line to web.config section :<dependentAssembly> <dependentAssembly>        <assemblyIdentity name=”System.IdentityModel.Tokens.Jwt” publicKeyToken=”31bf3856ad364e35″ culture=”neutral” />        <bindingRedirect oldVersion=”0.0.0.0-4.0.20622.1351″ newVersion=”4.0.20622.1351″ />   </dependentAssembly>

ADFS Integration Code

Create New Feature in Habitat solution named as “Sitecore.Feature.AdfsAccount and following nuget packages ADFSAccounts Feature

Owin framework Assemblies Dependency Assemblies (will get included automatically )
1.       Owin

2.       Microsoft.Owin

3.       Microsoft.Owin.Host.SystemWeb

4.       Microsoft.Owin.Security

5.       Microsoft.Owin.Security.Cookies

6.       Microsoft.Owin.Security.OAuth

7.       Microsoft.Owin.Security.WsFederation

8.       Microsoft.AspNet.Identity.Owin

9.       Microsoft.IdentityModel.Protocol.Extensions

10.   System.IdentityModel.Tokens.Jwt

11.   Microsoft.AspNet.Identity.Core

12.   Microsoft.AspNet.Identity.EntityFramework

Configure the Owin framework pipeline to initiate the pipeline .In the “App_Start” folder  add “Startup.AdfsAuth.cs”  file and Startup.cs under project root folder.

Configure following properties in config file.
https://hostname&#8221; />

 Startup.cs:

using Microsoft.Owin;

using Owin;

[assembly: OwinStartup(typeof(Sitecore.Feature.AdfsAccount.Startup))]

namespace Sitecore.Feature.AdfsAccount
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
}
}

Startup.AdfsAuth.cs:

using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Owin;
using Microsoft.Owin.Security.WsFederation;
using Sitecore.Configuration;
using System.Threading.Tasks;
using System;
using Sitecore.Feature.AdfsAccount.Models;

namespace Sitecore.Feature.AdfsAccount
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
string hostName = Sitecore.Sites.SiteManager.GetSite(“SiteName”).Properties[“hostName”];

if (!(System.String.IsNullOrEmpty(hostName)))
{
app.Properties[“Microsoft.Owin.Security.Constants.DefaultSignInAsAuthenticationType”] = AdfsConstant.CookieName;

app.MapWhen(ctx => CheckDomain(ctx), site =>
{
Sitecore.Diagnostics.Log.Info(“Enter in owin setup”, this);
string wtrealm = Settings.GetSetting(AdfsConstant.Wtrealm);
string wreply = Settings.GetSetting(AdfsConstant.Wreply);
site.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = AdfsConstant.CookieName,
AuthenticationMode = AuthenticationMode.Passive,
});
site.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
{
AuthenticationType = AdfsConstant.AdfsProvider,
MetadataAddress = Settings.GetSetting(AdfsConstant.MetadataAddress),
Wtrealm = wtrealm,
Wreply = wreply,

TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
ValidAudience = wreply
},

Notifications = new WsFederationAuthenticationNotifications
{
AuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.StatusCode = 403;
Sitecore.Diagnostics.Log.Info(“Enter in owin response” + context.Response.ToString(), this);
return Task.FromResult(0);
},

SecurityTokenValidated = (ctx) =>
{
//Ignore scheme/host name in redirect Uri to make sure a redirect to HTTPS does not redirect back to HTTP
var redirectUri = new System.Uri(ctx.AuthenticationTicket.Properties.RedirectUri, UriKind.RelativeOrAbsolute);
if (redirectUri.IsAbsoluteUri)
{
ctx.AuthenticationTicket.Properties.RedirectUri = redirectUri.PathAndQuery;
}

return Task.FromResult(0);
}

}
});

});
}
}
private bool CheckDomain(IOwinContext ctx)
{
string hostName = Sitecore.Sites.SiteManager.GetSite(“SiteName”).Properties[“hostName”];
if (!System.String.IsNullOrEmpty(hostName))
{
Sitecore.Diagnostics.Log.Info(ctx.Request.Headers.Get(“Host”).ToString(), this);
if (ctx.Request.Headers.Get(“Host”).ToLower().Contains(hostName.ToLower()))
{

return true;

}

return false;
}
else return false;

}
}

  • Claims challenge

Following are the steps to build challenge the claim and reading the claim functionalities.

Add AdfsAccount controller.

We will build one Sitecore Login controller view rendering and assign to ADFs login page.

Add one action anmed as “tokenreciver” and exposed as Sitecore API and configure in ADFs server as a Relying Party url.

Sample code:

public ActionResult Login()
{
string LandingPage = “configure the application landing page;
if (!Context.User.IsAuthenticated)
{
var ctx = Request.GetOwinContext();
if (ctx != null)
{
ctx.Authentication.Challenge(
new AuthenticationProperties
{
RedirectUri = Settings.GetSetting(AdfsConstant.Wreply)
},
AdfsConstant.AdfsProvider);
}

return new HttpUnauthorizedResult();
}
return this.Redirect(LandingPage);
}

Reading token:

public ActionResult TokenReciver()
{

string link=string.empty;

string accessDenied = configure access denied url .;
string LandingPage = configure landing page url;
if (Context.User.IsAuthenticated)
{
link =  LandingPage;
}
// if user not authenticated assume to be new request from other application
else
{
if (CheckUserAndClaimExist(DefaultAuthenticationTypes.ApplicationCookie.ToString()))
{
link =  LandingPage;

}
}
return this.Redirect(link);
}

private bool CheckUserAndClaimExist(string cookieType)
{
bool isUserAuthenticated = false;
bool isRoleExist = false;
var ctx = Request.GetOwinContext();

var result = ctx.Authentication.AuthenticateAsync(AdfsConstant.CookieName).Result;
if(result==null)
Sitecore.Diagnostics.Log.Info(“result null:” , this);
ctx.Authentication.SignOut(cookieType);
if (result != null)
{
var claims = result.Identity.Claims.ToList();

// here you will get all groups/roles assign to user build logic to match the roles for access level.

var groups = GetGroups(result.Identity);
if (result.Identity != null)
{
Session[“isAuthenticated”] = true;

//Create sitecore user or asp.net user.
isUserAuthenticated = AddVirtualUserAndRoles(result.Identity, isRoleExist);
}
}
return isUserAuthenticated;
}

public static IEnumerable GetGroups(ClaimsIdentity claimsIdentity)
{
var enumerable =
claimsIdentity.Claims.Where(
c => c.Type == “http://schemas.xmlsoap.org/claims/Group&#8221;).ToList();
var list = new List();
foreach (
var str in
enumerable.Select(claim => claim.Value.ToLower()))
{

list.Add(str);
}
return list.ToArray();
}

public static bool AddVirtualUserAndRoles(ClaimsIdentity userIdentity)
{
bool isValidUser = false;
var userName = string.Format(“{0}\\{1}”, Context.Domain.Name, userIdentity.Name);
try
{
Security.Accounts.Role userRole = Context.Domain.GetRoles().Where(role => role.Name == string.Concat(Context.Domain.Name, @”\”, Settings.GetSetting(“Role”))).FirstOrDefault();

var virtualUser = AuthenticationManager.BuildVirtualUser(userName, true);
var groups = GetGroups(userIdentity as ClaimsIdentity);
if (groups.Contains(Settings.GetSetting(“PortalRole”).ToLower(), StringComparer.OrdinalIgnoreCase))
virtualUser.Roles.Add(userRole);

virtualUser.Profile.Email = GetNameIdIdentifier(userIdentity as ClaimsIdentity);
virtualUser.Profile.Name = userIdentity.Name;

isValidUser = AuthenticationManager.Login(virtualUser);
var tracker = Sitecore.Analytics.Tracker.Current;
if (tracker != null)
tracker.Session.Identify(virtualUser.Identity.Name);

return isValidUser;
}

catch (Exception ex)
{
Log.Error(“Login Faile!”, ex);
return false;
}
}

Reference Blogs: http://www.dotnetcurry.com/windows-azure/1158/using-adfs-azure-single-signon-aspnet-mvc

 

How to resolve handshake with cloud mlab mongodb when connection type is SSL?

How to resolve handshake with cloud mlab mongodb when connection type is SSL?

Override the “UpdateMongoDriverSettingsProcessor” pipeline.

 

Sample code :

 

public class UpdateMongoDriverSettings: UpdateMongoDriverSettingsProcessor

{

/// <summary>

/// This pipeline is override for conection delay or handshake with cloud mlab mongodb when connection type is SSL

/// </summary>

/// <param name=”args”></param>

public override void UpdateSettings(UpdateMongoDriverSettingsArgs args)

{

Assert.ArgumentNotNull(args, nameof(args));

Int32 defaultValue = 120;

 

Int32 socketTime = String.IsNullOrEmpty(string.Format(CultureInfo.InvariantCulture,Settings.GetSetting(“MongoDB.SocketTimeout”))) ? defaultValue : Int32.Parse(Settings.GetSetting(“MongoDB.SocketTimeout”), CultureInfo.InvariantCulture);

Int32 ConnectTimeout = String.IsNullOrEmpty(Settings.GetSetting(“MongoDB.SocketTimeout”)) ? defaultValue : Int32.Parse(Settings.GetSetting(“MongoDB.ConnectTimeout”),CultureInfo.InvariantCulture);

Int32 WaitQueueTimeout = String.IsNullOrEmpty(Settings.GetSetting(“MongoDB.SocketTimeout”)) ? defaultValue : Int32.Parse(Settings.GetSetting(“MongoDB.WaitQueueTimeout”),CultureInfo.InvariantCulture);

 

if (args != null)

{

args.MongoSettings.SocketTimeout = new TimeSpan(0, 0, 0, socketTime);

args.MongoSettings.ConnectTimeout = new TimeSpan(0, 0, 0, ConnectTimeout);

args.MongoSettings.WaitQueueTimeout = new TimeSpan(0, 0, 0, WaitQueueTimeout);

}

Log.Info(String.Format(CultureInfo.InvariantCulture,”UpdateMongoDriverSettingsArgs changed”), this);

}

 

}

 

 

 

<configuration xmlns:patch=”www.sitecore.net/xmlconfig”>

<sitecore>

<pipelines>

<updateMongoDriverSettings>

<processor type=”MogoDbExtension.UpdateMongoDriverSettings, Assembly Name” />

</updateMongoDriverSettings>

</pipelines>

 

<settings>

<setting name=”MongoDB.SocketTimeout” value=”120″ />

<setting name=”MongoDB.ConnectTimeout” value=”120″ />

<setting name=”MongoDB.WaitQueueTimeout” value=”120″ />

</settings>

</sitecore>

</configuration>

 

How to do Configuration patching in Sitecore

In Real development many time we find lot of scenario where we have to patch the configuration. In Sietcore there is one thumb rule that all type of patching configuration file will add under “\App_Config\include” folder.

All given below patch section will add only under <sitecore> tag in config file. Sitecore have custom module which dynamically added all configuration at runtime.

Following are some requirements and examples.

  • Merging the config files: -A

    s example in Sitecore all setting will exist in Sitecore.config file under Include folder.

As example if you want to create a switcher for any logic that you can enable and disable the execution of code from configuration.

Create one new config File name as “z.SitecoreSetting.config” and add setting in this file as follows:

<setting name=”SwitchOnOff” value=”true” /> 

Note: At run time this setting will be add in Sitecore.config file.

  • How to add or update attribute of any configuration: – We can add the new attribute or update the existing attribute value also.

As example you got the requirement from Client that language will not append in Web URL.

Following are the step to implement this:

Create one new config File name as “z.SitecoreLinkManger.config” and add setting in this file as follows:

You have to add  “patch:attribute” tag containg the name of existing attribute and new value.

“<configuration  xmlns:patch=”http://www.sitecore.net/xmlconfig/&#8221; xmlns:set=”http://www.sitecore.net/xmlconfig/set/”&gt;

<sitecore>

<linkManager defaultProvider=”sitecore”>

<providers>

<add name=”sitecore”>

<patch:attribute name=”languageEmbedding”>never</patch:attribute>

</add>

</providers>

</linkManager>

</sitecore>

</configuration>

 

  • How to insert the config element before or after specific configuration?

In this requirement we have to add out custom pipeline, events or etc. Please see the below httpbegin request pipeline example.

Patch:before  Example

<configuration xmlns:patch=”http://www.sitecore.net/xmlconfig/”&gt;

<sitecore>

<pipelines>

<httpRequestBegin>

<processor type=”Your custom class name”,   DLL Name”      patch:before=”processor[@type=’Sitecore.Pipelines.HttpRequest.LayoutResolver, Sitecore.Kernel’]”/>

</httpRequestBegin>

</pipelines>

</sitecore>

</configuration>

 

patch:after Sitecore Example:-

 

<!– Sitecore.config –>

<test>

<processor type=”test1″ />

<processor type=”test2″ />

<processor type=”test3″ />

</test>

<!– Patch file –>

<test>

<processor type=”testA” patch:after = “processor[@type=’test2′]”/>

</test>

The configuration used at runtime is:

<test>  <processor type=”test1″ />

<processor type=”test2″ /><processor type=”testA” />  <processor type=”test3″ />

</test>

<processor type=”test2″ />

<processor type=”testA” />

<processor type=”test3″ />

</test>

Use Handlebar template to bind JSON from Sitecore MVC Controller

In Sitecore MVC as we all know how to bind data synchronously by using inbuilt View and controller rendering but now  we will see in this article how we can bind the Sitecore Item data as json to view using handlebar template framework in asynchronous call.

Following are the steps we have to follow:

  1. Add handlebar framework reference to your layout. Handlebar file is hosted on cdn also it is up to you to direct reference from cdn or download and add to your solution

https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.10/handlebars.amd.js

  1. Create MVC controller inheriting the MVC/Sitecore MVc base controller.
  2. Add action named as example GetArticle() to controller class and return type would ben JSON result set by using Json() method
  3. Create one repository class which bind the model.
  4. Register route for controller override the Sitecore MVC pipeline.
  5. Implement AJAX call and bind with the handlebar template

Controller Class:

public class ArticleController : Controller

{

private readonly IArticleRepository _articleRepository;

public ArticleController () : this(new ArticlerRepository ())

{

}

public AccountsController(IArticleRepository articleRepository)

{

this. _articleRepository = articleRepository;

}

 

[HttpGet]

public JsonResult GetArticle ()

{

List<Article> lstArticle=     this. _articleRepository.GetArticle();

return Json(lstArticle, JsonRequestBehavior.AllowGet);

}

}

Model Class:

public class Article

{

public  string Url { get; set; }

public string Title { get; set; }

public string ShortDescription { get; set; }

}

Repository class interface: Create interface for repository class

interface IArticleRepository

{

string List<Article> GetArticle();

}

Repository class:

public class ArticlerRepository : IArticleRepository    {

/// <summary>

/// Get article sitecore

/// </summary>

/// <returns></returns>

 

public List<Article> GetArticle()
{

List<Article> lstArticle = new List<Article>();
Item aticleRootItem = Mvc.Presentation.RenderingContext.Current.Rendering.Item;

if (aticleRootItem != null && aticleRootItem.HasChildren)
{
foreach (Item childrenItem in aticleRootItem.Children)
{
Article objArticle = new Article();
if (childrenItem.IsDerived(Templates.Article.ID))
{

objArticle.Url = childrenItem.Fields[“Url”]!=null?childrenItem.Fields[“Url”].Value : string.Empty;
objArticle.Title= childrenItem.Fields[“Title”] != null ? childrenItem.Fields[“Title”].Value : string.Empty;
objArticle.ShortDescription = childrenItem.Fields[“ShortDescription”] != null ? childrenItem.Fields[“ShortDescription”].Value : string.Empty;

lstArticle.Add(objArticle);
}
}
}

return lstArticle;
}

}

 

Register route for controller override the Sitecore MVC pipeline

<pipelines>
<initialize>
<processor type=”RegisterWebApiRoutes, dll name”
patch:before=”processor[@type=’Sitecore.Mvc.Pipelines.Loader.InitializeRoutes, Sitecore.Mvc’]” />
</initialize>
</pipelines>

using Sitecore.Pipelines;
using System.Web.Mvc;
using System.Web.Routing;
/// <summary>
/// Register Routes for controller
/// </summary>
public class RegisterWebApiRoutes
{
public void Process(PipelineArgs args)
{
RouteTable.Routes.MapRoute(“Api”, “api/Article/{action}”, new
{
controller = “Article”
});
}
}

Bind article Data on UI using Handlebar framework: Create one Sitecore MVC rendering view named “Articlelst.cshtml”and this handlebar template for article list.

//Handle bar template will rendered articles on page load

*************************************************************************************

Handle Bar template definition for Article list

*************************************************************************************

“<” script id=”application-declined-template” type=”text/x-handlebars-template” “>”

{{#each lstArticle }}

{{{Title}}}

{{{Title}}}

{{{ShortDescription}}}

{{/each}}

“<” / script “>”

Add this JavaScript function to View on document ready function:

$(document).ready(function () {

function GetArticle() {

var url = ‘api/Article/GetArticle’;

$.ajax({

type: get,

contentType: ‘application/json; charset=UTF-8’,

url: url,

cache: false,

success: function (data, status) {

var articleData = JSON.parse($.trim(data.lstArticle));

var source = $(“#article-template”).html();

var template = Handlebars.compile(source);

$(‘.Article-content’).empty();

$(‘.Article-content’).append(template(articleData));

},

error: function (status) {

console.log(“error”, data);

}

});

}

});

 

 

Handlebar reference urls:

https://www.sitepoint.com/a-beginners-guide-to-handlebars/

http://javascriptissexy.com/handlebars-js-tutorial-learn-everything-about-handlebars-js-javascript-templating/

http://handlebarsjs.com/