Sitecore Missing valid xDB license

Problem – In Sitecore versions 8.1 and above Sitecore analytics is not working and Sitecore logs show below information

INFO  **********************************************************************
INFO  xDB is disabled.
INFO
INFO  Tracking is enabled.
INFO
INFO  Missing valid xDB license.
INFO  **********************************************************************

Cause - Sitecore added an additional key to its license file. Sitecore 8.1 requires this new key to enable xDB features. Following could be the reason:

  • Your license does not contain this new key.
  • Your license does not allow xDB features.

Solution
Sitecore 8.1 now requires a license with the “Sitecore.xDB.base” key to enable all features of the Experience Platform. If your license file does not contain this key, Sitecore will default to Experience Management (CMS-only) mode. Any customers or partners with a license to Experience Platform should contact their account manager or login to SPN if they are missing this key.

Click here for more details

Share thisEmail this to someonePrint this pageTweet about this on TwitterShare on FacebookShare on Google+Share on TumblrShare on LinkedIn

System.Reflection.TargetInvocationException error when Rebuilding #Sitecore Solr Indexes

Hi All,

We have a multilingual #Sitecore site. When I was rebuilding the #Sitecore indexes, I was getting a weird error that is

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.

2016-06-01 19_06_37-Bentley - Microsoft Visual Studio (Administrator)

Generally we click on cross button, and rebuild the index again, sometime it works. :P

But in my case it’s not working. So I dig into the issue.

First of all I just opened the local solr url in browser like this http://localhost:8983/solr/

And then click on logging button on the left side and saw there were so many errors as shown in the below image.

2016-06-08_0851

By looking into the image, we can see that there are some language specific error. Like “zh” for Chinese, “ko” for Korean.

 

So now what to do?

 

Then after some searching I found that we have to do something with physical solr files. Now go to solr folder where you have configured solr for your project. Let’s assume you have configured solr with the name “project_master” and “project_web”. So follow the steps –

1)      Go to “solr/project_master/conf” folder.

2)      Then you will find an xml file named “schema.xml” there.

3)      Open this schema.xml file in notepad or so and search for “dynamicField” that is under fields section.

If you don’t find schema.xml file in conf folder then you need to follow following steps –

1)      Go to sitename/Sitecore

2)      Log into Sitecore with username and password.

3)      Then click on Sitecore button that is in left bottom corner.

4)      Then navigate to Control Panel, a screen will popup like following image.

2016-06-08_1038

5)      In this there are 2 links, then you need to click on “Generate the Solr Schema.xml file”.

2016-06-01 19_11_21-Sitecore

 

6)      You will see there are 2 fields “Source File” and “Target File”.

7)      In the Source File you need to provide a default schema.xml file. You can download default schema.xml here.

8)      In the Target File provide the target folder, where you want it to be.

9)      Now you are ready to customize “schema.xml” file.

 

When you will open this schema.xml, you will find that lots of dynamic fields are there something like this –

<dynamicField name=”*_t” type=”text_general” indexed=”true” stored=”true” />

 

Note – Before making changes in schema.xml you need to take care of apache server. In your PC click on “Start” button and search for “Monitor Tomcat”, click on it. You need to click on “Stop service”, after that you can make changes in schema.xml file.

 

In these dynamic field search for “zh, ko”, and you will find that there are no entries with these names, so now we need to make entry for these language types like below image. Make sure you have entry for each language that is causing error.

2016-07-01_1153

What “*” means, it will include all the entries ending with e.g. “t_zh”.

There are several “dynamicField type” like text_general, string, boolean, int, date, location, tint, tlong, tfloat, tdouble, tdate, pint, currency, ignored, random etc. I am using “text_general” here.

 

It’s done, no. There is still something we need to do.

Start you Tomcat (Apache) service again by opening Monitor Tomcat.

Now you again need to go to #Sitecore and rebuild your index again.

Finally it’s done now.

If you got error again, then you need to follow this process again then check the logging and make sure all language specific entries are there.

Thanks to Ravindra Singh Rathore, he helps me in this as well.

