Surendra Sharma

Surendra Sharma

Search This Blog

Friday, September 7, 2018

Course : Getting started with Azure Tools

Today I successfully completed one more course certification "Getting started with Azure Tools" from Udemy. Its a 6.5 hours of free course delivered by Payal Shah.

Getting started with Azure Tools
Getting started with Azure Tools

In this course I learned
  • Introduction
  • Azure Functions
  • Azure Logic Apps
  • Azure Cosmos DB
  • Azure Event Grid
  • Azure IoT Hub
  • Azure DevTest Labs
  • Azure Key Vault
  • Azure Storage Account

I encourage everybody to attend this useful course on AZURE.

Sunday, September 2, 2018

Course : Introduction to Python for Data Science

Finished the course "Introduction to Python for Data Science" successfully on EDX offered by Microsoft by 98%.

Introduction to Python for Data Science
Introduction to Python for Data Science

I study below modules in this course
1. Python Basics
2. List - A Data Structure
3. Functions and Packages
4. Numpy
5. Plotting with Matplotlib
6. Control Flow and Pandas
7. Final Exam and Course Wrap-up

Tuesday, August 28, 2018

Sitecore Event: Move item to datewise folder automatically based on date field


You may have items such as news, publication, blog, events etc. that contain date field.

Its great to show these items according to datewise so that each item should place in "YYYY > MMM > dd" path. This type of content structure is good to locate the item quickly.

Whenever content editor creates such item with specified date and save the item, our job is to fire an event to move that item in the respective date folder. If date folder is not exist then it should be created automatically and move the item into that.

In below image there are two year folders - 2017 and 2018. I am adding new item "Test News Article 111" and selected its date as "12-Feb-2016". When I click on save button, my event automatically created folders 2016, February and 12 and moved the item under that.

Moving news item to datewise folder automatically
Moving news item to datewise folder automatically


Implementation Details

Create 3 template items in Sitecore for Year, Month and Date at path “/sitecore/templates/Project/Common/Content Types” as below

Name – Year Folder
Template - /sitecore/templates/System/Templates/Template
Icon - Business/32x32/calendar.png

Name – Month Folder
Template - /sitecore/templates/System/Templates/Template
Icon - Business/32x32/calendar_31.png

Name – Day Folder
Template - /sitecore/templates/System/Templates/Template
Icon - Business/32x32/calendar_7.png

Create constant to specify different news items details as
 
namespace Sitecore.Foundation.SitecoreExtensions
{
    using Sitecore.Data;

    public struct Constants
    {
        public struct DateWiseStructure
        {
            public static readonly ID NewsArticleTemplateID = new ID("{B69277AD-E917-4B9F-9136-A12E0A3E462F}");
            public static readonly ID NewsArticleParentID = new ID("{FBF578DE-0640-43CF-91C1-492ECD093BC4}");
            public static readonly string NewsDateFieldName = "NewsDate";
            public static readonly ID YearFolderItemTemplateID = new ID("{B64C595D-FE20-44B1-96CC-38F292730437}");
            public static readonly ID MonthFolderItemTemplateID = new ID("{F1183F76-17AC-4DF3-877C-85726A16EECA}");
            public static readonly ID DayFolderItemTemplateID = new ID("{A443C72F-8A0B-4816-BCEF-D537905A7331}");
        }
    }
}

To implement such functionality, we need to write below code for Save event

