Sitecore SXA – Way of adding Custom Front End Assets


The Sitecore has change the website development with launch of the SXA with their first release and now they have make their vision very clear about how to quickly ship the website to market via this very powerful tool.

The Issue

While working on one of the SXA website build project, I came across one strange finding. Even if you selected Bootstrap 4 as your grid system for website. There are may out of the box bootstrap css classes are missing. This leads to some investigation ad found of the Sitecore SXA has ported just grid related styles(bootstrap-grid.css) to Sitecore SXA but not the full bootstrap main css(bootstrap.css)

Now, I have two concerns, first how can we add this the Sitecore SXA way without touching existing MVC layout or creating new layout? and Secondly, how can you only enable/import this to selective websites?

The Fix

After some googleing and reading few of Sitecore documents, found following steps will help get the answers to both above mentioned concerns.

  1. Create new base theme item of type /sitecore/templates/Foundation/Experience Accelerator/Theming/Base Theme under path /sitecore/media library/Base Themes (one can use insert options too). In my example I have given name bootstrap 411.
  2. Create a Styles folder item of type /sitecore/templates/Foundation/Experience Accelerator/Theming/Folders/Styles (one can use insert option) under the newly created base theme item above.
  3. Upload the css file to this styles folder using media upload feature. In my example I have uploaded bootstrap.css
  4. Navigate to the site specific theme item under media library. For example, /sitecore/media library/Themes/Tenant1/Website1
  5. In the Base Themes multi-select link field select the newly created base theme item in step 1 above
  6. Publish all newly created items in step 1 and 2
  7. Publish altered website specific theme item

Verification

New styles should work if the newly added stylesheet render on the page. To verify style link is render on website page or not we need to turn The Asset Optimizer off for the site (by default this is on and if it is already turned off you can skip these steps)

  1. In the Content Editor, navigate to sitecore/content/<Tenant>/<Website>/Presentation/Page Designs.
  1. In the Asset Optimization section, in the Styles Optimizing Enabled and Scripts Optimizing Enabled fields, to override styles and scripts optimization settings, select:
    • Default – to inherit global settings.
    • Yes – to always enable optimization for this site.
    • No – to always disable optimization for this site.

3. Publish the Page Design Item

4. Navigate to the web application in the browser and open the page view source and look for the newly created item path in the head section. In my example, looking for bootstrap-411(don’t mind the hyphen as it is due to link manager options settings)

<link href="/-/media/base-themes/bootstrap-411/styles/bootstrap.css" rel="stylesheet" />

Further to verify, also check other website within the same CMS and check the page source view for absence of newly added stylesheet.

In above example, we have added Style Sheet asset but this same can be done for Scripts assets as well

Happy Sitecore SXA website development…!!!

References

Sitecore Docker – Run CM sites on HTTPS


While working on the integrating Sitecore’s CM’s functionality with third party Digital Asset Management(DAM) system, I came across one interesting issue where I wanted my container applications to run on https.

The Issue

After integrating the third party DAM with Sitecore CMS, it found out that, while using local website on developer machine, the developer is not able to load the SSO login page. While loading that page below error messages logged in browser’s console.

Access to the WebCrypto API is restricted to secure origins. Compact View requires HTTPS when used outside localhost (for development).

As clearly stated I am not using localhost as host to access my cm and seems like CM needs to be securely severed over https where as we, for local development, use non secure protocol http.

The Fix

The solution is simple looking form 35,000 feet. Needs CM urls to be serving content over the secure HTTPS protocol. But when actually started digging in details, it is fun and very learning experience.

Performed following steps to achieve this on our local docker development environment.

  1. Clone or download below repository

https://github.com/michaellwest/docker-https

  1. Open the startup/createcert.ps1 for editing and change following parameter’s default value
  • $certificatepassword – from b to more secured passowrd string
  • $dnsNameList – by default the value is *.dev.local. Change this value to match your host pattern. You can specify individual host comma(,) separated.

Note

Alternatively, you can can pass those two as parameter while firing createcert.ps1 command.

3. Open docker-compose.yml file and navigate to cm service and perform following changes:

  • Add new environment parameter HOST_HEADER and set cm host value to it. If you have multiple host(this is what in my case), specify them semicolon(;) separated list. For example host1.dev.local;host2.dev.local
  • Under the volumes bind the new volume for folder startup to c:\startup path of container.
  • Under the port bind the https’s default secure port 443 with the next available container port

