Tuesday, December 27, 2016

Working with Sitecore SPEAK dialog

In old world of Sitecore (Sheer UI), you used to work with SheerResponse to open the dialog box as shown below

SheerResponse.ShowModalDialog(new ModalDialogOptions(url)
{
  Width = "100",
  Height = "200",
  Response = true,
  ForceDialogSize = true
});

The same logic will work when you are opening a SPEAK page as a dialog from a non-speak interface

Sitecore documentation here is a good start to understand various options. This blog is not about re-iterating those options but something that is not documented (or at least i haven't seen).

I was in a situation where I had 2 SPEAK pages and I wanted to open second page as a modal dialog from the first SPEAK page. Though the last section of above documentation provides you a reference but documentation is incomplete.

When you are trying to open one SPEAK page from another in a modal form (i.e. until you respond to the dialog you cannot do anything on the parent window, either by means of taking some action or closing the window) you have to follow these steps

  1. Add a DialogWindow rendering in your SPEAK page
  2. Add Frame component in DialogWindow placeholder
  3. Set the Frame Source URL property to the second SPEAK page you want to open in the dialog window. I am doing this in code as shown below
            showDialog: function (td) {
                try {
                    //adding couple of querystrings as the dialog shows the content based on these parameters (passed from first page)
                    td = td || 0;
                    var app = this;
                    var jd = Sitecore.Helpers.url.getQueryParameters(window.location.href)['jd']; 
                    var url = "SecondPage?jd=" + jd
                    if (td != 0)
                        url = url + "&td=" + td;
    
                    app.Frame1.set("sourceUrl", url);
                    app.DialogWindow1.show();
                }
                catch(exception)
                {
                    console.log("Error occured while loading the dialog: " + exception.name + ", " + exception.message + ", " + exception.stack)
                }
            }
    
    

  4. Set the hight and width as 100% (this does not work in Sitecore 8.2) to ensure that frame occupies the whole area of the dialogwindow component

    Frame component properties

  5. Set the Background style to static (to ensure that background is greyed and you cannot do anything until you respond to the dialog window)

    DialogWindow component properties

Hope this helps






Sunday, November 27, 2016

Installation Instructions for Sitecore QuartzScheduler Module

Installation Instructions for Sitecore QuartzScheduler module


Module works with Sitecore 8, 8.1 update 3. Tested it with 8.2 but apart from trigger detail dialog, everything seems to work. 
Please follow these steps to install the packages in a zip file

  1. Install TDS.Sitecore.QuartzScheduler.Core.update package
  2. Install TDS.Sitecore.QuartzScheduler.Matser.update package
  3. Re-build Master Index

  4. At this point you are ready to define your jobs and triggers

  5. Optional steps
    1. Install TDS.Sitecore.QuartzScheduler.Master.Content.update package to install out of the box job definitions
      Note: If you are installing this package, see notes below each job to ensure you don’t run it twice
    2. This package contains job definitions for:
      • HelloWorld demo job
      • Archive Job performance statistics
      • Cleanup Publish Queue (Sitecore job) - invoked from a quartz job
        • In Sitecore agent /task configuration, set interval to 00:00:00 to disable Sitecore invoking this job
      • Cleanup History (Sitecore job) - invoked from a quartz job
        • In Sitecore agent / task configuration, set interval to 00:00:00 to disable Sitecore invoking this job
      • Cleanup Event Queue (Sitecore job) - invoked from a quartz job
        • In Sitecore agent / task configuration, set interval to 00:00:00 to disable Sitecore invoking this job








    3. Restart App Pool
Add Log4Net configuration as mentioned below
Under <log4net> node, add appender for Sitecore.QuartzScheduler as shown below


      
      
      
        
      
      
    

Add corresponding logger just below </root> element, as shown below

 
      
      
    


Known issue with Sitecore 8.2
Problem
Trigger detail dialog does not take the whole window width and hight. This apperas to be Frame control issue.

Workaround
Work around to this is you can open triggerdetail page by copying jobdetail and trigger detail id as given below

/sitecore/client/Applications/QuartzScheduler/Pages/TriggerDetails?sc_lang=en&jd={97EEE137-5303-4CF9-87A2-CEF8B68DB9C2}&td={68975F6D-9C5B-4C26-99AF-5537A87244C7}


You can get the trigger detail and job detail id from job detail page. When you click on the trigger item in the list control, console shows you the id of the trigger, you can copy from there.


Thursday, November 24, 2016

Overview of Sitecore QuartzScheduler

In this blog I am highlighting the features and usage of Sitecore QuartzScheduler Module. This will be useful for anyone who wants to use this module

Problem this module addresses

  • Until know scheduling and knowing how your jobs are performing in Sitecore has been a challenge. By default jobs execute based on the sliding duration of app pool start and hence it is not predictive enough.
  • You dont know how long jobs are taking and whether they are having race conditions
  • I cannot execute a particular job on-demand
  • I cannot define multiple and complex schedules for a job


Solution

  • Sitecore QuartzScheduler is an attempt to address these pain points. This is based on industry proven Quartz Scheduler for .net - enterprise scheduler framework


Features
  • Bulit on Quartz.net - industry proven enterprise job scheduler
  • Manage and Define Jobs and when those jobs will trigger (according to server clock time and not app pool recycle sliding time)
    • Define triggers based on duration every few hours, minutes or seconds
    • Define triggers to fire daily
    • Define triggers that fire only certain days of the week
    • Define triggers that fire monthly once on any given day
    • If none-of the above suits your need - Define custom triggers based on cron- expression guidelines of Quartz.net
  • Job Performance Dashboard showing
    • Job Performance Average and Maximum time it has taken
    • Individual Job Performance - from last app pool recycle
    • Current Execution Status and next fire times for each job trigger defined
  • Execute a job on-demand (instead of waiting for schedule to trigger)
  • Download job performance data as a Json file (in the event you are recycling the app pool and want to retain this data before you do so)
  • Out of the box jobs for
    • Cleanup Publish Queue
    • Cleanup Event Queue
    • Cleanup History
  • You can create your own jobs and create definition items in Sitecore through Sitecore SPEAK app
  • Extensible - create your own trigger statistics store to store performance benchmarks for longer term rather than in application cache

Feature walk-through

Launch and Navigation

Quick launch button in the Launchpad

Sitecore QuartzScheduler - Sitecore Launchpad button


Simple navigation

Sitecore QuartzScheduler - Simple Navigation


Dashboard

To view Job performance summary on what is the avg time taken by a job and maximum time it has taken so far

Sitecore QuartzScheduler - Job Performance Summary


To view individual job performance trend

Sitecore QuartzScheduler - Job Performance Trend
Sitecore QuartzScheduler - Job Performance Trend



To view current job execution status and when the next trigger for each job will fire

Sitecore QuartzScheduler - Current Job Execution Status

Manage Jobs

Ability to manage and define your own jobs which are implemented according to Quartz.net guidance

Sitecore QuartzScheduler - Manage Jobs

Create / Edit Jobs

Sitecore QuartzScheduler - Crete / Edit Jobs

Create / Edit Triggers

Sitecore QuartzScheduler - Create / Edit Triggers

Refer installation instructions on my blog post here OR on Sitecore marketplace once it becomes available



Monday, October 3, 2016

Sitecore Experience Accelerator (SXA) - Overview

Until very recently, building sites on Sitecore was intense development effort and required some good understanding of Sitecore and its capabilities to extend, customize and build content editor friendly sites keeping all the non-functional requirements such as Responsive Web Design, Flexibility to re-arrange components quickly on any page, Create completely new page as needed by business with short-turn around time.

All of this was possible but you had to do lot of groundwork to be able to create a sustainable model for various brands in the enterprise to meet their marketing / consumer needs.

There were few accelerators in the Market such as Brainjocks SCORE, Keystone and ZenGarden from Cognifide. All of these accelerators promised to reduce your effort in building a site with some fundamental principles such as OOB Responsive, ready-to-use components such as Snippets, Carousels, Navigation components etc. And they all aimed for reducing the amount of effort to take your sites to market and ability to easily author content without getting involved in development / assembly cycles.

Of-course each of them has its own pros and cons and has its own learning curve for developers, assemblers and content authors but it provides the agility brand organizations look for.

Lot of fortune 500 and multi-brand organizations expected this functionality to come out of the box from Sitecore and looks like they soon realized the need for one such capability to stay relevant in the market and accelerate time to market for these organizations to bring their digital properties to their consumers. With greater adoption comes greater responsibility and greater promises :)

