Kentico Layout Webpart Without the Chaos

In Kentico, a Layout Webpart (or Layout Widget) is a component you can drop into a WebPartZone that itself defines new WebPartZones.

If you check out the documentation on building your own custom Layout Webpart, you’ll find its a nutty mess of string concatenation, tables, and magic javascript. If you have more simpler needs, as I did, you will be sorely disappointed: who would want to maintain that over time.

The gist of the example given in the documentation is to generate a layout on the fly, presumably calling AddZone at the right place. This will output the markup needed to dynamically create a zone for other Webparts to be added.

Just ask your designer to go in there and tweak some styles. They can update C# strings no problem right?

If, like me, you find this approach to be completely unacceptable, you might start wondering about a better way. And indeed, spelunking in the CMS base classes can prove fruitful. There is an overload for AddZone that takes a parameter for a container. So you just need to drop some placeholders in your view (.ascx file) and use them in the code behind:

ThreeColumnLayout.ascx
1
2
3
4
5
6
7
8
9
10
11
<div class="row">
  <div class="col-3">
    <asp:PlaceHolder runat="server" ID="Left"></asp:PlaceHolder>
  </div>
  <div class="col-3">
    <asp:PlaceHolder runat="server" ID="Middle"></asp:PlaceHolder>
  </div>
  <div class="col-3">
    <asp:PlaceHolder runat="server" ID="Right"></asp:PlaceHolder>
  </div>
</div>

Then just override PrepareLayout as follows:

ThreeColumnLayout.cs
1
2
3
4
5
6
7
8
9
protected override void PrepareLayout()
{
    // Dynamically generate zone IDs and names
    StartLayout(keepExistingControls: true);
    AddZone(this.ID + "_left", this.ID + " Left", Left);
    AddZone(this.ID + "_middle", this.ID + " Middle", Middle);
    AddZone(this.ID + "_right", this.ID + " Right", Right);
    EndLayout(addToControls: false);
}

All of this comes about because the ZoneID of a WebpartZone needs to be unique on a page, even if you use the same Layout Webpart twice on a page. The PrepareLayout hook allows you to reliably generate unique IDs.

Still, Kentico support should bury the example they have in their docs into an “Advanced Custom Layouts” section. No one’s first introduction to building a user control should be a StringBuilder.

Comments