Sitecore 8.2 Rendering Issues

We experienced issues with shared layout on few of our pages. Presentation assembling seemed not following Presentation Detail Information Flow.

Based on Sitecore documentation this is a flow

rendering

 

  • SharedLayout option uses __Rendering field
  • FinalLayout option uses __Final Rendering field
  • Going from right to left, if a field has a layout delta, it goes to the field to its left to gather more presentation information.

After the investigation we noticed that on Save Button click in Experience Editor, the full share layout is saved and not the delta in __rendering fields. ( in case when a page is inheriting renderings from standards values).

Sitecore provided us with a patch. You can request one – the reference number is 144214

Is your xDB Cloud Consumption plan right for you ?

When I join my current project first thing I did as architect is an audit.  Make sure that architecture is optimized for current traffic and all best practices has been followed.  The client website use Sitecore xDB Cloud with xDB Plus subscription. It allows you up to 250 000 contacts at anytime and up to 2 500 000 interactions per month.

Contacts

How it’s measured: Total identified contact stored at any time.

Interactions

How it’s measured: Net new interaction created in a given period of time.

I check our current consumption to find out that we can switch to xDB base subscription and pay 30% of what are paying right now.

In some cases you better pay overage price before switch to the next subscription plan.

2017-10-24 11_42_15-xDB - Sales Enablement - March 2015 V2.pptx [Protected View] - PowerPoint

In case you want to generate your own reports or load data directly from mongo, you can access to your xDB database using and mongo viewer application.
Open your connectionstrings.config file and find the “analytics” connection string:
mongodb://{user-name}:{password}@{host1}:{port1},{host2}:{port2}/{guid}-Analytics?ssl=true;replicaSet={hostX}
You have replicaset on XdbCloud so use the host1 and port1 to connect.
Set up values in the following way:

con 2

con 2

But the best approche is to use  sitecore xDB Cloud API

https://gateway-xdb-scs.cloud.sitecore.net/api/xdb/Consumption/licenseId/deploymentId/year/month

where

  • licenseId – your Sitecore license ID
  • deploymentId – the unique identification of the deployment
  • year – the consumption year
  • month – the consumption month

Important

To ensure that your customers only access their own xDB sets, you must use a valid authentication token whenever you make a call to the xDB Cloud API. You can generate these tokens by using a valid Sitecore license file to call the SSO Encode Sitecore License endpoint. You must include the generated token as a HTTP header in all other requests called X-ScS-Nexus-Auth.

Visit this page -> xDB Cloud Consumption

Dynamic Multi Layer Image using Sitecore Custom Handler

In a few Sitecore projects that I was working on, we needed an image based on unlimited combination of sub layers.

For example, for one of our clients, on every product page, we had an image with a map of the United States and Canada with highlighted regions where their products were available (see image below). To render this map and generate the image on the fly, we needed a mechanism. We couldn’t afford to have combinations for each 50 states, 10 provinces and 3 territories.

regional availability

Map of North America with Highlighted Regions

In order to display this image I had to identify the regions to be highlighted as a parameter.

<img src="/~/map/all,ca_quebec,ca_atlantic,ca_ontario,ca_western,us_west,us_north_west,us_south_west,us_central,us_north_east,South%20East.jpg" alt="">

Another example is a shower configuration tool. For the customers/end-users, our vision was to create an immersive, engaging and personalized user experience with the shower/tub shower configuration tool (see pictures below). Users can thus build their dream shower by using all available parts and preview it in real time while building their shopping list. Once again, think about all the variants involved to be combined (bases, tiles on the wall, and shower doors).

Here is a solution that I came with in order to ease the code and save time :

Register a new custom handler

1.       Add a new custom handler configuration into node

<customHandlers>
      <handler trigger="~/map/" handler="maax_map.ashx"/>
 </customHandlers>

2.  Add a new custom handler configuration into handlers node

<handlers>
.
.
.
   <add verb="*" path="maax_map.ashx" type="Maax.Classes.ImageHandler, MaaxWebsite" name="Maax.ImageHandler" />
.
.
.
 </handlers>

3.Add custom halnder into node

 <httpHandlers>
.
.
.
 <add verb="*" path="maax_map.ashx" type="Maax.Classes.ImageHandler, MaaxWebsite" />
