#Sitecore Templates Back to Basics

We see a lot of blogs on cool things, but what I believe is missing lately are blogs on the basics of Sitecore. It has also been mentioned in the Sitecore community that we don’t have enough blog posts about the basics. So I will be doing more of these. Ironically. recently I have been holding training sessions with my colleagues at RBA. They are in roles such as QA, Strategist and Front-End development. All of them need to use Sitecore, but really don’t know the what and why Sitecore is the way it is.

I wanted to start with Templates. How I present this will be a little technical, but most of it will be broken down for easier understanding. Keep in mind this blog is geared towards the non back-end developers, but will be somewhat technical. This should give someone a basic understanding of Sitecore templates.

To explain how templates work I want to use a car as an analogy. Lets say we need to create a window sticker for a car. What fields would you need to do that?

On a window sticker you would probably see something like this.

Standard Details

  • VIN
  • Interior Color
  • Exterior Color
  • Standard Equipment
  • Options
  • Price
  • Etc…

Optional Equipment

  • Options Selected

In order to store this information we would need some sort of data structure. That is where a Sitecore template comes in to play. A template would have fields defined in order to create a window sticker item that will hold the information needed. Using this template we can create multiple window sticker items. Items btw as you can guess are created from templates. Everything you see in Sitecore is basically an item.

Template Creation

We are going to start with a simple template creation. In the Sitecore content tree the templates are usually found in the [might have a path here]/sitecore/templates folder. If you need to ever find a template for an item quickly you will see the path in the item Quick Info section. Even the Templates folder is made up of a template. See the example below.

Moving on to template creation. Typically a developer would create a new template by right clicking on one of the sections in the templates folder. For most of you reading this basic guide you don’t have to worry to much about it, but if you are curious or a new developer in the Sitecore world. This is what you will see.

We will just create a new template under User Defined. When creating a new template we will just use the default standard template. The name will be Window Sticker.

After it is created you will see several sections. For this blog on basics though we will just mainly be concerned about the Builder tab up on top. When clicking that you will see the following.

This is where we will defined the data structure for the Window Sticker item. Templates allow you to group common fields in sections. In this example we have a Standard Details section and a Options section. Each have their own fields defined. The Type of field should be determined by the most user friendly option for content entry.

Item Creation

After a template is created it usually inserted by right clicking on the item in the content tree you want to insert it under. In this case using the template created above we created a Window Sticker Item. You will see the following fields in the item. As you can see the fields we created in the template is present on the item create from the template. The Template path in the Quick Info section will take you to the template of the item if you need to make some edits.

Inheritance

One last thing to go over. One of the most powerful things about Sitecore templates is that they can inherit from other templates. So what does that mean? Well suppose you had an address section on several templates. You only need to create one address template and the other templates that need to use the same field can inherit from that template. When the item is created from the template that contains the inherited template the item will not only have the template fields, but the inherited ones too.

For instance let’s create a template called Factory Address.

The Window Sticker will inherit the Factory Address template. By default it already inherits the Standard template.

So now when you view the item created with the Window Sticker template you will see the Factory Address section.

Wrap Up

So I hope I gave you a basic understanding how Sitecore templates are created. There are many settings on them you can play around with, but for those that are non-technical I hope this gave you a basic understanding of them. Please reach out to me if you have any questions.

Using #Sitecore SXA Variants With a Single View

Let me start out by saying I felt this was a good route to take although may not be everyone’s first choice. There are more than one way to accomplish things correct? Here is how I do it.

What is a Variant?

A variant in SXA allows you to change the rendering output to display differently as needed. You can learn more about them by clicking here.

How to Setup a Variant

In SXA you will find the variants under /sitecore/content/[path]/Presentation/Rendering Variants. You will want to create a Variants parent item (/sitecore/templates/Foundation/Experience Accelerator/Rendering Variants/Variants) and underneath Variant Definition items (/sitecore/templates/Foundation/Experience Accelerator/Rendering Variants/Variant Definition). It is very important to name the Variants parent item the same name as your rendering that you will create. That is how SXA ties them together.

When adding the component to the page you will see the variants added.

The Code

In the view model we will inherit from the VariantsRenderingModel.