Note

The container host port needs to be new port which is not been use by any other services.
  • Lastly, change the entypoint to the path of startup.ps1 file under the startup folder bound under the volumes in above step for startup folder.

After all above changes to CM service of docker-compose.yml file will look something like below

services:
  ...
  cm:
    image: ${REGISTRY}sitecore-xm-cm:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION}
    entrypoint: powershell.exe -NoLogo -NoProfile -File C:\\startup\\startup.ps1
    volumes:
      - .\src:C:\src
      - .\startup:C:\startup
    ports:
      - "44001:80"
      - "44002:443"
    networks:
      default:
        aliases:
          - cm.dev.local
          ...
    environment:
      HOST_HEADER: cm.dev.local
      ...

4. Copy folder startup and it’s content to same folder where your docker-compose.yml file is.

5. Open the powershell in elevated mode and execute following command

PS> cd <<docker-compose.yml file's folder path>>
PS> ./startup/createcert.ps1

Above powershell script will generate three files cert.cer, cert.pfx and cert.password.text under the startup folder.

This command will also generate the self-signed wildcard certificate and install to your system’s local certificate store under personal.

To verify that run mmc and open local computer certificate store.

Self signed wildcard certificate for *.dev.local

6. Now, is the time to fire up the container for sitecore. To do so run following docker compose command

PS> docker-compose up -d

After successful execution the container services will be up and one can access the host binding with https. For example https://cm.dev.local in this case.

Advance trouble shooting

  1. To check the certificate is exist after the createcert.ps1 script execution. This command can be run on both your local and against cm container as well.
PS> Get-ChildItem -Path cert:\LocalMachine\My
  1. To verify the binding under the container’s IIS for the specified hosts use following commands
PS> Get-Website -Name 'Default Web Site'
  1. To get all the bindins and their port details for a website
PS> Get-WebBinding -Name 'Default Web Site'

References

DEF – Pipeline batch ribbon button issue


This is going to be a short blog for fixing issue I came across while working on custom pipeline creation and execution for Sitecore’s Data Exchange Framework(DEF or DxF).

The issue

While the Pipeline Batch item is selected, buttons on DATA EXCHANGE toolbar at top does not behave how they should.

Immediately after selecting pipeline item, I noticed all buttons in ribbon is visible and clickable. Secondly, clicking on Run Pipeline Batch Button does not works. I was neither starting execution of pipeline nor displaying any visible error messages. See below image for more details:

The fix

I started investigation and collecting events what could have done the damage. Found that before last deployment it was behaving the way it should be. Huuummm… that’s good hint, isn’t it? The last release just deployed files to CMS server. This is soothing to my ears as investment scope is drastically reduced to files. The content automatically gone out of equation.

To fix this, I tried install DEF SDK package first with just deploying file artifacts and skipping any content installation.

Unfortunately, that does not work ….!!! 😦

Next best bet is obvious and try to re-install the DEF framework package with deploying files only.

And that does the trick ….!!!! (Dance)

Update:

The file \App_Config\Sitecore\DataExchange\Sitecore.DataExchange.Local.config was missing. Placing this file from Package has actually fixed the issue.

Happy Data Sync and import using Sitecore Data Exchange Framework. 🙂

Sitecore CMS not showing graph on Launch pad


This morning when I login to one of none production environment I found that the graph was not loading on Sitecore CMS launch pad.

When I did into more details and found out the ajax request to get the data are failing with server error(HTTP-500). As shown in below image the response of the API call does not providing any information or clue.

Immediately, I jumped onto logs and found following entry in there.

 The remote server returned an error: (403) Forbidden.

The full exception looks like below.