Sitecore launched their own accelerator, influenced from ZenGarden and following Sitecore Habitat development guidelines which is based on Helix architecture principles, called SXA (Sitecore Experience Accelerator), what an apt name :).

First and foremost advantage of SXA is now its a first class resident of Sitecore. Though it needs its own license you don't have to rely on additional contracts / support levels.

In this blog post I want to highlight some of the key features of SxA and what it promises to bring on the table.

Key Features


  • Drag and Drop toolkit
  • Contextual information to the component (in terms of styling, allowed components etc)
  • New simplified page architecture
  • Wire framing mode for building sites - Allows repid prototyping - Allows content authors to enter content even prior to design being created
  • Export / Import visual designs - Allows Creation of information architecture and design team work on it to apply visual design 
  • ~80 pre-built components - Own gropuings, own components can be added
  • Mobile first with responsive and adaptive options
  • SXA extends capabilities for developers, designers, content authors etc..

New Page Architecture

Page Designs - Defines the way that the page is architected
  • Where you would ideally keep your header, content and footer
  • Attends to the layout in Sitecore
  • Defines sections in the pages

Partial Designs - Different main components of the page. For example:  Header, Footer, Main content area
  • Allows you to Design independently
  • Reuse it on multiple pages
  • Different styles of headers for different sections