public class SuperfnaturalViewModel: VariantsRenderingModel
    {
         public string RenderingVariant { get; set; }

    }

The repository will inherit from the VariantsRepository. Using the method FillBaseProperties the necessary information to retrieve the variant information will be added to the model.

internal class SupernaturalRepository : VariantsRepository, ISupernaturalRepository
    {
        public override IRenderingModelBase GetModel()
        {
            SupernaturalViewModel supernaturalViewModel = new SupernaturalViewModel();

            FillBaseProperties(supernaturalCardsViewModel);
           
            return SupernaturalViewModel;
        }
    }

In the view we will get the selected variant using the FieldNames value (can also set this value in a variable in the view model). I know not the name (FieldNames?) I expected either.

string VariantGuid = Model.Rendering.Parameters["FieldNames"];

Checking What was Selected

Check default or if nothing is seletected.

@if (Constants.SupernaturalVariants.Default == VariantGuid || string.IsNullOrEmpty(VariantGuid))

View code goes here, you know HTML.

Check for the image left variant.

@if (Constants.SupernaturalVariants.ImageLeft == VariantGuid)

View code goes here, you know HTML.

Final Thoughts

Lots of ways to do this I am sure, but this was something I was familiar with and pretty easy for others to use in my opinion. There may be a better way, but as Adam Sandler says.

Adding Buckets with Rules to #Sitecore SXA Explained

It has been awhile since I created buckets in Sitecore and last time I did might of been before SXA was released. After some help from the Sitecore community here are the steps I took.

Create Bucketable Template

On the standard values of the template I wanted to be part of the bucket under the Configure ribbon I clicked on Bucket.

Make Sure you Keep Parent Child Relationship

The following was important and was something that was overlooked at first. On the Standard values on the same template you set the Configuration for Buckets the following had to be checked. Bucketable and Lock child relationship. The lock is really important so you don’t lose any child folders such as the Data folder. You will never find it again if you don’t.

Add Setting with Rules

Now we need to decide on folder structure and how we assign the bucket rule. To be honest I don’t remember doing this pre SXA days. Anyway rule was simple. What is important is the format. In this case I wanted yyyy/MMMM.

/sitecore/system/Settings/Buckets/Item Buckets Settings

Set the Parent Bucket

For lack of a better term it is important that you set the parent item that the bucket items will go under as bucket.

Final Results

When you right click you will now notice when you insert an item it will be stored in a bucket folder structure and the Data folder will be with it. On a side note I did use a Page Branch in order to create the structure of the item being inserted. More about those later.

Buckets are the Perfect Tool for Any Job

#Sitecore Forms Country DropDown List with Geo IP Country Lookup

I needed a Sitecore Form with a country dropdown list. It would also have to default to the country that Sitecore’s Geo IP would detect. To accomplish this I had to do the following steps.

Create the class

The class inherits from the DropDownListView Model and implements the following code. The list of the countryselectoritems is what the view (later step) will use to populate the dropdown list.

This is the what the countryselectoritem is defined as:

 public class CountrySelectorItem
 {
      public string CountryCode { get; set; }
      public string CountryName { get; set; }
      public string SelectedItem { get; set; }
 }

The code is as follows:

using Sitecore.Diagnostics;
using Sitecore.Data.Items;
using Sitecore.ExperienceForms.Mvc.Models.Fields;
using System.Collections.Generic;
using static Supernatural.Feature.WhitePaper.Models.CountryDropDownModel;

namespace Supernatural.Feature.WhitePaper.FormFields
{
    public class CountryDropDown : DropDownListViewModel
    {
        protected override void InitItemProperties(Item item)
        {
            Assert.ArgumentNotNull((object)item, nameof(item));
            base.InitItemProperties(item);
        }

        protected override void UpdateItemFields(Item item)
        {
            Assert.ArgumentNotNull((object)item, nameof(item));
            base.UpdateItemFields(item);
        }

        public List<CountrySelectorItem> Countries()
        {
            List<CountrySelectorItem> countrylist = FormHelper.GetCountryList();           
            return countrylist;
        }
    }
}

