Sunday, 17 September 2017

WFFM : Customizing export form data to excel functionality

Leave a Comment
In previous blog posts, I have explained how to create custom SQL provider and custom save to database action to store form data into SQL database. If you’re interested to know the context of the customization, checkout this blog post. In this blog post, I’ll explain how to customize export form data to excel functionality so that form reports include user’s browser information.

Environment Detail

Sitecore 8.2 update 5 (CMS only mode), Web Forms for Marketers 8.2 rev. 170807

Implementation

I’ve decompiled Sitecore.WFFM.Services.dll assembly to find out the code which invokes export form data to excel functionality.

It seems that we cannot override few methods inside of Sitecore.WFFM.Services.Pipelines.ExportToExcel.ExportFormDataToExcel class. So I created a duplicate copy of this class and added my custom logic to include user’s browser information into form reports.

Add a patch config file to configure custom export to excel functionality:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
  <sitecore>
    <pipelines>
       <!--EXPORT TO EXCEL--> 
      <exportToExcel>
        <processor patch:instead="processor[@type='Sitecore.WFFM.Services.Pipelines.ExportToExcel.ExportFormDataToExcel, Sitecore.WFFM.Services']" type="Website.WFFM.Pipelines.CustomExportFormDataToExcel, Website" />
      </exportToExcel>
    </pipelines>    
  </sitecore>  
</configuration>
That's it! Comments and suggestions are most welcome. Happy coding!
Read More...

WFFM : Create custom Save to Database Action

Leave a Comment
In last blog post, I have explained how to create custom SQL provider to store form data into SQL database. If you’re interested to know the context of the customization, checkout the last blog post. In this blog post, I’ll explain how to create a custom save to database action.

Environment Detail

Sitecore 8.2 update 5 (CMS only mode), Web Forms for Marketers 8.2 rev. 170807

Implementation

  1. Create a new SaveToDatabaseAction class and inherit WffmSaveAction class.
  2. Write custom logic to add new FieldData to form field list dynamically while saving form data.

  3. Build the code and deploy assembly in bin folder of your Sitecore instance.
  4. Navigate to Sitecore content tree and create a new Save To Database save action under /sitecore/system/Modules/Web Forms for Marketers/Settings/Actions/Save Actions node.
  5. Add a config patch to specify WFFM connection string.
    <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
      <sitecore>
        <settings>
          <setting name="WFM.ConnectionString" value="wfm" set:value="wffm" />
        </settings>
      </sitecore>  
    </configuration>
  6. Select the relevant WFFM form and add Save To Database action in Save Actions.

  7.  Select the relevant WFFM form and in the Submit section, un-check Save Form Data To Storage checkbox so that form data won’t get saved multiple times into the SQL database.
  8. Publish Sitecore related changes.
In next blog post, I’ll explain how to customize export form data to excel functionality so that form reports include user’s browser information. Comments and suggestions are most welcome. Happy coding!
Read More...

WFFM : Customizing SQL form data provider

Leave a Comment

Requirement

I’ve got a task where I have to save user’s browser information (Browser name and version) into Sitecore WFFM SQL database as part of the every WFFM form submission. Website support team would like to know the user’s browser that is being used for accessing the production site, so that they don't have to request this information while troubleshooting any issues the user has reported via the Feedback/Troubleshooting Contact Us form.

Environment Details

Sitecore 8.2 update 5 (CMS only mode), Web Forms for Marketers 8.2 rev. 170807

Implementation

I’ve decided to customize WFFM save to database functionality and add new FieldData to form field list dynamically while saving form data. This new FieldData will consist user’s browser information (Browser name and version). This implementation can be achieved by below three ways:
  1. Customizing SQL form data provider
  2. Create new save to database action
  3. Create a custom field. 
We have to also modify export form data to excel functionality so that form reports include user’s browser information. In this blog post, I’ll explain how to create custom SQL provider to store form data into SQL database.

WFFM Configuration

In the \Website\Data folder of your Sitecore instance, attach the Sitecore_Wffm.mdf database to the SQL Server, and add a connection string with the name “wffm” in the ConnectionStrings.config file, located in the \Website\App_Config folder.
<add name="wffm" connectionString="Data Source=(local);Initial Catalog=instance_name_wffmDB;Integrated Security=False;User ID=sa;Password=12345"