Renderings (components)
- Anything from RTA, navigation structure, image, splitter (multiple columns)
- simple text, or complex component on the page that is integrating with external data

Build Sites with Wireframes

Create Wireframes

  • Created directly in Sitecore (avoids traditional wireframes)
  • Can start building pages while design is happening in parallel
  • Content entry can start directly after the information architecture phase
  • Ultimately gets transformed into actual site end of the day
  • Design and Content entry can happen in parallel (time to market)

Export and Import Site Design

  • Exports entire information architecture into html javascript and css files (nothing Sitecore specific)
  • Can be handed over to design agencies and they can start applying css styles, color. Placeholders to add css classes
  • Design agency does not need to have any Sitecore experience
  • Site building knowledge
  • Re-Imported into SXA
  • Saved into a theme (applied to a site)
  • You can import several themes on the site
  • Design agency can provide 3-4 different flavors of how the site looks and can flip / flop all the while navigating through the site

Business Benefits


  • Reduced Time to Market
  • Parallel Site Co-Production
  • Bring personalization and Content testing from phase 2 to phase 1 (usually an afterthought)
  • Simple and Fast Content Maintenance - Customer / Business users (Non Developers) are able to create new pages and sections. Do small changes themselves
  • Brand Governance - Increased governance usually means less design flexibility  but with SXA provides more tools and page layout options for the business user, while still adhering to brand IA guidelines
  • Rendering Variants - Customer can choose / create their own variants, but for governance sake you may provide them the options to choose from
  • Responsive Design by Default - Users do not need to be responsive experts. Adaptive options also available
  • Multi-site capabilities - share designs, enforce governance across many sites

Happy SXA, Hope my next Sitecore engagement will involve adventure with this :)


Saturday, August 27, 2016

Handling Sitecore DateTime Fields - Client and Server Side

I was in a tricky situation when I was working on one of my SPEAK page and I had certain date fields on the page. Adding to that complexity I wanted to allow user to be able to select time as well.

I decided to use SPEAK DatePicker and TimePicker (not documented by Sitecore) components. I had to use two different components as DatePicker allows you to only pick up date.

Note: Sitecore SPEAK TimePicker component will appear in the design layout -> Add Renderings option and you can find its JavaScript files at this location WebsiteRoot\sitecore\shell\client\Business Component Library\version 2\Layouts\Renderings\Common\TimePickers

One might ask why is it a challenge? Well, before I could pass my date field value to my entity service I have to manipulate the date as the inputs are coming from two different fields and it should be in a way that Sitecore understands it on the servers side.

So I had three  different formats to handle -

  1. Combining Date and Time picker format
  2. JavaScript native date format 
  3. Sitecore server side ISO date format

Handling it on client side (in JavaScript)

I created these functions to help me combine DatePicker and TimePicker values (in "Thhmmss" format) and return me one single date as shown below


        GetDateTime: function (date, strTime) { //date is from DatePicker.getDate() & strTime is TimePicker.get("time") function
            if (date != null) {
                var dtNewDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
                console.log("Date without time: " + dtNewDate);
                if ((typeof strTime != 'undefined') || (strTime != "")) {
                    strTime = strTime.substring(strTime.indexOf("T")+1, strTime.length);
                    console.log("Time Value: " + strTime);
                    var hours = Math.floor(strTime.substring(0, 2)); //To avoid NaN values (if parseInt was used)
                    var mins = Math.floor(strTime.substring(2, 4));
                    var secs = Math.floor(strTime.substring(4, 6));
                    console.log("Hours : Minutes : Seconds =>  " + hours + " : " + mins + " : " + secs);
                    dtNewDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), hours, mins, secs, 0);
                }
                console.log("Date being returned : " + dtNewDate.toDateString());
                return dtNewDate;
            }
            else
                return null;
        },