50616 09:48:50 ERROR [Experience Analytics]: System.Net.WebException: The remote server returned an error: (403) Forbidden.
   at System.Net.HttpWebRequest.GetResponse()
   at Sitecore.Xdb.Reporting.Datasources.Remote.RemoteReportDataSourceProxy.GetData(ReportDataQuery query)
   at Sitecore.Xdb.Reporting.ReportDataProvider.c__DisplayClass18_0.b__1()
   at Sitecore.Xdb.Reporting.ReportDataProvider.GetCachedDataForQuery(ReportDataQuery query, Func`1 ifNotAvailableInCache, Nullable`1 ifModifiedSince)
   at Sitecore.Xdb.Reporting.ReportDataProvider.ExecuteQueryWithCache(ReportDataQuery query, ReportDataSource dataSource, CachingPolicy cachingPolicy)
   at Sitecore.Xdb.Reporting.ReportDataProvider.GetData(String dataSourceName, ReportDataQuery query, CachingPolicy cachingPolicy)
   at Sitecore.ExperienceAnalytics.Api.ReportDataService.ExecuteQuery(IReportQueryData queryData, CachingPolicy cachingPolicy)
   at Sitecore.ExperienceAnalytics.Api.ReportingService.RunQuery(ReportQuery reportQuery)
   at Sitecore.ExperienceAnalytics.Api.Http.AnalyticsDataController.Get(ReportQuery reportQuery)

Fix

After further investigation found out the Reporting keys were not aligned between CM and Reporting server in the ConnectionStrings.config file.

<add name="reporting.apikey" connectionString="84090dc97055b10532a054da067df368" />

Further reading

Sitecore Publishing Service – Part 2 – Install and Configure Module


Now that Publishing service is deployed, configure and up in Part – 1, the next bit is to install and configure Sitecore publishing service module in Sitecore CM and CD. This part is very simple and strait forward. So lets get started…

The Sitecore publishing module is nothing but Sitecore package and needs to be installed the same way as other Sitecore packages. This package contains all the necessary artifacts for this module to perform it’s job.

Download

The Sitecore Publishing Module can be downloaded from here.

Note

Just check the the version compatibility with Sitecore version where you wanted to implement this publishing service/module. For this you need to navigate to individual release page and check the compatibility detail at start of the page under the main heading.

Install publishing module

To install Sitecore publishing module, one can use OOTB Sitecore installation wizard.

==========================================================
***Important! Copy and save this information***
==========================================================
    BEFORE YOU CLICK NEXT:
    - Ensure you have installed and configured the Sitecore Publishing Service (this module only enables integration with the service)
        Documentation detailing how to install the service is available seperately.

        [Warning] This module will not work without a properly configured service instance.  No items will be able to be published.
    
    AFTER YOU CLOSE THE WIZARD:
    After the package is installed, follow these steps to complete the Sitecore Publishing Module installation:
    - Configure the service endpoints:
        Add a configuration file which overrides the 'PublishingServiceUrlRoot' setting to point to your service module        
        Make sure the address contains a trailing slash
        e.g.
            <?xml version="1.0" encoding="utf-8"?>
            <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
              <sitecore>
                <settings>
                  <setting name="PublishingServiceUrlRoot">http://sitecore.publishing/</setting>
                </settings>    
              </sitecore>
            </configuration>
    - Configure the Content Delivery Servers:
        Ensure that the following file is in the website 'App_Config/Modules/PublishingService' directory:
            * Sitecore.Publishing.Service.Delivery.config
        Ensure that the following files exist in the website 'bin' directory:
            * Sitecore.Publishing.Service.dll
            * Sitecore.Publishing.Service.Abstractions.dll
            * Sitecore.Publishing.Service.Delivery.dll

Note

Just before installation process starts, installer will prompt the information about configurations and artifacts needed for the Sitecore Module and services to work. As instructed, copy and save that instruction shown in above(From version 3.1.3).

Configure

Once installation of the module is successful, in CM perform following steps:

For CM

For example:

http://my-sitecore-publishing-service.azurewebsites.net/

Note

Make sure the URL is post-fix with forward slash(/) at the end.

For CD

  • Navigate to <website root>/App_Config/Modules/PublishingService folder in both the CM and CD app services
  • Copy Sitecore.Publishing.Service.Delivery.config file from CM to above folder in CD
  • Navigate to <website root>/bin folder in both the CM and CD app services
  • Copy below library files to CD’s bin folder from CM
    • Sitecore.Publishing.Service.dll
    • Sitecore.Publishing.Service.Abstractions.dll
    • Sitecore.Publishing.Service.Delivery.dll

