Migration

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:

module Scrivito
  class Obj < BasicObj
    def self.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”).

Attention! 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 %>
  Allgemeine Seite
<% 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>Seitentitel</h3>
  <%= scrivito_tag :div, @obj, :title %>
</div>

Attention! 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, the 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. However, there might be reasons for deviating from this convention, e.g. when migrating boxes to widgets.

Step 1: Create a migration for the object classes

CMS object classes and attributes can be created using migrations. With Fiona 7 applications, it is common practice to create migrations programmatically only instead of using the graphical administration interface for this.

So, as the first step, create a migration for the object class of the widget by executing the following command in the Rails console:

rails generate scrivito:migration CreateTextImageWidget

This creates an empty migration file, “scrivito/migrate/timestamp_create_text_image_widget_migration.rb.” Please provide it with the following content:

class CreateTextImageWidgetMigration < Scrivito::Migration
  def up
    Scrivito::ObjClass.create(name: 'TextImageWidget', attributes: [
      {name: 'header', type: :html},
      {name: 'image', type: :reference}
    ])

    Scrivito::ObjClass.find('Image').attributes.add(name: 'blob', type: :binary)
  end
end

The first block makes the widget object class known to the system. The object class has two attributes, “header” for the headline, and “image” for the image link.

Why are images linked to 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.

The second block extends the existing “Image” object class with a “blob” attribute for the binary data.

Attention! Fiona 7 “blob” attributes are not compatible with the classical “blob” attributes. The latter are invisible to Fiona 7, causing existing images not to be effortlessly reusable in Fiona 7.

Step 2: Run the migration

Having provided the migration, you can now run it using the following command:

bundle exec rake scrivito:migrate

Step 3: Create 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, :header %>
<%= scrivito_image_tag widget, :image %>

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

<%= scrivito_thumbnail 'Text Image Widget', :image do %>
  Ein Widget mit einem Bild und einer Überschrift.
<% end %>

Attention! As with page details views, neither “fiona7_tag” nor “fiona7_tag_list” must be used here.

Step 4: 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 “widget” type. If you wish to include TextImageWidgets in pages of the “Publication” type, create a migration that adds such a “widget” type attribute to the “Publication” object class:

rails generate scrivito:migration AddMainContentAttributeToPublication

Provide the generated migration file with the content below to add the “main_content” attribute of the “widget” type to the “Publication” object class:

class AddMainContentAttributeToPublicationMigration < ::Scrivito::Migration
  def up
    Scrivito::ObjClass.find('Publication').attributes.add(name: 'main_content', type: :widget)
  end
end

Now, run the migration:

bundle exec rake scrivito:migrate

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 “Scrivito::Obj” class. The extended definition of "Scrivito::Obj” should read:

module Scrivito
  class Obj < BasicObj
    def self.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 5: 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.”

Step 6: Optionally create your own widget classes

As opposed to the standalone mode, the legacy mode does not require a Ruby class to be present for a widget. Sometimes, however, it is beneficial to have such a class, e.g. to be able to provide a widget type with individual methods.

The legacy mode offers two ways to create a Ruby class for a widget, in the global namespace, or in the Scrivito namespace.

Applied to the TextImageWidget, this means that you can either provide the “app/models/text_image_widget.rb” file containing

class TextImageWidget < Scrivito::BasicWidget
end

or the “app/models/scrivito/text_image_widget.rb” file containing this:

module Scrivito
  class TextImageWidget < BasicWidget
  end
end

The second variant (Scrivito namespace) is particularly suitable if you want to convert existing classes and objects (e.g. boxes from a box model) to widgets while keeping the application downwards compatible. This way, boxes as well as boxes that have already been converted to widgets could be used in parallel.

You can create widgets for other page types, too, applying the same procedure as described above. See The Ruby API for details.