Monday 29 June 2015

How to hide Quick Info section using code in Sitecore

1 comment
In this blog I am going to explain how to hide the Quick Info section in the content editor using code. We can show/hide Quick Info section manually by using below steps:
  1. Click on top-left burger menu and then click on Application Options from the menu. The Application Options dialog popup will appear.

  2. Check/uncheck Quick Info section checkbox in content editor tab and click on OK.

Whenever a user gets successfully login then Sitecore executes the loggedin pipeline. Below custom processor is added to loggedin pipeline which sets a flag in the user profile to hide Quick Info section:
using Sitecore.Pipelines.LoggedIn;
using Sitecore.Shell;

namespace Sitecore.Ramblings
{
    public class QuickInfo:Sitecore.Pipelines.LoggedIn.LoggedInProcessor
    {
        /// <summary>The process.</summary>
        /// <param name="args">The args.</param>
        public override void Process(LoggedInArgs args)
        {
            const string DefaultQuickInfo = "false";

            Sitecore.Diagnostics.Assert.ArgumentNotNull(args, "args");
            Sitecore.Diagnostics.Assert.IsTrue(
              Sitecore.Security.Accounts.User.Exists(args.Username),
              args.Username);

            var user = Sitecore.Security.Accounts.User.FromName(
              args.Username,
              true);

            Sitecore.Diagnostics.Assert.IsNotNull(user, "user");

            var sitecoreDomain = Sitecore.SecurityModel.DomainManager.GetDomain(
              "sitecore");

            Sitecore.Diagnostics.Assert.IsNotNull(sitecoreDomain, "sitecoreDomain");

            if (user.Domain != sitecoreDomain
              || user.Name.ToLower().EndsWith("\\" + sitecoreDomain.AnonymousUserName))
            {
                Sitecore.Diagnostics.Log.Warn(this + " : unexpected security domain or user : " + user.Name, this);
                return;
            }

            var key = "/" + args.Username + "/UserOptions.ContentEditor.ShowQuickInfo";

            if (!string.IsNullOrEmpty(user.Profile[key]))
            {
                user.Profile[key] = DefaultQuickInfo;
                user.Profile.Save();
            }

            //bool showQuickInfo = UserOptions.ContentEditor.ShowQuickInfo;
        }
    }
}
Then patch below configuration change to add custom processor in loggedin pipeline and save the configuration file in App_Config\Include folder:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <processors>
      <loggedin>
        <processor patch:after="processor[position()=last()]" type="Sitecore.Ramblings.QuickInfo, Sitecore.Ramblings" />
      </loggedin>
    </processors>
  </sitecore>
</configuration>
Now login in Sitecore content editor and Quick Info section will be hidden.

References:
  1. Sitecore Blog by John West
Comments and suggestions are most welcome. Happy coding!
Read More...

Tuesday 23 June 2015

Sitecore 8 : General Link Field : Target attribute bug

Leave a Comment
Recently I have faced one issue with Sitecore 8 update 3. If you are using General Link field type and choose insert internal link then the target attribute will not be correctly set. Insert link popup window gives three options in target window dropdown list:


If you select Active Browser then your target attribute will be rendered as “Active Browser
<a href="/BlogPage" target="Active Browser">Blog Title</a>
If you select New Browser then your target attribute will be rendered as “New Browser
<a href="/BlogPage" target="New Browser">Blog Title</a>
It means that target attribute is not rendering properly. Correct way of rendering is:
Active Browser:
<a href="/BlogPage">Blog Title</a>
New Browser:
<a href="/BlogPage" target="_blank">Blog Title</a>
The easiest solution to fix this bug is update Root field value of item {ABF3B317-CFCA-441A-815A-F810AB1EDB0D} or /sitecore/client/Applications/Dialogs/InsertLinkViaTreeDialog/PageSettings/TargetsSearchPanelConfig in Core database.  Update the existing value sitecore/client/Applications/Dialogs/InsertLinkViaTreeDialog/PageSettings/Targets to sitecore/client/Business Component Library/System/Texts/Targets


Now insert link popup window gives four options in target window dropdown list:

  1. SelectTarget : Opens the linked document in the same frame as it was clicked (this is default).
    <a href="/BlogPage">Blog Title</a>
    
  2. _blank : Opens the linked document in a new window or tab.
    <a href="/BlogPage" target="_blank">Blog Title</a>
    
  3. _parent : Opens the linked document in the parent frame.
    <a href="/BlogPage" target="_parent">Blog Title</a>
    
  4. _top : Opens the linked document in the full body of the window.
    <a href="/BlogPage" target="_top">Blog Title</a>
    
Comments and suggestions are most welcome. Happy coding!
Read More...

Monday 22 June 2015

How to display/hide a Sublayout based on language

Leave a Comment
Recently I’d stumbled upon a post on Sitecore Community regarding how to display/hide a Sublayout based on a language version.