The function FormHelper.GetCountryList() can be implemented any way you want. I am using Sitecore XP so there is a country list available. I simply build a list of CountrySelectorItems. One of the important parts of the code is the Geo IP country retrieval. We will retrieve the country from the IP address using Sitecore’s Geo IP lookup and set the SelectedItem to that country. That way when we render the dropdown we know which country value should be selected (aka defaulted). Here is one example:

 public static List<CountrySelectorItem> GetCountryList()  
        {
            List<CountrySelectorItem> countrylist = new List<CountrySelectorItem>();

            Database contextDB;

            if (Sitecore.Context.Database.Name == "core")
            {
                contextDB = Sitecore.Configuration.Factory.GetDatabase("master");
            } 
            else
            {
                contextDB = Sitecore.Context.Database;
            }

            Item countriesfolder = contextDB.GetItem(LanguageCountry.CountriesFolder);

            string activecountrycode = GeoIpHelper.GetGeoIpCountry();

            foreach (Item country in countriesfolder.GetChildren().Where(a => a.DoesItemInheritFrom(LanguageCountry.CountryTemplate)))
            {
                string countrycode = country.Fields[LanguageCountry.Fields.Country].Value;
                CountrySelectorItem countrySelectorItem = new CountrySelectorItem();
                countrySelectorItem.CountryName = country.DisplayName;
                countrySelectorItem.CountryCode = countrycode;

                if (!string.IsNullOrEmpty(activecountrycode) && countrySelectorItem.CountryCode.ToUpper() == activecountrycode.ToUpper())
                {
                    countrySelectorItem.SelectedItem = countrySelectorItem.CountryCode;
                }
                countrylist.Add(countrySelectorItem);
            }

            return countrylist;

        }

Create the View

The view is simple. I took an existing view from a list rendering and used that as a starting point.

@using Sitecore.ExperienceForms.Mvc.Html
@using Supernatural.Feature.Media.Models
@model Supernatural.Feature.Mmedia.FormFields.CountryDropDown

@{
var countrylist = Model.Countries();
}

@Html.DisplayTextFor(t => Model.Title)
Select Your Country @if (countrylist != null) { 
foreach (CountryDropDownModel.CountrySelectorItem countryselitem in countrylist) 
{ 
if (countryselitem.SelectedItem == countryselitem.CountryCode) 
{ 
<option class="flags-@countryselitem.CountryCode.ToLower()" selected value="@countryselitem.CountryCode">@countryselitem.CountryName</option> 
} 
else 
{ 
<option class="flags-@countryselitem.CountryCode.ToLower()" value="@countryselitem.CountryCode">@countryselitem.CountryName</option> 
} 
} 
}
@Html.ValidationMessageFor(m => Model.Value)

Sitecore Item Setup

In /sitecore/system/Settings/Forms/Field Types/Lists you will see several list types. This is where I added the new list type. I chose the Field Type template under /System/Forms/Field Type. I called it Country Drop Down List.

Under the settings I put the following. The rest I used the default.

Under the appearance section. I chose Icons that match what the other lists had. Once important not is to make sure BackgroundColor was set to Grass to blend in with the other list field types.

When you go to the Form Builder you will now see the Country Dropdown List as selection.

This is what the form will look like when the field is rendered. I clicked the down arrow in this example and US was the default.

That is it. I may include this as a separate install in the near future. I will update this blog if I do.

Thoughts On The #Sitecore Symposium 2022 #SitecoreSYM #SitecoreMVP @RBAConsulting

It took me a bit to gather my thoughts and get back to normal at the Symposium. I was pretty excited about all the new things presented and can’t wait to start implementing the new stuff.

The Beginning

Not much to report. Got there and registered and met my RBA co-workers for the first time in person and some other fellow Sitecore lovers. It was great to not be on Teams/Zoom and interact. We were all probably thinking I thought you were taller/shorter. Well maybe that was just me. Had a great night at the RBA dinner and then it was back on the train home.

The Sessions

Boarded the train with my new RBA flag and made it in time for the opening. It didn’t disappoint. It was a great way to start things off. Got to take some selfies with co-workers new and old. This year’s them for the Symposium was Meet Every Moment. Nice! Here are some of my favorite sessions.

