Customizing Widget List Rendering

Customizing Widget List Rendering

In this tutorial, which is based on the Scrivito Example App, we’re going to show you how nicely styled lists can be rendered using nested widget lists.

For you to benefit the most from this tutorial, basic knowledge of how Scrivito’s content classes work and how they integrate with React is required.

With Scrivito, every page is usually made up of widgets that are contained in a single widget list belonging to the respective page. To this widget list, plain content widgets (e.g. for text and images), but also structure widgets (columns, boxes, and the like) can be added.

Widget lists can be made available on pages and in widgets by providing the corresponding Scrivito class with one or several attributes of the widgetlist type.

The widgetlist type is the key to structuring content. For example, each column of a column widget needs to be represented by a widgetlist attribute for being able to accommodate text, image, and other content widgets, or even structure widgets.

Why apply custom logic?

Widget or page attributes of any type can be rendered using Scrivito.ContentTag. In the case of widgetlist attributes, Scrivito.ContentTag renders the individual widgets one after the other in the order they have in the widget list. This is the most common use case.

However, what if you wanted to display an ordered or unordered list, with each item being a structure widget for using more than one widget per list item? In this case, each widget contained in a widget list would have to be rendered individually so that custom styles can be applied to them.

Let’s start.

Create the widgets

We require two widget types, a ListWidget that editors can add to pages, and a ListItemWidget for combining several widgets into one list item.

The ListWidget

In a Scrivito-based app like the Example App, all widget classes are defined in dedicated folders in the ”src/Widgets” directory. Let’s create a “ListWidget” folder and a file named “ListWidgetClass.js” in this directory first.

The ListWidget we are going to define is a regular widget type in the sense that editors can select it from the widget browser when they want to add a widget to a page or to a structure widget.

Our ListWidget displays its contents (any number of ListItemWidgets – we’ll define this type later) as an unordered list, but you can change this according to your demands. Place the code in the “src/Widgets/ListWidget” folder using the file names given below.

Jumping straight in, note that the widgetlist attribute, items, has an only parameter that restricts its contents to ListItemWidget instances. In other words, the only kind of widgets that can be added to any ListWidget are ListItemWidgets.

As you can see, next to the items widget list, the ListWidget class is equipped with a further attribute: cssClass. It’s for letting editors specify the name of the CSS class to use for the list. The component of the widget renders the contents of the instances (i.e. items) using Scrivito.ContentTag to which the specified CSS class name (or “list-group” as the default) is passed:

We’ve specified ul as the tag to use (the default is div) so that we can render the list elements with li later on. All that’s left to do is to make the CSS class name editable on the properties view of the widget:

The ListItemWidget

Let’s turn to the items that can be added to our ListWidget, ListItemWidgets. Like the former, the latter has two attributes, a content widget list and, again, cssClass. Note that we are using the onlyInside parameter in the model class to specify that a ListItemWidget can only be placed into a ListWidget.

Via the widget’s component below, each ListItemWidget instance is rendered as an <li> element using Scrivito.WidgetTag, including the custom styles provided in the cssClass attribute of the individual list items. Inside the <li> element, the content widget list is rendered using Scrivito.ContentTag.

Finally, as with the ListWidget, we’ll make an individual list item’s CSS class name editable:

That’s it! Everything should be in place now.

Use it! 

It should be possible now to place a ListWidget onto a page.

Initially, a ListWidget is empty. Just add items to it and widgets to the items and arrange everything to your liking!

You can assign CSS classes to the list via its properties dialog. The same applies to the individual items.

There's potential everywhere!

You’ve customized the display of widgetlist attributes, that’s fantastic! Now, how about extending the result even further? You could, for example, use enum or multienum attributes for offering a set of CSS class names for each of the list styles, so editors don’t have to enter them manually.