View Models (a.k.a. Cells)
General description
A cell is an object that represent a fragment of your UI. The scope of that fragment can embrace an entire page, a single comment container in a thread or just an avatar image link.
Cells are faster than ActionView. While exposing a better performance, you step-wise encapsulate fragments into cell widgets and enforce interfaces.
Decidim Cards
card_for @instance
will render the corresponding default card for each component instance.
If a card for the given resource is not registered, a basic (default) card is shown.
To render a specified size/variation include the size
option as a symbol
: card_for @instance, size: :m
Card M
To render a label to identify the type of component renderized add to the context
the label
option.
The label
option accepts this arguments:
-
false
or"false"
will not render the label from the localest(model.class.model_name.i18n_key, scope: "activerecord.models", count: 1)
-
true
or"true"
will render the translation from -
"whatever string"
will render it as String
Introducing a Card Cell to a component
-
Add the module cell paths to cell view paths in
decidim-<module>/lib/decidim/<module>/engine.rb
initializer "decidim_<module>.add_cells_view_paths" do Cell::ViewModel.view_paths << File.expand_path("#{Decidim::<Module>::Engine.root}/app/cells") Cell::ViewModel.view_paths << File.expand_path("#{Decidim::<Module>::Engine.root}/app/views") # for partials end
-
The attribute
card
of the resource is defined indecidim-core/lib/decidim/resource_manifest.rb
:# The cell to use to render the card of a resource. attribute :card, String
In your
decidim-<component>/lib/decidim/<component>/component.rb
register the resource and set the card value. Note that the model class for your resource must include theDecidim::Resourceable
concern for this to work:component.register_resource(:<my_resource>) do |resource| resource.class = "Decidim::<Component>/<MyResource>" # eg. "Decidim::Proposals::ProposalDraft resource.card = "decidim/<component>/<my_resource>" # eg. "decidim/proposals/proposal_draft" resource.component_manifest = component end
module Decidim module <Component> class <MyResource> < Decidim::ApplicationRecord include Decidim::Resourceable # ... end end end
-
The Cell Class, following the convention, will reside in
decidim-<component>/app/cells/decidim/<component>/<my_resource>_cell.rb
:module Decidim module <Component>s class <MyResource>Cell < Decidim::ViewModel def show render # renders decidim-<component>/app/cells/decidim/<component>/<my_resource> end end end end
-
The Cell Views will be in the
decidim-<component>/app/cells/decidim/<component>/<my_resource>
and defaults toshow.erb