AngularJS and Sitecore

AngularJS and Sitecore

I’ve been using a lot of jQuery and it’s the same old manipulating the DOM to get a page to look, feel and work the way I want it to work. There’s nothing wrong with this but I wanted to explore other JS libraries, from the thousands available, to possibly find a replacement or a complimentary library for jQuery.

After playing with AngularJS, I found its simplicity and its MVC capabilities very useful. Instead of manipulating the DOM, like jQuery, you can use AngularJS to extend HTML and treat HTML like XML to perform objectives such as creating custom tags. AngularJS uses jQLite, which is a version of jQuery, but if jQuery is already present on your site, it will use your version of jQuery instead.

Below is a simple example to showcase a powerful use of AngularJS that requires very little coding as found on their website.

<script src=”//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js”></script>
<div ng-app>
    <label>Name:</label>
    <input type=”text” ng-model=”yourName” placeholder=”Enter a name here”>
    <hr>
    <h1>Hello {{yourName}}!</h1>
</div>
 

The app above is simple, declared as an Angular JS app by the “ng-app” attribute on the <div> tag. Every markup within the <div> is part of the declared app. The “ng-model” attribute, “yourName”, has been data bound to the <input> tag, hence it constantly listens to the <input> tag and upon entering any value within the <input> tag the value entered can be instantly displayed using mustache tags. In this example, the value would be {{yourName}}. This example demonstrates how powerful AngularJS is, because this code in jQuery would require at least a few lines of JavaScript.

Integrating AngularJS with Sitecore

I work with Sitecore almost daily, so I wanted to push it a bit further and see how AngularJS could integrate with Sitecore. To put it to the test, I chose to display a list of items from Sitecore using AngularJS.

With a typical Sitecore implementation, this is accomplished by getting the list of items and data binding the list to an asp:Repeater (then the rest is history). For this example, I focused on getting the list of items and data binding the list of items to a scope in AngularJS to let the app handle the rest.