Things really started moving fast on Wednesday. First got to the Symposium just in time to see Mindy Kaling. I am a big fan and my daughters are too. She had great advice that I passed on to my daughters.

One of the sessions I attended was Building the perfect composable tech stack. Some of the things I learned:

  • Look at best tech despite what Sitecore owns.
  • Fit the right stack for the customer.
  • The tech stack is constantly changing.
  • Tech stack should be flexible.

I also saw From discovery to live sites: A multisite solution at scale using SXA for Central Garden & Pet. Altudo using their OneWeb solution was able to solve a complex issue of having several multi sites.

Next it was Evaluating legacy to composable: United Airlines’ journey to futureproof development. Love the roadmap of what they came up with and will help knowing what to leave in the past and move forward with.

Of course I got to present with one of my co-workers and my co-workers presented as well.

Pictures courtesy of RBA Consulting.

The Party

The party for this year’s Symposium was at the Museum of Science and Industry. I haven’t been there in over 20 years so it was great to see it again.

The MVP Summit

The MVP Summit started with a round table discussion. Got some great insights on E-Learning and CDP. At night we all went to the Punch Bowl. It was great catching up with everyone. We go the inside scoop of a lot things that I can’t share yet.

One of the things I do want to mention is Content Hub One. I am very excited about this new product offering. I think it will be an important piece for new and old clients that want to get their content in the cloud.

The Beanbag Chairs

Well I have been wanting a bean bag chair for a long time. There were tons of them at the Sitecore Symposium. So for my birthday this year I asked for one. It looks nice with my Sitecore pillows and MVP plaque. I think I will keep adding to my collection of pillows.

Final Thoughts

Composable and Cloud are the first words that come to mind when I think of the 2022 Symposium. It comes as no surprise as that is where things are not only going that way for Sitecore, but the IT industry in general. Personalization is probably the best thing you can do to get the most use for your website. With CDP and Personalization it is easier than ever. Hopefully we will see more clients take advantage of that so the can “Meet Every Moment”. The roadmap is there to do everything now it up to us to drive it.

Da #Sitecoresym 2022 Chicago Style Guide From a Illinoisan

The Chicago Super Fans have spoken.

Hard to believe that the Sitecore Symposium will take place in Chicago this year. Being a Chicago native (suburbs of Chicago) I am obviously pretty excited about this. Not only do I get to take the train to the Symposium I was blessed to be picked as a speaker. To top it off I get to meet some of my coworkers in person. With this blog I hope to give someone an idea of what it is like at the symposium mixed in with a little Chicago style.

Dress for the weather. It’s October in Chicago. There are days you can wear shorts, but the temperature goes up and down quite a bit. In the mornings it is cold, but by the afternoon it warms up.

Make sure you stop and visit every sponsor. Don’t forget to thank them. In Chicago we try to be polite whether we mean it or not.

No doubt the symposium has some great food. Being in Chicago you will find we have some of the best food. Especially our pizza and hot dogs (no ketchup is allowed on hot dogs, don’t even ask). Everyone else’s is inferior.

Take it all in. You are at the Sitecore Symposium in Chicago! Grab as many buttons as you can for your lanyard. Network, Network, Network. Find some new friends to check out the museums, get some shopping done at Michigan avenue and check out the bean.

Chicago is rich in history. From Al Capone to the great Chicago fire there is not shortage of cool, strange and mysterious history here. I suggest reading up on it. We also have had a lot of movies filmed here such as Batman (Christian Bale version) and Transformers. Let’s make history at they Symposium!

Did he really say that?

So there is my short take on all of this. I am proud of where I grew up and live if you can’t tell. This is the most excited I have been for something in a long time. If you see me at the Symposium and have any questions don’t hesitate to ask. When you get a chance also check out SitecoreGabes take on Chicago here.

Getting Started Quickly with #Sitecore CDP (Customer Data Platform)

Sitecore CDP formerly Boxever is something you are probably hearing a lot about these days. As a developer you can implement it easily and as a marketer you can take advantage of some of the features as soon as it is implemented. Here are the steps in order I did to get started.

1. Get a sandbox account.

