Widgets and In-Place Editing

This guide assumes that Fiona 7 has been installed and initialized in legacy mode. In the following, the relevant steps for adapting an existing application so that it uses Fiona 7 technology are described.

Editing content in place

The content stored as attribute values in the CMS can easily be made editable in place. For this, the fiona7_tag helper is available. This API corresponds to scrivito_tag, however, RailsConnector objects may be passed to it.

This makes it easy to replace RailsConnector code such as

<h1><%= display_field @obj, :title %></h1>

with Fiona 7 code:

<%= fiona7_tag(@obj, :title, :h1) %>

Editing navigations in place

Navigations and object lists can be created using fiona7_tag_list. This method displays a marker for creating a new page. Furthermore, the list can be sorted.

Initially, the list of available page types is empty. The available types can be defined using the valid_page_classes_beneath method of the global Obj class part of the Scrivito engine. So, create the “app/models/scrivito/obj.rb” file and add the following code to it:

class Obj < RailsConnector::BasicObj
  in_place do
    def valid_page_classes_beneath(parent_path)
      ['Publication']
    end
  end
end

This causes the Publication type to be offered when creating a page. You can make the page types that should be available depend on the path of the parent object (parent_path).

Each page type offered requires a thumbnail view for displaying a respective icon in the page type browser. Thumbnails are displayed by a Rails view located at “app/views/type_name/thumbnail.html.erb”. Thus, the Publication type requires the “app/views/publication/thumbnail.html.erb” file:

<%= scrivito_thumbnail 'Publication', :content do %>
  General page
<% end %>

Details view and further attributes

For some attributes it doesn't make sense to edit them in place (e.g. show_in_navigation). Editing controls for these attributes are best placed on the details view of the page. The details view can be opened via the corresponding item of the page menu.

This menu item is selectable if a details view exists for the page type concerned. You might, for example, make the title of Publication pages editable by placing the following code into the “app/views/publication/details.html.erb” file (named in accordance with the “app/views/type_name/details.html.erb” pattern):

<div>
  <h3>Page title</h3>
  <%= scrivito_tag :div, @obj, :title %>
</div>

Do not use fiona7_tag or fiona7_tag_list in details views. Also, in details views, @obj is an instance of the Scrivito::BasicObj class and not of RailsConnector::BasicObj, causing the methods defined on Obj or Publication not to be available. How these restrictions originating from compatibility with Scrivito can be dealt with is described in The Ruby API.

Widgets

A Fiona 7 application lets you create widgets in the same way a Scrivito application does. The procedure is illustrated below for an exemplary TextImageWidget that combines an image with a headline. Following a convention for Fiona 7 and Scrivito, widget names should be suffixed with Widget, and page names with Page to be able to instantly identify the purpose of the corresponding object classes.

Step 1: Create a widget model

First, create the widget model in which all of the widget's attributes are defined. For this, create a file, “app/models/image_text_widget.rb”. The class needs to be derived from the Widget class which is derived from Scrivito::Widget.

class ImageTextWidget < Widget
  attribute :headline, :html
  attribute :image, :reference
end

If, as in the example above, a Widget class references objects, they are always derived from Scrivto::BasicObj and not from RailsConnector::BasicObj. How this restriction originating from compatibility with Scrivito can be dealt with is described in The Ruby API.

The class makes the widget object class known to the system. The object class has two attributes, headline for the headline, and image for the image link.

Why are images linked in widgets?

If the type of the image attribute were :binary, the image data could be stored directly inside the widget. However, an image included in a widget in this manner would not be reusable because the image wouldn't exist as an individual object. For this reason it has become a common practice to create images as objects based on an object class named Image and include them in widgets and pages using a reference.

Step 2: Create the show and thumbnail views

For a widget to be usable on a web page, two views need to be created, “app/views/WidgetName/show.html.erb” for displaying its content, and “app/views/WidgetName/thumbnail.html.erb” for displaying an icon or an image in the widget selection dialog (also known as widget browser).

For the TextImageWidget the following files are used:

“app/views/text_image_widget/show.html.erb”:

<%= scrivito_tag :h3, widget, :headline %>
<%= scrivito_image_tag widget, :image %>

“app/views/text_image_widget/thumbnail.html.erb”:

<%= scrivito_thumbnail 'Text Image Widget', :image do %>
  A widget with an image and text.
<% end %>
As with page details views, neither fiona7_tag nor fiona7_tag_list must be used here.

Step 3: Using widgets

The last step is to make widgets usable on pages. For this, the objects representing the pages require at least one attribute of the widgetlist type. If you wish to include TextImageWidgets in pages of the Publication type, extend the class to include such an attribute as follows:

class Publication < Obj
  in_place do
    attribute :main_content, :widgetlist
  end
end

To have the main_content rendered and make it editable on Publication pages, add the following line to the view of the Publication object class:

<%= fiona7_tag :div, @obj, :main_content %>

Opening a Publication page now exhibits a marker for main_content you can use to manipulate widgets. It still isn't possible to add widgets to the page, however, because the list of widgets in the widget selection dialog is empty, as initially was the case with page types in the page type browser.

The selection of widget types to be offered is controlled by the valid_widget_classes_for instance method of the Obj class. The extended definition of Obj should read:

class Obj < RailsConnector::BasicObj
  in_place do
    def valid_page_classes_beneath(parent_path)
      ['Publication']
    end

    def valid_widget_classes_for(attribute)
      ['TextImageWidget']
    end
  end
end

You can now use the TextImageWidget in the main_content attribute on pages of the Publication type. The headline of such a widget can now be edited in place, and you can upload images using drag and drop.

Step 4: Optionally create details views for widgets

As with pages, widgets may also have details views for editing widget attributes that cannot or should not be edited in place, e.g. an attribute for the background color. By convention, the details view of a widget type is rendered by a file located at “app/views/WidgetName/details.html.erb”.