Scrivito 0.40.0

Destruktive Änderungen

Das Gem, mit dem das Scrivito SDK über das Gemfile in die Rails Applikation eingebunden werden kann, heißt nun „scrivito“. Es beruht auf den Gems „scrivito_sdk“ und „scrivito_editors“, die nun aus dem Gemfile entfernt werden müssen, in das sie zuvor eingetragen wurden.

Trennung von UI und der Application Assets

In früheren Versionen von Scrivito war die Benutzerschnittstelle für die In-place-Bearbeitung ein Teil der Applikationsseite: die Assets des UI wurden in das Applikationsfenster geladen und im Kontext der Applikation ausgeführt. Dies führte zu Problemen:

  • CSS-Konflikte und die Schwierigkeit, den richtigen Z-Index zuzuweisen.
  • Die „Vorschau“ der Seite war nicht realistisch, da sie weiterhin Assets des UI eingebunden hat, die das Aussehen und Verhalten der Seiten maßgeblich beeinflussen konnten.
  • Damit die Applikation in der Lage ist, Scrivitos UI darzustellen, muss sie spezielle Assets und Markups einbinden. Views der Applikation, die nicht die Assets und das Markup enthielten (beispielsweise Fehlerseiten), konnte die Benutzerschnittstelle nicht darstellen.

Um diese Probleme zu vermeiden, rendert das Scrivito UI die Seiten der Applikation nun in einem speziellen iFrame. Damit sind die Browserfenster des UI und der Applikation voneinander getrennt und können sich nicht mehr beeinträchtigen.

Das iFrame aktivieren

Für Redakteure ist diese Änderung transparent: das UI sieht fast genauso aus wie vorher und verhält sich auch so. Jedoch müssen in der neuesten Scrivito-Version besondere Layout-Templates in den View der Applikation eingebunden werden. Diese scrivito_dialog.html.*-Templates befinden sich unterhalb von „app/views/layouts/“ und ermöglichen es, Detail-Dialoge anzuzeigen.

In neuen Applikationen werden diese Templates automatisch vom „install generator“ angelegt. Bei bestehenden Applikationen, für die das Scrivito SDK aktualisiert werden muss, kann dieser Generator einfach erneut ausgeführt werden. Die fehlenden Templates lassen sich mit rails g scrivito:install anlegen.

Hinweis: im scrivito_dialog.html.*-Template müssen alle Scrivito-Assets eingebunden werden, die normalerweise in der Datei application.js oder application.css eingebunden werden.

Neue Filteroptionen

Der Content Browser ermöglicht es nun, die angezeigten Filter feiner zu granulieren. Dafür gibt es drei Filtertypen:

  • tree
  • radio_button
  • check_box

Der tree-Filter ist eine Erweiterung der bereits in der vorigen Content-Browser-Version existierenden Filter. Mit ihm können die Filterknoten hierarchisch angeordnet und damit logisch gruppiert werden. So kann ein genau definierter, komplexer Filtersatz bereitgestellt werden.

Die radio_button und check_box-Filter ermöglichen es, Radio-Buttons für die Einzelauswahl oder Checkboxen für die Mehrfachauswahl anzubieten. Mit ihnen kann ein Redakteur die Ergebnisse des angewendeten Filters weiter einschränken. Diese Filter können nicht hierarchisch strukturiert werden.

Zusätzlich zu diesen neuen Filtertypen gibt es einige neue Optionen, mit denen definiert werden kann, wie die Filter einem Redakteur beim Öffnen des Content Browsers angezeigt werden:

  • expanded - die Unterelemente eines Filters sind initial sichtbar
  • selected - Filterobjekte sind vorausgewählt
  • icon - spezifiziert ein Icon für den Filter

Um zu definieren, was ein Filter zurückgibt, kann entweder die bekannte query-Option oder die neue „Field-Operator-Value“-Option (FOV). Die query-Option hat Vorrang vor der FOV-Option und überschreibt diese, wenn vorhanden. Die FOV-Option kann mit Hilfe der Schlüsselwörter field, operator und value  spezifiziert werden, die äquivalent zu den Argumenten sind, die scrivito.obj_where übergeben werden können. Die FOV-Option sollte bevorzugt werden, da sie es dem Content Browser ermöglicht, die Struktur der Suchanfrage zu erkennen und weitgehend zu analysieren. In hierarchisch strukturierten Filtern können field und operator auf einem übergeordneten Filter-Level spezifiziert werden.

Eine vollständige Filterdefinition könnte folgendermaßen aussehen:

