Fiona 7 offers two operation modes, the standalone
mode, which is exclusively oriented towards Scrivito, and the legacy
mode in which Fiona 7 is also compatible with the Rails Connector.
In compatibility mode (legacy
) the CMS object model classes are derived from RailsConnector::BasicObj
(mostly indirectly via Obj
). The name of an object class must be exactly the same as the name of the model class on which it is based. This poses a problem if one wants to use the APIs of the Scrivito SDK because this SDK expects the names to be identical, too.
Since there is no multiple inheritance in Ruby, this conflict cannot be solved by means of the programming language itself.
Fiona 7 solves it by introducing the concept of shadow classes: Using the in_place
block in a class derived from RailsConnector::BasicObj
causes an additional, hidden class to be created.
Fiona 7 uses this hidden class as a replacement for the missing global class to handle all internal functions. If, for example, attributes defined in the Homepage
are queried, the Homepage
class that inherits from Scrivito::BasicObj
is loaded first if it exists. If it doesn't, another attempt is made, this time with ShadowClasses::Homepage
.
If, for example, you want to equip the Homepage
object class with a headline
attribute you want to be editable in place, take a look at the definition of the Homepage
class in the application:
class Homepage < Obj
end
The Obj
class in turn inherits from RailsConnector::BasicObj
, as usual:
class Obj < RailsConnector::BasicObj
end
Now, the headline
attribute should be added to the Homepage
class using the in_place
block:
class Homepage < Obj
in_place do
attribute :headline, :string
end
end
This modification makes it possible to use fiona7_tag @obj, :headline
to make the headline
attribute of the Homepage
editable in place where appropriate.
The in_place
block internally creates the ShadowClasses::Homepage
class which inherits from ShadowClasses::Obj
. If the in_place
block is used in the Obj
class, the definition can be found in ShadowClasses::Obj
, meaning that two classes are automatically created that look roughly like this:
class ShadowClasses::Obj < Scrivito::BasicObj
end
class ShadowClasses::Homepage < ShadowClasses::Obj
attribute :headline, :string
end
Hence, you can define an attribute globally for all existing object classes by placing it into the in_place
block of the Obj
class:
class Obj < RailsConnector::BasicObj
in_place do
attribute :show_in_navigation, :enum, values: ['yes', 'no']
end
end
Inside the in_place
block, all functions can be used that are usually available for classes derived from Scrivito::BasicObj
, e.g. valid_widget_classes_for
for restricting the available widgets, or description_for_editor
for specifying a descriptive text for page or widget types.
The class hierachy of the application is currently (1.5.x) not reflected in the shadow classes, meaning that only the attributes and methods are available that are defined in Obj
or in an object class itself.
The following does not work as intended:
class ArticlePage < Obj
in_place do
attribute :headline, :string
end
end
class NewsPage < ArticlePage
in_place do
attribute :summary, :html
end
end
In this case, the NewsPage
object class only includes the summary
attribute (as well as the attributes originating from Obj
), but not headline
.
If inheritance with shadow classes cannot be provided otherwise (e.g. by means of mixins), you can apply the following pattern as a last resort:
class ArticlePage < Obj
def self.inherited(subclass)
super
subclass.class_eval do
in_place do
attribute :headline, :string
end
end
end
end
class NewsPage < ArticlePage
in_place do
attribute :summary, :html
end
end