Add Needed JavaScript Code to Any Page in #Sitecore

Many Sitecore sites need different tracking scripts on their website, but for different environments. For instance you might have multiple Azure sites hosting the same site, but in different environments that could be tracked (Dev, QA, Stage, Prod for instance). The proper script should generate for each site instance. This is one way to solve the issue, but I am sure there are other solutions.

In Sitecore I created a Script Settings Folder template. Each folder item contains a Script Setting item. You can have multiple.

I have a configuration filed that contains the settings of the host names for each environment.

    <configuration xmlns:patch="">
     <setting name="DEV_SERVER_NAME" value="" />
     <setting name="QA_SERVER_NAME" value="" />
     <setting name="PROD_SERVER_NAME" value=", " />

In the code below in a view (default in this case) the following code is added. The code will compare the current host to what is in the settings and render the appropriate scripts.

string headscripts = "";
string bodyscripts = "";

//Get Parent Item of Script Folder
var scriptdir = Sitecore.Context.Item.Database.GetItem(8DD8956D-7477-41A8-A879-8D3003995F7E);

//Get Hostname from Sitecore to Match the Current Enviroment
string[] hostname = Sitecore.Context.Site.HostName.Split(new char[] { '|' });

//The reason for a string array is because you may have multiple servers like prod that use the same scripts
string[] devservername = Sitecore.Configuration.Settings.GetSetting("DEV_SERVER_NAME").Split(new char[] { ',' });
string[] qaservername = Sitecore.Configuration.Settings.GetSetting("QA_SERVER_NAME").Split(new char[] { ',' });
string[] prodservername = Sitecore.Configuration.Settings.GetSetting("PROD_SERVER_NAME").Split(new char[] { ',' });
string scriptsettingitem = string.Empty;
    scriptsettingitem = "DEV";
if (qaservername.Intersect(hostname).Any())
    scriptsettingitem = "QA";
if (uatcdservername.Intersect(hostname).Any())
    scriptsettingitem = "PROD";
//Synthesis was used in the syntax below, but use whatever works for you. 
if (!string.IsNullOrEmpty(scriptsettingitem))
foreach (var childfFolderItem in scriptdir.InnerItem.Children.AsStronglyTypedCollectionOf<IScriptSettingsFolderItem>())
   if (childfFolderItem.Name == scriptsettingitem)
    foreach (var scriptitem in childfFolderItem.InnerItem.Children.InnerChildren.AsStronglyTypedCollectionOf<Foundation.Interfaces.Models.I_ScriptSettingBaseItem>())
       headscripts = headscripts + scriptitem.HeadTag;
       bodyscripts = bodyscripts + scriptitem.BodyTag;

So simple for the most part. What are some other ways to get this done? I would like to learn some other techniques for this.

Milwaukee #Sitecore Meetup Recap. @ParagonDev @layeronemedia #mkesug

This meetup was a big honor for me. I got to present for the first time ever at a public Sitecore meetup. I was nervous going into it for several weeks, but I did my best to prepare. Special thanks go to Joe Ouimet and Derek Dysart for giving me the opportunity to present and putting the meetup together. Also for Paragon Consulting for the awesome food and drinks and Layer One Media for hosting.

I did my presentation on the Sitecore Data Exchange Framework. My goal was to show the demo of my Reddit feed process and get others thinking about how they could use the DEF. I believe I accomplished that and hopefully I wasn’t too confusing. My code and marketplace module are out there so they can be used as a starting point. Also I will probably do an updated DEF blog series for the latest version.

So here we are in tweets and pictures for presentation 1:

Hey my favorite Paragon local sales person from Paragon joined me.

Presentation 2 had me excited. Anything that involves Alexa and Sitecore I am interested in. The topic was “Expanding the reach of your Sitecore Content with Voice-Activated Assistants”. It was presented by Benjamin Adamski and Jeroen de Groot. They did a fantastic job explaining all the benefits and where things are headed.


Well Milwaukee it has been great. I hope to make the next one.


#Sitecore Experience Editor Fixing Datasource Error 404.15 (Too Many Children)

Recently I came across an error that I have not seen before. It seemed this error was only happening on one item. This might be something you never come across or eventually will. Either way there is a good way to prevent it.

The error I saw was below. This happened when you tried to add a datasource to a specific rendering. Not the most descriptive, but it looks like Sitecore returns a big query string of an item’s children.

