ICMS Backend

ICMS Backend provides a uniform administration interface for modifying application resources. It comes with a modular authentication and authorization system, CRUD functionality and an Asset Manager for handling files of any kind.

Asset Manager

The Asset Manager is an important part of ICMS Backend. It lets you manage all of your assets in one location and share them between resources. In the documentation for the Assetable plugin below we explain how to add the asset manager to your models.

Any type of file can be handled by the Asset Manager but there are additional features for handling common multimedia files with resizing/focus, metadata and much more for images and automatic screenshots for videos, etc.

Alot of effort has gone into making the Asset Manager a useful tool, rich with too many features to list here. However, any installation of ICMS Backend has the Asset Manager available in the top right hand corner so it's easy to get started and see what it offers.

Authentication

Authentication in ICMS Backend is handled by a pluggable authentication adapter. Two adapters are included with the framework and others can be added as needed.

Included Authentication Adapters

None Adapter

This is the default (dummy) adapter that implements the methods required by the interface but doesn't actually do anything. This gets you up and running quickly but allows anyone to access the administration interface without any kind of authentication.

Devise Adapter

The second adapter included is the Device Adapter that simply integrates the well known Devise gem with the ICMS framework.

Authorization

Authorization, just like authentication, is handled by a pluggable adapter. Two adapters are included and others can be addded if needed.

With authorization enabled you will find a Roles section in the administration interface where permissions can be granted to specific roles (that subsequently are associated with an authorizer).

Included Authorization Adapters

None Adapter

This is the default (dummy) adapter that implements the methods required by the interface but doesn't actually do anything. This gets you up and running quickly but allows anyone with access to the administration interface to take any action without authorization.

Cancan Adapter

An adapter integrating the cancancan gem with the ICMS framework.

Plugins

Assetable

Any model that uses the plugin assetable can make use of the built in Asset Manager. A typical use case might look something like this:

class BlogPost < ActiveRecord::Base
  icms do
    assetable
  end
  has_photo :cover, folder: "Blog Post Photos"
end

The assetable plugin injects a number of helper methdods into the model:

has_attachment(name, options = {})

Specifies a one-to-one association with the IcmsBackend::AssetManager::Asset class. It allows you to add an asset regardless of type to your class, taking advantage of the Asset Manager interface for uploading/selecting assets.

A has_one association called name will be created, allowing access to the asset on the class instances.

Options
:accepted

The name of a MIME type group that can be defined in an initializer:

config.asset_manager.mime_types.my_mime_types = ['audio/mpeg3', 'application/pdf']
# Defaults to: IcmsBackend.config.asset_manager.mime_types.attachment
:folder

Specify the root folder for chosing assets from when selecting an asset for this association. It defaults to IcmsBackend::AssetManager::Configuration::DEFAULT_FOLDER_NAME that can be configured through IcmsBackend.config.asset_manager.default_folder_name

If the folder doesn't exist it will be created as a new root level folder. Root level folders cannot be deleted through the Asset Manager interface to ensure the integrity of this layer of organization.

Usage Examples:
has_attachment :certificate, accepted: :my_mime_types
has_attachment :curriculum, folder: 'users'

has_attachments(name, options = {})

Specifies a one-to-many association with the IcmsBackend::AssetManager::Asset class. It allows adding assets to any class, taking advantage of the Asset Manager interface for uploading/selecting assets.

A has_many association called name will be created, allowing access to the asset on the class instances.

Options
:max

The maximum number of assets that you may pick from the Asset Manager.

See the documentation for has_attachment for more available options.

Usage Examples:
has_attachments :certifications, max: 5

has_audio(name, options = {})

Specifies a one-to-one association with the IcmsBackend::AssetManager::Audio class. It allows you to add an audio file to your class, taking advantage of the Asset Manager interface for uploading/selecting audio files.

A has_one association called name will be created, allowing access to the audio asset on the class instances.

Options
:accepted

The name of a MIME type group that can be defined in an initializer:

config.asset_manager.mime_types.my_mime_types = ['audio/mpeg3']
# Defaults to: IcmsBackend.config.asset_manager.mime_types.audio
:folder

Specify the root folder for chosing audios from when selecting a video for this association. It defaults to IcmsBackend::AssetManager::Configuration::DEFAULT_FOLDER_NAME but can be configured through IcmsBackend.config.asset_manager.default_folder_name

If the folder doesn't exist it will be created as a new root level folder. Root level folders cannot be deleted through the Asset Manager interface to ensure the integrity of this layer of organization.