Happy Coding :)

 

 

Share thisEmail this to someonePrint this pageTweet about this on TwitterShare on FacebookShare on Google+Share on TumblrShare on LinkedIn

Multiple datasource locations to Single Sublayout or Rendering in #Sitecore

Hello All,

In one of our project I faced a requirement to give multiple Datasource location to single Rendering, so that they can select whatever datasource they need. After doing some research I found that it is possible to give multiple datasource. For this first of all Login to your Sitecore.

Let’s say you have a #Sitecore structure like this -

Sitecore

-Content

-Site Node

-Globals

-Datasource Folder

-Home

-_Resource

-Datasource Folder

-Item 1

-_Resource

-Datasource Folder

 

Now we need to set 2 Datasource Locations for single Rendering. For this follow the below steps-

1)      Go to particular rendering where you want to set datasource

2)      Let’s say go to

-sitecore

-content

-Layout

-Renderings

-Your Rendering

3)      Click on “Your Rendering”

4)      Then in right hand side go to “Editor Options”

5)      Firstly, go to “Datasource Template” field.

Click on “Insert Link”, a pop up will open, in which you need to select “Datasource Folder Template”

DataourceLocationPE

 

6)      In “Editor Options” go to “Datasource Location” field

7)      Then in the “Datasource Location” write this query –

. /_Resource|query:./ancestor-or-self::*[@@templatename=Site Node Template Name'] /*[@@templatename='Globals Folder Template Name']/*[@@templatename=Datasource Template']

DatasourceLocationPE

What does this query means –

1)      This query is divided by pipe sign (|)

2)      In which “_Resource” is the first datasource location (Left part of pipe sign (|)), that is let’s say we want to give datasource to “Home” item’s rendering. So first you can see there is “_Resource” folder directly under “Home” item, so it is the path of that “_Resource” folder

3)       Now we have 2nd datasource location (Right part of pipe sign (|)), that is a query. In this query you need to set “Template Names”. Let’s say you want to set 2nd location to “Datasource Folder” that is under “Globals” Folder. So all you need to do is to set “Template Name” starting from your “Site Node” to that “Globals Folder Template”, don’t include datasource folder template in this. If your datasource is under any other node under Globals folder, then need to set template names just above your datasource folder.

For ex – Your sitecore tree is like – sitecore/content/sitenode/globals/datasource folder, so set template names starting from sitenode template to globals folder.

4)      Here it is all. Now go to “Home” item.

5)      Click on “Presentation” tab.

6)      In that click on “Details”.

7)      A pop up will open in which click on “Your Rendering”

8)      Then in the “General” tab, go to “Data Source” field and click on “Browse”, now you can see there are 2 datasource location, in which you can select datasource from either Globals Folder’s Datasource or _Resource Folder’s Datasource.

Datasource_Location

Happy Coding :)

Share thisEmail this to someonePrint this pageTweet about this on TwitterShare on FacebookShare on Google+Share on TumblrShare on LinkedIn

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

Share thisEmail this to someonePrint this pageTweet about this on TwitterShare on FacebookShare on Google+Share on TumblrShare on LinkedIn

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

 

 

 

 

Share thisEmail this to someonePrint this pageTweet about this on TwitterShare on FacebookShare on Google+Share on TumblrShare on LinkedIn

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
Share thisEmail this to someonePrint this pageTweet about this on TwitterShare on FacebookShare on Google+Share on TumblrShare on LinkedIn

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

Share thisEmail this to someonePrint this pageTweet about this on TwitterShare on FacebookShare on Google+Share on TumblrShare on LinkedIn

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;
}

 

Share thisEmail this to someonePrint this pageTweet about this on TwitterShare on FacebookShare on Google+Share on TumblrShare on LinkedIn

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.

 

Share thisEmail this to someonePrint this pageTweet about this on TwitterShare on FacebookShare on Google+Share on TumblrShare on LinkedIn

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

 

Share thisEmail this to someonePrint this pageTweet about this on TwitterShare on FacebookShare on Google+Share on TumblrShare on LinkedIn