The end result looks something like this.

    <script src=”//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js”></script>
    <script src=”//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js”></script>
    <div class=”angularjs-app”>
        <div class=”list-data”>
            <asp:HiddenField runat=”server” ID=”ListCtrlData” />
        </div>
        <script type=”text/javascript”>
            //<![CDATA[
            var data = $('.list-data input[type=hidden]‘).val();
            data = JSON.parse(data);
            function ListCtrl($scope) {
                $scope.list = data;
            }
            //]]>
        </script>
        <div ng-app>
            <div ng-controller=”ListCtrl”>
                <ul>
                    <li ng-repeat=”item in list”>
                        {{ item.title }}
                    </li>
                </ul>
            </div>
        </div>
    </div>

Let’s break it down.

        <div ng-app>
            <div ng-controller=”ListCtrl”>
                <ul>
                    <li ng-repeat=”item in list”>
                        {{ item.title }}
                    </li>
                </ul>
            </div>
        </div>

The “ng-controller” defines the initial scope with methods to control behavior within the scope. “ng-repeat”, “item in list”, acts the <asp:Repeater> as it loops through the list provided and outputs, using mustache tags, values. Hence the goal is to data bind the list of items from Sitecore to the “list”. This is accomplished by first getting the list of items, then serializing it to JSON and storing the list within the hidden input field of ID “ListCtrlData”.

        public class ChildItems
        {
            public string title { get; set; }
        }
        private JavaScriptSerializer serializer = new JavaScriptSerializer();
        protected void Page_Load(object sender, EventArgs e)
        {
            Item currentItem = Sitecore.Context.Item;
            List<Item> descendants = currentItem.GetChildren().Where(i => i.TemplateName == “Destination Category”).ToList();
            List<ChildItems> children = new List<ChildItems>();
            if (descendants != null)
            {
                foreach (Item item in descendants)
                {
                    if (item != null)
                    {
                        ChildItems childItems = new ChildItems();
                        if (item.Fields["Title"] != null)
                        {
                            childItems.title = item.Fields["Title"].ToString();
                        }
                        children.Add(childItems);
                    }
                }
                ListCtrlData.Value = serializer.Serialize(children);
            }
        }

I won’t go into details about getting items from Sitecore. Let’s assume the list of items from Sitecore has been successfully added to a list of child items, List <ChildItems> children. The next step is to serialize the list to the hidden input, taken care of on the line below.

ListCtrlData.Value = serializer.Serialize(children);

Now that we have our json string within the “ListCtrlData” hidden input, we can pass the value to the “list” within the “ListCtrl” controller in AngularJS.

        <script type=”text/javascript”>
            //<![CDATA[
            var data = $('.list-data input[type=hidden]‘).val(); // Get serialized Value
            data = JSON.parse(data); // Parse Serialized Value
            //]]>
        </script>

After getting the serialized data, data, we need to parse it with JSON in order to convert the data to a JavaScript Object. Next we create a function for our “ListCtrl” controller within which we will data bind the data object to the “ng-repeater”.

function ListCtrl($scope) {
            $scope.list = data; // Databind data to the list.
       }

The data object ends up looking something like:

[
                {"title": “Item A Title”}
                {"title": “Item B Title”}
                {"title": “Item C Title”}
                {"title": “Item D Title”}
                {"title": “Item E Title”}
]

Hence the output ends up being:

Item A Title

Item B Title

Item C Title

Item D Title

Item E Title

 Conclusions

 AngularJS can be integrated with Sitecore but it takes a few additional steps to convert the data source to JSON then data bind the data to an AngularJS control. This can be useful when creating AJAX oriented modules or mini-apps within a Sitecore site, but I wouldn’t recommend using it for the entire implementation at the moment. I know most developers, especially backend developers, are terrified of a site being entirely JAVASCRIPT; however, I would encourage developers to explore more on integrating AngularJS with any Back End language.  It may be worthwhile.

For more info, visit http://angularjs.org/

 Download example files:

list

list_ascx

Read More Comments


In the Early Days of CMS

In the early days of Web Content Management Systems (CMS), there was a nice man on the sales team who’d once asked me: “Jeremy, why do you developers hate every CMS?” The answer was simple but nuanced: at the time, the platforms did not speak to us as developers.

There were plenty of CMS platforms out there, though most would force a developer into using esoteric patterns which were contrary to the way that a problem would be approached if it were a fully custom solution; contrary to what we knew to be the best way. As well, many of them came with large libraries of pre-built controls. At first glance this sounds like a good thing; however, after the world has seen the same control countless times over, something a little different is often required. Hence the problem: primarily, developers found themselves in situations where the pre-built controls–that were supposed to save them time–were of no use. Solutions often had to be built from scratch.

Ultimately, many of the CMS platforms boiled down to frustrating systems with time-savers which saved no time at all. It’s no wonder that the development team cringed every time a new platform came onto the scene.

After a while, we acclimated. We learned the patterns and they became second nature to us. We would play nice in the sandbox with them, but we didn’t have to like them. And then an interesting thing happened: we evaluated Sitecore for the first time. Initially we had a difficult time understanding it; it seemed quite foreign. One was left with the inevitable question: “how do I create a page?”

Following the developer training, it quickly became clear why we were having a difficult time: it did not behave like the CMS platforms to which we were accustomed. It was abstract and followed object-oriented practices. There were a few “ah-ha” moments that lead us to realize exactly how powerful the Sitecore CMS platform was. It would let us do anything as long as it was properly tied back to the CMS API; not to mention that it’s quick to get out of the way when required. Add in a proper inheritance model and you have a platform with far more flexibility and re-usability than any CMS platform that had been evaluated to date.

When explaining something intangible and abstract, I often like to relate it to something tangible. The early page-based CMS platforms were similar to Lincoln Logs®: they gave a pretty good indication as to how they should be assembled and a project could be built quite quickly. An abstract CMS, like Sitecore, is more akin to a ball of clay: it doesn’t tell you what it’s supposed to be or what form it is supposed to take. One thing is undeniable: so much more can be made with a ball of clay than could be built with Lincoln Logs®.

CMS platforms have certainly come a long way.

Read More Comments


More Fun Than a Barrel of Encrypted Certificates

Recently, Q was tasked with enabling authentication into a government agency’s Sitecore CMS using a U.S. Government issued Common Access Card (CAC). I know it sounds scary; but don’t worry, we’re professionals.

The first question that you may ask is: “what is a CAC card?” It, as with many great things in this world, is a simple entity with a complex purpose; specifically, to identify an individual using two-factor authentication. Similar to your ATM card, you’re able to be identified because you have the two requisite items: you have the card in your possession and you know the PIN associated with the card.

Read More Comments


Considering Sitecore? Take Note of Recent Changes

By Wyatt Queener, Vice President, Strategy

July was a month full of big announcements for Q partner and WCM leader, Sitecore. While Sitecore continues to follow a flexible size-based model for its CMS solution, the company announced changes to its North American pricing model on July 1. Sitecore also announced the launch of the App Center, an online marketplace of on-demand applications, services, and integration solutions developed for Sitecore’s Customer Engagement Platform. According to Sitecore, the App Center will serve as an “ecosystem of pluggable cloud applications [that] will include email marketing, social media monitoring, Windows Azure hosting, Search Engine Optimization (SEO), translation and web compliance.” These recent changes align with the company’s ongoing push to offer more robust analytic, marketing and customer engagement capabilities in addition to content management, raising the bar in the web content management (WCM) space.

Read More Comments


The Week’s Top Tweets (July 15)

1. Sitecore Acquires Pectora to Bridge the Gap Between Print and Digital Worlds

Earlier this month, Q CMS partner Sitecore announced its acquisition of the development team and intellectual property of Pectora. Pectora, previously a long-term Sitecore technology partner, provides web publishing solutions for integration with print-based projects.  The new effort combines print and web design teams to deliver more dynamic, personalized, customer-facing print media including brochures, catalogs and magazines.

Read More Comments