Usage Examples:
has_audio :product_demo, accepted: [:mp3]
has_audio :overview, folder: :products

has_audios(name, options = {})

Specifies a one-to-many association with the IcmsBackend::AssetManager::Audio class. It allows you to add audio files to your class, taking advantage of the Asset Manager interface for uploading/selecting audio files.

A has_many association called name will be created, allowing access to the audio asset on the class instances.

Options
:max

The maximum number of audio files that you may pick from the Asset Manager.

See the documentation for has_audio for more available options.

Usage Examples:
has_audios :gallery, max: 3

has_document(name, options = {})

Specifies a one-to-one association with the IcmsBackend::AssetManager::Document class. It allows you to add a document to your class, taking advantage of the Asset Manager interface for uploading/selecting documents.

A has_one association called name will be created, allowing access to the document asset on the class instances.

Options
:accepted

The name of a MIME type group that can be defined in an initializer:

config.asset_manager.mime_types.my_mime_types = ['application/pdf', 'text/plain']
# Defaults to: IcmsBackend.config.asset_manager.mime_types.document
:folder

Specify the root folder for chosing documents from when selecting a document for this association. It defaults to IcmsBackend::AssetManager::Configuration::DEFAULT_FOLDER_NAME but can be configured through IcmsBackend.config.asset_manager.default_folder_name

If the folder doesn't exist it will be created as a new root level folder. Root level folders cannot be deleted through the Asset Manager interface to ensure the integrity of this layer of organization.

Usage Examples:
has_document :data_sheet, accepted: :my_mime_types
has_document :curriculum, folder: 'users'

has_documents(name, options = {})

Specifies a one-to-many association with the IcmsBackend::AssetManager::Document class. It allows adding documents to any class, taking advantage of the Asset Manager interface for uploading/selecting documents.

A has_many association called name will be created, allowing access to the document asset on the class instances.

Options
:max

The maximum number of documents that you may pick from the Asset Manager.

See the documentation for has_document for more available options.

Usage Examples:
has_documents :certifications, max: 5

has_photo(name, options = {})

Specifies a one-to-one association with the IcmsBackend::AssetManager::Photo class. It allows for adding a photo to any class, taking advantage of the Asset Manager interface for uploading/selecting photos.

A has_one association called name will be created, allowing access to the photo asset on the class instances.

Options
:accepted

The name of a MIME type group that can be defined in an initializer:

