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

Limiting Available Widget and Page Types 

Limiting Available Widget and Page Types 

As a developer, you might be asked to limit the selectable widget and page types to a particular subset, depending on the widget field or the page type. In a news article, for example, you might want to prevent editors from using a video widget, while this restriction should not apply to blog posts. Or, with page types, it makes sense, for example, to disallow creating a landing page or a blog post in the product catalog section of a website.

The Scrivito SDK offers two Ruby callback methods to support implementing these two use cases. For further details, please refer to the Scrivito SDK API documentation.

Permitting widgets

For restricting the use of widgets, the Scrivito SDK calls the valid_widget_classes_for method of the CMS page (Obj) or widget (Widget) concerned whenever a widget is to be added in place. You can define the method like this, for example:

def valid_widget_classes_for(field_name) if field_name == "blogcontent" [BlogPostWidget, TextWidget] end end

To this method the name of the widget field in question, field_name, is passed. Simply apply Ruby comparisons to the value of this parameter to specify the widgets to be available in the widget browser.

You can define this method in the obj.rb model file, so that it is called for all CMS object classes. Alternatively, or additionally, the method can be defined for a particular CMS object class. This might be handy if there are many widget attributes with different names, and you don't want them all to show up in your method.

Note that this method can also be defined for widget object classes. This lets you restrict the widgets to be available in container widgets.

For differentiating according to the intended use of particular widget attributes, give these attributes names that reflect their purpose, e.g. content and row_content, and implement the callback as a name switch:

def valid_widget_classes_for(field_name) case field_name when "content" [ TextWidget, VideoWidget, SliderWidget, ImageWidget ] when "row_content"   [ TwoColumnWidget, ColorWidget, TeaserWidget ] else []     end end

To summarize, the valid_widget_classes_for method lets you define the widget types to be available on specific pages or inside specific attributes or widgets. Complementary to this top-down approach, there is the valid_container_classes method as a bottom-up counterpart for specifying the page or widget classes a particular widget class may occupy (as with nested widgets).

Permitting page types

For permitting specific page types, i.e. CMS object classes, in a particular section of your website, the Scrivito SDK calls the valid_page_classes_beneath class method on the Obj class whenever a new page is to be created in place.

def self.valid_page_classes_beneath(path) if path.try(:start_with?, '/en/catalog/products') [ProductCategory, Product] end end

This method lets you define the page types to be offered in the page type browser at a particular location in the object hierarchy. This location is passed to the method as the path of the parent object to which the new page is to be added as a child. Please be aware that path can be nil.

As an alternative to hard-coding the permitted classes, you can also compute them in several ways:

# Using Enumerable#reject class Obj def self.valid_page_classes_beneath(parent_path) Scrivito.models.pages.reject do |page_class| [MyHiddenDocPage, MyHiddenBlogPage, MyHiddenNewsPage].include?(page_class) end end end # Using Array#- class Obj def self.valid_page_classes_beneath(parent_path) Scrivito.models.pages.to_a - [MyHiddenDocPage, MyHiddenBlogPage, MyHiddenNewsPage] end end # Using Enumerable#reject and the parent path class Obj def self.valid_page_classes_beneath(parent_path) Scrivito.models.pages.reject do |page_class| page_class.allowed_beneath?(parent_path) # Assuming your models respond to #allowed_beneath? end end end