Content Type Plugins

August edited this page Aug 12, 2013 · 13 revisions

Content in Concerto 2 is designed around a plugin model where additional types of content, supplementing the initial Graphics, Ticker Text, etc, can be added to the system via plugins. These plugins can define custom upload forms, views, and player display code to control the end-to-end flow working with a new type of content in Concerto 2.

Official Concerto plugins

For a plugin to be included as part of Concerto by default, it should meet some basic criteria:

  • Have a code review performed by a dev team member
  • Be licensed under a license compatible with Concerto's own (Apache v2), with a license text inside the repository
  • Be inside the concerto Github organization with access granted to dev team members
  • Be accessible for at least a few key dev team members to upload to on Rubygems

Upload Form

The content upload form in Concerto 2 is controller with a series of partials, letting you override specific components of the form or the entire form if necessary. The default form is broken down into three partials: top, middle, and bottom. Each of these partials is passed the FormBuilder as form, allowing you to use form.text_field :name and alike. You can mix and match what pieces you want to override in a plugin. As an example, the Graphic content type only defines a custom top which adds a file upload field, the rest of the form uses the default middle and bottom sections. You can also replace the entire form with your own custom form if this 3 blocks don't provide suitable flexibility for your plugin.

Top

The top form partial (_form_top.html.erb) is traditionally used to capture the most important part of the content, like the file being uploaded, ticker text entry, path to an RSS feed, etc. The default form_top just captures a string for the data field.

Middle

The middle form partial (_form_middle.html.erb) captures the generic metadata that applies to most content in Concerto 2. Fields like the content name, duration, start time, end time, and feeds are all captured here. To build your own middle form, you may find it useful to pull in some of the the partials used to render the individual fields that have advanced markup or JavaScript. The form_elements directory contains partials to render the start and end date blocks, duration slider, and feed selector elements.

Bottom

By default, the bottom form partial (_form_bottom.html.erb) provides a simple submit button, nothing too fancy here. If you create your own bottom, please be sure to add a submit button somewhere on the page for folks to upload their content.

Complete Customization

If you would not like to use the 3 form block approach that the default content types use, you're welcome to define your own full form creating a _form_full.html.erb partial. If a content type has a full_form it will render this file instead of the 3 blocks. Note, a full form is responsible for displaying error messages if the content cannot be saved.

Tab Icon

If you'd like to specify an icon for the tab then add a partial called _tab_icon.html.erb. An example would be the simple-rss tab icon, which is simply <i class="ficon-rss-sign"></i>.

This icon is also used in the submission tiles under browse content, and has opacity applied to it.

Content Display Views

In addition to the form used to upload the content, a content type plugin must also define partials to control how the content is displayed throughout the admin UI. We use a series of render_ partials to do this, where types are the different places in the UI content is shown. Currently the only types this author is aware of is grid, used for the grid-style content listing, and default, used everywhere else. If a type-specific render partial is missing, like render_grid, the system will fall back to a default rendering partial for that type. In the grid instance, this partial renders a generic content icon.

These partials are called with a local content variable with the content to render. To render content that requires a file, we can call use a url returned from display_content_path to access the file returned from a model's render method as described below.

As an example, for Graphic content we use render_grid (_render_grid.html.erb) to generate an image tag that renders a small thumbnail of the content and the default (_render_default.html.erb) returns the full sized graphic.

Model

Each content type should define it's own model for the new content, inheriting from Content or DynamicContent as appropriate. To customize the behavior of this content you probably want to define several methods / variables:

Display Name

The name of this content type as it should be displayed must be defined in a DISPLAY_NAME variable, containing a string like "Video" or "Ticker Text". This string is only used for display purposes throughout the admin ui.

Set Kind

Each content needs to be associated with a Kind in Concerto 2. A Kind represents the type of block on a screen that the content should be rendered in. Currently, Concerto 2 has Ticker, Graphics, and Text kinds which roughly map to ticker fields, large graphics areas, and sidebar text. We recommend using an after_initialize hook to set the set the Kind of the content, this can be as simple as self.kind = Kind.where(:name => 'Graphics').first (from Graphic.rb).

Render

If the content can't be displayed as plain text or HTML, you'll need to implement a render method which should return the File is to be displayed. We use this in the Graphic class to resize and return an image to users. The render method will get called with all the params passed in the URL to display the content. The controller displaying the result expects a File-like object that responds to file_contents, file_name, and file_type.

Pre Render

The pre_render method is called on each piece of content before it's information is passed along to the frontend to be rendered in a screen. The method is called with two parameters: the screen the content is going to be displayed on, and the field that content will be in. You can use this information to perform any specific transforms necessary to render the content in a specific field. This method doesn't need to return anything, but should cache that information until render_details is called.

Render Details

When content information is returned to a screen, we call render_details with no arguments to figure out what should be passed along to the screen. In the default case (including Ticker Text), we return a hash with the content's data field stored in the data attribute. For Graphics, we use this method to build a URL to the image to be rendered, using the cached values from pre_render.

Form Attributes / Strong Parameters

We use Strong Parameters in Concerto 2 to help secure forms and prevent data from getting changed that we would rather not have changed. This also means that unless a field is whitelisted, forms won't be able to write to them. We define a class method self.form_attributes which should return an array of attributes to be allowed in the content upload form for this content type. If you are using the default fields from the middle form you probably want to make a call to super() to get those default fields from Content and concat your own onto the array. The Graphic class has a good example, adding a nested media field to support the file upload.