scrivito.content_browser.filters =
 obj_class:
   field: '_obj_class'
    options:
      binary_resources:
        expanded: true,
        value: ['Pdf', 'Image']
        icon: 'image'
        options:
          images:
            selected: true
            title: 'Images'
            value: 'Image'
          pdf:
            title: 'PDFs'
            value: 'Pdf'
      other_resources:
        value: ['Contact', 'Location']
        options:
          contacts:
            title: 'Contacts'
            value: 'Contact'
          location:
            title: 'Locations'
            value: 'Location'


  image_size:
    title: 'Image Size'
    field: 'size'
    type: 'radio_button'
    expanded: true
    options:
      thumbnail:
        title: 'Thumbnail'
      content:
        title: 'Page'
      banner:
        title: 'Banner'


  languages:
    title: 'Languages'
    field: 'language'
    type: 'check_box'
    expanded: true
    options:
      en:
        title: 'English'
      fr:
        title: 'French'
      es:
        title: 'Spanish'

Diese Definition würde eine Liste von Filtern ergeben, wie sie in der linken Spalte auf dem Screenshot dargestellt wird.

Migration

Eine alte Filterdefinition zu migrieren ist einfach. Die alte Definition kann ohne Anpassungen zum option-Schlüsselwort der neuen Filtereinträge hinzugefügt werden. Wenn die icon-Option darin enthalten ist, muss gegebenenfalls der scrivito-content_browser-icon-Präfix entfernt werden. Beispiel:

# bisher

images:

  title: 'Images',
  query: scrivito.obj_where('_obj_class', 'equals', 'Image')
  icon: 'scrivito-content_browser-icon-image'

# jetzt
legacy:
  options:
    images:
      title: 'Images',
      query: scrivito.obj_where('_obj_class', 'equals', 'Image')
      icon: 'image'

Weitere destruktive Änderungen

  • Die Methode, mit der eine Kopie eines Widgets erstellt werden kann, wurde von clone in copy umbenannt, um das API synchron zu Obj#copy zu halten. Der Aufruf der Methode hat sich nicht geändert. Ein Widget, dessen ID widget_id ist, kann mit dem folgenden Code von der homepage zu einer sub_page kopiert werden:
    sub_page.update(widget_field: sub_page.widget_field + [homepage.widgets['widget_id'].copy])
  • Scrivito::BasicWidget#copy schließt nun die Felder des widget-Typs ein. Kopiert man also Widgets aus Widget-Feldern, umfasst dies auch die Widget-Felder, die das zu kopierende Widget enthält.
  • Die Scrivito::ObjsCollection-Klasse wurde in Scrivito::ObjCollection umbenannt, und die Scrivito::MembershipsCollection Klasse wurde in Scrivito::MembershipCollection umbenannt, um die Namensgebung über alle Collection-Klassen des SDKs konsistent zu machen.
  • Scrivito::ObjClass.all gibt nun eine Scrivito::ObjClassCollection zurück.
  • Das scrivito_reload JS-Event wird nicht mehr getriggert, und dieses Event wird zu Version 1.0.0 entfernt. Bitte nutzen Sie stattdessen die neue jQuery-Methode reload. Diese Änderung wurde vorgenommen, da das JS-Event zu mächtig war. Es verursachte häufig Probleme bei der Fehlerbehebung, da die Methode viele Seiteneffekte hat, die die neue Methode nicht mit sich bringt. Bitte ersetzen Sie alle $.trigger("scrivito_reload")-Aufrufe durch  $.scrivito("reload").
  • Bislang wurde der veröffentlichte Inhalt aktualisiert, nachdem das Promise, das von $.scrivito("save") zurückgegeben wurde, erfüllt war. Nun aktualisiert $.scrivito("save") den Inhalt sofort (auch, wenn das Promise noch nicht erfüllt wurde):
  • var scrivito_field = $('…');
    scrivito_field.scrivito('content');
    // > 'old content'
    scrivito_field.save('new content');
    
    // Saving…
    scrivito_field.scrivito('content');
    // > 'new content'
    
    // Finished saving.
    scrivito_field.scrivito('content');
    // > 'new content'

Neue Features und Verbesserungen

Widgets wiederherstellen

In den Ansichten „Alle Änderungen“ und „Gelöscht“ können über die Benutzerschnittstelle nun gelöschte Widgets wiederhergestellt werden.

Widget-Hierarchien kopieren

Wenn Widgets über die Benutzerschnittstelle kopiert werden, werden nun alle darin enthaltenen Widgets ebenfalls kopiert. Darüber hinaus umfasst Scrivito::BasicWidget#copy nun auch die Felder des widget-Typs, einschließlich aller darin enthaltenen Widgets.

Voreingestellte Objektklassen für Content-Typen registrieren

