Sitecore and GatherContent Integration | Part-2 | Challenges and Solution

In an earlier post, I wrote an overview on Sitecore and GatherContent Integration Overview and the challenges we faced. In this post, you’ll see many other challenges that we faced with GatherContent and Sitecore Integration and how to crack them.

I got the source code of GatherContent Module thanks to the devs. It’s also available on GitHub.

We faced many challenges with it, but we managed to fix the issues one by one and get it to work. Some of them were fixed by the GatherContent Dev Team.

Most of the changes were done in GatherContent.Connector.SitecoreRepositories project.

Challenges:

  1. Different folder structure
  2. Zero-width space
  3. Blank space in GatherContent
  4. Sitecore General link, Number and Checkbox support
  5. Alt Text for Images
  6. Redirect Rule Issue

Here’s how we resolved them

  1. Different folder structure
    – By Default, GatherContent store images in /Sitecore/media library/GatherContent/*ItemName* — This was fixed by the GatherContent Developer. They provided an option to provide the path in the configuration, which was extremely helpful.

At that point, we had a couple of more templates to be mapped. All the items that you import from GatherContent will have the images folder inside stored in /Gather Content/* – This was going to be very big as the data from GatherContent is large. So I added an option for the required templates in the separate folders, so that folders are categorized properly and no folder will have many child image folders.

This was getting referred to in SimpleMediaRepository.cs. In the constructor, just set the proper names and in the ResolveMediaPath function, and set the proper data source path for each item template. You can do the required template check as per your needs.

public virtual string ResolveMediaPath(CmsItem item, Item createdItem, CmsField cmsField)
        {
            string path;

            //Field scField = createdItem.Fields[new ID(cmsField.TemplateField.FieldId)];
            //string dataSourcePath = GetItem(scField.ID.ToString())["Source"];
            //if (!string.IsNullOrEmpty(dataSourcePath) && GetItem(dataSourcePath) != null)
            //{
            //	path = dataSourcePath;
            //}
            //else
            //{

            if (string.Equals(item.Template.TemplateName.ToLower(), "deal"))
            {
                path = string.IsNullOrEmpty(cmsField.TemplateField.FieldName)
                    ? string.Format(DealsFolderRoot + "/{0}/", ItemUtil.ProposeValidItemName(item.Title))
                    : string.Format(DealsFolderRoot + "/{0}/{1}/", ItemUtil.ProposeValidItemName(item.Title), ItemUtil.ProposeValidItemName(cmsField.TemplateField.FieldName));

                SetDatasourcePath(createdItem, cmsField.TemplateField.FieldId, DealsFolderRoot);
            }
            else if (string.Equals(item.Template.TemplateName.ToLower(), "event"))
            {
                path = string.IsNullOrEmpty(cmsField.TemplateField.FieldName)
                    ? string.Format(EventsFolderRoot + "/{0}/", ItemUtil.ProposeValidItemName(item.Title))
                    : string.Format(EventsFolderRoot + "/{0}/{1}/", ItemUtil.ProposeValidItemName(item.Title), ItemUtil.ProposeValidItemName(cmsField.TemplateField.FieldName));

                SetDatasourcePath(createdItem, cmsField.TemplateField.FieldId, EventsFolderRoot);
            }
            else
            {

                path = string.IsNullOrEmpty(cmsField.TemplateField.FieldName)
                    ? string.Format(MediaFolderRoot + "/{0}/", ItemUtil.ProposeValidItemName(item.Title))
                    : string.Format(MediaFolderRoot + "/{0}/{1}/", ItemUtil.ProposeValidItemName(item.Title), ItemUtil.ProposeValidItemName(cmsField.TemplateField.FieldName));

                SetDatasourcePath(createdItem, cmsField.TemplateField.FieldId, MediaFolderRoot);
            }
            //}

            return path;
        }

You can customize the folder structure for different templated items getting imported into Sitecore by using this method.

2. Zero-width space

In the Geo-Location field — there was one junk character coming to the Sitecore. It wasn’t visible at all. You’ll see it when you move the blinking keyboard cursor using arrow keys in the beginning or at the end. I tried to investigate what that character was and I found that it’s the Zero-width space getting added in GatherContent. So, it’s clear — when an item is getting imported from Gather, we have to remove the Zero-width space from the data. The problem is on the GatherContent side which affects the website.

We faced this for many fields in Sitecore like Checkbox, General Link and Number field. So during import, we just replaced \u200B (Unicode of Zero-width space) with an empty string.

3. Blank space in GatherContent

The ContentAuthor can press Shift+Enter to go to the new line in the Plain-Text field in the GatherContent. When the item was imported it had (tab) four spaces between the content where Shift+Enter was pressed. To solve, just replace the spaces with the empty string. I did that for the required fields in Sitecore.

if (cmsField.TemplateField.FieldType == "Multi-Line Text" || cmsField.TemplateField.FieldType == "Rich Text")
{
    value = value.Replace("    ", String.Empty);
}

4. Sitecore Checkbox, Number, General link field support

MappingsController in GatherContent.Connector.WebControllers has the mapping stored between the GatherContent template and Sitecore template. You can customize the required mapping here and modify the importing logic in ItemsRepository.

Checkbox: Initially, I used the Plain-Text field in GatherContent and added a note which says – 0 means false and 1 means true. But then the best way I found is to have one checkbox. When checked — map 1 with Sitecore checkbox and if untick in Gather, map 0 with Sitecore checkbox.

In the ItemsRepository added the following code in the MapText function.

case "Checkbox":
    {
        value = string.Empty;
        var val = StringUtil.RemoveTags(cmsField.Value.ToString().Replace("\u200B", "")).Trim();
        if (val == "1")
        {
            value = "1";
        }
        else
        {
            value = "0";
        }
        break;
    }

General Link – This was added by the GatherContent dev team. Similarly, as the checkbox, General Link logic is added in the Items Repository.

5. Image Alt Text – By default, Alt text field is empty in Sitecore. I used a short and meaningful description which we used as an ALT, so while adding the image I modified the code to add the alt text of an image as soon as the image was created in Sitecore. The change is in ItemsRepository for passing the proper alt text to CreateMedia() function in the SimpleMediaRepository for adding the alt text after creating an image item.

6. Lowercase URL Redirect Rule

After one of the deployments, the connector stopped working. In that deployment, one of the changes which were deployed was enforcing lowercase redirect rule in the config file, which was affecting the .asmx web service. Internally — GatherContent call the web service — http://sitecoreinstance/services/mappings.asmx

When you try to import/update, you’ll see the following error. It is because Soap requests to web service are case sensitive.

The solution is to negate .asmx from the redirect rule.

<add input="{URL}" negate="true" pattern="\.asmx" ignoreCase="true" />

You can see the changes on GitHub — https://github.com/nikkipunjabi/gathercontentsc7

If you have faced any such issue and solved it, please share your solve in comments section.

Happy Sitecoring!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.