config.asset_manager.mime_types.my_mime_types = [image/jpeg', 'image/png']
# Defaults to: IcmsBackend.config.asset_manager.mime_types.photo
:folder

Specify the root folder for chosing photos from when selecting a photo for this association. It defaults to IcmsBackend::AssetManager::Configuration::DEFAULT_FOLDER_NAME but can be configured through IcmsBackend.config.asset_manager.default_folder_name.

If the folder doesn't exist it will be created as a new root level folder. Root level folders cannot be deleted through the Asset Manager interface to ensure the integrity of this layer of organization.

:versions

Specify a hash of versions that will be created when a photo is chosen from the Asset Manager. The key becomes the name of the version and the value is expected to be a string on the format "[width]x[height]".

The cropping of the original photo will be made intelligently, using the focus point from the original and the format specified for the version. This is a design choice that probably works fine 99% of the time. In rare cases where the result is not what was expected it is always possible to insert a new, modified, original and create version from that one instead.

Example Usage:
has_photo :front, folder: :products, accepted: :my_mime_types
has_photo :back, versions: { small: '640x480', medium: '800x600', large: '1024x768' }

has_photos(name, options = {})

Specifies a one-to-many with the IcmsBackend::AssetManager::Photo class. It allows adding photos to any class, taking advantage of the Asset Manager interface for uploading/selecting photos.

A has_many association called name will be created, allowing access to the photo asset on the class instances.

Options
:max

The maximum number of photos that you may pick from the Asset Manager.

See the documentation for has_photo for more available options.

Usage Examples:
has_photos :gallery, max: 10

has_video(name, options = {})

Specifies a one-to-one association with the IcmsBackend::AssetManager::Video class. It allows you to add a video to your class, taking advantage of the Asset Manager interface for uploading/selecting videos.

A has_one association called name will be created, allowing access to the video asset on the class instances.

Options
:accepted

The name of a MIME type group that can be defined in an initializer:

config.asset_manager.mime_types.my_mime_types = ['audio/mpeg3']
# Defaults to: IcmsBackend.config.asset_manager.mime_types.video
:folder

Specify the root folder for chosing videos from when selecting a video for this association. It defaults to IcmsBackend::AssetManager::Configuration::DEFAULT_FOLDER_NAME but can be configured through IcmsBackend.config.asset_manager.default_folder_name

If the folder doesn't exist it will be created as a new root level folder. Root level folders cannot be deleted through the Asset Manager interface to ensure the integrity of this layer of organization.

Usage Examples:
has_video :product_demo, accepted: :my_mime_types
has_video :overview, folder: :products

has_videos(name, options = {})

Specifies a one-to-many association with the IcmsBackend::AssetManager::Video class. It allows you to add videos to your class, taking advantage of the Asset Manager interface for uploading/selecting videos.

A has_many association called name will be created, allowing access to the video asset on the class instances.

Options
:max

The maximum number of videos that you may pick from the Asset Manager.

See the documentation for has_video for more available options.

Usage Examples:
has_videos :gallery, max: 3

Authorizer

The Authorizer plugin defines a model as an entity that can be used to authorize others. Examples of this might be a User or AdminUser model (or both).

The plugin doesn't require any options and the usage is as simple as a line in the icms block of your model:

icms do
  authorizer
end

Authorizable

The Authorizable plugin defines a model as something that can be authorized. This, most likely, will be the majority of your models such as blog posts, comments, users, etc.

The plugin usage is as simple as a line in the icms block of your model:

icms do
  authorizable
end

Options

:permissions

Every authorizable has basic CRUD permissions but, if needed, you may specify other, custom, permissions for each resource. For example:

class Invoice < ActiveRecord::Base
  icms do
    authorizable permissions: [:print, :send]
  end
end

The additional permissions will automatically appear in the Roles section for the current resource. For example:

Resource Create Read Update Delete Print Send
Invoice
User

Dashboard

ICMS Backend introduces the concept of dashboards. A dashboard is the glue between the administration interface and the application. It describes how a model should be presented, which fields should be included in the form, which fields can be searched, etc.

A simplified example dashboard might look like:

class PostDashboard < IcmsBackend::BaseDashboard

  # A hash that describes the type of each of the model's fields.
  ATTRIBUTE_TYPES = {
    title: Field::String.with_options(searchable: { attribute_name: :translations_title }),
    content: Field::Text.with_options(searchable: { attribute_name: :translations_content }),
    cover: Field::Asset,
  }

  # An array of attributes that will be displayed on the model's index page.
  COLLECTION_ATTRIBUTES = [
    :id,
    :title,
  ]

  # An array of attributes that will be displayed on the model's show page.
  SHOW_COMPONENTS = [
    { type: :titled_show_attribute, name: :title },
    { type: :titled_show_attribute, name: :content },
  ]

  # An array of components that will be displayed on the model's form (new and edit) pages.
  FORM_COMPONENTS = [
    :title,
    :content,
  ]

end

In the context of the Dashboard, a number of methods are available to provide customization possibilities for the current application. You may find that you need to add custom actions or buttons in various places of the interface or perhaps you want to move the dashboard resource to another place in the menu tree.

Below is a list of the most important helper methods but for a full list it is recommended to take a look directly at the class IcmsBackend::BaseDashboard.

Dashboard Helper Methods

resource_action(name, options = {}, &block)

Adds an action to the show/edit/index views of the resource.

resource_action is a convenient way of adding custom resource actions for a Dashboard.

Options
:add_to_index

A boolean determining the visibility of the button on the row of the resource in the index list. Defaults to false.

:confirm

A confirmation message that needs to be accepted for the action to take place.

:if

A boolean or proc that determines the visibility of the resource action button in the IcmsBackend interface. If a proc is given, the current view context will be passed as a parameter and the proc is expected to return a boolean. Defaults to true, always showing the button.

:icon

The name of a material design icon that appears next to the button label. Valid icon names can be found at Material Icons. By default no icon is shown.

:label

The label for the button. It defaults to name

:method

The HTTP method used for submitting the form of the resource action. Defaults to GET

:mode

The button mode. It can be either :link, :button or :submit. The :method option only applies to :button and :submit :mode. :link renders a normal link, :button render a normal button while :submit renders a button that submits the form with all parameters using the method :method. Defaults to :button

:type

A symbol representing the type of action (and route to generate). It can be either :member or :collection. Defaults to :member

Usage Examples:

The simplest use of resource_action is by passing it the name of an action. This causes IcmsBackend to look for a "my_show" in the "IcmsBackend::Products" controller.

class ProductDashboard < IcmsBackend::BaseDashboard
  resource_action :my_show
end

A more complex example adding a "Statistics" button to the show view of products:

class ProductDashboard < IcmsBackend::BaseDashboard
  resource_action :download_statistics,
                  icon: 'timeline',
                  if: -> (view, resource) { view.action_name == 'show' },
                  label: 'Statistics'
  do
    @product = requested_resource
    # Show download statistics for this product in a custom view.
  end
end

collection_action(name, options = {}, &block)

Adds a a collection action to the index view of the resource.

A collection action, like the name suggests, operates on a collection of records. A button will appear in the IcmsBackend interface, calling this action with the selected resource IDs in a hidden form element.

This method is used internally for plugins such as Publishable that needs to add "Publish" and "Unpublish" actions but it is also convenient for quickly adding custom actions that present information about or modify a collection of records. collection_action is usually called from within a Dashboard.

Options
:always_active

A boolean determining if the collection action button is active or not, regardless if any records are selected or not. Default to false, allowing the button to toggle based upon the current selection.

:icon

The name of a material design icon that appears next to the button label. Valid icon names can be found at Material Icons. By default no icon is shown.

:if

A boolean or proc that determines the visibility of the collection action button in the IcmsBackend interface. If a proc is given, the current view context will be passed as a parameter and the proc is expected to return a boolean. Defaults to true, always showing the button.

:label

The label for the collection action button. It defaults to name

:method

The HTTP method used for submitting the form of the collection action. Defaults to POST

Usage Examples:

The simplest use of collection_action is by passing it the name of an action. This causes IcmsBackend to look for a "favorites" action in the "IcmsBackend::Products" controller.

class ProductDashboard < IcmsBackend::BaseDashboard
  collection_action :favorites
end

A more complex example:

class ProductDashboard < IcmsBackend::BaseDashboard
  collection_action :touch, label: 'Touch us!', if: -> (view) { true }, method: :post do
    products = Product.find params[:batch_action_ids]
    products.update_all updated_at: DateTime.now
    redirect_to '/admin/products', notice: "#{products.count} products updated"
  end
end

custom_action(name, options = {}, &block)

Adds a custom action to the expanding button of the resource views.

A custom action doesn't operate on any particular record but rather serves as a convenient way for adding a custom action to present any needed information about the current collection.

custom_action is usually called within a Dashboard.

Options
:icon

The name of a material design icon that constitutes the button. Valid icon names can be found at Material Icons.

:if

A boolean or proc that determines the visibility of the custom action button in the IcmsBackend interface. If a proc is given, the current view context will be passed as a parameter and the proc is expected to return a boolean. Defaults to true, always showing the button.

:tooltip

The tooltip for the custom action button. It defaults to name

Usage Examples:

The simplest use of custom_actiontt> is by passing it the name of an action.

class ProductDashboard < IcmsBackend::BaseDashboard
  custom_action :favorites
end

sidebar_menu_parent

A method that returns the name of the parent in the menu tree. It can be overridden but by default looks like this:

def sidebar_menu_parent
  :content
end

resource_class

A method that returns the class of the current resource. This needs to be overridden if the name cannot be inferred from the name of the dashboard. By default it looks like this:

def resource_class
  name.gsub('Dashboard', '').constantize
end

Page

IcmsBackend::Page connects a dashboard to a model instance and provides the context needed in order to render the administration interface. This is mostly transparent to the developer so we will not discuss it here.

Field

ICMS Backend also introduces the concept of "fields". A field is a class that extends IcmsBackend::Field::Base and, in the very simplest form, might look something like this:

# icms_backend/field/date.rb
module IcmsBackend
  module Field
    class Date < Base
    end
  end
end

In the Dashboard section above we saw the use of a couple of fields in the ATTRIBUTE_TYPES hash. This is the main use of fields - we define a dashboard that describes which fields a model has and then where they should be presented. For example we can see the :title attribute in the COLLECTION_ATTRIBUTES. This will tell ICMS Backend that we want to show the attribute title in the index page of the resource and since we have declared title to be a Field::String we know how to deal with it.

Every field type has a partial for each render context (index, show, form and search) that takes care of rendering the field. For example, Field::String has the following partial for the search context:

# app/views/fields/string/_search.html.haml
= f.input field.search_form_attribute_name,
          as: :string,
          required: false,
          label: field.human_attribute_name,
          input_html: { value: field.search_form_value(params), class: field.html_class }

results matching ""

    No results matching ""