Wenn Inhalte über den Content Browser hochgeladen werden, muss eine Objektklasse, die dem Content-Typ entspricht, festgelegt werden. Zu diesem Zweck – und natürlich auch für applikationsspezifische Anwendungsfälle – bietet das SDK nun ein API, mit dem Standardobjektklassen für Content-Typen registriert werden können:

scrivito.register_default_obj_class_for_content_type(mapping)

Zur Registrierung übergibt man der Methode eine Zuordnung (mapping) aus Name-Wert-Paaren. Jedes Paar besteht aus einem Content-Typ-Schema als Name und einer Objektklasse als Wert. In den Content-Typ-Schemata können Platzhalter sowohl für den Dateityp als auch für den Content-Typ genutzt werden.

Initial beinhaltest das Scrivito SDK zwei Zuordnungen:

  • image/* -> 'Image'
  • */* -> 'Download'

Um die einem Content-Typ zugeordnete Objektklasse auszulesen, übergibt man der Methode den Content-Typ als String: scrivito.default_obj_class_for_content_type(content_type).

Beispiele:

scrivito.register_default_obj_class_for_content_type({
  'audio/mp3': 'MyMp3', // Register a default for all MP3s.
  'audio/*': 'MyAudio' // Register a default for all other audio files.
});

scrivito.register_default_obj_class_for_content_type({
  'image/*': 'MyImage', // Override factory default for image files.
  'image/png': 'MyPng', // Register default for PNG images.
  '*/*': 'MyDownload' // Override factory default for all other files.
});

scrivito.default_obj_class_for_content_type('image/png');
//> 'MyPng'
scrivito.default_obj_class_for_content_type('image/gif');
//> 'MyImage'
scrivito.default_obj_class_for_content_type('audio/wav');
//> 'MyAudio'
scrivito.default_obj_class_for_content_type('spam/eggs');
//> 'MyDownload'

Darüber hinaus wurde das Download-Model zum install-Generator hinzugefügt. Um das neue Model zu einer bestehenden Applikation hinzuzufügen, rufen Sie bitte den Generator erneut auf: rails g scrivito:install

Editor für Binärattribute

Das Scrivito Editors Gem enthält nun einen Editor für die Bearbeitung von binary-Attributen. Redakteuren zu ermöglichen, Attribute dieses Typs zu bearbeiten oder deren Inhalt auszutauschen, ist damit genauso einfach, wie einen scrivito_tag oder einen scrivito_image_tag-Aufruf zum Markup hinzuzufügen. Redakteure können nun per Drag-and-Drop die dafür vorgesehenen binary-Elemente einer Seite befüllen; der Inhalt wird dann vom CMS gespeichert. 

Voreingestellt können binäre Dateien nur ausgetauscht und nicht gelöscht werden. Sie können es Redakteuren jedoch ermöglichen, binary-Daten zu löschen, indem Sie eine data-scrivito-editors-allow-delete-Option zu dem betreffenden scrivito_tag-Aufruf hinzufügen. Dadurch kann der Redakteur den binary-Inhalt per Klick auf einen Button entfernen.

