I have been challenged to integrate Angular web-application with Sitecore, I needed to create an ability for Content Authors to edit content that is coming from Angular Application.
So lets think for a second, I have an angular application that has all of my design and all of my logic and templates and controllers and so on. Sitecore is serving as a database. Customer would like to edit content in Experience Editor, not in the Content Editor, they would like to edit everything on the web page, the only way to do it, is to build the web site in Sitecore recommended way, by using the the MVC way. Create Layouts, Controllers, Models and so on. But we don’t want to rebuild it all. We would like to do this faster without rebuilding it.
First thing is to figure out how to inject MVC into the Angular Template, within the Sitecore Layout. After my research has been done I stopped on an article by Sitecore MVP Alexander Smagin (Using Angular Directives in Sitecore Edit Mode).
In this tutorial I will show, how you can get going really fast without rebuilding everything in Sitecore.
What we will need to have in our project:
- Sitecore Layout (Layout.cshtml)
- Sitecore Controller (AngularController.cs)
- Angular Template (index.html)
- Angular Module (myangular.js)
- Sitecore Template
- Sitecore Layout
- Sitecore Item
So lets begin!!!
Step 1: Lets Create a Sitecore Template
If you do not know how to create a Sitecore Template , here is a quick tutorial (How to create a Sitecore Template?)
- Content
- Title – Single-Line Text
- Text – Rich-Text Editor
- Image – Image
Save your work and add __Standard Values. You result should look something like this.
Step 2: Lets Create a Sitecore Layout (Layout.cshtml)
Lets go ahead and open Visual Studio and create a Layout. Right click on Views folder and a View and name is angularLayout.cshtml and paste the following code in the angularLayout.cshtml:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using Sitecore.Mvc | |
@using Sitecore.Mvc.Extensions | |
@using sitecore.local.Controllers | |
@{ | |
Layout = null; | |
} | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>@Html.Sitecore().CurrentItem.Name</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script> | |
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-sanitize.js"></script> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> | |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> | |
<script src="~/Scripts/mysite/myangular.js?v=1.1"></script> | |
</head> | |
<body ng-app="sc.sample"> | |
<div class="container" ng-controller="SampleDemoController"> | |
<div sample-component='{ | |
Title: "@Html.RawJsEncodedString(@Html.Sitecore().Field("Title"))", | |
Text: "@Html.RawJsEncodedString(@Html.Sitecore().Field("Text"))", | |
Image: "@Html.RawJsEncodedString(@Html.Sitecore().Field("Image"))" | |
}'></div> | |
</div> | |
</body> | |
</html> |
We will add Controller and Angular Module next.
Step 3: Lets Create a Sitecore Controller (AngularController.cs)
Go to Controllers folder and add new Controller and name it AngularController.cs and paste the following code in there:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Web; | |
using System.Web.Mvc; | |
using Sitecore.Mvc.Extensions; | |
namespace sitecore.local.Controllers | |
{ | |
public static class Angular | |
{ | |
public static IHtmlString RawJsEncodedString<T>(this HtmlHelper<T> htmlHelper, HtmlString str) | |
{ | |
var test = str.ToString(); | |
if (test.IsEmptyOrNull()) | |
{ | |
return new HtmlString(string.Empty); | |
} | |
return new HtmlString(HttpUtility.JavaScriptStringEncode(test)); | |
} | |
} | |
} |
Step 4: Lets Create an Angular Module (myangular.js)
Go ahead and create myangular.js under the Scripts folder, and paste the following code in there:
Make sure to change your templateUrl.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('sc.sample', [ | |
'ngSanitize' | |
]).directive('sampleComponent', function () { | |
return { | |
scope: { | |
data: '=sampleComponent' | |
}, | |
templateUrl: `[template path]/index.html` | |
}; | |
}).controller('SampleDemoController', ['$scope', function ($scope) { | |
$scope.data = { | |
Title: 'Title', | |
Text: 'Text', | |
Image: '<img src="">' | |
}; | |
}]).filter('asTrusted', ['$sce', function ($sce) { | |
return function (text) { | |
return $sce.trustAsHtml(text); | |
}; | |
}]) |
And finally you can either add your own template or use this one for the learning purposes. This is just a sample, use your imagination how you can go about it.
Step 5: Lets Create an Angular Template (index.html)
This is just a simple angular template that uses Bootstrap, and it will bind the content with the Sitecore (@Html.Sitecore().Field) method.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<section class="row page-header sampleComponent spaced-row" ng-show="data"> | |
<div class="col-xs-12"> | |
<h1 class="header" ng-bind-html="data.Title | asTrusted"></h1> | |
</div> | |
<article class="col-xs-7 col-md-8"> | |
<p ng-bind-html="data.Text | asTrusted"></p> | |
</article> | |
<figure class="col-xs-5 col-md-4"> | |
<span ng-bind-html="data.Image | asTrusted"></span> | |
</figure> | |
</section> |
Now since we have done all the work in Visual Studio. Lets go ahead and build it, and Publish it to Sitecore.
Once Everything is Published we will go ahead and connect all of the code that we have done to our template, and start creating items, based on this template.
Step 6: Lets Create a Sitecore Layout in Content Editor.
You should have something similar to this:
And your Data information for this Layout will look like this:
How we will have to go back to our __Standard Values and add this Layout to the Template that we have created.
So go and select __Standard Values and select Presentation Details
Select the appropriate Layout and you are good to go.
Create and item and you open in Experience Editor, and this item renders the layout that comes from the .html page with angular directive, you can edit everything, that you see on the page.
If you have any question, please do not hesitate to reach out to me, comment here or connect with me on Twitter @tmamedbekov
All the magic is so simple. Great example. What are the pitfalls to use this approach in real development?
LikeLiked by 1 person
Placeholders, so that means personalization might be having problems. Working on resolving it. Will have a tutorial soon.
LikeLiked by 1 person
Hm… Could you be a little bit more specific with the problem description? It seems you can provide controller rendering components and place it into any placeholder…
LikeLiked by 1 person