using Sitecore.Collections;
using Sitecore.Data;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
using Sitecore.Data.Managers;
using Sitecore.Globalization;
using Sitecore.SecurityModel;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Sitecore.Foundation.SitecoreExtensions.Extensions
{
    /// <summary>
    /// Save Event to create folder struture datewise in Sitecore content tree
    /// </summary>
    public class ItemSaveEventHandler
    {

        /// <summary>
        /// Check language version is exist for the item
        /// </summary>
        /// <param name="item"></param>
        /// <param name="contextLanguage"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool HasGivenLanguageVersion(Item item, Language contextLanguage, Database database)
        {
            try
            {
                if (item != null && item.Languages != null && contextLanguage != null)
                {
                    Item languageSpecificItem = database.GetItem(item.ID, contextLanguage);
                    if (languageSpecificItem != null && languageSpecificItem.Versions.Count > 0)
                    {
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                Sitecore.Diagnostics.Log.Error("Error while checking language version of item " + item.ID + " Error is " + ex, typeof(BasicUtil));
            }

            return false;
        }

        /// <summary>
        /// Save Event method to create folder struture datewise in Sitecore content tree
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        public void OnItemSaved(object sender, EventArgs args)
        {
            if (args == null || Sitecore.Context.Site.Name.ToLower().Equals("publisher")) return;

            Item itemToOrganize = Sitecore.Events.Event.ExtractParameter(args, 0) as Item;

            if(itemToOrganize == null || itemToOrganize.Name.ToLower().Equals("__standard values") || !itemToOrganize.TemplateID.Equals(Constants.DateWiseStructure.NewsArticleTemplateID))
            {
                return;
            }

            Item parentOfTypeAutosave = null;
            Database master = Sitecore.Configuration.Factory.GetDatabase("master");

            parentOfTypeAutosave = SitecoreUtil.GetItem(Constants.DateWiseStructure.NewsArticleParentID, master);

            if (parentOfTypeAutosave == null || BasicUtil.IsOfTypeFolder(itemToOrganize)) return;

            string dateFld = string.Empty;

            ID dayFolderTemplateID;
            if (itemToOrganize.TemplateID.Equals(Constants.DateWiseStructure.NewsArticleTemplateID))
            {
                dateFld = Constants.DateWiseStructure.NewsDateFieldName;
                dayFolderTemplateID = Constants.DateWiseStructure.DayFolderItemTemplateID; //Day Folder Template ID
            }
            else
            {
                return;
            }

            Item _currentYearItem = null;
            Item _currentMonthItem = null;
            Item _currentDayItem = null;
            bool _yearFolderExist = false;
            bool _monthFolderExist = false;
            bool _dayFolderExist = false;
            DateTime date = ((DateField)itemToOrganize.Fields[dateFld]).DateTime.Date;

            LanguageCollection languages = LanguageManager.GetLanguages(master);
            Item langItem = null;
            DateTime langDate = DateTime.MinValue;
            if (date == DateTime.MinValue)
            {
                foreach (Language language in languages)
                {
                    if (HasGivenLanguageVersion(itemToOrganize, language, master))
                    {
                        langItem = master.GetItem(itemToOrganize.ID, language);
                        langDate = ((DateField)langItem.Fields[dateFld]).DateTime.Date;

                        if (langDate != DateTime.MinValue && date < langDate)
                        {
                            date = langDate;
                        }
                    }
                }
            }

            List<Item> yearItems =
                parentOfTypeAutosave.Children.Where(
                    x => x.TemplateID.Equals(Constants.DateWiseStructure.YearFolderItemTemplateID) && x.Name.Equals(date.ToString("yyyy"))).ToList();

            if (yearItems.Any())
            {
                _yearFolderExist = true;
                _currentYearItem = yearItems.First();
                List<Item> monthItems = _currentYearItem.Children.Where(x => x.TemplateID.Equals(Constants.DateWiseStructure.MonthFolderItemTemplateID) &&
                    x.Name.ToLower().Equals(date.ToString("MMMM").ToLower())).ToList();

                if (monthItems.Any())
                {
                    _monthFolderExist = true;
                    _currentMonthItem = monthItems.First();

                    List<Item> dayItems = _currentMonthItem.Children.Where(x => x.TemplateID.Equals(dayFolderTemplateID) && x.Name.Equals(date.ToString("%d"))).ToList();

                    if (dayItems.Any())
                    {
                        _dayFolderExist = true;
                        _currentDayItem = dayItems.First();
                    }
                    else
                    {
                        _dayFolderExist = false;
                    }
                }
                else
                {
                    _monthFolderExist = false;
                }
            }
            else
            {
                _yearFolderExist = false;
            }

            if (!_yearFolderExist)
            {
                using (new SecurityDisabler())
                {
                    TemplateID yearTemplateId = new TemplateID(Constants.DateWiseStructure.YearFolderItemTemplateID);
                    _currentYearItem = parentOfTypeAutosave.Add(date.ToString("yyyy"), yearTemplateId);
                }
            }
            if (!_monthFolderExist)
            {
                using (new SecurityDisabler())
                {
                    TemplateID monthTemplateId = new TemplateID(Constants.DateWiseStructure.MonthFolderItemTemplateID);
                    _currentMonthItem = _currentYearItem.Add(date.ToString("MMMM"), monthTemplateId);
                }
            }
            if (!_dayFolderExist)
            {
                using (new SecurityDisabler())
                {
                    TemplateID dayTemplateId = new TemplateID(dayFolderTemplateID);
                    _currentDayItem = _currentMonthItem.Add(date.ToString("%d"), dayTemplateId);
                }
            }
            if (itemToOrganize.Parent.Name.Equals(_currentDayItem.Name)
                && itemToOrganize.Parent.Parent.Name.Equals(_currentMonthItem.Name)
                && itemToOrganize.Parent.Parent.Parent.Name.Equals(_currentYearItem.Name)) return;

            using (new SecurityDisabler())
            {
                itemToOrganize.MoveTo(_currentDayItem);
            }
        }
    }
}

Create custom config file to register this event as

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
    <sitecore>
        <events>
            <event name="item:saved">
                <handler type="Sitecore.Foundation.SitecoreExtensions.Extensions.ItemSaveEventHandler,Sitecore.Foundation.SitecoreExtensions" method="OnItemSaved"/>
            </event>
        </events>
       
    </sitecore>
</configuration>

That’s it.

Now whenever you are creating any such news item, it will move to correct date folder.

Note :- If you have not specified any value in date fields then that item will move to 0001 > 01 > 01 folder.

I hope you enjoy this Sitecore article. Stay tuned for more Sitecore related articles.

Till that happy Sitecoring :)

Please leave your comments or share this article if it’s useful for you.