At this point, the publishing will start working, if there is only one default Internet publishing target is there. The Publishing Module has overwritten few of Sitecore default settings for publishing. So after installation of publishing module, one may notice change in UI for the Publishing. Please read here for more details about visual changes and changes in types of publishing.

The last part -3 will cover some specific configuration for Azure PaaS environment and some advance setting of Sitecore Publishing Service. So stay tuned and enjoy content publishing….!!!

Content sync with RAZL script


Hi Sitecore Enthusiastic,

Recently come across very great strategy to sync content between two instances of Sitecore using a very powerful tool called Razl form Hedgehog.

Please read more about Razl here.

I have used this tool before mainly to compare the content between two different databases. For example production CM and Pre-production CM. Today, I came across very new and great features with latest version of Razl offering call tasks and executing task using Razl scripts.

It is offering content sync tasks to be exported in a file(or call script) as xml format and later one can use that to sync data in different environment using Razal script.

For more information about Razl task, read official document here.

The great part of this task is you can cherry pick what you want to sync out of the whole Sitecore content tree. You can go deep up to the field level with your sync task.

once you have a list of tasks ready, you simple can export that as script and execute it with command or create scheduler task to run that script using command and it will do the sync between source and target connections.

Razl.exe /script:Migrate.xml
Razl.exe /script:"c:\Site Migration\Razl.xml"

Even if you want to go one level further you can automate this sync task post publishing(perhaps not ideal, if frequent publishing is happening) or you can hook it post deploy task in you CD script(if your build contains TDS/unicorn content items).

You must be wondering this is great tool and great way to sync, but what if I am trying to sync big chunk of content items!!!???.
You can use another great feature of Razl called Lightening Mode(obviously you can configure this in you script as well). This mode really boost the performance of sync script if your CoplyAll task is configured to do bulk copying of items.

As far as logging concern, Razl Script mode will output actions as they happen to the command prompt, this output can be written to a text file if required using following command sample.

Razl.exe /script:"c:\Site Migration\Razl.xml" >> c:\logs\RazlScriptLogs.txt

Tip: Single arrow > will create the file if missing and if exist, overwrite the content of file.
Double  arrow >> will create the file if missing and if exist, it will append to the file.

If a log folder has been already configured in the Razl GUI than Script mode will also write to the log file under configured log folder.

Thanks for reading.

Happy Content Sync…!!!

Reference
Script – https://hedgehogdevelopment.github.io/razl/script.html
Connections – https://hedgehogdevelopment.github.io/razl/connections.html
Lightning mode – https://hedgehogdevelopment.github.io/razl/comparing.html#lightning-mode

Set dynamic datasource for template field in Sitecore multi-site


This is to share some of the tricks you can use while dealing with multi-sites with Sitecore CMS while designing content solutions.

While dealing with multi-site, we all come across scenario where we want data of some fields to be different per site based on where that item exist. In other words, want to load dynamic data in link types of fields for the data present in that local site.

Of course, the answer is use Sitecore query instead of fixed path. The trick I wanted to share is how to formulate that query.

Lets take one example(I feel if you explain with real life example, people are tend to understand more quickly).

My multi-site content information structure is laid out as follow:

Content

SiteA

Home (All the navigable pages goes here)

Configuration (Master settings for site and features)

Data Library (As name suggested this holds data for the site)

SiteB

Home

Configuration

Data Library

Now, lets assume you have SiteA for Asia-Pacific and SiteB for Europe and there are country data items present under Data Library for both respected sites as shown in picture below.

multi-site-information-structure

Now, you want content editor to select only countries present under that site in field called “Supported Countries” for site’s Configuration item.

sitea-configuration-for-country-items-as-datasource

You can have following Sitecore query as Source of field Supported Countries for the Site Configuration template.

