RTE Snippet

RTE snippet is used when you have to write same html again and again or have some content that look the same but maybe with difference in text in RTE, you should consider making a snippet.

You need to follow some steps for creating RTE Snippet –

1) Switch to core database

At the bottok2m right of your screen there is a database icon, click this to open the context menu and select core.

ChangeDB

2) Go to Snippet under settings node

Once switched to core database browse the following node

(sitecore/system/settings/Html Editor Profiles/Rich Text Default/Snippets)

5424496037_f7f34fd7ac_b

3) Insert a new snippet

You can either duplicate a snippet that already exists or add a new one.

To add a new snippet right click to Snippet folder

5425096460_14e282d12b

And create a snippet using the following template:
/sitecore/templates/System/Html Editor Profiles/Html Editor Snippet

5425096528_a2c4cc0294_z

This template consists of two fields, a header field and a value field.

a) In the header field you can write the name that is the title of snippet.

b) In the value field you input the html that should be pasted into the html field when the editor chooses the snippet.
CoreDbSnippet

Snippet is created now, now you can use it. Don’t forget to switch to master database.

How to use Snippet –

Go to the item that has Rich Text Editor (RTE) type field. Then click to “Show Editor”.

When you press the “Insert Code Snippet” button you will see the new snippet that you have just created. Then you can use it by clicking that snippet.

EditorSnippets

WFFM custom save action not woking on CD environment

We configured CM/CD environment for a website. When using Web Forms for Marketers in a CD environment, We faced an issue on custom save action, It was not working, it did not log any error in sitecore logs and it goes to next action like redirect and success page. 

There is a simple and easy way to resolve this issue, on WFFM custom save actions we need to mark checked on “Client Action” option.

ClientAction

 

 

 

 

Sitecore upgrade recommendations and best practices

If you are planning to upgrade your Sitecore to latest version, there are a few different ways of doing it. But be careful. Sitecore upgrades aren’t always straightforward.

Sitecore upgrade could introduce many problems if it’s done without planning. Here I will talk about recommendations and best practices to follow-up while doing upgrade

There are two upgrade approaches mentioned below–

  • Install of 8.X and migration of content
  • Incremental upgrades as per Sitecore’s documentation

Lets talk about each approach in detail

Install of 8.X and migration of content

o   In this approach we can move content (content items and media library) from old Sitecore installation to new fresh Sitecore installation via Sitecore packages. It’s a quick upgrade approach for small websites but it’s not the recommended approach.

o   Pros

  • Quick upgrade process for small websites

o   Cons

  • Not supported by Sitecore
  • Migrating content to a new solution can be a bit risky since the moved items are not updated and new versions of the UpdateInstallationWizard performs some post installation steps which fixes some field values on standard fields
  • Migrating Sitecore users to new solution reset their password. Admin has to resent password to all the users
  • Migrating content to new solution does not work well for larger projects, it’s become time consuming as compare with installing the upgrade packages

Incremental upgrade

If you are upgrading from 6.6 to 8.1, for example, this approach requires a series of intermediate steps of installing packages, updating configuration files and running update scripts on the databases

o   Pros

  • Supported by Sitecore
  • No need to worry about package installation and user migration
  • Give opportunity to migrate analytics database
  • Opportunity to upgrade Sitecore modules like WFFM and ECM without losing data

o   Cons

  • With this approach we have to run upgrade two time first during development and second before prod release with content freeze
  • Content freeze time in this upgrade is bit longer than earlier

Steps to do Sitecore Incremental upgrade