Should be able to get a login for the CDB Sandbox from your Sitecore rep. You can find the sandbox site here. This is a shared sandbox so you will need to be careful not to change anything that someone else has setup. It is ok to look and see what others have setup. That is one advantage of a shared sandbox.

When you first login to your sandbox account you should see a message like this:

2. Get your keys and Create Point of Sale Value.

To get your keys go to the gear icon at the bottom left and select System Settings then API Access.

Copy both keys. Please note in my example I did not use the API Token.

3. Create Point of Sale

Selected System Setting then Point of Sale. Click on the create button and fill out the required fields. In my case since I am using the Lighthouse Demo I called my POS LighthousePOS. Well I can’t remember if I created or it was already out there.

4. Implement code. (SXA Example)

The next step is to implement the script needed to integrate CDP with your site. The script should look like the following. As of this blog the target version should be 1.2 and s.src should be 1.4.8. You will need to add your client key.

// Define the Boxever queue
   var _boxeverq = _boxeverq || [];
   // Define the Boxever settings
   var _boxever_settings = {
       client_key: 'client key goes here', // Replace with your client key
       target: 'https://api.boxever.com/v1.2', // Replace with your API target endpoint specific to your data center region
       cookie_domain: '.lighthouse.localhost', // Replace with the top level cookie domain of the website that is being integrated e.g ".example.com" and not "www.example.com"
       pointOfSale: "LighthousePOS",
       web_flow_target: "https://d35vb5cccm4xzp.cloudfront.net"
};
   // Import the Boxever library asynchronously
   (function() {
        var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true;
        s.src = 'https://d1mj578wat5n4o.cloudfront.net/boxever-1.4.8.min.js';
        var x = document.getElementsByTagName('script')[0]; x.parentNode.insertBefore(s, x);
    })();

I kept this pretty simple and for now created a script and put it under the Base Themes\Main Theme\Scripts folder. I created a script item called cdp-script.

5. Create an Experiment

From the menu expand Experiments and choose Web. Click on the Create Experiment button.

From there you want to click on the add variant button.

After you click on Add Variant there will be a side menu that will appear. Choose My Library Templates.

We will choose a simple popup takeover.

Change anything you want to. In this case I changed the background and font colors. You can also change HTML and script

Once done, make sure you click on the Save button then Close when you see the checkmark.

You will see the new Popup in a list. Click on the Preview button, enter in your site with the CDP script and click the go button. If everything worked correctly you should see the popup.

Once the site opens, in this case my local demo site you will see the popup created.

Another option to try is Experiences the setup is similar to Experiments. You can find on the same menu as Experiments.

This should get you started. I would take a look at what others have done since it is a public sandbox. There are a lot of possibilities with CDP and we are only scratching the surface. For more information on getting started please take a look at this video that was released as I was putting together this blog.

#Sitecore Lucene to SOLR Index Upgrade Tips

Recently I did a Lucene to SOLR upgrade. Even though SOLR has been out a while you may still run into instances that you may need to upgrade. This I hope gives you a small guide on some of the things you need to do other than installing the SOLR server.

1. Turn on switch and rebuild on indexes. You can find more information about that here. Don’t forget to add your custom indexes as well.

2. Convert string to string[]. I ran into an issue where a field was coming back with a null. Looking at the SOLR server and doing a query I found that the following would come back as null.

["27ae232e906349b083d612f2ebb7a173", "3fd1ef6aac954936bb8133d5f60ebfee", "9b8e4140b9fe4ecb99c41e0454b31b2e"]

Looking at it further found that the following code needed to be changed.

From:
  [IndexField("tags")]
  public string Tags { get; set; }
To:
  [IndexField("tags")]
  public string[] Tags { get; set; }

Basically the string needed to be a string array.

3. Make sure you check the class references.

From:
Sitecore.ContentSearch.LuceneProvider.LuceneSearchIndex, Sitecore.ContentSearch.LuceneProvider
To:
Sitecore.ContentSearch.SolrProvider.SolrSearchIndex, Sitecore.ContentSearch.SolrProvider

4. Don’t forget to rebuild the indexes and make sure everything you expect is there.

On a side not every time I hear SOLR I think of this movie.

#Sitecore Hackathon 2022 Adventure. #SCHackathon