After examining the rendering I noticed the query that was used in the datasouce location would actually query all children.

The easy fix was to create a components folder and keep the datasource items in there. Then the query could be changed to the following which would only look for that folder. No more errors. Of course, you can expand on the query such as adding the specific templates of the datasource.


#Sitecore #SCHackathon 2019 Battle of the Team X-Men Developers @ParagonDev

A third year in a row participating in the Sitecore Hackathon with my coworkers at Paragon. I have learned from the previous years I have done this not to make the same mistakes, mostly. See Top 5 Reasons of Failure and Top 5 Reasons the Experience Was Better. However, nothing is ever smooth in the world of web development. So here is a quick summary and lessons learned for next time.


We made sure we could get into the GitHub repos. All was good there.

Hours 1-2:

Got the hackathon rules and we started coming up with ideas. I am just going to fix my install for 9.1 that I should have done beforehand that I cannot figure out why it is not working. Well I hopefully can get that finished soon. Okay we came up with some decent ideas and time to start documenting those ideas.

Hours 3-4:

Oh look 9.1 is still not quite installed. My teammates probably want to send me over to Magneto’s team at this point. However at least our idea is solid, but wait a minute…

Hours 5-6:

We need a new idea as all our ideas were already done in different variations. Hey, look at that finally got Sitecore 9.1 working.

Hours 7-12:

Alright we have an idea that solves a problem. Let the coding begin!

Hours 13-17:

Okay finished coding. Let’s surprise our teammate with the new idea we came up with while he was taking a break. He thinks it is a good idea and documentation has begun.

Hours 18-21.5

Video created, documentation created, GitHub repo checked. Let’s finish this up and get it checked in.


Time to sleep.

Summary and Lessons Learned

Well I haven’t learned all my lessons. I should have not assumed 9.1 would install as easy as 9.0. In my defense I did have food poisoning the day before and still feeling it. Despite that setback and getting an idea off the ground we made it in time this year. Win or lose I love doing this contest every year. It is a good time to bond with co-workers who I may not normally work and learn new things. One big thing we learned this year was keep the idea simple. That 24 hours comes quick. Solve a problem with your idea, but make sure you can do it in a good time. Documentation takes longer than you think.

Going into the Sitecore Hackathon:


My Second #Sitecore Technology MVP Journey. #SitecoreMVP

I debated if I should write a blog about becoming an Sitecore MVP again, but decided why not. I love blogging so this is a good chance to talk about the last year and my goals for this year. It is a like a diary for my future tech self.

Last year’s goals:

  • Write good quality blogs. (Hey it is an opinion not a fact.)
  • Attend all the local Sitecore meetups and network with local developers. (I made some new friends this way.)
  • Reach out help others in Slack and Sitecore Stack Exchange. (Did my best here, but I don’t always have the right answer.)
  • Create Sitecore Runner Buttons and bring them to the Symposium.
    Using my new MVP status network with the Sitecore family better. (Sorry if I talked too much.)
  • Participate in the Sitecore Hackathon. (Still catching up on sleep.)
  • Make a VLog. (Even bought a new camera last year. This one did not happen. :()
  • Update my DEF Redditt Module in the Sitecore Marketplace. (I have this almost ready just need the time.)

This year’s goals:

  • Write some more good quality blogs. (Does this one count? ;))
  • Attend all the local Sitecore meetups including one in Milwaukee. (Make sure you order enough food for me.)
  • Reach out help others in Slack and Sitecore Stack Exchange. (I love helping others so I won’t stop trying.)
  • Create Sitecore Runner Buttons and bring them to the Symposium. (If you did not get this highly sought after collectible I will be bringing them again.)
  • Using my new MVP status network with the Sitecore family better. (I am not hiding. Well behind this keyboard I am.)
  • Participate in the Sitecore Hackathon again. (Maybe I should sleep before it starts.)
    Make a VLog. (I have to make this happen.)
  • Finish that update on my DEF Redditt Module in the Sitecore Marketplace. (I am going to release it before the end of the year.)

If you are an MVP hopeful and you are reading this now I want to leave you with some advice the guy that was supposed to at the Sitecore Symposium said in a movie once. I put this quote right up there with Rocky quotes.

Image result for will smith pursuit of happiness quote