Also once I retrieve date from Sitecore and if they happen to be blank (or not set) I have to show that appropriately on DatePicker and TimePicker components. For that I created couple of other functions

        GetDateString: function(date)
        {
            if (date.getFullYear() > 0) //Sitecore sets year as zero (if date is not set)
                return (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear(); //to show in mm/dd/yyyy format
            else
                return "";
        },

        GetTimeString: function (date) {
            if (date.getFullYear() > 0)
                return this.pad(date.getHours()) + ":" + this.pad(date.getMinutes());
            else
                return "";
        }

Handling it on ServerSide

Despite of date being sent appropriately to the entity service, when Sitecore was persisting the date it was setting the value as 1/1/0001. This was for a simple reason that you need to convert it into ISO date for Sitecore. I figured this out from this blog

So I had to do this:

StartTime = DateUtil.IsoDateToDateTime(entity.Fields["Start Time"].Value);


Few other important links from Sitecore documentation

Date / Time Types
Date / Time Best Practices
Date / Time Conversions

Hope this helps

Wednesday, July 20, 2016

Working with Sitecore SPEAK Chart Controls

This post will help some of you to speed up Sitecore SPEAK development wherein you need to use chart controls and avoid spending time figuring out why some of the things don't work the first time as expected.

Get your hands on some out of the box implementations right away

If you are implementing pages having chart controls, you need to look at this Sitecore SPEAK app and then start navigating into the implementation code on your local sitecore instnace. 

To access Sitecore SPEAK app that comes out of the box with default sitecore installations you need to navigate to this url http://sitecoreinstancename/sitecore/client/Applications/Demos/SpeakCharting/Area. From this page you can navigate to different chart implementation pages.

The codebase (javascript page files) and json data for all these pages are located in your website root folder at this path \SitecoreInstanceName\Website\sitecore\shell\client\Applications\Demos\SpeakCharting 

Getting the Chart Data

  1. For your chart to work, you need to add ChartDataProvider and any of the chart controls that you want to work with on your page / tab
  2. You may also create chart field definition items under your page settings to map it to CategoryChartField, SeriesChartField and ValueChartField (depending on the chart) as shown below
  3. ChartField Settings

  4. For your chart data provider, you may want to get data from your own APIs. If that is the case you can setup the DataUrl property of the ChartDataProvider to the path of your API e.g./api/sitecore/ReportData/GetPerformanceSummary where ReportData is your controller and GetPerformanceSummary is your controller action
  5. In your page code, create requestOptions object (which also can contain dataUrl if you dont want to set it up at design time in control properties)

  6.          var requestOptions = {
                  parameters: "",
                  onSuccess: function (result) {
                      app.getDataCallback.apply(app, arguments);
                  }, 
              };
    

  7. Very importantly, configure the error handler for ChartDataProvider so that you know if there are any issues retriving your chart data (in case you have any custom logic than simply getting and returning values from Sitecore)

  8.           this.ChartDataProvider.on("error", function (errorObject) {
                  console.log('Error in ChartDataProviderJobPerformance: ' + errorObject);
              });
    

  9. ChartDataProvider does not call your API until you yourself make a call to its getData function

  10.           this.ChartDataProvider.viewModel.getData(requestOptions);
    

Data Format and Helper Functions

Another important thing to note is ChartControls expect data in a specific Json format. I was returning valid list of json objects in this format [{}, {}, {}] but chart won't show up any data and no errors are thrown. Even ChartDataProvider was showing that it has the "data" property appropriately setup.

Now when I looked at some of the sample data json files in the location I mentioned before, I figured out that everything has some consistent structure.

So I created some helper functions to return my data in this format

{
  "data": {
    "dataset": [
      {
        "data": [
          { },
          { },
          { }
        ]
      }
    ]
  }
}


Helper Functions in my Controller to wrap my data in this format:

public static string GetJsonSerializedData(object data)
        {
            string jsonData = JsonConvert.SerializeObject(data, Formatting.None, new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });
            string requiredStructure = "{" +
                                    "\"data\": ";
            jsonData = jsonData.Insert(0, requiredStructure);
            jsonData = jsonData.Insert(jsonData.Length, "}");

            return jsonData;
        }

