...

Design Pattern: Tag Pages instead of Categories

Episerver categories is one way to deal with taxonomy on a web site. But often I find that I prefer a simpler, more transparent approach of having Tag Pages replace them. Here's how.

Episerver categories were nice. Back when they were introduced people were using Nokia 3310 (as pictured above), anyone who owned a house was a millionaire and we hadn't yet fully acknowledged how fast we are destroying the planet with global warming. You might even say, it was a better, simpler time. But things evolve and demands rise. And today I rarely think of using the old categories.

First of all, they haven't really evolved in the same pace as the rest of the CMS. They still live in Admin mode. The only way of translating them is through XML language files and they are just not really user friendly. To list elements in a category you either have to rely on external search such as Find or Vulcan or go the dark route of FindPagesWithCriteria (the evil that must not be named).

The concept of Tag Pages is really simple:

Have a page type called Tag Page (or whatever you feel is appropiate).
This is an easy one - just create a new page type.

Make a place in your content structure for your tags or taxonomy or categories. This is what mine looks like:

skills.PNG

Work with your taxonomy through Tag Pages just as you would with categories - except that now they are content with all the benefits that comes with that. Like support for multiple languages, permissions, publish flows and versioning.

Have a content area on your pages restricted to only accepting that content type. Now you can assign content to a taxonomy simply by dragging and dropping.

    public class BlogPostPage : SitePageBase
    {
        [AllowedTypes(AllowedTypes =new Type[] { typeof(TagPage)})]
        public virtual ContentArea Tags { get; set; }
    }

 

If you want to list content in a given taxonomy you can simply look it up using the Softlinks repository. This is how I do it in my generic List Block that I can use to both list on tag pages or show descendant blog posts on other page types.

            IEnumerable<BlogPostPage> baseList = null;
            if (_loader.Service.Get<PageData>(p) is TagPage)
            {
                //If current page is a tag page, then look for softlinks, otherwise descendents
                var _soft = ServiceLocator.Current.GetInstance<IContentSoftLinkRepository>();

                var links = _soft.Load(p, true);
                baseList = links.Select(l => _loader.Service.Get<PageData>(l.OwnerContentLink)).Where(sp => sp is BlogPostPage).Cast<BlogPostPage>().OrderByDescending(s => s.StartPublish);
            }
            else
            {
                var descendents = _loader.Service.GetDescendents(p);
                baseList = descendents.Select(s => _loader.Service.Get<PageData>(s)).Where(s => s is BlogPostPage).Cast<BlogPostPage>().OrderByDescending(s => s.StartPublish);
            }
            baseList = FilterForVisitor.Filter(baseList).Cast<BlogPostPage>();

Make sure you in your renderings iterate through the items in the list - and that you do a full meta refresh after changes to get it displayed properly.

@using EPiServer.Core
@using EPiServer.Web.Mvc.Html

@model AllanTech.Web.Models.ViewModels.PageViewModel<AllanTech.Web.Models.Pages.BlogPostPage>

@Html.FullRefreshPropertiesMetaData(new[] { "Tags","HeaderImage"})
<div class="container">
    <div class="row">
        <!-- Latest Posts -->
        <main class="post blog-post col-lg-8">
            <div class="container">
                <div class="post-single">
                    <div class="post-thumbnail"><img src="@Html.ResizeImageWithFallback(Model.CurrentPage.HeaderImage,Url.ContentUrl(ContentHelpers.GetStartPage().DefaultBlogImage),1200)" alt="..." class="img-fluid" @Html.EditAttributes(p => p.CurrentPage.HeaderImage)></div>
                    <div class="post-details">
                        <div class="post-meta d-flex justify-content-between" @Html.EditAttributes(x => x.CurrentPage.Tags)>
                            <div class="category">
                                @if (Model.CurrentPage.Tags != null)
                                {
                                    foreach (var tag in Model.CurrentPage.Tags.Items.Select(cai => cai.GetContent()).OfType<AllanTech.Web.Models.Pages.TagPage>())
                                    {
                                        @Html.PageLink(tag)
                                    }
                                }
                            </div>
                        </div>
...

Blog Posts

...

Hack-Your-Future Copenhagen - Awesome Concept!

In the center of Copenhagen a team of volunteer IT professionals are teaching groups of passionate, dedicated and talented refugees, asylum seekers and immigrants coding skills, to help them land jobs in an IT industry starving for skilled workers. It's working - and it's an awesome concept!

...

Heading to Helsinki Dev Meetup

Thursday, November 8th I'm really excited to once again have been invited to join the Episerver Developer Meetup in Helsinki!

...

Design Pattern: Tag Pages instead of Categories

Episerver categories is one way to deal with taxonomy on a web site. But often I find that I prefer a simpler, more transparent approach of having Tag Pages replace them. Here's how.

...

FB2PDF - How Abandonware Gets Distributed

A long time ago I did a small weekend project to fix a problem my wife was having with her e-reader. I shared it on my blog and then forgot all about it. Until now, that is.

...

CMS Audit Update - Visitor Groups included

Earlier this year Nicola Ayan released a nice little plugin that I instantly liked, the CMS Audit tool. It's a great way to get an easy overview over what is being used where in your CMS. In a talk about my favorite addons I showed it at Episerver Ascend Copenhagen and straight away got a question from the audience: Can we use this tool to see where visitor groups are being used? Well, now you can.

...

Webcast: Addons In Real Life @ CodeArt

Last week I did a couple of talks at Episerver User Group meetings in Denmark about how I've tweaked my Episerver installation at codeart.dk in order to work as a great blogging platform. I also showcase a few of the addons I'm currently working on. Now I recorded the talk, so if you have a 23 minutes to spare, then grab a coffee and make some popcorn and have a look.

...

Custom Views for an Interface

Ever played around with adding custom views in Episerver CMS? It's a really powerful way to extend the UI. But why does it work when you register your view for a model class, but not for an interface implemented by that model? I had a look and found out.

...

Admin Mode Plugin to Manage Content Type Suggestions

If you have a site with a lot of different content types, it can be a good idea to help Episervers Automatic Content Type suggestion feature along. Here is a basic Admin mode tool - in good old webforms (yes, I washed my hands after I made it) that will let administrators / and super-editors configure exactly which content types to suggest when.

...

Auto Tagging Using Search

You don't always have to go the full AI route to get AI like results. In this blog post I'll describe an approach I've used several times (and for multiple purposes) with pretty decent results. Instead of classification algorithms, deep learning or neural networks I'll just simply query my favorite search engine.

...

Which Dojo Topics are published in the Episerver CMS UI?

If you, like me are venturing into the mythical and magical world of dojo-in-episerver-ui, where elfs and wizards rule, you might also find this list useful.

...

Storage Performance Aftermath - ElasticSearch Joins the Fight

In 3 previous blog posts I compared various azure storage technologies with regards to performance and scalability in typical web usage scenarios. I was actually done with the series, but with all that interesting data, I decided to throw my current favorite search/storage/no-sql technology into the mix to get an idea about how it all compares. So - ElasticSearch enters the competition!

...

Azure Storage Performance Showdown (Post 3)

This is the 3rd post in my Azure Storage Performance comparison. So far we've examined the typical scenario of storing/retrieving data that most dynamic websites of today deal with. In this post, we'll take a closer look at Update and Delete - and finally review the financial aspects.

Post Comments()