Adding Custom Dropdown Button in #Sitecore 9 to Content Editor Ribbon

I published a blog recently for creating a dropdown in the Rich Text Editor (RTE). You can find that here. I needed to do something similar for the content editor, so the same functionality could be done in text fields by saving the value in the clipboard.

In this case I will be adding a Token button to the Ribbon in the content editor. This button will contain a drop down.

In the Core database in the content editor you can add a button using the following path. I added the Tokens directory which is a Chunk item.

/sitecore/content/Applications/Content Editor/Ribbons/Chunks/Tokens/

Underneath the chunk I created a Large Gallery Button item. This type of item contains a drop down as seen above.

In my Visual Studio project, I added two files. The structure is below. This structure should match the structure in your site.

Gallery Tokens.xml contains the following code. The highlighted area is important as that tells Sitecore where to find the CSS code for the button and the code behind.

In the CodeBeside in the xml code it points the following extension. This extension will get the list of items in Sitecore and build a drop down list.

  1. public class CopyTokenMenu: GalleryForm {  
  2.     protected Menu Options = new Menu();  
  3.     static readonly Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase(“master”);  
  4.     readonly Item _parentTokenFolder = master.GetItem(“/sitecore/content/CustomerPortal/Site Settings/Tokens”);  
  5.     public override void HandleMessage(Message message) {  
  6.         Assert.ArgumentNotNull((object) message, nameof(message));  
  7.         if (message.Name != “item:load”) {  
  8.             base.HandleMessage(message);  
  9.         } else {  
  10.             Invoke(message, true);  
  11.         }  
  12.     }  
  13.     protected override void OnLoad(EventArgs e) {  
  14.         if (_parentTokenFolder == null || !_parentTokenFolder.HasChildren) {  
  15.             return;  
  16.         }  
  17.         Assert.ArgumentNotNull((object) e, nameof(e));  
  18.         base.OnLoad(e);  
  19.         if (Context.ClientPage.IsEvent) {  
  20.             return;  
  21.         }  
  22.         Options.Controls.Add(new LiteralControl(

    Copy token to place within your text:


  23.         foreach(Item token in _parentTokenFolder.Children) {  
  24.             Options.Controls.Add(new LiteralControl(“<p><button class=button title=’copy’ id=\”” + token.Fields[“TokenValue”].Value + “\” onclick=copytext(‘” + token.Fields[“TokenValue”].Value + “‘)><img src=\”/temp/iconcache/office/16×16/documents_empty.png\”></button>&nbsp;” + token.Fields[“TokenValue”].Value + ” – “ + token.Fields[“Description”].Value + “</p>”));  
  25.         }  
  26.     }  
  27.     private static Item GetCurrentItem() {  
  28.         string queryString1 = WebUtil.GetQueryString(“db”);  
  29.         string queryString2 = WebUtil.GetQueryString(“id”);  
  30.         var index1 = Language.Parse(WebUtil.GetQueryString(“la”));  
  31.         var index2 = Sitecore.Data.Version.Parse(WebUtil.GetQueryString(“vs”));  
  32.         Database database = Factory.GetDatabase(queryString1);  
  33.         Assert.IsNotNull((object) database, queryString1);  
  34.         return database.Items[queryString2, index1, index2];  
  35.     }  
  36. }  

    This is the token item created that will be read in for the button drop down.

    This is the style sheet code that is referred to in the xml file.

    In the Home Ribbon in the Content Editor the Token button now appears. Clicking it will bring down a drop-down list. Clicking on the icon will copy the value to the clipboard.

    That is, it. I hope this helps some of you. I enjoyed doing this and wanted to make sure it was documented as it could be difficult at first to figure out all the pieces.

Second Annual Chicago Meets Milwaukee #Sitecore Meetup Recap. @ParagonDev @GeekHive @_Americaneagle @jouimet @DDysart #SitecoreSym

After attending the first combined Sitecore meetup last year I was hoping the combined meetup would happen again. Well my hopes were answered. Joe from Geekhive invited me to speak on the Sitecore Symposium panel. I couldn’t wait to share my experience.

When I got there the usual food and goodies were there. The pizza was very good even though it was from Wisconsin.

The first presentation was on Coveo Hive. I am always impressed with Coveo and they continue to improve their product making them a vital search framework in the Sitecore world.

Looks like Hive introduces many new and exciting things.

Next was the Sitecore Symposium Panel. Joe from Geekhive did a great job hosting. It was great reliving the Symposium experience and sharing with others what we learned.

This meetup reminded me of one my favorite crossovers. I can’t wait for the next one.

#Sitecore October 2018 Chicago Meetup Impressions

This was the second Sitecore meetup this year. This one was at a different location. It was at Productive Edge in downtown Chicago. It was a scenic walk from the train. The office itself was setup nice. A lot of the attendees will be at the Sitecore Symposium, so it was nice to connect with them. We also used the Symposium app scan on the network menu to connect with each other. Of course, they had my favorite pizza, Lou Malnati’s.

The first presentation was a joint effort by Ryan Kuchler and Will Rolloff. This covered Context Marketing from both a marketer’s point of view and developers’ point of view. One of the things I believe that are overlooked by clients after a Sitecore site is complete is the powerful marketing tools that are in Sitecore.

Summary of topics:

  • Marketers – Get to know Context Marketing and deliver personalization to your audiences with out of the box Sitecore features and configurations – Today!
  • Developers – Architect and deploy the right application components that enable the business to drive context marketing and scaling it to meet your organizations needs using Microsoft Azure

They did an excellent job presenting and it was the best presentation I have seen on Context Marketing. I walked away with much more specific understanding on how all the different pieces worked. I especially liked the parts were previous versions of a page were compared to a new page, setting the score for each campaign and swapping out presentations based on visits. I will be using this information in the future.

Last, but not least Will presented tips for first time Symposium attendees. I wish I had these for my first Symposium. Even so it being my second Symposium coming up I still learned a few things.

One thing he forgot to mention. Take all the Sitecore bling you can with you.

Sitecore Symposium for Newbies #SitecoreSYM @ParagonDev

So last year being my first Symposium I did not know what to expect. I know there will be a lot of new attendees this year, so I wanted to give you some advice to make it the best experience that it can be.

Network, Network, Network

Starting at the airport I must have made at least five contacts with people also travelling to the Symposium. Waiting for my plane and the bus to the hotel. Also, I met in person a few people I have talked to online. I even ran with one of them. Yes, running with someone is a good way to network. As you make connections always make sure you have a bunch of business cards with you, so they contact you for whatever reason. A lot of the people you will meet may be someone you work on a project with in the future or may need to reach out to for some help.

Get to Know Your Co-Workers.

A lot of us work remote and don’t interact with our co-workers daily. If we do it is usually via email, skype, slack, WebEx etc.… Being at the Symposium face to face with people you work with can help establish a better working relationship. The old saying a face with the name is never more so true in today’s world. I also ran with one of my co-workers.

Get some nice bling.

From the time you arrive at the Symposium to the time you leave there are so many things with different Sitecore branding that you can take with you. I collected several buttons, flashlights, a hotel key, small plastic beer mugs, glasses, ice cubes you name it with Sitecore logos on it. Not to mention I got a lot of cool stuff from all the vendors there. Including stuff like pop sockets and socks.

Give some nice bling.

I mentioned buttons above and this year I decided to do my own to trade and give out. I think this will not only be a good way to promote my blog site, but break the ice with several other attendees. The company I work for Paragon was giving out cool flashlights last year. I made sure to hand those out whenever I could.

Be comfortable and dress nice.

Working remote I honestly don’t dress business casual these days. The recommended dress for the Symposium is business casual. I normally wear running shoes, but I thought I would get something that was like a classic sneaker, but could also work with business casual attire. Well good-looking shoes does not equate to comfortable. I was in so much pain it got harder to walk around every day (you will do a lot of walking). I learned my lesson and this year I plan on wearing shoes that are broken in and comfortable. You can look up business casual attire since it is interpretation is open, but considering you will be representing your employer there you want to dress nice. I am fortunate enough to have shirts with Paragon’s logo on it.

See you all there!


Adding RTE RichText Custom DropDown List in #Sitecore 9

Recently I had to do a custom implementation for an RTE dropdown list in Sitecore 9. I used @jammykam’s example to get started. This was done in a previous version of Sitecore. You can find it here. Granted the implementation did not change too much between versions, but if you are searching for a way to do it in Sitecore 9 this should help since there is at least one minor difference I found.

So, to not disturb the out of box RTE profiles I duplicated an existing one.

I created a custom dropdown button in the part of the RTE toolbar I would like to have the button available.

To tie the Rich Text Profile with its own EditorConfiguration pipeline a Configuration Type was added to the profile.

In the Visual Studio solution, I created the following which will define the button, add CSS and add JavaScript.

The InsertToken.xml contains the following:

  1. <? xml version = “1.0”  
  2. encoding = “utf-8” ?> < control xmlns: def = “Definition”  
  3. xmlns =; > < RichText.InsertToken > span.InsertToken {  
  4.     background – image: url(‘/sitecore/shell/Themes/Standard/Images/Editor/WebResource.png’) !important;  
  5. } < /RichText.InsertToken> < /control>  

    The InsertToken.js contains the following. Telerik controls were used in later versions of Sitecore including 9 instead of the RadEditor controls.

  6. Telerik.Web.UI.Editor.CommandList[“InsertToken”] = function(commandName, editor, args) {  
  7.     var val = args.get_value();  
  8.     editor.pasteHtml(val);  
  9.     args.set_cancel(true);  
  10. };  
  11. jQuery(document).ready(function($) {  
  12.     loadCSS = function(href) {  
  13.         var cssLink = $(“<link rel=’stylesheet’ type=’text/css’ href='” + href + “‘>”);  
  14.         $(“head”).append(cssLink);  
  15.     };  
  16.     loadCSS(“/sitecore/shell/Controls/Rich Text Editor/InsertToken/InsertToken.css”);  
  17. });  

    The InsertToken.css contains the following. The reason for this CSS code is so that the button in the RTE appears correctly. @Ja

    span.InsertToken {

  18. background – image: url(‘/temp/iconcache/office/16×16/document_json.png’) !important;  
  19. }  

    Under Pipelines\RichTextEditor an override to the EditorConfiguration was created.

    You can use DotPeek or another decompiler to get the code to override, but the main thing you want to change is the following in this case. Note the ItemsPerRow kept the column values in one single line.

  20. case “Html Editor Custom Drop Down Button”:  
  21.     var editorSplitButton1 = new EditorSplitButton {  
  22.         Name = str1, ShowIcon = true, ItemsPerRow = “1”, ImageUrl = “/temp/iconcache/office/24×24/document_json.png”  
  23.     };  
  24.     EditorSplitButton editorSplitButton2 = editorSplitButton1;  
  25.     SetProperties((EditorTool) editorSplitButton2, obj);  
  26.     EditorConfiguration.SetChildren(editorSplitButton2.Items, obj);  
  27.     toolbar.Tools.Add((EditorToolBase) editorSplitButton2);  
  28.     continue;  

    The list of values is fed from Sitecore. The token item contains a Description and TokenValue field.

    SetChildren is called which in turns calls GetTokenList to retrieve the values and set the dropdown.

  29. private static void SetChildren(EditorDropDownItemCollection items, Sitecore.Data.Items.Item parent) {  
  30.     Assert.ArgumentNotNull((object) items, “items”);  
  31.     Assert.ArgumentNotNull((object) parent, “parent”);  
  32.     foreach(Sitecore.Data.Items.Item obj in parent.Children) {  
  33.         if (parent.Name == “Insert Token” && obj.TemplateName == “Html Editor List Item”) {  
  34.             items = GetTokenList(items);  
  35.         } else {  
  36.             if (obj.TemplateName == “Html Editor List Item”) {  
  37.                 items.Add(obj[“Header”], obj[“Value”]);  
  38.             }  
  39.         }  
  40.     }  
  41. }  

  42. private static EditorDropDownItemCollection GetTokenList(EditorDropDownItemCollection items) {  
  43.     Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase(“master”);  
  44.     Item parentTokenFolder = master.GetItem(“/sitecore/content/Tokens”);  
  45.     if ((parentTokenFolder == null) || (!parentTokenFolder.HasChildren)) {  
  46.         return items;  
  47.     }  
  48.     foreach(Item token in parentTokenFolder.Children) {  
  49.         items.Add(token.Fields[“TokenValue”].Value + ” – “ + token.Fields[“Description”].Value, token.Fields[“TokenValue”].Value);  
  50.     }  
  51.     return items;  
  52. }  


    After the changes you should see the RTE button in the editor and selecting it should insert the text that was predefined.