Customizing SQL form data provider

  1. Create a new CustomSqlFormsDataProvider class and inherit SqlFormsDataProvider class.
  2. Write custom logic to add new FieldData to form field list dynamically while saving form data.

  3. Add a config patch as below to configure CustomSqlFormsDataProvider.
    <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
      <sitecore>
        <wffm>
          <analytics>
            <formsDataProvider patch:instead="*[@ref='/sitecore/wffm/analytics/analyticsFormsDataProvider']" ref="/sitecore/wffm/analytics/customSqlFormsDataProvider"/>
            <customSqlFormsDataProvider type="Website.WFFM.Providers.CustomSqlFormsDataProvider, Website">
              <param name="connectionStringName">wffm</param>
              <param name="settings" ref="/sitecore/wffm/settings"/>
              <param name="connectionProvider" ref="/sitecore/wffm/analytics/connectionProvider"/>
            </customSqlFormsDataProvider>
          </analytics>
        </wffm>
      </sitecore>  
    </configuration>
  4. Select the relevant WFFM form and in the Submit section, select Save Form Data To Storage checkbox.
  5. Publish Sitecore related changes. Build the code and deploy assembly in bin folder of your Sitecore instance.
In next blog post, I’ll explain how to create a custom save to database action. Comments and suggestions are most welcome. Happy coding!

Update:

After publishing this blog post, I had a nice fruitful conversation with Sitecore MVP Kamruz Jaman regarding this implementation. If you are not already using custom SQL provider in your solution then prefer to create a custom field to handle above scenario. Nevertheless, this WFFM blog post series will give you fair idea about how to customize SQL form data provider and export form data to excel functionality.

Read More...

Saturday, 9 September 2017

WFFM upgrade issue : List field values are empty in Form Designer

Leave a Comment
Recently, I was involved in Sitecore upgrade project and encountered few issues. In this blog post, I am going to explain the issue related to WFFM module upgrade. 

Issue

We have upgraded to Sitecore 8.1 Update 3 CMS only mode and upgraded WFFM module as well. After upgradation, we are seeing an issue in WFFM form designer. The problem is related to WFFM Radio List field or Drop List field in Form Designer where we are no longer able to see the list items which were present there before the upgrade.  See below screenshot:


Radio List field or Drop List field related item data was saved in Parameters field as you can see from the below  screenshot:


I’ve tested this functionality on vanilla Sitecore 8.1 update 3 + WFFM instance. After my initial troubleshooting, it seems that Sitecore WFFM 8.1 is now using Localized Parameter field to display the items in Radio List field or Drop List field.


WFFM 8.1: Whenever we create new form item, Radio List field or Drop List field value gets stored in Parameters and Localized Parameter field. Radio List field or Drop List field is using Localized Parameters field to show those values in the Form Designer

I’ve reached out to Sitecore support team and they have registered this behavior as a bug in the current version of the WFFM module. To track the future status of this bug report, please use the reference number 75227.

Since WFFM 8.0 Localized Parameters are used for the purpose of localization. There is a specific piece of code which was supposed to be executed as post upgrade action, but was not invoked. This code was supposed to copy value from Parameters fields to Localized Parameters to keep this upgrade transition seamless. Since, this code did not execute, intended didn't happen and we have faced the issue. This behavior is not reproducible in WFFM 8.2.

Solution

  1. As a workaround, you can manually copy the value from the Parameters field to the Localized Parameters field in your Radio List field or Drop List field items that are located under form items.
  2. If you have many forms/fields you can ask Sitecore support to provide a script that you can run against your Sitecore instance which will copy the value from the Parameters field to the Localized Parameters field. You have to run the given .aspx page and enter the full path to the folder where your web forms are located (e.g. “/sitecore/system/Modules/Web Forms for Marketers/Website” or “/sitecore/system/Modules/Web Forms for Marketers/library”) to the textbox field. Click the “Update” button. This will updated web forms in master database.
    I’ve modified the support patch to meet our requirements:
    • Web forms are located at many different places in the Sitecore content tree. We have to find out full path for every web form and repeat the update process for every web form. This process seems cumbersome. Though it is possible to specify common root for all form items, given script is designed to work on items from specific templates only. But it will be more expensive to traverse whole tree compared to specific form folders. I’ve modified the script to find out all the referrers of form template (/sitecore/templates/Web Forms for Marketers/Form {FFB1DA32-2764-47DB-83B0-95B843546A7E}) using Sitecore link database. You can also use Sitecore Powershell Extensions to achieve same output.
    • We want to avoid publishing operation as it may publish unwanted or work in progress changes to web database and make those changes live. In this case, I’ve modified database name in the script to modify web form field items in web database as well. So, there will not be a need to publish these changes from master to web database. However, please ensure to run script on master as well so that any subsequent publish does not overwrite your changes in web database.
