How to setup your site in “Live” Mode OR How can I review my site even before publishing (i.e. just after saving)? OR How can I preview items in workflow before they are approved?

 

The Problem:

How to setup your site in “Live” Mode

OR

How can I review my site even before publishing (i.e. just after saving)?

OR

How can I preview items in workflow before they are approved?

This is one of the basic requirements for the content editors to review the site just after they have saved the item/page and before publishing it to web.

The Solution no.1 

Override GetMediaUrl in MediaProvider

 

namespace NaeemSpace.CustomMediaProviders
{

public class MediaProvider : global::Sitecore.Resources.Media.MediaProvider
{
public override string GetMediaUrl(MediaItem item, MediaUrlOptions options)
{
var retUrl = base.GetMediaUrl(item, options);

var query = System.Web.HttpContext.Current.Request.QueryString;
if (query[“sc_mode”] != null)
{
return retUrl + “&sc_mode=” + query[“sc_mode”];
}
else
{
return retUrl;
}

}

}

Update the mediaProvider section in config

<mediaProvider type=”NaeemSpace.CustomMediaProviders.MediaProvider, NaeemSpace.CustomMediaProviders” patch:instead=”mediaProvider[@type=’Sitecore.Resources.Media.MediaProvider, Sitecore.Kernel’]”/>

and ensure the setting “Preview Publishing target” is checked for the preview publishing target. This will ensure that the workflow items not in the final workflow can be published in the preview website and the querystring “sc_mode=preview” will ensure that you are viewing the item from preview database.

Capture

The Solution no 2:

Sitecore provides an out of box functionality to accomplish this.

You need to setup a “review” website with some proper filters so that you can review our changes before publish or even if your workflow items are not approved state.

“Review” site/mode is also called as “Live” Mode (purely meaning that you are not live but are viewing the site as if it is live.

In the review site the items are visible as soon as you save the item.

To your ‘<Sites>’  config uration  section add a review site

<site name=”preview_website” hostName=”preview.website.com” virtualFolder=”/” physicalFolder=”/” rootPath=”/sitecore/content” startItem=”/home” database=”master” domain=”extranet” allowDebug=”true” cacheHtml=”true” htmlCacheSize=”10MB” registryCacheSize=”0″ viewStateCacheSize=”0″ xslCacheSize=”5MB” filteredItemsCacheSize=”2MB” enablePreview=”true” enableWebEdit=”true” enableDebugger=”true” disableClientData=”false” filterItems=”false” enableWorkflow=”true” />

database=”master” will ensure that the contents are loaded from master website

filterItems=”false” will ensure that’s items are not filtered

enableWorkflow=”true” will ensure that it will manage workflow items too.

Any caveats:

Yes this functionality comes up with following restrictions or a caveat

  • It will display only “publishable” items. ( I will not call it as a caveat as the site respects any publishing restrictions including workflow status, item and version visibility)
  • Caching Implications/Restrictions – the live site can’t cache rendering outputs and controls. So you need to clear up the cache as you view the site and

any search indexes pointing to web might not work.

Advertisements

How to fix the following rendering errors on saving an item

How to fix the following rendering errors on saving an item

  • “The item contains broken links in these fields: – _Renderings
  • or “The item contains broken links in these fields: – _Final Renderings

Source of error:

  • The error happens because in the presentation details of the item some control has an invalid data-source or has a missing place holder settings
  • Especially if you are not watching the item in Raw Mode and still you see a Raw GUID for the data source or place holder then that is exactly the issue.

How to fix it:

  • First of all open the item’s presentation details by clicking the “presentation” tab on the ribbon and then click on “Details” button to open the layout details.
  • Click the shared/final layout as the case may be and then “edit” link to edit the layout.

pic 01 - layout details

  • Now select controls one by one and press “edit” to check if which control has a messed up data source or placeholder setting.

pic 02 - edit layout details

  • See, that for the header control, the field Order Link is showing a GUID data source although we are not viewing it in raw mode. Simply press “Clear” and use “Insert Link” or other options there to update the link and save . You are good to go.

pic 03 - clear and update datasource

Adding a custom button to the ribbon in Sitecore Ribbon/Tab

 

Please follow the steps below to add a button (E.g. a button which calculates Time based on the Time zone with respect to the server time zone).

Step 1: First login to the CMS instance using admin privileges and select the core database.

db selector

The Sitecore Ribbon is made up of 3 things – Ribbon, Strip and Chunk.

  • The Ribbon looks like a tool bar.
  • The Strip looks like a section on the Ribbon.
  • The Chunk looks like the button on the Strip.

whats is this

Step 2:  Go to “/sitecore/content/Applications/Content Editor/Ribbons/Chunks” using content editor and create a chunk called “Calculate Time” . Set the Header and ID for the chunk.

create chunk

Step 3:  Go to “/sitecore/content/Applications/Content Editor/Ribbons/Strips” using content editor and create a strip called “Calculate Time”  inside Publish Strip and set the Reference field to the path to the “Calculate Time”  chunk.

create strip

Step 4:  Go to “/sitecore/content/Applications/Content Editor/Ribbons/Chunks/Calculate Time” using content editor and create a button called “Calculate Time”  inside strip and set the header , Icon and  click fields

create button

Step 5:  Open “Commands.config” and add a command as highlighted.

commands config

Step 6:  Now create a web page and name it ‘CalculateTime’. (The name space can be ‘CustomButtons.Core.Sitecore.Shell.Framework.Commands.CalculateTime’). Create a calendar to select date a drop down to select time and time zone and the supporting code behind to display the converted time based on time zone. And there you go.

Code Behind 1 and 2 and UI:

UI

code behind 2

code behind 1

Output: Select date, time and time zone and press “calculate”.

Output

 

Hope you liked the explanation.

Publishing Target missing Issue while publishing content

You might have experienced this issue where the publishing target is missing while publishing the content as below.

Capture

There is a very easy solution to this issue – grant a language:read permission to “/sitecore/system/Languages/en” for the base/root user so that all users can get this access.

Capture2

Hope this works for you too.

 

How to move and rename Items from Source to Destination path in Sitecore using Sitecore PowerShell

Here is the simple script for this:

# database name

$db = “master:”

# source path

$sourcePath = “/sitecore/content/Generic Content/Generic Pages/Basic Generic Item”

# destination path – task was to move the generic pages from generic location to country based locations

$destinationPath = “/sitecore/content/USA/Generic Content/Generic Pages/Basic Generic Item”

$itemsList = Get-ChildItem -recurse -Path ($db + $sourcePath) | Where { $_.TemplateName -eq “Generic Pages” }

$itemsList | ForEach-Object {

# task was to append parent name to the new item

$newName = $_.Name + “-” + $_.Parent.Name

if(![string]::IsNullOrEmpty($newName)){

Move-Item -Path $_.ProviderPath -Destination ($db + $destinationPath + “/” +                    $newName)

Write-Host “Moved Item: ” $newName  ” to path: ” ($db + $destinationPath)

}else{

Write-Host “Could not move Item: ” $newName

}

}

How to handle and configure Sitecore Launch Pad Buttons, sections, sort order and grouping

Please have a look at the Sitecore Launch pad with lots of buttons.

These buttons can be configured to show and hide based on users and roles.

Lets take an example and say that we have a role – configmanger which is responsible for managing lot of configurable items including this launch pad.

Capture

First of all switch to CORE database and go to this location – /sitecore/client/Applications/Launch Pad/PageSettings/Buttons

You can add new buttons here and also control the grouping and order of the buttons and the link which will open on clicking the button.

E.g. Suppose if you want to show 2 separate buttons to show English and French Content you can create 2 buttons in the location – /sitecore/client/Applications/Launchpad/PageSettings/Buttons/ContentEditing

Name these 2 buttons as English Content and French Content and set their title, link properties to define the title and the link where it will go to when clicked.

capture 2

Also do not forget to assign a READ permission to the 2 buttons paths for the role – configmanager.

capture 3

Now you can see 2 additional buttons on Launch pad in Content Editing sections.

capture 4

If you want to remove these 2 buttons simply revoke – configmanager roles permission on these 2 button paths. See below both buttons are missing now.

capture 5

Hope this article helps you in configuring the launch pad.

Get Rid of Extra HTML Tags(e.g p tags etc) from the Rich Text Editor while saving

Method 1: Override and disable the filters as needed

Step 1: Update the following config setting:

<settings xmlns:patch=”http://www.sitecore.net/xmlconfig/”&gt;

<setting name=”HtmlEditor.DefaultConfigurationType“>

<patch:attribute name=”value”>YourProject.Custom.Controls.CustomRichTextEditor, YourProjectDLLName </patch:attribute>

</setting>

</settings>

 

Step 2: Override Sitecore.Shell.Controls.RichTextEditor.EditorConfiguration as below:

using Sitecore.Data.Items;

using Telerik.Web.UI;

namespace YourProject.Custom.Controls

{

public class CustomRichTextEditor : Sitecore.Shell.Controls.RichTextEditor.EditorConfiguration

{

public CustomRichTextEditor(Item profile)

: base(profile)

{

}

 

protected override void SetupEditor()

{

base.SetupEditor();

Editor.DisableFilter(EditorFilters.ConvertToXhtml);

Editor.EnableFilter(EditorFilters.IndentHTMLContent);

Editor.StripFormattingOptions = EditorStripFormattingOptions.MSWordRemoveAll

| EditorStripFormattingOptions.ConvertWordLists

| EditorStripFormattingOptions.Css

| EditorStripFormattingOptions.Font

| EditorStripFormattingOptions.Span;

Editor.NewLineMode = EditorNewLineModes.Br;

}

}

}

 

Method 2: Override and remove the tags as needed

Step 1: Update the following config setting:

<settings xmlns:patch=”http://www.sitecore.net/xmlconfig/”&gt;

<setting name=”HtmlEditor.DefaultConfigurationType“>

<patch:attribute name=”value”>YourProject.Custom.Pipelines.ProcessRichTextInParagraphOnRender, YourProjectDLLName </patch:attribute>

</setting>

</settings>

Step 2: Override Sitecore.Shell.Controls.RichTextEditor.EditorConfiguration as below:

 

namespace YourProject.Custom.Pipelines

{

public class ProcessRichTextInParagraphOnSave

{

public void Process(SaveRichTextContentArgs args)

{

if ((args.Content.Trim().StartsWith(“<p>”) && args.Content.Trim().EndsWith(“</p>”)))

args.Content = string result = Regex.Replace(HttpUtility.HtmlEncode(args.Content), @”</?p\b.*?>”,

String.Empty,RegexOptions.IgnoreCase);

}

}

}

A list of filters are listed in Telerik’s documentation – http://docs.telerik.com/devtools/aspnet-ajax/controls/editor/managing-content/content-filters

 

Compare Sitecore Vs Solr Items

Have you ever faced any urgent Production issue where your deployment succeeded and site is working fine and then you come to know that the number of items in the Solr and Sitecore don’t match and you also want to see the delta of those differences. You can also use this information to setup a threshold to setup alerts if the mismatch of items surpasses a defined limit(I used Amazon’s SNS(Simple Notification Service) to notify via email and text to the Production SWAT team as soon as threshold passed the limit)

This Powershell script will be very handy for you. The base idea is that you get detaisl of items from your Sitecore master and web database and also Solr master and web databases. Once you have these JSONs in hand comparing those objects would not be that difficult. Just filter out the columns you need and you are good to go.

//First Get Items From Sitecore Master Database
$childsMaster = Get-ChildItem master:/sitecore/content/../Products -Language * -Version *
write-host “Count of items Product Catalog(Master): ” $childsMaster.length

//Then Get Items From Sitecore Web Database
$childsWeb = Get-ChildItem web:/sitecore/content/../Products -Language * -Version *
write-host “Count of items Product Catalog(Web): ” $childsWeb.length

//Then Get Items From Sitecore Solr Master
$items_catalog_index_master = wget “http://search.intouch.usastg.mktest.com/solr/catalog_index_master/select?q=marketsku_s%3A*&fq=_language%3Aen-CA&rows=9999&fl=marketsku_s&wt=json&indent=true&#8221; | ConvertFrom-Json
write-host “Count of items catalog_index_master: ” $items_catalog_index_master.response.numfound
#$items_catalog_index_master.response.docs.marketsku_s

//Then Get Items From Sitecore Solr Slave
$items_catalog_index_web = wget “http://indexing.intouch.usastg.mktest.com/solr/catalog_index_web/select?q=marketsku_s%3A*&fq=_language%3Aen-CA&rows=9999&fl=marketsku_s&wt=json&indent=true&#8221; | ConvertFrom-Json

write-host “Count of items catalog_index_web: ” $items_catalog_index_web.response.numfound

#$items_catalog_index_web.response.docs.marketsku_s
write-host “Compare Sitecore Master Vs Web Databases”

Compare-Object $childsMaster $childsWeb -PassThru
write-host “Compare Sitecore Solr catalog_index_master Vs catalog_index_web”

Compare-Object ($items_catalog_index_master.response.docs.comparefieldname) ($items_catalog_index_web.response.docs.comparefieldname)

write-host “Compare Master Database Vs Solr catalog_index_web”
Compare-Object ($childsMaster.comparefieldname) ($items_catalog_index_web.response.docs.comparefieldname) -PassThru

Sitecore Errors

 

 

Issue:

So here is the scenario

You are running the home page of a Sitecore website.

–        The page runs perfectly from the CD servers

–        The page runs perfectly from the “Experience editor” mode from the CM servers

–        But when you run the page from “Preview” mode from CM servers, it give you above error

You are redirected to the no layout error page like this:

http://sitecorewebsitename.com/sitecore/service/nolayout.aspx?item=%2f&layout=%7b00000000-0000-0000-0000-000000000000%7d&device=Default

Well, now if you manually create this URL –

http://sitecorewebsitename.com/?sc_itemid=%7B110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9 %7D&sc_mode=preview&sc_lang=en

Now preview works, and this is a very annoying error.

 

There can be multitude of reasons for the error, as you don’t know if this is a publishing issue, or security issues as Preview mode used anonymous user to show the item and if the item does not has anonymous access enabled you might have got this error. We tried to fix the problem by targeting these probable causes. But nothing was working.

 

So after lot of toiling we figured out that this was the reason for the error –

In preview mode Sitecore looks for the item configured in preview database in CM server pointing to preview. But if that CM server is not configured then you will get this error.

Solution:

On CM servers, if the Preview servers are not configured, then the database must be pointing to “Master” for preview proposes.

Go to Site settings of the website in Sitecore.config( location: WebsiteApp_ConfigInclude)

 

<site name=”website” enableTracking=”true” virtualFolder=”/” physicalFolder=”/” rootPath=”/sitecore/content” startItem=”/home” database=”master” domain=”extranet” allowDebug=”true”cacheHtml=”true” htmlCacheSize=”50MB” registryCacheSize=”0″ viewStateCacheSize=”0″ xslCacheSize=”25MB” filteredItemsCacheSize=”10MB” enablePreview=”true” enableWebEdit=”true”enableDebugger=”true” disableClientData=”false” cacheRenderingParameters=”true” renderingParametersCacheSize=”10MB”/>

Sitecore 8.1 and Active Directory 1.3 Integration

Sitecore 8.1 AD 1.3 Module Integration

Integrating the Active Directory module with Sitecore allows you to import, authenticate and manage the AD users, roles and profiles inside the Sitecore.

 

Let’s assume that we want to accomplish the following:

–        We have a Sitecore Instance already running and we want to integrate the AD users, roles and profiles of our company for authenticating and managing permissions on the Sitecore items

–        So we need to first import the users, roles and profiles list inside Sitecore user manager, role manager and then assign appropriate permissions to the users.

–        So let’s try to accomplish this

o    First lets integrate the AD

o   Assign proper permissions to the AD users to access Sitecore Items

 

ð  AD Integration:

–        First we will have to setup an Sitecore instance if we are starting from scratch else we can use an existing instance.

–        Then we will install the “Active directory Module 1.3”(for Sitecore 8.2). Sitecore provides a matrix as if which AD module works with which Sitecore version.

–        After installing proper AD module,  we will configure, verify and test the AD integration.

–        Note : Please backup your existing instance source files, databases, configs in case a rollback is needed.

 

1-     First of all Setup a banana Sitecore Installation using The 8.2 Sitecore Installer from (if starting from scratch)- https://dev.sitecore.net/Downloads/Sitecore_Experience_Platform/82/Sitecore_Experience_Platform_82_Update2.aspx

(Use the web installer Sitecore web application installer)

 

2-     InstallAD 1.3 Module” package  from –

https://dev.sitecore.net/Downloads/Active_Directory/1_3/Active_Directory_1_3.aspx (Use Active Directory 1.3 rev.161017)

o   After installation verify the following changes to the Sitecore website folder

  • App_ConfigIncludeldap.config – provides LDAP Confuguration
  • BinLightLDAP.dll – LDAP DLLs
  • BinLightLDAPClient.dll – LDAP DLLs
  • SitecoreadminLDAPLogin.aspx – Single sign-on page
  • SitecoreadminProviderStatus.aspx – AD status page

 

3-     Perform the following Configuration changes for AD to work with Sitecore :

  1. ConnectionStrings.config

Add LDAP Connection string under <connectionStrings> section.

Note: ‘mydomain.mywebsite.com’ the AD server name.

<add name=”LDAP_CONN” connectionString=”LDAP://mydomain.mywebsite.com:389/DC=mywebsite,DC=com” />

  1. Domains.config

Add a new domain under <Domain> section.

Note: “usa” is the domain name.

           <domain name=”usa” ensureAnonymousUser=”false” />

  1. Sitecore.config

Update the <switchingProviders> section.

In the switching provider section you have to provide additional settings for membership, role manager and

profile settings specifying what the new AD providers are. See the bold entries below

<switchingProviders>

<membership>

<provider providerName=”sql” storeFullNames=”true” wildcard=”%” domains=”*” />

      <provider providerName=”ad” storeFullNames=”false” wildcard=”*” domains=”usa” />

</membership>

<roleManager>

<provider providerName=”sql” storeFullNames=”true” wildcard=”%” domains=”*” ignoredUserDomains=”” allowedUserDomains=”” />

<provider providerName=”ad” storeFullNames=”false” wildcard=”*” domains=”usa” />

</roleManager>

<profile>

<provider providerName=”sql” storeFullNames=”true” wildcard=”%” domains=”*” ignoredDomains=”” />

</profile>

</switchingProviders>

  1. Web.config

Update the <membership>, <rolemanager> and <profile> sections as below.

These settings specify 2 things- one who is the new membership, role or profile provider and second that you are switching the provider from SQL to the one you are adding.

<membership defaultProvider=”sitecore” hashAlgorithmType=”SHA1″>

<providers>

<clear />

<add name=”sitecore” type=”Sitecore.Security.SitecoreMembershipProvider, Sitecore.Kernel” realProviderName=”switcher” providerWildcard=”%” raiseEvents=”true” />

<add name=”switcher” type=”Sitecore.Security.SwitchingMembershipProvider, Sitecore.Kernel” applicationName=”sitecore” mappings=”switchingProviders/membership” />

<add name=”sql” type=”System.Web.Security.SqlMembershipProvider” connectionStringName=”core” applicationName=”sitecore” minRequiredPasswordLength=”1″ minRequiredNonalphanumericCharacters=”0″ requiresQuestionAndAnswer=”false” requiresUniqueEmail=”false” maxInvalidPasswordAttempts=”256″ />

<add name=”ad” type=”LightLDAP.SitecoreADMembershipProvider” connectionStringName=”LDAP_CONN” applicationName=”sitecore” minRequiredPasswordLength=”1″ minRequiredNonalphanumericCharacters=”0″ requiresQuestionAndAnswer=”false” requiresUniqueEmail=”false” connectionProtection=”Secure” connectionUsername=”LDAP-Server-UserName” connectionPassword=” LDAP-Server-Password” attributeMapUsername=”sAMAccountName” enableSearchMethods=”true” enablePasswordReset=”false” />

</providers>

</membership>

<roleManager defaultProvider=”sitecore” enabled=”true”>

<providers>

<clear />

<add name=”sitecore” type=”Sitecore.Security.SitecoreRoleProvider, Sitecore.Kernel” realProviderName=”switcher” raiseEvents=”true” />

<add name=”switcher” type=”Sitecore.Security.SwitchingRoleProvider, Sitecore.Kernel” applicationName=”sitecore” mappings=”switchingProviders/roleManager” />

<add name=”sql” type=”System.Web.Security.SqlRoleProvider” connectionStringName=”core” applicationName=”sitecore” />

<add name=”ad” type=”LightLDAP.SitecoreADRoleProvider” connectionStringName=”LDAP_CONN” applicationName=”sitecore” attributeMapUsername=”sAMAccountName” cacheSize=”2MB” username=” LDAP-Server-UserName ” password=” LDAP-Server-Password” />

</providers>

</roleManager>

 

<profile defaultProvider=”switcher” enabled=”true” inherits=”Sitecore.Security.UserProfile, Sitecore.Kernel”>

<providers>

<clear />

<add name=”sql” type=”System.Web.Profile.SqlProfileProvider” connectionStringName=”core” applicationName=”sitecore” />

<add name=”switcher” type=”Sitecore.Security.SwitchingProfileProvider, Sitecore.Kernel” applicationName=”sitecore” mappings=”switchingProviders/profile” />

</providers>

<properties>

<clear />

<add type=”System.String” name=”SC_UserData” />

</properties>

</profile>

4-     Verify AD Integration:

  1. Execute page – http://sitename/sitecore/admin/ProviderStatus.aspx(e.g. http://testad/sitecore/admin/ProviderStatus.aspx )
  2. It will show which Provider is active for which domain

See snapshot

 

 

 

5-     Verify from Sitecore admin:

  • Open Sitecore user manager and role manager to verify that you have successfully imported the AD users and roles.

 

6-     Filtering the AD users to get selective users:

  • In the “ad” provider stringers in the membership, role manager or profile strings you can add this extra filter.
  • The highlighted filter will only pull “members of Lead developers from Developers Group from the AD Organization”

<add name=”ad” type=”LightLDAP.SitecoreADMembershipProvider” connectionStringName=”LDAP_CONN” applicationName=”sitecore” minRequiredPasswordLength=”1″ minRequiredNonalphanumericCharacters=”0″ requiresQuestionAndAnswer=”false” requiresUniqueEmail=”false” connectionProtection=”Secure” connectionUsername=”LDAP-Server-UserName” connectionPassword=” LDAP-Server-Password” attributeMapUsername=”sAMAccountName” enableSearchMethods=”true” enablePasswordReset=”false” customFilter=”(memberOf=CN=Lead Developers,OU=Developers Group,OU=USA,DC=mywebsite,DC=com)” />

 

ð  Assigning permissions to users:

–        There are multiple ways to assign permissions to the Sitecore items to these users. It would be a different topic to discuss.

–        But let me provide an example how I can add permissions using a Sitecore PowerShell script.

–        The script(e.g. this script assigns permissions of “Sitecore Author” to all Lead developers)

$userIdentity = “usaLead Developers

$userPassword = “SitecorePassword”

$users = Get-User $userIdentity -ErrorAction SilentlyContinue

foreach ($user in users) {

if($user -eq $null) {

Add-Rolemember -Rolename “sitecoreAuthor” -MemberName $users

}

}