Please note: I am using Json.net Nuget package to serialize my entities into Json and I have to mention the format of the date to show it in human readable format. The list of objects is wrapped around the outer structure required for chart control to work.

public static string AddJsonHeader(string jsonData)
        {
            if (!String.IsNullOrEmpty(jsonData))
            {
                string requiredStructure = "{\"data\": {" +
                                            "\"dataset\": [";
                jsonData = jsonData.Insert(0, requiredStructure);
                jsonData = jsonData.Insert(jsonData.Length, "]}}");
            }
            return jsonData;
        }

Now after doing all this, I am able to see my chart data coming up and being shown nicely


SPEAK Chart


Hope this helps others working on SPEAK applications and using chart controls


Sunday, June 12, 2016

Handling NameValueList field types in Sitecore SPEAK

It was a  tedious task to handle NameValueList field type while I was working on building a Sitecore SPEAK application and one of my template had a NameValueList field type as an expected input from content authors which was the basis as list of parameters to pass it to my application. I had to keep it dynamic and hence I decided to use NameValueList as this can be configured for each item independently as key value pairs.

The problem I faced is to read this list of key value pairs and provide it as items to be bound to ListControl on my SPEAK page.

Natively, Sitecore stores NameValueList field as shown below (you can see this when you enable raw values)


NameValueField-Sitecore Content Editor View


NameValueField-Sitecore Raw Values View

I had to write two functions to deal with this field value in Sitecore SPEAK application, one to get list of json objects from this tokenized field value and another one to send it back to Sitecore in the format desired (tokenized string) from the list of json objects.

Snippet of the first function (to get list of Json objects as string) :

        GetJobDataMapJson: function (jobDataMap) {
            var jsonJobDataMap = [];
            var arrKeyValue = jobDataMap.split("&");

            if (arrKeyValue != null && arrKeyValue.length %gt; 0) {
                for (i = 0; i < arrKeyValue.length; i++) {
                    var arrKeyValuePair = arrKeyValue[i].split("=");

                    var newJobDataMap = {
                        "itemId": arrKeyValuePair[0],
                        "Key": arrKeyValuePair[0],
                        "Value": arrKeyValuePair[1]
                    };

                    jsonJobDataMap.push(newJobDataMap);
                }
            }

            console.log('Json Job Data Map as string : ' + JSON.stringify(jsonJobDataMap));
            return jsonJobDataMap;
        }

Please note the json property "itemId" that is being set as the same value as key. This is important if you are binding this json data to controls such as ListControl otherwise your events such as selectedItem etc will not work without having itemId

The second function (to translate json objects into namevalue string expected by Sitecore)

        GetJobDataMapString: function (jsonJobDataMap) {
            console.log('In GetJobDataMapString with ' + jsonJobDataMap);
            if (jsonJobDataMap != null && jsonJobDataMap.length > 0) {
                var jobDataMapString = "";
                for (i = 0; i < jsonJobDataMap.length; i++) {
                    jobDataMapString = jobDataMapString + jsonJobDataMap[i].Key + "=" + jsonJobDataMap[i].Value;

                    if (i < jsonJobDataMap.length - 1)
                        jobDataMapString = jobDataMapString + "&";
                }
                return jobDataMapString;
            }
        }

Finally the code for your ListControl to bind with this json data and your events to work

 
                   var jsonJobDataMap = app.GetJobDataMapJson(entity.JobData);
                   app.ListControl.set("items", jsonJobDataMap);

Hope this helps to someone trying to do something similar.


Saturday, May 14, 2016

Sitecore SPEAK MultiSelectList - Getting it to work

In my SPEAK application I wanted user to be able to select multiple options in a list. Sitecore SPEAK ListControl can be extended to be able to use it as a checkbox list / multiselect list. In this blog post I am explaining the workings of MultiSelectList control which is an extension of Sitecore SPEAK ListControl

  1. You need to first add a ListControl on your Sitecore page and a MultiSelectList component as shown below 



  2. Configure the ListControl "Behaviour" property as "MultiSelectList". Note: This is irrespective of the name / id of the control you have added in the first step. 



  3. This basically extends ListControl capabilities and make some of the additional functions available to your Javascript page code such as
        • checkItem(item)
        • checkItem(itemId)
        • checkItems(array of items)
        • checkItems(array of itemIds)
        • uncheckItem(item)
        • uncheckItem(itemId)
        • uncheckItems(array of items)
        • uncheckItems(array of itemIds)
  4. You would first bind the List control Items property under Data Bindings to the datasource component Items property (e.g. {Binding DataSource.Items})


  5. Now you would have a situation where you have all the items (original source) shown in the list and user selected option somewhere else that you are receiving perhaps by calling an Item web APIs OR entity service APIs. To ensure that you show the selected items appropriately you need ensure that the list control has items in the first place (i.e. data source has retrieved items from Sitecore). Here is how you do it


  6.  app.DataSource.on("change:hasItems", function () {
                    for (var i = 0; i < entity.UserSelectionsList.length; i++) {
                        app.ListControl.viewModel.checkItem(entity.UserSelectionsList.itemId);
                    }
    }
                });
    


  7. Her is how it looks like


