Creating and Modifying Widgets with Ruby

Creating a CMS object with widgets

Suppose, you need to provide a couple of pre-built pages to your editors because you want to ensure that the pages have a particular structure. Here's how this can be done using the Scrivito SDK: 

Copy
# Create a page with a two-column widget and some widgets in the columns
# One of the widgets is an image widget whose image is preset

an_image = Image.create(
  _path: '/scrivito.jpeg', 
  blob: File.open('/path/to/image.jpg')
)

DescriptionPage.create(
  _path: "/descriptions/page1",
  main_content: [
    TwoColumnWidget.new(
      column1: [
        TextWidget.new(text: "Column 1 text"),
        ImageWidget.new(image: an_image)
      ],
      column2: [
        TextWidget.new(text: "Column 2 text")
      ]
    )
  ]
)

This code assumes that the page object class, “DescriptionPage,” as well as the widget object classes, “TwoColumnWidget,” “TextWidget,” and “ImageWidget,” exist. If they don't, create the object classes first.

The “main_content” attribute of the “DescriptionPage” class is a widgetlist attribute to which a two-column widget is added. Both its columns are filled with further widgets.

The “image” attribute of the “ImageWidget” needs to be of the reference type.

Accessing and modifying widgets

The contents of a widgetlist attribute of a given CMS object can be retrieved like so:

Copy
# The contents of a widget field yields an array of Scrivito::BasicWidget objects

my_widget_field_widgets = @obj[:my_widget_field]
my_widget_field_widgets = @obj["my_widget_field"]
my_widget_field_widgets = @obj.my_widget_field

The result is always an array of widgets, or an empty array if the widget attribute doesn't contain any widgets. Thus, you can iterate over the widgets and process them as desired.

A widget is contained either in a widgetlist attribute at the top level, or in another widget. You can use the container method to determine the origin of a widget, and the container_field_name method to retrieve the name of the attribute containing the widget:

Copy
# Determine the entity (Obj or Widget) that includes a widget and
# the name (string) of the widget field that contains this widget

my_container = my_widget.container
my_field_name = my_widget.container_field_name

After modifying a widget, make sure to update it in the CMS unless you are going to update the CMS object that contains the widget:

Copy
# Updating a widget individually

my_widget = @obj[:my_widget_field].first
my_widget.update(text: "Changed text")

# Updating a CMS object after modifying (one of) its widget attributes

@obj.update(my_widget_field: @obj[:my_widget_field].reverse)

That's it. Happy coding!