Comments and suggestions are most welcome. Happy coding!
Read More...

Sunday, 3 September 2017

Sitecore - Get items associated with email reminder task

Leave a Comment
In Sitecore, you can schedule to send an email reminder to one or more users. Occasionally an author may wish to be reminded of something regarding the item he is working on. Sitecore Reminders are made just for that. They also make the Administrator's work easier, by providing a suitable way of notifying Editors and other staff members about changes needed to be made. Reminder settings for an item are set in the Tasks section:


You can also set reminder settings for an item by clicking on Set Reminder in Review Strip of Sitecore Content Editor Ribbon.


Recently I have stumbled upon a situation where I have to find out all the items which are configured to use Email Reminder task.  Execute below SQL query on Core database to get list of item ids which are configured to use Email Reminder task.
SELECT ItemId FROM Tasks WHERE taskType='Sitecore.Tasks.EmailReminderTask,Sitecore.Kernel'
Comments and suggestions are most welcome. Happy coding!
Read More...

Saturday, 15 July 2017

A serious error occurred : Sitecore Experience Editor

Leave a Comment
Last week I have written a blog post about how to solve a mysterious Experience Editor error "An error occurred". This time I have again stumbled upon a similar error in experience editor (Sitecore 8.1 update 3).
A serious error occurred please contact the administrator.
As stated in my last blog post that there could be multiple reasons of such type of error. I’ve started the troubleshooting and noticed below two exceptions in log file:

Exception 1:
ERROR Error processing command url:/-/speak/request/v1/expeditor/ExperienceEditor.Social.SocialCenter.GetMessagesCount error:System.InvalidOperationException: Could not retrieve request class for url:/-/speak/request/v1/expeditor/ExperienceEditor.Social.SocialCenter.GetMessagesCount
   at Sitecore.ExperienceEditor.Speak.Server.RequestHandler.Process(HttpContext context)
   at Sitecore.ExperienceEditor.Speak.Server.RequestHandler.ProcessRequest(HttpContext context)

Exception 2:
ERROR Error processing command url:/-/speak/request/v1/expeditor/Optimization.ActiveItemTest error:System.InvalidOperationException: Could not retrieve request class for url:/-/speak/request/v1/expeditor/Optimization.ActiveItemTest
   at Sitecore.ExperienceEditor.Speak.Server.RequestHandler.Process(HttpContext context)
   at Sitecore.ExperienceEditor.Speak.Server.RequestHandler.ProcessRequest(HttpContext context)
Solving exception 1:
Exception 1 was related to Sitecore Social connect. We are using Sitecore in CMS only mode and have disabled Sitecore Social Connector config files. After troubleshooting, I’ve archived below item in core database so that it won’t appear in experience editor ribbon
/sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Page Editor/Social
Solving exception 2:

Exception 2 was related to Sitecore Content Testing. We were not using Sitecore Content Testing and disabled all the App_Config\Include\ContentTesting\*.config files. After troubleshooting, I found that Content Testing related features are not completely disabled by disabling config files. I was able to disable content testing completely by disabling InjectOptimizationViewMode.js file. To disable js file, navigate to the \Website\sitecore\shell\client\Sitecore\ExperienceEditor\Pipelines\InitializePageEdit folder, and change the InjectOptimizationViewMode.js file extension to .disabled.

I hope this blog post is helpful to some of you and save few minutes of troubleshooting. If this solution doesn’t help you then make sure to check out other blogs/SO posts related to this error as there can be other reasons for this “A serious error occurred please contact the administrator” error.  Comments and suggestions are most welcome. Happy coding! 
Read More...

Saturday, 8 July 2017

An error occurred : Sitecore Experience Editor