query:./ancestor::*[@@templateid='{B8313310-198B-4596-9532-7E39BAB33503}']/Data Library/*[@@templateid='{7CF67E0D-A30F-4C48-9247-69DE07821520}']/*

Let’s dive in details about how this query is formulated. Before doing that, please thoroughly go through image below.

sc-query-explained

The query is divided in the six parts:

  • Part 1: first part is query keyword, which informs Sitecore that the data source of this field is not just simple item path but complex Sitecore query.
  • Part 2: The the .(dot) present the current item. These items are highlighted in Red. In our example, it is Configuration item. As we are setting query for the field Supported Countries of template Site Configuration. Configuration item under SiteA and SiteB is actual instance of template.
  • Part 3: This is the tricky part, form current item we are getting the list of all the ancestor items. For Configuration item under SiteA, the ancestors are SiteA, Content and Sitecore. For SiteB, ancestors to Configuration items are SiteB, Content and Sitecore. These items are highlighted in violet color. Once we get the list of ancestors, we need to filter out the item which is of template type Site(id of this template is {B8313310-198B-4596-9532-7E39BAB33503}.
  • Part 4: From Filtered Site item, we need to dive in the the sub-tree of Library. To do this we can use the same method of filtering based on template id like we did in part 3 above, but this would be bit costly operation as we need to look for all children underneath site and then filter based on Site Data Library template. Here, I have used fixed path instead, assuming all the sites in this content tree have to have a item called “Data Library”. This is to demonstrate, one can use fixed path query as well with Sitecore query. These are highlighted in green color in content tree.
  • Part 5: The 5th part is same as part 3, except looking for ancestors, it is looking for children and then filtering the child with the template id {7CF67E0D-A30F-4C48-9247-69DE07821520}. This is to find folder type item of template Country Folder, which are highlighted in Sky-blue color in content tree.
  • Part 6: The last part is to get the list of all items under the Countries folder filtered in part 5 above. Here, I assuming none other item present under this folder except for template type Country. If you are looking for particulate type of items you can use filters to get those items. These items in content tree are highlighted in grey color as leaf nodes.

Tip: Be cautious while using descendant or //* in field’s datasource query. This is costlier read operations and may hit the performance of field rendering in Content editor.

Enjoy dynamic field data source and Sitecore query …!!!

Reference
https://sdn.sitecore.net/Reference/Using%20Sitecore%20Query/Sitecore%20Query%20Syntax.aspx

Ongoing publishing issue with Sitecore 7.2


Here I wanted to share simple solution to an ongoing issue of publishing with Sitecore 7.2 with my company. It is such a simple solution but took lots of efforts and time to get to it. Thought to share it so that if someone is facing same kind of issue, can be benefited out of it.

The problem:

Out marketing team(who is also responsible for the content management) continuously reporting us with the issue of publishing. They mentioned that whenever we try to publish any item, the publishing took lot of time to finish. Most of the time publishing dialog stuck at Initialization stage. This issue sometimes go worst, even after waiting for half an hour to 45 minutes the publishing dialog still shows initialization and we need to ask web admin guys to re-cycle application pool and start publishing again(this is worst case scenario).

Publishing Dialog Initalizing

So as a first step, I asked them to avoid bulky publishing. I also suggested then to avoid using publishing related items rather go to individual items changed and only publish those items. The reason is to minimize items count in publishing which keeps publishing process as short as possible and keep them moving.

Even though content authors follow my suggestions, the issue still persist. So we started investigating even more. We planned to take help of Sitecore support personal who visiting us once every month. He suggested us to compare all the config files with pure vanilla version and along with all the other files and folder so we can be absolute sure we are having all the goodies what should be there. After this huge activity we identified couple of missing files and configurations in both CM and CD environments.

So we have gathered all those missing pieces and deployed to the respected environments.

After this we have reported a side effect from marketing, that what ever we are deploying to Fail-over publishing target(which is our DR cum internal Preview servers) it also eventually published to production(which is very strange to us and this was not the behavior before we deploy the missing bits).

Root cause

So, I started investigating in context to new side effects. While going through the log file for CM server, my eyes struck with an strange log entry which looks something like below.

5768 2016-03-10 11:03:57 INFO AUDIT (ad\paragd): Execute workflow command. Item: master:/sitecore/content/Site1/Home/test, language: en, version: 11, id: {23005A37-6BB5-4025-AC5B-047A8D3F3719}, command: /sitecore/system/Workflows/Site1 Workflow/Draft/Submit, previous state: Draft, next state: /sitecore/system/Workflows/Site1 Workflow/Awaiting Approval, user: ad\paragd
ManagedPoolThread #3 2016-03-10 11:03:59 INFO Starting update of index for the database 'master' (1 pending).
ManagedPoolThread #3 2016-03-10 11:03:59 INFO Update of index for the database 'master' done.
ManagedPoolThread #16 2016-03-10 11:03:59 INFO Starting update of index for the database 'master' (1 pending).
ManagedPoolThread #16 2016-03-10 11:03:59 INFO Update of index for the database 'master' done.
5284 2016-03-10 11:04:00 INFO AUDIT (ad\paragd): Execute workflow command. Item: master:/sitecore/content/Site1/Home/test, language: en, version: 11, id: {23005A37-6BB5-4025-AC5B-047A8D3F3719}, command: /sitecore/system/Workflows/Site1 Workflow/Awaiting Approval/Approve, previous state: Awaiting Approval, next state: /sitecore/system/Workflows/Site1 Workflow/Approved, user: ad\paragd
5284 2016-03-10 11:04:00 INFO AUDIT (ad\paragd): [Publishing]: Starting to process 2 publishing options
4572 2016-03-10 11:04:00 INFO HttpModule is being initialized
568 2016-03-10 11:04:00 INFO HttpModule is being initialized
5456 2016-03-10 11:04:01 INFO Job started: Publish
2736 2016-03-10 11:04:01 INFO Job started: Publish to 'web'
.
.
.
2736 2016-03-10 11:04:01 INFO Job ended: Publish to 'web' (units processed: 11)
7052 2016-03-10 11:04:01 INFO Job started: Publish to 'web_Failover'
.
.
.
7052 2016-03-10 11:04:02 INFO Job ended: Publish to 'web_Failover' (units processed: 11)

Above lines, I found in the log just above the log line for manually triggering of publishing just for the single publishing target which is “fail-Over”.

4392 2016-03-10 11:04:18 INFO AUDIT (ad\paragd): Publish item: master:/sitecore/content/Site1/Home/test, language: en, version: 11, id: {23005A37-6BB5-4025-AC5B-047A8D3F3719}
3600 2016-03-10 11:04:28 INFO AUDIT (ad\paragd): Publish, root: {23005A37-6BB5-4025-AC5B-047A8D3F3719}, languages:en, targets:WWW_Failover, databases:web_Failover, incremental:false, smart:true, republish:false, children:false, related:false
3600 2016-03-10 11:04:28 INFO AUDIT (ad\paragd): [Publishing]: Starting to process 1 publishing options
2864 2016-03-10 11:04:29 INFO Job started: Publish
5240 2016-03-10 11:04:29 INFO Job started: Publish to 'web_Failover'

Solution

From above behavior on the log file, it was clear that the workflow has to do something with this. When I checked the default workflow assigned, I found that there is an auto publishing action configured with final stage of the workflow as shown in below screen grab.

Auto publishing action item configuration

But alone having auto publish action configured, should not be making publishing this slow. So I have investigated more and found the real culprit.

The auto published action is configured with deep=1 as parameters.
So now, I have dive into the de-compiled code and found this is very dangerous parameter configured with auto publishing action.
Having deep parameter set, you are instructing auto publisher to publish everything underneath the selected item(approving item here) to every publishing targets(in this case 2 targets).

So, if you are approving leaf node/item, the auto publishing will be quick as it will only publish that node along with no child. But if you are approving, lets say home node of the site, you are actually publishing not just that root home item but pretty much the whole site to all available publishing targets…!!!(Very shocking…isn’t it?).

So now after approving the item, when you trying to publish that home node to selected target, it always queue up in the publishing queue and Sitecore publishing dialog box show you Initialization message screen as shown above. The item publishing will be picked up when previous auto publishing job is done. This is the case with just one editor, if you have 5-6 content editor, then the situation can go into really worst.

So the easy solution is to remove that auto publishing action item which was publishing lot of unwanted items to all targets in background without any visible signs.

So we did that and everyone is happy ever after…..

But the story does not ended here. I was thinking while going to home that day, when the auto publishing action was configured and present with default workflow since the edges then why approving the item wasn’t picked by both the CD servers?

So next day, I have kept my investigation going and discover the ScalabilitySettings.config file which was missing on all CD servers. While deploying the missing configurations and file we have deployed this file on all CD serves started picking the events execution for all CDs.

So, happy publishing….!!!!

Reference

https://sitecorebasics.wordpress.com/2011/05/28/is-your-sitecore-publishing-stucks/