Original question: We have one presentation control (Sublayout) added in one Page. But we need to restrict for some specific language versions. How to do this?

We can achieve this functionality using Personalization. Select the Sublayout which you want to display/hide and personalize the Sublayout by creating new personalization condition.  See below screenshots to understand how to personalize the component.




This is how page is looking when hide component checkbox is unchecked.


This is how page is looking when hide component checkbox is checked.

If you're using Sitecore 8, then you can achieve same functionality by using versioned layouts too. You can configure presentation details of each language independently. Check this documentation which shows how to work with versioned layouts. Comments and suggestions are most welcome. Happy coding!
Read More...

Sunday 14 June 2015

Querying Lucene index with Sitecore ContentSearch API on Date field

Leave a Comment
Last month I’ve been involved in implementing Sitecore Content Search API for a project and stuck up in a situation where I have to index some Sitecore items and to perform some operations on Sitecore Date field type. Data template is having below fields:
BlogDate field is created with the type ‘Date’. I’ve to get all the blog items within a specific year.  Sitecore Content Search API enables us to write search queries using LINQ statements. I’ve written below code to get all items which are created using Blog template and belong to specific year:

POCO Class
public class BlogItem : SearchResultItem
{

    [IndexField("BlogTitle")]
    public string BlogTitle { get; set; }

    [IndexField("BlogDate")]
    public DateTime BlogDate { get; set; }

    [IndexField("BlogContent")]
    public string BlogContent { get; set; }
}
Lucene Index Configuration
<field fieldName="BlogTitle"                storageType="YES"  indexType="TOKENIZED"    vectorType="NO" boost="1f" type="System.String" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider" />

<field fieldName="BlogDate"                storageType="YES"  indexType="TOKENIZED"    vectorType="NO" boost="1f" type="System.DateTime" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider" />

<field fieldName="BlogContent"                storageType="YES"  indexType="TOKENIZED"    vectorType="NO" boost="1f" type="System.String" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider" />
C# Code
public void GetItemsByYear(int year)
        {
            ID blogTemplateId = new Sitecore.Data.ID("{48587868-4A19-48BB-8FC9-F1DD31CB6C8E}");
            var index = Sitecore.ContentSearch.ContentSearchManager.GetIndex("custom_index");
            List<BlogItem> allBlogItems = new List<BlogItem>();
            using (Sitecore.ContentSearch.IProviderSearchContext context = index.CreateSearchContext())
            {
                allBlogItems = context.GetQueryable<BlogItem>()
                                   .Where(s => s.TemplateId == blogTemplateId && s.BlogDate.Year == year).ToList();
            }            
        }
Unfortunately above code doesn’t return all items which are created using Blog template and belong to specific year and I can’t debug Lamba expression to know what is the exact value of BlogDate.Year. So I’ve started troubleshooting this issue. Sitecore stores date field value as ISO 8601 date time string format (yyyyMMddThhmmss). It can be verified in raw value:
I’ve also checked format of date field in Lucene index by Luke. Are you new to Luke? No problems. I would strongly suggest you to read this article by Dan to understand how to debug Lucene based ContentSearch in Sitecore. Below is the format of date field in Lucene index:
So basically value of data field is getting indexed in yyyyMMddThhmmss format. I’ve modified Lucene index configuration file as below for BlogDate field and added format=”yyyyMMdd”:
<field fieldName="BlogDate"                storageType="YES"  indexType="TOKENIZED"    vectorType="NO" boost="1f" type="System.DateTime" format="yyyyMMdd" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider" />
I re-indexed Lucene index and now Date field is stored in yyyyMMdd format:
One important thing to note here is that Lucene indexes date field in a whole number format i.e.  Year, month and day value are stored in same field. It means that I can’t compare date field value with only year or only month or only day. So if you want to query against a date field in Sitecore LINQ query then you must compare it with DateTime type. Therefore I’ve modified my code logic as below to filter out blog items based on a particular year:
public void GetItemsByYear(int year)
        {
            DateTime startDate = new DateTime(year, 1, 1);
            DateTime endDate = new DateTime(year + 1, 1, 1);
            ID blogTemplateId = new Sitecore.Data.ID("{48587868-4A19-48BB-8FC9-F1DD31CB6C8E}");
            var index = Sitecore.ContentSearch.ContentSearchManager.GetIndex("custom_index");
            List<BlogItem> allItems = new List<BlogItem>();
            using (Sitecore.ContentSearch.IProviderSearchContext context = index.CreateSearchContext())
            {
                allItems = context.GetQueryable<BlogItem>()
                                   .Where(s => s.TemplateId == blogTemplateId && s.BlogDate >= startDate && s.BlogDate < endDate).ToList();
            }            
        } 
This logic solved the problem and I am getting blog items for a specific year.  Comments and suggestions are most welcome. Happy coding! 
Read More...