.
.
.
</httpHandlers>

4. Code your own handler

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections;
using System.IO;
using System.Web.SessionState;
using System.Drawing;
using System.Drawing.Imaging;

using Sitecore.Data.Items;
using Sitecore.Data.Fields;

namespace Maax.Classes
{
    public class ImageHandler : IHttpHandler, IRequiresSessionState
    {
        private const string sessionMAP = "MAP";
        private string XLen = "110";
        private string YLen = "110";

        /// <summary>
        /// Get All Regions
        /// </summary>
        public List<Item> AllRegions
        {
            get
            {
                string query = "/sitecore/content/Meta-Data/Regional Contacts/Regions/*";
                return MaaxProductRepository.CurrentDatabase.SelectItems(query).ToList();
            }
        }

        #region IHttpHandler Members

        public bool IsReusable
        {
            get { return true; }
        }
        /// <summary>
        /// Respond to all request of /~/map/  This params is set in web.config file
        /// </summary>
        /// <param name="context"></param>
        public void ProcessRequest(HttpContext context)
        {
            //Hashtable used to store images created on the fly in session to be reuse later
            Hashtable ht;

            if (context.Request.FilePath != null)
            {
                //extract of the key from url t
                string key = context.Request.FilePath.Substring(7, (context.Request.FilePath.Length - 11));

                if (context.Session[sessionMAP] != null)
                {
                    //check if hashtable allready exist in session
                    ht = (Hashtable)context.Session[sessionMAP];
                    if (!ht.ContainsKey(key))
                    {
                        byte[] bitmapData = CreateImage(key);
                        ht.Add(key, bitmapData);
                    }
                }
                else//if not we have to create it
                {
                    ht = new Hashtable();
                    byte[] bitmapData = CreateImage(key);
                    ht.Add(key, bitmapData);
                    context.Session[sessionMAP] = ht;

                }

                Byte[] arrImg = (byte[])ht[key];
                if (arrImg != null)
                {
                    context.Response.Clear();
                    context.Response.ContentType = "image/jpeg";
                    context.Response.BinaryWrite(arrImg);
                    context.Response.End();
                }
            }
        }
        /// <summary>
        /// Create map image based on regions keyes
        /// </summary>
        /// <param name="key"></param>
        /// <returns>JPEG image in binairies array</returns>
        private byte[] CreateImage(string key)
        {
            try
            {

                string[] regions = key.Split(',');
                string background = regions[0];
                //verifying dimention of background image

                Item itm = AllRegions.First(s => s["Code"] == background);
                ImageField backgroundImageField = itm.Fields["ImageOverlay"];
                int width = int.Parse(backgroundImageField.Width);
                int hight = int.Parse(backgroundImageField.Height);

                using (Bitmap bit = new Bitmap(width, hight))
                {
                    Graphics g = Graphics.FromImage(bit);
                    // fill with background
                    g.Clear(Color.White);

                    foreach (string region in regions)
                    {
                        //extraction png images from region item
                        Item found = AllRegions.First(s => s["Code"] == region);
                        ImageField imageField = found.Fields["ImageOverlay"];
                        MediaItem mediaItem = imageField.MediaItem;
                        if (mediaItem != null)
                        {
                            Stream fStream = mediaItem.GetMediaStream();
                            if (fStream != null)
                            {
                                //drawing region image on background
                                Image img = Image.FromStream(fStream);
                                g.DrawImage(img, 0, 0, width, hight);

                            }
                        }
                    }

                    MemoryStream ms = new MemoryStream();
                    bit.Save(ms, ImageFormat.Jpeg);

                    byte[] bitmapData = ms.ToArray();
                    return bitmapData;
                }
            }
            catch
            {
                return null;
            }
        }

        #endregion
    }
}

Sitecore Print Experience Manager Case Study at Montreal Sitecore User Group

I had a pleasure in February to present a case study of Sitecore Print Management Studio at Montreal Sitecore User Group hosted by Nexio.  The solution implemented by client and Nexio was first in Quebec. It helped client to save a lot on money but more importantly ensure brand consistency, streamline the production process to reduce the time of creation of digital price book from 6 to 8 months to few weeks.

screen

To find out more, please see slides from my presentation. I would like to thank Nexio to allow me to share with a community.

Sitecore Meetup PXM