Weitere Verbesserungen

  • Das Scrivito-Editors-Gem wird nun mit dem neuesten Redactor-HTML-Editor in der Version 10 ausgeliefert. Bei Redactor-Fehlern wie „no such method“ in der JavaScript Konsole sollten Sie prüfen, ob noch veraltete Kopien des HTML-Editors im Assests-Ordner der Applikation liegen. Diese Kopien können erstellt worden sein, um das Verhalten des HTML-Editors zu modifizieren. Bitte löschen Sie die alten Assets und schauen Sie dich die neue Konfiguration an: scrivito.editors.html_editor.redactor.options.

  • Optionen für den Redactor können nun über ein neues JavaScript-API global gesetzt werden:

    //Beispiel: den HTML-Quellcode-Button bei HTML-Feldern verbergen:
    scrivito.editors.html_editor.redactor.options = { buttonSource: false }

  • Man kann auf ein Widget eines CMS-Objekts über die ID des Widgets zugreifen. Dies gilt auch für Widgets, die in Widgets enthalten sind. Wenn Sie beispielsweise ein Objekt obj haben und auf dessen Widget mit der ID widget_id zugreifen möchten, können Sie den folgenden Code verwenden:

    obj.widgets['widget_id']

  • Die Initialisierung von Bibliotheken, die mit Scrivito genutzt werden, machte es häufig erforderlich, Code zu duplizieren. Die Bibliothek musste initialisiert werden, wenn der DOM für Website-Besucher bereit war. Zudem musste Scrivitos content-Callback aufgerufen werden, nachdem der Inhalt von Redakteuren geändert worden war. Dies ist nicht mehr notwendig, da der Code für die Initialisierung dem content-Callback übergeben werden kann. Der Callback wird getriggert, wenn der DOM bereit ist, unabhängig davon, ob die In-place-Berarbeitung aktiviert ist, oder nicht. Dies hält den Code sauber und DRY. Das API des Callbacks bleibt gleich:

    scrivito.on('content', function(root_element) {   
      /* root_element will either be window.document or the widget that was changed */
      });

  • Die content-Methode des JavaScript-SDKs unterstützt nun date-Attribute. Dadurch ist es möglich, JavaScript Date-Objekte für date-Felder abzurufen. Beispiel:

    <%= scrivito_tag :div, @obj, :my_date, id: 'my-date-attribute' %>
    Wenn Sie obigen Code verwenden, um ein Datum zu rendern, können Sie auf das Date-Objekt folgendermaßen zugreifen:
    $('#my-date-attribute').scrivito('content')
    Diese Feature wird vom Date-Editor genutzt, um Fehler im Zusammenhang mit der Lokalisierung von Datumsangaben durch Rails zu verhindern.

  • Über das Javascript Search API können Anfragen nun mit der neuen Methode and kombiniert werden. Sie fügt alle Eigenschaften der zweiten Anfrage zu der ersten hinzu. Andere Query-Eigenschaften wie batch_size oder order werden nicht geändert, wenn eine Query hinzugefügt wird. Beispiel:

    var blog_posts = scrivito.obj_where('_obj_class', 'equals', 'BlogPost'); 
    var only_english = scrivito.obj_where('language', 'equals', 'en');  
    blog_posts.and(only_english);
    Dieses Beispiel ändert die Query zum Auffinden von BlogPosts so, dass nur englischsprachige Posts zurückgegeben werden, indem only_english zur Query hinzugefügt wird.

  • Der Widget-Generator erzwingt nun konsistente Widget-Namen, die jetzt auf Widget enden müssen. Beispielsweise generiert sowohl rails g scrivito:widget Headline als auch rails g scrivito:widget HeadlineWidget ein Widget mit dem Namen HeadlineWidget (headline_widget.rb).

  • Bisher verhinderte ein Bug in Rails (http://git.io/Gzo13Q), dass lange Queries sauber gecacht werden. Das SDK liefert nun einen Workaround für dieses Problem.

  • Das Scrivito-Editors-Gem verursacht keine JavaScript-Fehler mehr für enum oder multienum Felder, die mittels scrivito_tag gerendert werden.
  • Der Date-Editor lässt die Zeitangabe während des Editierens bestehen.

  • Der Date-Editor speichert seinen Inhalt nun, ohne NaN-Fehler in Safari und Firefox zu produzieren.

  • In Google Chrome führt das Verlassen des Text-Editors nicht mehr zum Verlust von Zeilenumbrüchen.

  • Das Markup wird nicht mehr geändert, wenn der Text-Editor geschlossen wird, ohne Änderungen vorgenommen zu haben. HTML, das in Scrivito importiert wird, wird neu formatiert, wenn es bearbeitet wird (beispielsweise werden Tags in Kleinbuchstaben umgewandelt). Dadurch ergaben sich Änderungen in der „Änderungen“-Ansicht auch dann, wenn keine Änderungen vorgenommen wurden.

  • Wenn möglich, erscheint die Einfügemarke nun an der Stelle, an der man geklickt hat. Wird allerdings komplexer HTML-Text gerendert (beispielsweise wenn ein Block an scrivito_tag übergeben wird), erscheint der Cursor am Ende des Bereichs.

  • Ein CSS-Problem, durch das Teile des Footers nicht sichtbar waren, wurde behoben.

  • Das Download-Model wurde zum install-Generator hinzugefügt.

  • Öffnet man eine Seite als authentifizierter Benutzer und wird dann zum Scrivito-UI weitergeleitet, bleibt der gegebenenfalls angegebene Anker erhalten.

  • Ein Problem mit dem Aufruf von $.scrivito('reload') im Details-Dialog wurde behoben.

  • Ein Problem bei der Darstellung des UI auf Seiten, die nicht das Scrivito UI enthalten, wurde behoben (beispielsweise statische Seiten und Fehlerseiten, die von Rails generiert werden).

  • Ein Problem beim Speichern von Links und Linklisten über das Javascript-API wurde behoben.

  • Ein Problem wurde gelöst, bei dem das UI auch nach der Abmeldung noch sichtbar war.

  • In der „migration working copy“ (rtc) können Änderungen an Widgets nicht mehr verworfen werden.