Six years doing the Sitecore Hackathon and one thing I learned is each year brings a new challenge. First off I had a great team. Our team name was R-Bacon-Sulting. I worked with two co-workers from RBA. One being a front-end developer and the other being Devops. All we needed was a project manager and a business analyst to complete the team. We chose the third category for the hackathon which was to make an enhancement to the MVP site.

As hard as we tried the goal of adding to the MVP site did not work out since we had trouble getting the site up and running and ran out of time. We did have a great idea and hope to one day we can implement it.

The bottom line is we all learned something and as co-workers we got to know each other better. In the end isn’t this what this mainly is about?

So here we go with the summary of what I learned this year (in Ted Lasso speak) because let’s face it there is always room for improvement. That is why I love what I do.

Under pressure is when we learn that we really have what it takes. We may be in unfamiliar territory, but we adapt and get better because of it.
So many things happen when you don’t succeed. Life is full of surprises. We just have to go with the flow and hope for the best as we learn. Even if it is not the fairy tale you want it is the fairy tale that is best for you to grow professionally.
Yeah I love to code, but you know what else I love to do? I love to teach people about coding. What you learn is always crucial to pass it on to others. Glad I got the opportunity to pass on some Sitecore things to the team and I also learned things from them.
Everyone that participated in the Hackathon will remember the good and the bad. You know what though, next year we need to be a goldfish and approach it like it is something new and exciting. Forget about what went wrong, but focus on the task at hand.
Special shout out to all that put on the Sitecore Hackathon every year and our team from RBA.

#Sitecore #Docker Containers Syncing Database Changes the Lazy Way

I have been using Docker/Containers for about six months. I have to tell you I really like using them. A recent project I am helping architect the solution for I decided to have the other developers use them. There were some hiccups along the way getting some developers setup, but so far it has worked out well. I think I convinced them change is good.

Ted Lasso Memes At Your Service!

Anyway one of the things I have learned is how easy it is to deploy things to containers. One of them being databases. Normally you would install Sitecore and serialize items or use Sitecore packages for changes. We are doing that. However we had multiple sites/tenants to create in SXA and wanted to make sure the team was in sync from the start. With the out of the box Sitecore tools for Docker it is easy to do.

If you look into your docker\data\mssql folder (could be a different folder depending how you setup your volume, but in this case I am using the default) you will find the ldf and mdf files for each Sitecore database. Just copy the ones for the database you want to share and put it in a shared folder for other developers. I actually stored them in Teams.

The developer who is installing the database should do a docker-compose down first. Then copy the database files to their local data\mssql folder. Once they are a copied to the other developer’s local data\mssql folder they will need to do a docker-compose up. Now they will have the same database changes as the other developer for their containerized Sitecore instance. BTW inside the mssql image you can view the database files.

So what happened? Was it magic? Well if you think PowerShell is magic then it was. As with custom web changes databases are also deployed into the images using the built in Sitecore tools. So as soon as the files are copied the watcher does its thing.

So one catch with this that I noticed recently. If you clean out your Docker Data\Deploy folders by running something like the clean.ps1 script it clears out the data\mssql folder. Which means the database changes could be lost. I will look for a workaround for this, but one thing that I did was create a clean script that keeps the database folder contents. See below for an example:

# Clean data folders
Get-ChildItem -Path (Join-Path $PSScriptRoot "\docker\data") -Directory | ForEach-Object {
    $dataPath = $_.FullName

    Get-ChildItem -Path $dataPath -Exclude ".gitkeep", "license.xml", "*.ldf", "*.mdf" -Recurse | Remove-Item -Force -Recurse -Verbose
}

# Clean deploy folders
Get-ChildItem -Path (Join-Path $PSScriptRoot "\docker\deploy") -Directory | ForEach-Object {
    $deployPath = $_.FullName

    Get-ChildItem -Path $deployPath -Exclude ".gitkeep", "license.xml", "*.ldf", "*.mdf" -Recurse | Remove-Item -Force -Recurse -Verbose
}

I will update this blog post I am sure as things evolve with Docker/Containers, but I hope for now this will give one way to share database changes. If you have a better way I would love to know.