Some Episerver websites has many categories configured. For Editors it’s easier when categories are sorted alphabetically. It’s possible to change category order in admin mode, but this requires to click “up” or “down” button few times. For this scenario you can use small code snippet with a plugin for sorting categories. It will add “Sort all” button on the categories view that sorts all categories alphabetically.
There is no buil-in way to add more buttons to categories list page, but we can use veeeeery old .NET feature- control adapters. Originally it was used for styling :), but here I will use it to modify existing controls without access to the source code.
To add new control adapter we have to create App_browsers folder in web application project and add Default.browser file.
The Default.browser is an XML with configuration of a source control that should be modified (System.Web.UI.WebControls.ContentPlaceHolder) and an adapter class (CategoriesContentPlaceholderAdapter).
1 2 3 4 5 6 7 8 9 |
<browsers> <browser refID="Default"> <controlAdapters> <adapter controlType="System.Web.UI.WebControls.ContentPlaceHolder" adapterType="AlloyTemplates.Business.Categories.CategoriesContentPlaceholderAdapter"> </adapter> </controlAdapters> </browser> </browsers> |
The adapter class inherits from ControlAdapter and it’s responsible for adding “Sort all” after “Add” button.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
using System; using System.Linq; using System.Web.UI.Adapters; using System.Web.UI.WebControls; using EPiServer.DataAbstraction; using EPiServer.ServiceLocation; using EPiServer.UI.WebControls; namespace AlloyTemplates.Business.Categories { public class CategoriesContentPlaceholderAdapter : ControlAdapter { private Injected<CategoryRepository> CategoryRepository { get; set; } protected override void OnInit(EventArgs e) { base.OnInit(e); if (this.Control.ID == "MainRegion" && this.Page is EPiServer.UI.Admin.Categories) { var addButton = this.Control.Controls.OfType<ToolButton>().FirstOrDefault(c => c.ID == "AddRootCategory"); if (addButton == null) { return; } var addButtonIndex = this.Control.Controls.IndexOf(addButton); var sortButton = new ToolButton { Text = "Sort all", SkinID = "Refresh" }; sortButton.Click += SortButton_Click; this.Control.Controls.AddAt(addButtonIndex + 1, sortButton); } } private void SortButton_Click(object sender, EventArgs e) { var sorter = new CategoriesAlphabeticalSorter(CategoryRepository.Service); sorter.Sort(); if (this.Control.FindControl("Grid") is DataGrid grid) { grid.EditItemIndex = -1; grid.DataSource = CategoryRepository.Service.GetRoot().GetList(); grid.DataBind(); } } } } |
I moved sorting logic to a separate class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
using System.Linq; using EPiServer.DataAbstraction; namespace AlloyTemplates.Business.Categories { public class CategoriesAlphabeticalSorter { private CategoryRepository _categoryRepository { get; } public CategoriesAlphabeticalSorter(CategoryRepository categoryRepository) { this._categoryRepository = categoryRepository; } public void Sort() { var category = this._categoryRepository.GetRoot(); SortChildrenRecursive(category.Categories); } private void SortChildrenRecursive(CategoryCollection categories) { if (categories.Count < 2) { return; } Sortchildren(categories); foreach (var category in categories) { SortChildrenRecursive(category.Categories); } } private void Sortchildren(CategoryCollection categories) { var orderedCategories = categories.OrderBy(x => x.Description).ToList(); var lastSortOrder = 0; foreach (var category in orderedCategories) { if (category.SortOrder <= lastSortOrder) { var categoryClone = category.CreateWritableClone(); categoryClone.SortOrder = ++lastSortOrder; this._categoryRepository.Save(categoryClone); } else { lastSortOrder = category.SortOrder; } } } } } |
After compiling the code “Sort all” button should appear on the Categories view.