Bei Fiona 7 gibt es zwei Betriebsarten, den ausschließlich an Scrivito orientierten standalone-Modus sowie den legacy-Modus, in dem Fiona 7 auch kompatibel zum Rails Connector ist.
Im Kompatibilitätsmodus (legacy) werden die Model-Klassen für Vorlagen von RailsConnector::BasicObj abgeleitet (meistens indirekt via Obj). Eine Vorlage muss genau so heißen, wie die Klasse, auf der sie basiert. Dadurch ergibt sich ein Problem, wenn man die APIs des Scrivito SDK benutzen möchte, weil dieses auch von dieser Namensgleichheit ausgeht.
Da es in Ruby keine mehrfache Vererbung gibt, lässt sich dieser Konflikt nicht mit den Mitteln der Programmiersprache lösen.
Fiona 7 löst dieses Problem mit dem Konzept der Shadow Classes: Wenn man in einer Klasse, die von RailsConnector::BasicObj abgeleitet ist, den in_place-Block nutzt, dann wird eine zusätzliche, versteckte Klasse angelegt.
Fiona 7 verwendet diese versteckte Klasse als Ersatz für die fehlende globale Klasse für die Abwicklung aller internen Funktionen. Werden beispielsweise die in Homepage definierten Attribute abgefragt, dann wird zunächst die Klasse Homepage geladen und verwendet, wenn sie von Scrivito::BasicObj erbt. Sollte dies nicht der Fall sein, wird es noch einmal probiert, diesmal mit ShadowClasses::Homepage.
Ein Beispiel: die Vorlage Homepage hat das Attribut headline, das in-place bearbeitbar werden soll. In der Applikation gibt es bereits eine Definition für die Klasse Homepage:
class Homepage < Obj
endDie Klasse Obj wiederum erbt ganz normal von RailsConnector::BasicObj
class Obj < RailsConnector::BasicObj
endNun wird in der Klasse Homepage das headline-Attribut im in_place-Block hinzugefügt:
class Homepage < Obj
in_place do
attribute :headline, :string
end
endNach dieser Änderung kann man an geeigneter Stelle fiona7_tag @obj, :headline einsetzen, um das Attribut headline der Homepage dort in-place bearbeitbar zu machen.
Intern wird durch den in_place Block die Klasse ShadowClasses::Homepage angelegt, die von ShadowClasses::Obj erbt. Wenn man den in_place Block in der Obj-Klasse nutzt, dann findet sich die Definition in ShadowClasses::Obj wieder.
Es werden also automatisch zwei Klassen definiert, die etwa wie folgt aussehen:
class ShadowClasses::Obj < Scrivito::BasicObj
end
class ShadowClasses::Homepage < ShadowClasses::Obj
attribute :headline, :string
endEs ist somit möglich, ein Attribut global, also für alle definierten Vorlagen, festzulegen, indem man den in_place-Block in der Obj-Klasse einträgt:
class Obj < RailsConnector::BasicObj
in_place do
attribute :show_in_navigation, :enum, values: ['yes', 'no']
end
endIm in_place Block können alle Funktionen genutzt werden, die sonst in den von Scrivito::BasicObj abgeleiteten Klassen verfügbar sind, z.B. valid_widget_classes_for zur Einschränkung der verfügbaren Widgets, oder description_for_editor zur Festlegung eines Beschreibungstextes von Seiten- und Widgettypen.