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 Symposium 2018 Day 4 #SitecoreSYM @ParagonDev

Another late night. Today the closing keynote looked at the future of Sitecore. Things are looking good and I am excited to use some of the new features that 9.1 will use. Today was the first day of the MVP summit and my first one. We visited Pandora. What a great surprise. Tomorrow I head home, a little wiser and more motivated. I have had a long career of many ups and downs, but the moments this week have been ones filled with some of the most ups ever. So here we go my day in pictures.

SIF What is next with Sitecore 9.1. A much-improved installation process. Also hear a graphical interface may be happening.

What is new in Sitecore 9.1?

Closing Keynote. No announcement where the next Symposium will be. I secretly hope Chicago, but I am guessing Las Vegas.

Pandora with my fellow MVP buddies:

Alright last day is tomorrow. Let’s do this.

#Sitecore Symposium 2018 Day 3 #SitecoreSYM @ParagonDev

Going to try and keep this short and sweet. Just got back from Universal Studios Walk and it is getting late.

Day started out with an organized 5k run. Pretty sure team Paragon won.

Lots of good presentations today.

Sarah Robb O’Hagan CEO of FlyWheel. What a great story and she is someone I can relate to with the whole fitness thing and all. I wonder if she will let me follow her on Strava.

IMG_6975

.NET CORE and Sitecore

Sitecore and Alexa Integration

JavaScript and JSS

Last, but not least party at Universal City Walk. I couldn’t believe how awesome it was. It was a good day to be an MVP as I got in to the fast lanes. I hope my wand works.

#Sitecore Symposium 2018 Day 2 #SitecoreSYM @ParagonDev

Second day of the Sitecore Symposium craziness is in the books. So many exciting things I got to see and do. So, I will try my best to tell it in pictures at a high level since it is past midnight here and I have to get up and run a race tomorrow.

The day started off with a run. I just kept going in circles. Still not a fan of running in Florida, but I was happy with my run.

The keynote was great. Looking forward to a lot of new things from Sitecore. Here are some highlights:

  • Sitecore and SalesForce has strengthened their partnership.
  • Cannondale Cycles site launched with a bike finder app that reads Garmin Data.
  • SickKids foundation is raising money to build a new hospital. Great charity.
  • NotImpossible is changing the peoples lives for the better. What a great company.
  • Sitecore has purchased StyleLabs to further their brand and infrastructure.

Presentation on Azure I attended.

Presentation on GDPR standards.

Presentation on world’s fastest Sitecore Deploy. (Fastest until we come up with something faster, lol).

The keynote speaker was amazing this year. Daymond John from Shark Tank really makes you think about things to apply to work and life. I wasn’t allowed to take any pics and post, so I will just give you his five tips for success.

S – Set Goals

H – Homework

A – Amor

R – Remember you are the brand

K – Keep on swimming

Last, but not least some drinks, food and swag just because.

Good night…

#Sitecore Symposium 2018 Day 1 #SitecoreSYM @ParagonDev

Sitecore Symposium 2018 is in full force. This year it is at Orlando. This one is special as this is the first one I am attending as an MVP. So here we go in pictures.

Welcome sign at the airport.

Meeting up with my awesome co-workers. We took a limo ride to the hotel thanks to Scott for winning a contest.

Staying at the Swan and Dolphin hotel. We had some time to kill before the festivities started.

Hey it’s Mickey Mouse!

Doing some biking for a great cause.

Food!

I want one of these pillows. Time for bed and maybe a run in the morning.

#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!

092018_0302_sitecoresym5

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 = http://schemas.sitecore.net/Visual-Studio-Intellisense&#8221; > < 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.

#Sitecore July 2018 Meetup Chicago Impressions

This was the first Chicago Sitecore meetup this year. It is always great to see familiar faces at these things and reconnect. Some of the attendees I have worked with in the past and/or is a client of Paragon. Also a lot of them I follow on Twitter, but have not met in person so it is good to put the name and face together.

I am not going to lie I always look forward to the food at these things. Lou Malnati’s is my favorite pizza. The bling is also nice too.

The first presentation was done Ahmed Okour and James Gregory from American Eagle, “Deep Dive into Sitecore Installation Framework”.

A lot of the stuff they went over were things I encountered doing my first Sitecore 9 install. It was nice to get a better picture on what happens behind the scenes. On another note I had to hold back the laughs along with others as the words “SIFless” and “Sharding” were mentioned.

The next presentation was done by Naim Al and James Gregory from American Eagle, “Understanding Sitecore Custom Analytics and Power BI”.

This was in interesting one. There was the out of the box Sitecore tool introduced as well as a third-party tool. Very useful stuff for Marketers.

After the presentations were over it was time to go. Not before snapping a few goodbye picks. I am hoping the next Chicago Sitecore meetup will be soon.