Leave a Comment
Lately, I have been involved in Sitecore upgradation project and I ran into below error in Sitecore experience editor after upgradation to Sitecore 8.1 Update 3.
An error occurred
The problem appeared in all web browsers. A quick google search has pointed me to various blogs/SO posts related to this error. Unfortunately, these posts don’t help me in rectifying this error. Therefore I have decided to write a quick blog post for those experiencing same error. I was not seeing any javascript related issues in browser console window. I have started deeper investigation in Sitecore logs files and found that below exception was getting logged:
ERROR Could not map index document field to property "UpdatedDate" on type  : String was not recognized as a valid DateTime.
Exception: System.FormatException
Message: Could not map index document field to property "UpdatedDate" on type Sitecore.ContentTesting.ContentSearch.Models.SuggestedTestSearchResultItem : String was not recognized as a valid DateTime.
Source: Sitecore.ContentSearch
   at Sitecore.ContentSearch.DocumentTypeMapInfo.SetProperty(Object target, String propertyName, String documentFieldName, Object value)
   at Sitecore.ContentSearch.DefaultDocumentMapper`1.MapFieldValuesToType[TElement](IDictionary`2 fieldValues, TElement result, DocumentTypeMapInfo documentTypeMapInfo)
   at Sitecore.ContentSearch.DefaultDocumentMapper`1.MapToType[TElement](TDocument document, SelectMethod selectMethod, IEnumerable`1 virtualFieldProcessors, IEnumerable`1 executionContexts, SearchSecurityOptions securityOptions)
   at Sitecore.ContentSearch.LuceneProvider.LuceneSearchResults`1.<GetSearchResults>d__a.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Sitecore.ContentTesting.ContentSearch.TestingSearch.GetSuggestedTests()
   at Sitecore.ContentTesting.Data.SitecoreContentTestStore.GetSuggestedTests(DataUri hostItemDataUri, String searchText)
   at Sitecore.ContentTesting.Requests.ExperienceEditor.SuggestedTestsCountRequest.ProcessRequest()
   at Sitecore.ExperienceEditor.Speak.Server.Requests.PipelineProcessorRequest`1.Process(RequestArgs requestArgs)

Nested Exception

Exception: System.FormatException
Message: String was not recognized as a valid DateTime.
Source: mscorlib
   at System.DateTimeParse.ParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style)
   at Sitecore.ContentSearch.Converters.IndexFieldDateTimeValueConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
   at Sitecore.ContentSearch.Converters.IndexFieldUtcDateTimeValueConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
   at Sitecore.ContentSearch.Converters.IndexFieldStorageValueFormatter.ReadFromIndexStorage(Object indexValue, String fieldName, Type destinationType)
   at Sitecore.ContentSearch.DocumentTypeMapInfo.SetProperty(Object target, String propertyName, String documentFieldName, Object value)
This exception was related to Sitecore Content testing. We are using Sitecore in CMS only mode and not using Sitecore Content Testing feature. I’ve followed this KB article to disabled Content Testing in Sitecore 8.1 Update 3. I was still getting Experience editor error after changing the ContentTesting.AutomaticContentTesting.Enabled setting value to false in the App_Config\Include\ContentTesting\Sitecore.ContentTesting.config file. Therefore I have decided to disable OPTIMIZATION ribbon strip which is related to Content Testing functionality. Archive the /sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Optimization item in the core database. It will completely disable the Optimization tab in the Experience Editor.
There are Attributes and PageProfileSettings chunks on this tab that are not related to Content Testing. If you use these chunks, you can move the following items:
/sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Optimization/PageProfileSettings
/sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Optimization/Attributes
under the /sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Experience item.
After following the instructions above, I no longer saw the Content testing related exception in log files and “An error occurred” notification is also disappeared in the Experience Editor.

I hope this blog post is helpful to some of you and save few minutes of troubleshooting. If this solution doesn’t help you then make sure to check out other blogs/SO posts related to this error as there can be other reasons for this “An error occurred” error.  Comments and suggestions are most welcome. Happy coding!

Update:
 I've blogged about my second encounter with similar error in experience editor. Read it here.
Read More...

Saturday, 8 April 2017

Adding Delete subitems action to Sitecore Context Menu

Leave a Comment
I have been working with Sitecore Data Exchange Framework 1.3 and got into a situation where I wanted to remove all subitems of a specific item without deleting that specific item. For example, let’s consider the below screenshot of Sitecore content tree:
I am working on CD Catalog Pipeline Batch item of Sitecore Data Exchange Framework 1.3 and whenever I click on Run Pipeline Batch button available in Data Exchange Ribbon, it creates multiple items under CD Catalog item from XML file. I am developing and testing custom XML provider for Data Exchange framework thus there is a frequent need to delete all subitems under CD Catalog item except CD Catalog item folder. If I right click on CD Catalog item then Sitecore Context Menu gives me option to delete CD Catalog item which will eventually delete all subitems under it but I don’t want to delete CD Catalog item folder.

Although Sitecore provides an option to delete subitems of a particular item.  In this case, I have to follow below steps:
  1. I have to navigate away from current item CD Catalog Pipeline Batch and have to select CD Catalog item in content tree. 
  2. I have to make sure that HOME ribbon is selected. Click on Delete subitems button available in Operations chunk.
I prefer to delete items using Context Menu Delete action rather than HOME ribbon Delete action because I don’t want to navigate away from my current item and I am not always working on HOME ribbon. I like customizing Sitecore client interface to fit my personal requirements and to speed up the development. Adding Delete subitems functionality to Sitecore Context Menu is easy. Follow below steps to add Delete subitems functionality to Sitecore Context Menu:
  1. Login into Sitecore Client and select Core database.
  2. Navigate to /sitecore/content/Applications/Content Editor/Context Menues/Default/Delete
  3. You will find item:delete(id=$Target) in Message field. Clear the content of Message field. 
  4. Create a new child item under /sitecore/content/Applications/Content Editor/Context Menues/Default/Delete node using template /sitecore/templates/System/Menus/Menu item. Set item name as Delete.
  5. Enter item:delete(id=$Target) in Message field and set Display name as Delete. Also set Icon field.
  6. Create a new child item under /sitecore/content/Applications/Content Editor/Context Menues/Default/Delete node using template /sitecore/templates/System/Menus/Menu item. Set item name as Delete Subitems.
  7. Enter item:deletechildren(id=$Target) in Message field and set Display name as Delete Subitems. Also set Icon field.
  8. Navigate to Master database and right click on CD Catalog item. You will notice Delete Subitems action is available in Sitecore context menu.
Comments and suggestions are most welcome. Happy coding!
Read More...

Sunday, 2 April 2017

XML provider for Sitecore Data Exchange Framework 1.3 - Part 2

Leave a Comment
In the previous blog post, I have explained about Sitecore Data Exchange Framework 1.3 and how to build XML provider for Data Exchange Framework. In this blog post, I’ll explain how to create and populate Sitecore items from the contents of a XML stream using XML provider for Data Exchange Framework 1.3.

I’ve created a XML file from this web address that contains information about different Music CDs. Each CD node in the XML file represents a single music CD. Each CD will be represented in Sitecore as an item. The synchronization process will read the music CDs information from the XML file and create Sitecore items for each. If a Sitecore item already exists for a CD in the file, the Sitecore item will be updated with the information from the file.
<CATALOG>
 <CD>
  <TITLE>Empire Burlesque</TITLE>
  <ARTIST>Bob Dylan</ARTIST>
  <COUNTRY>USA</COUNTRY>
  <COMPANY>Columbia</COMPANY>
  <PRICE>10.90</PRICE>
  <YEAR>1985</YEAR>
 </CD>
 <CD>
  <TITLE>Hide your heart</TITLE>
  <ARTIST>Bonnie Tyler</ARTIST>
  <COUNTRY>UK</COUNTRY>
  <COMPANY>CBS Records</COMPANY>
  <PRICE>9.90</PRICE>
  <YEAR>1988</YEAR>
 </CD>
</CATALOG>

Using XML provider for Data Exchange Framework 1.3

  1. Make sure that Data Exchange Framework 1.3 Sitecore package and Sitecore Provider for Data Exchange Framework 1.3 Sitecore package are installed in your Sitecore 8.2 instance.   
  2. Download XML Provider for Sitecore Data Exchange Framework-1.3 Sitecore package and install in your Sitecore 8.2 instance.
  3. Create a XML file. I’ve uploaded one sample XML file here. You may place this file wherever you want, but it must be accessible from your Sitecore server.
  4. In Sitecore, open Content Editor. Navigate to sitecore > system > Data Exchange. Create a new item using Empty Data Exchange Template and name it as XML Provider CD Catalog Tenant.

  5. Tick the checkbox for field Enabled.

  6. Navigate to /sitecore/system/Data Exchange/XML Provider CD Catalog Tenant/Endpoints/Providers. An endpoint is needed to identify the source file within the synchronization process. First we must create the folder into which XML system endpoints can be added. Create new item using template XML Systems Endpoints Root. This template is a command template. It does not prompt for the item name. The command template assigns the item name automatically.

  7. Next we must add an endpoint to the folder. Navigate to /sitecore/system/Data Exchange/XML Provider CD Catalog Tenant/Endpoints/Providers/XML System. Create a new XML System Endpoint and name it as CD Catalog XML System Endpoint.

  8. In XML Path field, enter the path of XML file. I’ve placed XML file into root folder of website. The path can be either a local XML file or a web address returning XML Data (http or https).
  9. In XML Node Name field, enter name of XML node which will be used to get a collection of matching nodes from XML Data.  I’ve entered CD as XML Node Name.

Read More...

XML provider for Sitecore Data Exchange Framework 1.3 - Part 1

Leave a Comment
Sitecore released the first version of Data Exchange Framework with Sitecore 8.2 initial release. Sitecore has already released three updates of Data exchange framework and Sitecore Data Exchange framework 1.3 is the latest release available.

Data exchange framework allows you to the transfer the data between two systems. You can think of the Data Exchange Framework as standalone ETL (Extract Transform Load) tool that extracts data from the source system, transform it as appropriate and loads them into the target system. Sitecore can be one of the two systems - either the source or target but it is not mandatory. This framework can be used for exchanging data between any two independent systems. A typical example can be product sync between your ERP and a Digital Asset Management system using Data Exchange framework. Developers can build their own custom provider that allow 3rd party system to serve as source or target system.

Documentation for data exchange is available here and steps for implementing a new provider is documented very well. Follow instructions from Developer Guide to build your own custom provider. After reading through the official documentation I thought it would be nice to create a working custom provider thus I have implemented XML System Provider for Data Exchange Framework. This provider reads XML data from file or web address and creates items into Sitecore. If you ever desired to extract daily hundreds of entries out of a XML stream and put into Sitecore then this XML provider for Data Exchange Framework can make your task easy.
I am using Data Exchange Framework 1.3 and Sitecore 8.2 Update 2 release. I’ve divided this topic into two blog posts:
  1. Building XML Provider for Data Exchange Framework 1.3
  2. Use XML Provider for Data Exchange Framework 1.3

Configuring Data Exchange Framework 1.3

  1. Download Data Exchange Framework 1.3 Sitecore package and install it in your Sitecore 8.2 instance.
  2. Download Sitecore Provider for Data Exchange Framework 1.3 Sitecore package and install it in your Sitecore 8.2 instance.

Building XML provider for Data Exchange Framework 1.3

In this blog post I am not going to re-write the provided documentation, but will touch up high-level steps and configuration and provide the code I have written while playing with Data Exchange framework. The full source code of XML provider is located on GitHub. I strongly encourage you to follow official documentation step by step to build your own custom provider for Data Exchange framework.
  1. In Visual studio create a  new “Class library” project using .NET Framework version 4.5.2  
  2. Add references to below three assemblies:
    a.    Sitecore.DataExchange
    b.    Sitecore.DataExchange.DataAccess
    c.    Sitecore.Services.Core
  3. Add Template Folder for XML Provider. Follow the steps mentioned here in official documentation.
  4. Add Endpoint Template. An endpoint represents a data source. The data source may support the ability to read data, to write data, or to both read and write data. The endpoint does not provide the ability to interact with the data source. It simply represents the data source.
    Examples of endpoints are:

    a.    URL for a web service used to read data from a CRM
    b.    Path to a directory used to read files
    c.    Connection string used to connect to a relational database

    I’ve created XML system endpoint which has below two fields:

    XMLPath: The path can be either a local XML file or a web address returning XML Data (http or https).
    Web Address Example: https://www.w3schools.com/xml/cd_catalog.xml
    XMLNodeName: Name of XML node which will be used to get a collection of matching nodes from XML Data. For example, XMLNodeName will be CD in below XML document:
    <CATALOG>
     <CD>
      <TITLE>Empire Burlesque</TITLE>
      <ARTIST>Bob Dylan</ARTIST>
      <COUNTRY>USA</COUNTRY>
      <COMPANY>Columbia</COMPANY>
      <PRICE>10.90</PRICE>
      <YEAR>1985</YEAR>
     </CD>
     <CD>
      <TITLE>Hide your heart</TITLE>
      <ARTIST>Bonnie Tyler</ARTIST>
      <COUNTRY>UK</COUNTRY>
      <COMPANY>CBS Records</COMPANY>
      <PRICE>9.90</PRICE>
      <YEAR>1988</YEAR>
     </CD>
    </CATALOG>
    
  5. Implement Endpoint Settings Plugin. The Endpoint settings class will store the configuration information once information is extracted from the Endpoint Sitecore item.

  6. Implement Endpoint Converter. A converter is needed to convert a Sitecore item that represents a XML System endpoint into an endpoint component for Data Exchange Framework, and that adds the endpoint settings plugin to the endpoint component.

  7. Add Pipeline Step Template. A pipeline step is needed to represent a logic involved with reading XML data from an endpoint and handling the data that is read. A template is needed to represent the pipeline step. It allows the pipeline step to be configured. 
  8. Implement Pipeline Step Converter. A converter is needed to convert a Sitecore pipeline step into a pipeline step component for Data Exchange Framework, and that adds the settings configured on the pipeline step item using the appropriate plugin.

  9. Implement Pipeline Step Processor. A processor is needed to implement the business logic for the pipeline step.

  10. Add Value Accessor Template. A value accessor is the component that is used to read a value (value reader) from a source object or write a value (value writer) to a target object.

    Data Exchange FrameworkC#
    Value accessorProperty
    Value readerProperty getter
    Value writerProperty setter
    A value reader is a component that is able to read a value from the source object. For example, if the source object represents a XML node (<CD>) from XML document, you might want to read the value of any specific XML element or field (e.g.: TITLE or ARTIST).
    <CD>
      <TITLE>Empire Burlesque</TITLE>
      <ARTIST>Bob Dylan</ARTIST>
      <COUNTRY>USA</COUNTRY>
      <COMPANY>Columbia</COMPANY>
      <PRICE>10.90</PRICE>
      <YEAR>1985</YEAR>
    </CD>
    

    A value writer is a component that is able to write a value to the target object. Being able to write values is an essential part of mapping values from the source object to the target object.

  11. Implement Value Accessor Converter. A converter is needed to convert a Sitecore value accessor item into a value accessor component for Data Exchange Framework.

In next blog post, I’ll explain how to use XML provider for Data Exchange Framework 1.3. Comments and suggestions are most welcome. Happy coding!
Read More...

Wednesday, 8 March 2017

Sitecore Experience Editor : Save button is disabled

Leave a Comment
Recently I was involved in Sitecore 8.1 upgradation project and stumbled upon into a situation where save button was disabled in Experience Editor. I’d made text changes into many fields but save button was greyed out and was not allowing to save the text changes.

During troubleshooting, I’ve found that below error was appearing in web browser console:
TypeError: saveButtonState.onchange is not a function.
It seems the JavaScript used by Sitecore in edit mode and the JavaScript files in the webpage are conflicting somehow. When using the Experience Editor for editing pages that utilize the jQuery JavaScript library, editing might not function properly and few errors may occur. This can happen because the Prototype JavaScript library used by the Experience Editor may conflict with jQuery utilized by the page and cause the browser to interpret Prototype calls as jQuery ones. Prototype.js plug-in is also using the $ as the global variable.

To avoid editing issues in Experience Editor use jQuery JavaScript library in the No-Conflict mode. I’ve added below code in layout page to avoid conflict in the page editor mode.
@if (Sitecore.Context.PageMode.IsPageEditor)
{
<script>$.noConflict();</script>
}
Comments and suggestions are most welcome. Happy coding!
Read More...

Sunday, 26 February 2017

Part 4: Sitecore 8.2 with SOLR 6.2

Leave a Comment
Hello, Sitecore enthusiasts! This is the fourth article of Sitecore 8.2 with Solr 6.2 blog series.

Create a custom SOLR Core for custom search index

  1. Copy the sitecore_configs (C:\Bitnami\solr-6.2.1-2\apache-solr\server\solr\configsets\sitecore_configs) folder and paste it in C:\Bitnami\solr-6.2.1-2\apache-solr\server\solr. Rename it to the sitecore_custom_master_index. Refer to this blog post for more information.
  2. Navigate to the Solr admin page.
  3. After login, navigate to Core Admin page and click on "Add Core" button.
  4. Fill in the 'name' and 'instanceDir' fields with sitecore_custom_master_index, and press the "Add Core" button to add the core into Solr. 
  5. You should be able to see that sitecore_custom_master_index core is now present in the list of cores available in your Solr instance.
  6. Repeat above steps and add a new core sitecore_custom_web_index.

Create custom index configuration file for custom SOLR core

  1. In our Sitecore project we should first add a custom .config file for our custom SOLR Core. Navigate to /App_Config/Include/ folder and add a new config file and name it as Sitecore.ContentSearch.Solr.Index.Custom.Master.config.
  2. Copy configuration contents from config file Sitecore.ContentSearch.Solr.Index.Master and paste it in newly created config file Sitecore.ContentSearch.Solr.Index.Custom.Master.config
  3. Open Sitecore.ContentSearch.Solr.Index.Custom.Master.config file and make below changes: 
    • Index Id : Index should be the same as it is in SOLR
      <index id="sitecore_custom_master_index" type="Sitecore.ContentSearch.SolrProvider.SolrSearchIndex, Sitecore.ContentSearch.SolrProvider">
    • Configuration : We’ll need an additional configuration file inside our project for new custom core. This configuration will connect our Sitecore Item and SOLR during rebuilding of indexes. All settings from this configuration file will be taken in during that process. Within the configuration file, you can specify new fields types and computed fields.
      <configuration ref="contentSearch/indexConfigurations/customSolrIndexConfiguration" />
    • Strategies : Here you can specify indexing update strategy.
    • Database : Database which we want to crawl.
      <Database>master</Database>
    • Root : Content root path from where we want to crawl.
      <Root>/sitecore</Root>
  4. Repeat above steps for sitecore_custom_web_index. Update index id as sitecore_custom_web_index and database as web in Sitecore.ContentSearch.Solr.Index.Custom.Web.config file.
  5. We have to create an additional configuration file inside our project for new custom core. Duplicate config file Sitecore.ContentSearch.Solr.DefaultIndexConfiguration.config and rename it as Sitecore.ContentSearch.Solr.CustomIndexConfiguration.config. Rename <defaultSolrIndexConfiguration> as <customSolrIndexConfiguration> in configuration file. We can define which templates we want to include in our index, we can add a custom computed field into our index and connect it to a class inside our project. There are a lot of settings in this file and you should customize them to your needs.
  6. The last step is to rebuild our custom index in Sitecore’s Index Manager. Go to Control Panel -> Indexing Manager and rebuild sitecore_custom_master_index and sitecore_custom_web_index.

Key Content Search Settings

Below are the several key settings which you should be aware of when using the Sitecore Content Search layer:
  1. ContentSearch.SearchMaxResults : This controls how many documents are returned to Sitecore when it queries Solr.  The default is 500 documents which is plenty.  Know that requests to Solr are made over HTTP, therefore the more requests you receive, the larger the response payload will be.
  2. ContentSearch.Solr.ServiceBaseAddress : This points to Solr, you should be able to take the value of this setting, paste it in a browser and get directly to Solr.
  3. ContentSearch.Update.BatchModeEnabled : Enabling this will certainly help committing documents to Solr when you are rebuilding or updating an index.
  4. ContentSearch.Update.BatchSize : This is used when the above setting is set to true.
  5. ContentSearch.EnableSearchDebug : Set this to true while you are debugging your search queries. You will also need to make sure log4net is also set to at least DEBUG.

Multiple Solr cores

For optimal performance Sitecore recommends that you always use multiple cores for your indexes. If you store all indexes in the same core, when you update an index the contents of all the other indexes in the same core are also cleared. As it is possible to rebuild indexes individually, some indexes will be left empty after rebuild. If you store each default index in a separate Solr core the names of these cores should match the names of the Sitecore indexes.
Multiple Solr cores may improve the performance of your search and indexing. For example, you should use separate cores for each index in a production environment and only share indexes on a single core in a development environment. The Solr website provides more detailed guidance and advice when configuring Solr.
Related read:
Comments and suggestions are most welcome. Happy coding!
Read More...