Learn how Scrivito CMS can help you deliver amazing digital experiences
See Scrivito CMS in action

Handling Reusable Content

Handling Reusable Content

A Scrivito website usually consists of several pages, each represented by its own CMS object. In addition to the pages, there is content that is — or could be — shared between different pages, images, for example. We call such shared pieces of content resources. Images are the most basic resources used on most if not all Scrivito websites, but, of course, other types exist as well, e.g. videos or PDF documents. Each of these resource types represents a particular file type, and we therefore call them “binary resources.”

However, one can think of resource types that do not represent a file, e.g. a contact person, a location, or a product. Resources of such types provide a dedicated place for keeping the pieces of information the individual entities consist of.

Resources in the CMS

As with pages, every resource is represented by a CMS object based on an object class that defines the properties and thus the type of the resource.

So, how do we display the information contained in a resource? Right, we simply use widgets. This enables editors to place a resource where they think is appropriate.

Widgets for displaying resources can be connected to a single resource or several resources at once by referencing them using a referencelist attribute. Additionally, attributes for controlling adjustment, size, etc. could be provided. For example, an “ImageWidget” that includes text might have an option for specifying whether the text should be displayed to the right or to the left of the image.

There is no limit regarding the number of widgets one may provide for displaying resources of a particular type. You could, for example, write a widget that displays the address and opening hours of a “Store” resource, as well as a widget that uses Google Maps to visualize the location of a store or even of several stores. Similarly, you could create a widget that is able to handle multiple resources of different types. For example, think of a “GalleryWidget” that displays a set of images for a given resource type (e.g. store, product). You could easily implement such a widget after adding a “gallery” attribute referencing an image to the resource types.

The possibility to separate resources and the way they are displayed on a page offers several advantages. The most prominent is that resources can be altered using a common tool, the Content Browser, and that changes to them are instantly reflected throughout your website.

Implementing resources

Enough theory, let's implement our own simple resource type, a “Product,” and the widget to display instances of it.

This guide is based on our instructions for integrating Scrivito you can complete in no time after creating your Scrivito account. Integrating Bootstrap is optional, but recommended for this tutorial.

The first step when adding a new type of content such as a resource to the CMS is to provide the CMS object model that represents it. For future products, create the app/models/product.rb file and set its contents to the following:

class Product < Obj attribute :title, :string attribute :price, :string attribute :image, :reference end
Note that we included the image by reference, meaning that the image is represented as an individual CMS object. Alternatively, files can also be directly included in a CMS object using a binary attribute.

It is almost always preferable to upload files individually and include them by reference since these files can then be reused. However, there are some cases where embedding a file into a resource makes sense. For example, think of a thumbnail image for a given image or a PDF file, or a press release available in several languages. Whenever several versions of the same resource exist, they probably can be handled more efficiently if they are kept together in a single CMS object.

As you can see, our products consist of three attributes only, a title, a price and a reference pointing to a product image. The resources are not rendered on usual pages, so we require a way to view and edit the ones already present. We can use Scrivito's Content Browser to view resources. However, to be able to edit them, we need to add a details dialog template to the resource type. So, create the app/views/product/details.html.erb file and provide it with the following content:

<%= scrivito_details_for 'Title' do %> <%= scrivito_tag :div, @obj, :title %> <% end %> <%= scrivito_details_for 'Price' do %> <%= scrivito_tag :div, @obj, :price %> <% end %> <%= scrivito_details_for 'Product image' do %> <%= scrivito_image_tag @obj, :image %> <% end %>

Finally, for making a “Products” category available in the Content Browser and supporting the creation of such products, we'll configure the Content Browser accordingly by adding the file app/assets/javascripts/editing/content_browser.js.coffee and changing it to:

scrivito.on 'load', -> scrivito.content_browser.filters = _obj_class: field: '_obj_class' options: Image: icon: 'image' Download: icon: 'generic' Product: enable_create: true preset: _obj_class: 'Product'

You can now create a new “Product” CMS object. Open the Content Browser by clicking the folder button on the Scrivito panel, then select the “Product” category from the list to the left. You should now see the “Create item” button as the first and only item. Click it to create the new product and edit it using the details view to the right:

Feel free to set the attributes to whatever you want or even use other or additional ones.

Providing a product widget

Let us create a widget for our product type so that we can have the actual products displayed on pages. You can use the widget generator to create the required files:

> rails g scrivito:widget product product:reference

This generator call creates a widget model class that includes one attribute, “product,” for referencing a “Product” CMS object. So, we only need to edit the views. First, let's equip the view template (app/views/product_widget/show.html.erb) with the following content:

<% if widget.product.blank? %> <strong>Please select a product</strong> <%= scrivito_tag :div, widget, :product %> <% else %> <div class="panel panel-default"> <div class="panel-heading"> <h4><%= scrivito_tag :span, widget.product, :title %></h4> </div> <div class="panel-body"> <%= scrivito_image_tag widget.product, :image, style: 'width:100%;' %> <div>Only <%= scrivito_tag :span, widget.product, :price %></div> </div> </div> <% end %>

This displays a message if no product reference exists or if it is empty. If one is referenced, all of its attributes are rendered. Now, let's add a “ProductWidget” to a page and make it point to the product we've created before.

To enable editors to change the referenced product, provide a details view for the widget, app/views/product_widget/details.html.erb:

<%= scrivito_details_for 'Product' do %> <%= scrivito_tag :div, widget, :product do %> <% if widget.product %> <%= widget.product.title %> <% else %> Please select a product <% end %> <% end %> <% end %>

What's next?

This was just an introduction. To further extend the possibilities of displaying products, you could:

  • Make it that clicking a “product” reference opens the Content Browser with the “Product” category being preselected.
  • You could implement a new “currency” attribute for the “ProductWidget” that allows the editor to determine the currency in which the price is displayed and automatically convert it.
  • Build a “ProductBundleWidget” that enables the editor to group “Products” and discount the total bundle price by a given percentage.