Experience Sitecore! | April 2021

Experience Sitecore!

Martin Miles on Sitecore

A nice way of using HTML Helper for accessing Rendering Parameters along with Glass Mapper

I very love Glass Mapper as (once being configured) it takes away from you much of the manual efforts of wiring up your models.

Often working with Rendering Parameters, I decided to simplify their usage by having a strongly-typed HTML Helper powered by Glass Mapper. Here is how the usage looks like:

<div class="@(Html.GetRenderingParametersClassFor<ISingleClass>(m => m.Class))">
   your content here
</div>

It benefits from usage simplicity and also from having IntelliSense. Here's an example of what ISingleClass looks like:

[SitecoreType(TemplateId = ISingleClassConstants.TemplateIdString)]
public partial interface ISingleClass : IGlassBase
{   
    [SitecoreField(ISingleClassConstants.ClassFieldName)]
    Guid Class { get; }
}

In Sitecore items of a given type may look as smth. similar below:


OK, won't make it any longer: here's the code that does all the magic:

public static class HtmlHelperExtensions
{
    public static string GetRenderingParametersClassFor<T>(this HtmlHelper html, Func<T, object> getField, string fieldName = "Class") where T : class
    {
        var selectedItem = GetSelectedRenderingParameter(html, getField);
        return selectedItem?[fieldName] ?? "";
    }


    private static Item GetSelectedRenderingParameter<T>(this HtmlHelper html, Func<T, object> getField) where T : class
    {
        T renderingParameters = GetRenderingParameters<T>(html);

        var selectedItemId = getField(renderingParameters)?.ToString();
        return Context.Database.GetItem(selectedItemId);
    }

    public static T GetRenderingParameters<T>(this HtmlHelper html) where T : class
    {
        //TODO: wire-up ISitecoreService to get resolved via DI of your choise
        var sitecoreService = new SitecoreService(PageContext.Current.Database);

        var parameters = RenderingContext.CurrentOrNull.Rendering["Parameters"];
        var nameValueCollection = WebUtil.ParseUrlParameters(parameters);
        var config = sitecoreService.GlassContext[typeof(T)] as SitecoreTypeConfiguration;

        var renderingParametersModelFactory = new RenderingParametersModelFactory(sitecoreService);
        return renderingParametersModelFactory.CreateModel<T>(nameValueCollection, config.TemplateId);
    }
}


Bonus: in some cases you may also want selecting a HTML tag from rendering parameters, for example your editors could choose between heading tags they want to be on your rendering (like H1, H2, H3, H4 or may be just a generating paragraph P-tag):

In that case you can add one more method into the above HTML helper class:

public static MvcTag TagFrom<T>(this HtmlHelper html, Func<T, object> getField, string className = null) where T : class
{
    var selectedItem = GetSelectedRenderingParameter(html, getField);
    string tag = selectedItem?["Tag"] ?? "";

    html.ViewContext.ViewBag.Tag = tag;

    if (!string.IsNullOrWhiteSpace(tag)) 
    {
        var tagBuilder = new TagBuilder(tag);
    
        if (!string.IsNullOrWhiteSpace(className))
        {
            tagBuilder.Attributes.Add("class", className);
        }
        
        html.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag));
    }

    return new MvcTag(html.ViewContext);
}

Once compiled, you can then render you tags as below:

@using (Html.TagFrom<ITagRenderingParameter>(m => m.Tag, "tag_class"))
{
    @Html.Glass().Editable(m => m.Title)
}

And choose which HTML tag just from a Rendering Parameters dropdown:

Hope this helps!

XBlog on Sitecore 10? That's possible!

I was using XBlog as nice and simple solution for maintaining the blogs on Sitecore (at least for editors), but unfortunately the original repo has not gone along with the progress Sitecore XP does - the last update dates as 3 years ago for some Sitecore 9 related configs, while the rest of it is 6 years old.

I tried using the 'Sitecore 9' branch of the original repo but unfortunately it did not go well. If installing it from the packages - then it had minor issues even with declared version 9.X, which in fact in fact had the very wide range of changes int between of 9.0.1 till 9.3. Not to say version 10.* therefore:

I decided to refactor it instead!

You may find the successful result of this exercise published at my corresponding GitHub repository, that one worked out for 10.1 and tested well there, but since all versions 10.X share the same runtime it should work universally on all of them.

Few notes on what has been done:

  • much unwanted legacy stuff such as support for WebForms has been entirely removed
  • the IDs of items have been retained, so that helps upgrading existing solution with 1000s of posts
  • there were changes done to reflect reworked Content Search of the XP platform
  • found and fixed in Bucket items creation logic, related to events suppression
  • serialization changed to the one using CLI, officially released as the part of Sitecore 10
  • few more minor changes and improvements in references, runtime, confutation, etc.

Please also note: XBlog uses fast query which declared to get deprecated in Sitecore 10.1, but that particular code works perfectly well, and I cross-tested it in debugger to confirm: the fast queries return that expected result I queried. Just for the future references, fast queries have been used in code\Areas\XBlog\Buckets\BucketFolderConfigurationManager.cs and code\Areas\XBlog\Import\ImportManager.cs files.

The resulted code can be found here: XBlog for Sitecore 10.1

Upgrading Sitecore like a Pro

Sooner or later, you'll face it - the need for Sitecore version upgrade. However, each Sitecore instance is unique, there is no universal method for an upgrade, therefore each upgrade path is bespoke.

In the past 10 years working with Sitecore I have done numerous upgrades, resulted in Upgrade Planning Strategy and a set of Upgrade Tips and Tricks. These tips will help saving 2-3 times (!) on spent efforts, comparing to direct approaches.
Last but not the least. versions 10 and 10.1 brought new challenges and options of migrating existing solutions into containers. I will explain your options and propose best approach on this as well.

I have lodged the speech proposal for SUGCON 2021 so fingers crossed for me to be chosen. Once happened, I will share the whole presentation and sides updating this blog post.

There is still no "silver bullet" for Sitecore upgrades, but following tips from my proposed session will eliminate risks, reduce efforts, and bring you confidence while upgrading your instances.

If being chosen, I will tell you about:

  1. How to approach the whole instance upgrade
  2. What are the upgrade time-wasters
  3. Common and potential traps to avoid
  4. Dealing with configuration upgrade, and why that's not as complicated as initially seems to be
  5. Upgrading your solution codebase, including ORM (Glass etc.) and DI
  6. Employing automations with PowerShell
  7. Upgrading databases and how to approach
  8. Even more automation to add
  9. How to treat deprecated Sitecore APIs and obsolete code
  10. Migrating forms from WFFM
  11. Upgrading to version 10 containers and how 10.1 changes the upgrades
  12. Testing your upgrade strategies
  13. Going live
  14. Summary of tips and findings from this session
Stay tuned!