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:
-
falseor"false"will not render the label from the localest(model.class.model_name.i18n_key, scope: "activerecord.models", count: 1) -
trueor"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.rbinitializer "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
cardof the resource is defined indecidim-core/lib/decidim/resource_manifest.rb:# The cell to use to render the card of a resource. attribute :card, StringIn your
decidim-<component>/lib/decidim/<component>/component.rbregister the resource and set the card value. Note that the model class for your resource must include theDecidim::Resourceableconcern 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 endmodule 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