We normally divide upgrade process in eight steps

  1. Analysis and Planning
    1. What is initial and target Sitecore version
    2. How many Sitecore modules are installed in current Sitecore version
      • i.      Do these modules support target Sitecore version? Check Sitecore modules compatibility by clicking here (https://kb.sitecore.net/articles/541788)
      • For Sitecore modules such as Email Campaign Manager, Web Forms for Marketers, or the CRM connector, be aware that each module has its own upgrade path and compatibility timeline
    3.  Is there any Sitecore customizing done in Sitecore that will not be available in target version
    4.  Does current infrastructure support target Sitecore version
    5. Customers should check with their Sitecore sales rep to ensure that an upgrade to version 7.5 or 8 is fully supported by their current Sitecore license.
  2. Run Sitecore Upgrade
    • Setup project on local development machine (codebase and database)
    • Depending on initial Sitecore version start upgrade process
    • Take backup of complete code and database after upgrading to next Sitecore version
    • Make sure to upgrade Sitecore supported modules as well
    • Once upgrade reach to target version. Login to Sitecore and perform below steps –
      • Publish an item
      • Try to change presentation of item
      • Create item
      • Delete an item
  3. Internal Testing
    • Setup dev site
    • QA will do smoke testing of website and record and error found. Common error after upgrading from version to 6 to 7 is
      • The major API change between 6 and 7 is Sitecore.Search. This can be a big task depending on project size and lucene usage
      • If there are some modules installed which are not supported by Sitecore then update their code to support new API
      • If there any customization in Sitecore using OLD API that may not work in new version
  4. Bug fixing
    • Fix the issues raised by QA
  5. Alpha Testing
    • QA will run one more round of testing and validate issues raised during internal testing
  6. Beta Testing
    • Setup UAT environment so that client can validate website
  7. Preparation for Prod release
    • This is content freeze and code freeze step. From the start of this step till prod release client’s content team is not allow to make any update on content tree
    • Take latest database backups from production server and restore it on local development machine
    • Run upgrade again from initial Sitecore version
    • To save some time and avoid any human error we can do below
      • Install the Sitecore recommended upgrade packages and run the sql scripts.
      • For config updates don’t do it again instead copy all the configs from back that was created during initial upgrade for specific Sitecore version. Manually updating config files consumes lots of time and increase chances of error because of human mistake.
    • Merge any code update to UAT (if client IT team is doing it)
      • i. Make sure client IT team is not doing any major code update using initial version Sitecore API
    • Smoke testing of website by QA
    • Client can validate website and latest content
  8. Prod Release

Reset sitecore admin password

Most easy way to reset sitecore/admin password to b is just run following script on core database.

UPDATE [aspnet_Membership] SET Password='8dC23rEIsvuttG3Np1L4hJmJAOA=', PasswordSalt='joeLPwcwMq6L7kyuVfVS7g==' WHERE UserId IN (SELECT UserId FROM [aspnet_Users] WHERE UserName = 'sitecore\Admin')

If your admin user name is different then Admin just update the “sitecore\Admin” in the above script with your admin user name.

Good read on this topic - http://www.sitecoredevelopment.com/MarkGraber/2010/June/Cannot-Login-to-Sitecore.aspx

Thanks and cheers

Canonical URL for Sitecore Items

Adding Canonical URL for Sitecore Item

SEO (Search Engine Optimization) best practice suggest you to use a single URL for a particular resource. Content with duplicate URLs are given lower rankings by crawlers and instead of using multiple canonical URLs and redirecting to it’s item URL to show in address bar for a particular resource, we should use search engine’s recommended canonical tag. This tag will be added in html head tag. It’s a link tag with rel=”canonical”. This rel property is used as a hint for crawlers to consider the actual URL of the resource and should be used in their indices for ranking purpose. Take a look at sample canonical tag.

<link rel=”canonical” href=”https://example.com/resource” />

How to add a canonical tag for sitecore Item?

To add a canonical tag for your sitecore item, use following code in your page load function in your layout file. This function will call GetCanonicalUrl() function to retrieve canonical URL for the current requested Item. The following code lines will create a tag with rel=”canonical” and add it into html head tag. Remember the head tag should be runat=”server” to access it in code behind.

var canonicalUrl = GetCanonicalUrl();
if (!canonicalUrl.IsNullOrEmpty())
{
var canonicalTag = new HtmlLink { Href = canonicalUrl };
canonicalTag.Attributes["rel"] = “canonical”;
Header.Controls.Add(canonicalTag);
}

Add the following GetCanonicalUrl() function in your same layout file to identify the canonical URL for current Item. Here in addition I have created a setting to ignore any number of trailing slash.

<setting name=”IgnoreTrailingSlash” value=”true”/>

The following function will retrieve the current sitecore item URL, if you are using the aliases in your site then it will resolve them also and will get existing item’s URL as your canonical URL.

/// <summary>
/// Retrieving canonical URL
/// </summary>
/// <returns>Link render in meta data</returns>
private string GetCanonicalUrl()
{
var request = HttpContext.Current.Request;
var uri = new Uri(request.Url, request.RawUrl);
string url = HttpUtility.UrlDecode(uri.AbsolutePath);
string baseUrl = uri.GetComponents(UriComponents.Scheme | UriComponents.Host, UriFormat.Unescaped);
string canonicalUrl = “”;
if (Sitecore.Configuration.Settings.AliasesActive && Sitecore.Context.Database.Aliases.Exists(url))
{
Sitecore.Data.Items.Item targetItem = Sitecore.Context.Database.GetItem(Sitecore.Context.Database.Aliases.GetTargetID(url));
canonicalUrl = string.Format(“{0}{1}”, baseUrl, Sitecore.Links.LinkManager.GetItemUrl(targetItem));
}

 string itemUrl = Sitecore.Links.LinkManager.GetItemUrl(Sitecore.Context.Item);

if (url != itemUrl)
{
canonicalUrl = string.Format(“{0}{1}”, baseUrl, itemUrl);
}

 var ignoreTrailingSlash = Sitecore.Configuration.Settings.GetSetting(“IgnoreTrailingSlash”);

if (!canonicalUrl.IsNullOrEmpty())
{
if (!ignoreTrailingSlash.IsNullOrEmpty() && ignoreTrailingSlash.Equals(“true”))
{
return canonicalUrl.TrimEnd(‘/’);
}
else
{
return canonicalUrl;
}
}
return null;
}

 

GlassView with strongly typed context item and model

I have recently started working with Sitecore MVC using glass mapper. In my project I have several view renderings where I need to access the details of datasource item and as well as current context item. I knew that GlassView class takes the type of model as generic type argument and then if there is data source mentioned for the view rendering then it creates the model from data source item otherwise it creates the model from current context item.

Here my requirement was to use both (model as my data source and current context item) as strongly typed objects in my view renderings. Hence I started to look into the GlassView class and found some interesting public methods and properties that are useful to developers:

Properties:

S.No. Name Purpose
 1. ContextItem Returns the item specified by the current context item.
 2. DataSourceItem Returns the item specificed by the data source only. Returns null if no datasource set.
 3. LayoutItem Returns either the item specified by the DataSource or the current context item.

 

Methods:

S.No. Name Purpose
 1. GetContextItem Returns the Context Item as strongly typed.
 2. GetDataSourceItem Returns the Data Source Item as strongly typed.
 3. GetLayoutItem Returns the Layout Item as strongly typed.
 4. GetRenderingParameters Returns the parameters as strongly typed.

 

As there is out of box support available for strongly types in GlassView for data source and as well as context item so we started with defining a variable in our view renderings as below:

@inherits GlassView<MyDataSource>@{

var pageItem = GetContextItem<MyContentItem>();

}

<div>@pageIem.Title</div>

 

But this was tedious to verify that developers in my team were using this strongly typed approach instead of using the context item directly so I created small abstract class by inheriting from GlassView:

public abstract class CustomGlassView<TModel, TPageItem> : GlassView<TModel>where TModel : classwhere TPageItem : class

{

private TPageItem pageItem;

public TPageItem PageItem

{

get { return pageItem ?? (pageItem = this.GetContextItem<TPageItem>()); }

}

}

 

Now in my view renderings I am able to put the two strongly types for my view class as below:

@inherits CustomGlassView<MyDataSource, MyContentItem><div>@PageItem.Title</div>

This helps a lot in working with view renderings and the same can be done for parameters.

Thanks.

 

Extend Sitecore Dedicated Publishing Log

There is now a separate publishing log in Sitecore 7.2. Any operations happening as part of the publishing pipeline will now log to this file. This includes AUDIT entries. Mainly for backwards compatibility reasons, the main log.txt will still show main publishing related entries.

Challenge
Extend the Sitecore dedicated publishing log to show main publishing entries so that it’s easy for website admin to review publishing actives

Solution
We can can use Sitecore’s “Sitecore.Publishing.Diagnostics.PublishingLog” to write any custom information into publishing log file. In our case we have followed below steps to achieve it -

  • Create a class with the name let’s say  “PublishLogExtensions.cs” and inherit it from PublishItemProcessor
  • Code of this class looks something like below

public class PublishLogExtensions : PublishItemProcessor
 {
 public override void Process(PublishItemContext context)
 {
 Assert.ArgumentNotNull(context, "context");
 Assert.ArgumentNotNull(context.PublishOptions, "context.PublishOptions");
 Assert.ArgumentNotNull(context.PublishOptions.SourceDatabase, "context.PublishOptions.SourceDatabase");
 Assert.ArgumentNotNull(context.PublishOptions.TargetDatabase, "context.PublishOptions.TargetDatabase");
 Assert.ArgumentCondition(!ID.IsNullOrEmpty(context.ItemId), "context.ItemId", "context.ItemId must be set!");
 Assert.ArgumentNotNull(context.User, "context.User");

Database sourceDatabase = context.PublishOptions.SourceDatabase;
 Database targetDatabase = context.PublishOptions.TargetDatabase;
 ID itemId = context.ItemId;
 string userName = context.User.Name;
 Item item = context.PublishHelper.GetItemToPublish(context.ItemId);

if (item.HasContextLanguageVersion())
 {
 PublishingLog.Info("Publishing Path :" + item.Paths.FullPath.ToString() + ", ID: " + item.ID.ToString() + ", Item Language Verion: " + item.Language.Name + ", By User : " + userName);
 }
 }
}
  • Above code is will append below information to publishing log about items that gets published
    - Item Path
    - Item GUID
    - Language version
    - User who published this item
  • Finally you need to create a patch config file to hook this class to pipeline and config file looks like below
<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<publishItem>
<processor type="Class,Assembly"                    patch:after="processor[@type='Sitecore.Publishing.Pipelines.PublishItem.UpdateStatistics, Sitecore.Kernel']" />
</publishItem>
</pipelines>
</sitecore>
</configuration>

After following above steps you should be able to see below entries on publishing log

publishing-log

 

Google Events Integration with Sitecore

Purpose of this module

With the help this module user can easily create onclick events on different elements like anchors. Content editor can edit arguments of google events directly from Sitecore without opening code file.

What is google event tracking

  • Event Tracking is a method available in the ”ga.js” tracking code that we can use to record user interaction with website elements.
  • To track any event we need to call “on click” attribute with tracking arguments on anchor tag.
  • The specification for the _trackEvent() method is:
    _trackEvent(category, action, opt_label, opt_value, opt_noninteraction)

How this module work

To use this module please follow below steps –

  1. Install the provided Sitecore package. Package name is “GoogleEventTracking-1.0.zip”
  2. Update your web.config file to replace standard GetLinkFieldValue processor with the custom one
    1. Standard GetLinkFieldValue –
      <processor type=”Sitecore.Pipelines.RenderField.GetLinkFieldValue, Sitecore.Kernel” />
    2. Custom (Replace standard with this)
      <processor type=”Oasis.GoogleEventTracking.CustomGetLinkFieldValue, Oasis.GoogleEventTracking” />
  3. Once above setting is updated open Sitecore content tree. You can add google events to anchors using two fields type in Sitecore
    1. Rich Text Editor
    2. General Link
  4. To insert google event using Rich Text Editor follow below steps –
    1. Select any item which Contains RTE field.
      sitecorecode-GET1
    2. Select show editor option highlighted in above image. In RTE type any text like “Google Event”. Select this text and insert link on this text by selecting Hyperlink Manger from the tools of RTE.
      sitecorecode-GET2
    3. Select Analytics Events tab in Hyperlink Manager Popup and enter events details in the form as shown in below image
      sitecorecode-GET3
    4. Click ok when you are done
    5. Accept the changes in RTE and save the Sitecore item. This event will look like below in html of page. You can see this in Sitecore as well by clicking on HTML tab of RTE
      <a onclick=”_gaq.push(['_trackEvent','Category','Action','Label',1]);”>goolge event</a>
  5. To insert google event using General Link Field Type follow below steps –
    1. Select any item which Contains General Link field.
    2. Inset link detail by selecting Insert option Link
      sitecorecode-GET4
    3. To crate google event click on Google Event option highlighted in above image. It will open a popup with the form. Fill the form with proper argument for google event
      sitecorecode-GET5
    4. Click ok when you are done
    5. Save the Sitecore item. This event will look like below in html of page. You can see this in Sitecore as well by selecting raw value checkbox
      onclick=”_gaq.push(['_trackEvent','Category','Action','Label',Value]);”

Note – This package is based on assumption that webpages are already rending google event tracking js provided by google.

Sitecore Package is available on Sitecore market marketplace Click here to download

 

How to use Sitecore dictionary domain in your Sitecore project

Purpose of this article is to explain new developers how to properly used dictionary domain. Good technical explanation of dictionary domain can be found here

Sitecore 6.6 introduces the concept of dictionary domains. In any database, you can create any number of dictionary domains, which are items based on the System/Dictionary/Dictionary Domain data template. On each dictionary domain you can specify the fallback domain. If certain key is not found in site specific dictionary domain then program will search key in fallback domain.

Follow below steps to use dictionary domain in your Sitecore website:

  1. Based on your Sitecore content tree structure create item of template “/configuration/sitecore/sites/site”. We normally use below structure in our project where we organize different sites in different folders in case of multi-site environment (you can use same structure for single website as well) and each site contains 2 node under it. One is used to store global setting (Used to store all global meta data used on different pages of website like header, footer) of this website and other is home item under which all pages of website get store
                Sitecore
                            Content
                                        Site One Node
                                                    Global Settings
                                                                Sample Dictionary Domain
                                                    Home
  2. Under dictionary domain folder you can add dictionary entries. You can create folder as well under dictionary domain to organize dictionary entries in logical structure. You can also nest dictionary domains
  3. Once dictionary domain structure is created in Sitecore content tree next step is to use dictionary in layout or sublayouts. There are two ways to use Sitecore dictionary

         i.    Define Dictionary domain in Sites setting in web.config.
                 a.  With this approach open web.config file and add dictionary domain attridute                                                                         (dictionaryDomain=”Sample Dictionary Domain”) to your  managed sites                                                                       (/configuration/sitecore/sites/site)
                b.  dictionaryDomain attribute in web.config could be name of dictionary domain or GUID of dictionary                                  domain
                c.  Use below code to get dictionary phrase using key in code
                                Sitecore.Globalization.Translate.Text(“key”);  

         ii.    You can also define dictionary domain in code as shown below                                                                                                  Sitecore.Globalization.Translate.TextByDomain(“Domian”,”Key”);

Must Read:

http://www.sitecore.net/Learn/Blogs/Technical-Blogs/John-West-Sitecore-Blog/Posts/2012/11/Sitecore-ASPNET-CMS-6-6-Features-Dictionary-Domains.aspx

As with any other pipeline, you can add processors to, remove processors from, and override processors in the getTranslation pipeline. For example, when porting an existing ASP.NET site into Sitecore, you could add a processor that looks for entries in the resource files from the old site if no entry for a key exists in the Sitecore dictionary system.

SITECORE CDN CONNECTOR for Sitecore 7.x

Challenge – Existing Sitecore CDN connector available at click here is not working with Sitecore 7.2

https://marketplace.sitecore.net/en/Modules/Sitecore_CDN_Connector.aspx

Solution

Follow below steps –

  1. Download source code from github https://github.com/NTTDATA/SitecoreCDN
  2. Open this source code in visual studio. Go to project properties and update target framework to .Net framework 4.5zProject Property
  3. Update reference of below DLLs in this project to use new  DLLs from Sitecore 7.2
    1. HtmlAgilityPack
    2. Sitecore.Kernel
  4. Build the project and you should be all set to use this connector

In case of multisite environment you have to take care of 2 points –

  1. Update site name in sites patch define in config file SitecoreCDN.config

<sites>
<sitename="yoursitename">
<patch:attributename="cdnHostName">imagerepo</patch:attribute>
</site>
</sites>

  1. If you are using SiteDefinition.config to manage multiple sites then make sure SitecoreCDN.config execute after SiteDefinition.config file. One thing you can do is update name of SitecoreCDN.config by adding prefix “Z” like ZSitecoreCDN.config

CDN Sitecore connector package for Sitecore 7.2 can be downloaded from here

Conclusion – Existing CDN Sitecore connector contains reference of old DLLs  and .net framework. By updating reference it will start working with latest Sitecore version