Tuesday, December 3, 2013

Language filter on items in sitecore workbox

Sitecore doesn't provide the feature to filter the items in workbox based on language. If we have multilingual site then it will be good if we have language filter option like page size in workbox. This will be very fishtail if the items count in workbox is very large then this will enable the workbox user to filter the items of a specific language.

To Create this filter, there are some settings in core database as well as we have to create the language filter control and have to implement the filter logic in work box based on language selection.

There are following steps which we need to follow 

Step1: Creating language filter control-  To create this add a class file named WorkboxLanguageFilter.cs

using Sitecore.Data.Items;
using Sitecore.Globalization;
using Sitecore.Shell.Framework.Commands;
using Sitecore.Shell.Web.UI.WebControls;
using Sitecore.Web.UI.HtmlControls;
using Sitecore.Web.UI.WebControls.Ribbons;
using System.Web.UI;
using Sitecore.Data.Managers;
using System.Collections.Generic;
using System.Linq;

namespace BusinessModules
{
    /// <summary>
    /// Represents a panel that displays workflows Language Filter.
    ///
    /// </summary>
    public class WorkboxLanguageFilter : RibbonPanel
    {
        /// <summary>
        /// Renders the panel.
        ///
        /// </summary>
        /// <param name="output">The output.</param><param name="ribbon">The ribbon.</param><param name="button">The button.</param><param name="context">The context.</param>
        public override void Render(HtmlTextWriter output, Ribbon ribbon, Item button, CommandContext context)
        {
            Sitecore.Data.Database masterDB = Sitecore.Configuration.Factory.GetDatabase("master");
            IEnumerable<Language> languages = LanguageManager.GetLanguages(masterDB).Where(a => a != Sitecore.Globalization.Language.Parse("fr-CA"));
         

            string @Language = Registry.GetString("/Current_User/Workbox/Language", "All");
            output.Write("<div class=\"scRibbonToolbarPanel\">");
            output.Write("<table class=\"scWorkboxPageSize\"><tr><td class=\"scWorkboxPageSizeLabel\">");
            output.Write(Translate.Text("Select Language:"));
            output.Write("</td><td>");
            output.Write("<select class=\"scWorkboxPageSizeCombobox\" id=\"lang\" onchange='javascript:scForm.invoke(\"Laguage_Change\")'>");
            output.Write("<option value=\"All\"" + (@Language == "All" ? " selected=\"selected\"" : string.Empty) + ">All</option>");
            foreach (Language language in languages)
            {
                string oneWordLangName = language.CultureInfo.DisplayName.Split(' ')[0];
                output.Write("<option value=\"" + language.CultureInfo.Name + "\"" + (@Language == language.CultureInfo.Name ? " selected=\"selected\"" : string.Empty) + ">" + oneWordLangName + "</option>");
            }
            output.Write("</select>");
            output.Write("</td></tr></table>");
            output.Write("</div>");
        }
    }
}

 Step1: Sitecore Core database Settings- Create the highlighted Items in core DB and give your assembly reference.








Step3:Workbox filter logic - Create a class file AdvancedWorkboxForm.cs get the code of workbox by using RedGate Reflector from the dll - "Sitecore.Client" (Stecore.Shell.Applications.Workbox.WorkboxForm,Sitecore.Client)
 Add the below property and update the the function in the decompiled code and update the assembly reference in below .xml file(Workbox.xml-Website\sitecore\shell\Applications\Workbox) .


    







        /// <summary>
        /// Gets or sets the Language.
        /// </summary>
        /// <value>
        /// The Selected Language.
        /// </value>
        public string SelectedLanguage
        {
            get
            {
                return Registry.GetString("/Current_User/Workbox/Language", "All");
            }
            set
            {
                Registry.SetString("/Current_User/Workbox/Language", value);
            }
        }

private DataUri[] GetItems(WorkflowState state, IWorkflow workflow)
        {
            Assert.ArgumentNotNull((object)state, "state");
            Assert.ArgumentNotNull((object)workflow, "workflow");
            ArrayList arrayList = new ArrayList();
            DataUri[] items = workflow.GetItems(state.StateID);
            if (items != null)
            {
                foreach (DataUri index in items)
                {
                    Item obj = Context.ContentDatabase.Items[index];
                    if (SelectedLanguage == "All")
                    {
                        if (obj != null && obj.Access.CanRead() && (obj.Access.CanReadLanguage() && obj.Access.CanWriteLanguage()) && (Context.IsAdministrator || obj.Locking.CanLock() || obj.Locking.HasLock()))
                            arrayList.Add((object)index);
                    }
                    else
                    {
                        if (obj != null && obj.Language.CultureInfo.Name == SelectedLanguage && obj.Access.CanRead() && (obj.Access.CanReadLanguage() && obj.Access.CanWriteLanguage()) && (Context.IsAdministrator || obj.Locking.CanLock() || obj.Locking.HasLock()))
                            arrayList.Add((object)index);
                    }
                }
            }
            return arrayList.ToArray(typeof(DataUri)) as DataUri[];
        }

Final Worbox filter will look like below




Wednesday, February 13, 2013

Customizing Sitecore RTE

Sitecore uses telerik RAD editor for the RTE fields. The described behavior is by design for the editor and can be reproduced on the demo editor on telerik web site.
http://demos.telerik.com/aspnet-ajax/editor/examples/overview/defaultcs.aspx

There are two Profiles for this editor
1. Default Profile- There is limited options are available.


2. Full Profile- There is more text formatting options are available.


By default sitecore uses the default profile, we can set this to Full Profile by changing
<setting name="HtmlEditor.DefaultProfile" value="/sitecore/system/Settings/Html Editor Profiles/Rich Text Default"/>
To
<setting name="HtmlEditor.DefaultProfile" value="/sitecore/system/Settings/Html Editor Profiles/Rich Text Full"/>

If you want that whenever the Content in RTE will get enclosed in <p> tag when accept the changes, you can do with following way

1. add a class

public class WrapInP
{
 public void Process(SaveRichTextContentArgs args)
  {
    if(!string.IsNullOrEmpty(args.Content) && !args.Content.StartsWith("<p>"))
      {
        args.Content="<p>"+args.Content+"</p>";
      }
  }
}

2. Add the pipeline

<!-- Transforms markup from the Rich Text Editor before saving it as a rich text field value. -->
      <saveRichTextContent>
        <processor type="BusinessModules.WrapInP, BusinessModules"/>
      </saveRichTextContent>


This will get executed when you click accept button in RTE and paragraph will get inserted.

This is one example, we can do much more customization with RTE.