Documentation for MultiSelectList control can be found here


Saturday, March 26, 2016

Sitecore Entity Service - Stack Overflow Exception

There is a very fine print in Sitecore Entity Service documentation available here as mentioned below

Note that an entity cannot contain a property of a type that is derived from Sitecore.Services.Core.Model.EntityIdentity.

There may be more behind this statement based on my experiment with entity service.

In one of my entity service the entity I was implementing, inheriting from EntityIdentity, I had list of weekdays selected by the end user and I used Days of week list to avoid creating my own list of items. Property looked like this

        private List<Item> _daysOfWeek;
        public List<Item> DaysOfWeeks
        {
            get
            {
                if (_daysOfWeek == null)
                    _daysOfWeek = new List<Item>();
                
                return _daysOfWeek;
            }
            set { _daysOfWeek = value; }
        }

Item could be any other Sitecore Item (system defined OR your own)

Now from my page code javascript when my entity service is trying to fetch an entity, it is not even hitting the FindById method of my repository inheriting from
Sitecore.Services.Core.IRepository
and the worker process crashes by throwing stack overflow exception.

Finally, I had to create my own class having itemId, itemName and certain other properties as a POCO class and had to write my own transformation logic to and from Sitecore items to my this entity. This resolved the problem

Hope this will help other people working on Sitecore Entity Service and facing StackOverflowException crashing their worker process (w3wp.exe)



Saturday, March 12, 2016

SPEAK Common Navigation Menu

Usually in your Sitecore SPEAK application you may have more than one pages in the application. Like any other application how do you tie them together through a common navigation which you want to maintain at one place rather than repeating it on every page. Here is a small post which will help you in achieving that.


  1. Let us assume you have 3 pages in a SPEAK application called "NewApp" as shown in the Pages folder in the picture below


  2. Speak Application Structure
    Speak Application Structure
  3. I also created a Navigation folder to maintain navigation related items in one place. This folder contains items of type "HyperlinkButton Parameters" and I added 3 items one for each page as shown below


  4. Adding-Navigation-Item

  5. Now configure each HyperlinkButton parameter item to point to a page you want to navigate to in its properties windows (when you double click that item in Sitecore Rocks - Sitecore explorer) - as shown below


  6. Configuring-HyperlinkButton-Parameter

  7. Do the same thing for Dashboard and EventListing pages


  8. Now setup the HyperlinkButton group on the Dashboard page with placeholder key as ApplicationContent.Navigation and Datasource location as shown below



  9. HyperlinkButtonGroup-Configuration


  10. Set the SelectedItemId of HyperlinkButton Group component to the the Dashboard Hyperlinkbutton properties definition item as shown in the above diagram


  11. Repeat steps 5 and 6 for Event Listing and Event Detail page setting SelectedItemID to respective Hyperlinkbutton properties definition item. If on other pages you dont have ApplicationContentNM or ApplicationContentNMI components - you may need to replace ApplicationContentMI component with the one of these two to have ApplicationContent.Navigation placeholder available for you to assign your HyperlinkButtonGroup component in that placeholder.


  12. Finally it should look like this


  13. Final-SPEAK-Common-Navigation-App


Hope this helps.

Saturday, February 13, 2016

Making Sitecore Habitat work with C# 6

Issue:


Post installation of Sitecore habitat locally, I was facing issues with runtime view compilations which are related to new C# syntax introduced in C# 6.0. The snapshot of an issue is shown below



Sitecore Habitat runtime issue related to C# 6.0
Yellow screen of death



Solution:


For this to work with ASP.NET MVC 5.x, you need to refer to the new CodeDom package from microsoft which adds compiler configuration to refer to the new codedom.

Add this section in your Habitat web.config inside configuration element