Archive for the ‘Plugin Review’ Category

Plugin: “Micro-CMS” mit comatose

Donnerstag, April 3rd, 2008

Jede Webanwendung benötigt eigentlich ein Content-Management-System (CMS). Es gibt immer Unterseiten wie das Impressum, die AGBs oder Hilfetexte, deren Inhalt man ab und zu aktualisieren muss. Diese Texte statisch im entsprechenden View einzubinden ist schlechter Stil und erschwert die Wartung.

comatose ist ein Plugin, welches ein kleines CMS implementiert. Man kann Texte in der Datenbank ablegen und darauf mit render zugreifen, als ob man ein Partial rendern würde. Das Plugin erzeugt auch gleich das Backend zum verändern der Texte und liefert hilfreiche Rake-Tasks zum synchronisieren des Contents zwischen Development und Production-Umgebung mit.

Installation

Die Installation läuft nicht besonders anders ab als bei anderen Plugins auch. Der aktuelle Code des Comatose-Projekts ist von Rubyforge zu Google-Code umgezogen. Man installiert es aus den aktuellen Quellen mit

ruby script/plugin install http://comatose-plugin.googlecode.com/svn/trunk/comatose

Der Installationsprozess schließt mit dem Hinweis, was als nächstes zu tun ist:

ruby script/generate comatose_migration

um eine Migration zu erzeugen, die die Tabellen für das CMS initialisiert. Diese muss anschließend mit

rake db:migrate

ausgeführt werden.
Fast geschafft! Jetzt noch in der routes.rb folgende Zeilen hinzufügen (comatose_root muss in die letzte Zeile der routes.rb):

map.comatose_admin
map.comatose_root ''

Falls eine URL aufgerufen wird, die von keiner anderen Route erkannt wurde (z.B. www.beispiel.de/impressum) greift die comatose_root-Route und sucht die Comatose-Seite mit dem Namen “Impressum” heraus und zeigt sie an.

Achtung! Damit die Einträge in der routes.rb so funktionieren, muss unbedingt (auch in Development-Umgebung) der Server neu gestartet werden. Für Rails 2.0+ muss außerdem (vor Serverneustart) die Plugins acts_as_list und acts_as_tree installiert werden (ruby script/plugin install acts_as_list), andernfalls schlägt man sich mit Meldungen wie

undefined method `acts_as_tree' for #<Class:0x376faf4>

herum.

Sinnvolle Konfiguration

In der environment.rb sollte unbedingt folgender Konfigurations-Block eingefügt werden:

Comatose.configure do |config|
config.helpers << ApplicationHelper  # Falls das restful_authentication-Plugin benutzt wird
# wird der Autor einer CMS-Seite anhand des Usernamens gespeichert.
config.admin_includes << :authenticated_system
config.admin_get_author do
current_user.login
end  # Application-Helper im comatose-Controller verfügbar machen
config.helpers << ApplicationHelper

# Falls restful_authentication-Plugin benutzt wird,

# kann so der Zugriff auf das CMS auf angemeldete Benutzer beschränkt werden  config.includes << :authenticated_system
config.authorization        = Proc.new { true }
config.admin_authorization  = :login_required

# Fragment-Caching erstmal ausschalten.

config.disable_caching = true

end

Das wichtigste ist natürlich, den Zugriff auf den Admin-Bereich einzuschränken, da ansonsten jeder Besucher der Website den Inhalt verändern kann! :login_required ist eine Methode des restful_authentication-Plugins und sollte je nach Seite mit einer eigenen Methode ergänzt werden, die nur Admin-User erlaubt.

Zweiter wichtiger Punkt ist das abschalten des Fragment-Cachings. In der Production-Umgebung ist es sonst aktiviert, funktioniert aber nicht richtig- beim Fragment-Caching speichert Rails die Ausgabe von Partials, wozu aber erstmal ein geeigneter Speicherplatz organisiert werden muss (/tmp-Ordner, etc.). Zum ausprobieren des Plugins ist es daher sinnvoll diese Funktion abzuschalten. (Tuning-Maßnahmen wie Caching erschweren das Debugging und sollten erst eingebaut werden, wenn die Performance wirklich am Limit ist).

Neustart des Servers nicht vergessen- und schon kann es losgehen.

Benutzung

Unter der URL /comatose_admin ist jetzt die Admin-Oberfläche des CMS verfügbar. Die Benutzung sollte eigentlich selbsterklärend sein. Artikel können geschachtelt in einer Baumstruktur angelegt werden. Der Zugriff auf die einzelnen Artikel erfolgt über den Titel bzw. den Pfad der Titel. Für die Ausgabe stehen verschiedene Parser zur Verfügung, so dass man der Inhalt nicht unbedingt HTML sein muss. RedCloth ermöglicht z.B. das formatieren von Fettdruck, Überschriften usw. ohne HTML-Tags.

Um eine Seite aus dem Comatose-CMS anzuzeigen, kann man innerhalb der Template einfach

<%= render :comatose=> 'pfad/name' %>

aufrufen, wobei Pfad die Namen aller übergeordneten Seiten und Seite der Name der anzuzeigenden Seite ist (getrennt durch “/”).

Wärend die Anzeige über render für Textbausteine innerhalb einer Seite gedacht ist, können Comatose-Seiten auch einzeln angezeigt werden. Durch die Angabe von

map.comatose_root ''

in der letzten Zeile von route.rb haben wir ja schon eine Default-Route auf Comatose gesetzt. D.h. wenn die URL von keiner der anderen Routen verarbeitet werden kann, wird sie als Comatose-Pfadangabe behandelt. Die Idee scheint logisch, in der Praxis habe ich das aber nicht zum laufen bekommen. Zunächst mal wird bei diesen Seiten nicht das Default-Layout benutzt, was man aber durch die zusätzliche Angabe von :layout => ‘application’ ändern kann. Das zweite Problem ist, dass die View-Helper nicht geladen werden. Ich verwende beispielsweise einige Helper um Menüs (Tabs, etc.) darzustellen, was bei einer Comatose-Seite nicht funktioniert.

Aus Kommentaren des Comatose-Wiki habe ich den Trick, die Helperklassen per confg.include zuzuweisen (siehe Konfigurationsabschnitt oben), was aber bei mir aber nicht funktioniert hat.

Letztendlich habe ich einfach eine spezielle “Page”-Action in einem Controller erzeugt, dessen Template nur

<%= render :comatose=> params[:path].join('/') %>

enthält. Der letzte Eintrag in der Routes.rb lautet dann

map.cms '*path', :controller => 'home', :action => 'page'

Die spezielle Anweisung *path enthält die URI-Bestandteile als Array (daher muss weiter oben per join(’/') wieder der ursprüngliche Pfad rekonstruiert werden).

Weitere Funktionen

Im Content der Seiten kann man auch auf Ruby-Variablen zugreifen. Das ist sehr praktisch um den Content anzupassen, z.B. durch aktuelle Statistiken, das Datum oder den Benutzernamen. Ähnlich wie bei einem Partial muss dabei die Variable dem Render-Aufruf übergeben werden, z.B. so:

<%= render :comatose=>'welcome', :locals=>{ :username=>'USERNAME' } %>

In der Content-Seite mit der Überschrift ‘welcome’ kann dann so auf die Variable zugegriffen werden:

Hallo {{ username }}!

Komplexere Anweisungen sind mit sogenannten “Drops” möglich: Einem Drop kann man Codeblöcke zuweisen, die dann innerhalb der Comatose-Seite aufgerufen werden können. Die Templatesprache von Comatose ermöglicht dabei auch for-in-Konstruktionen etc.
Weiteres dazu gibt aus auf den Wiki-Seiten des Comatose-Projekts

Bewertung

****. (4/5 Sternen)

Positiv: Nützliches Plugin, großer Funktionsumfang, elegante Einbindung in Rails (render :comatose, rake-Tasks)

Negativ: Für viele Anwendungen überdimensioniert, Benutzung von zahlreichen Plugins, die zusätzlich Speicher benötigen. Standard-Konfiguration läuft nicht fehlerfrei in Production-Umgebung (wenn Fragment-Caching nicht konfiguriert wurde).

Fazit

Es handelt sich um ein nützliches und sehr leistungsfähiges Plugin. Meine anfängliche Begeisterung hat sich aber gelegt, da für viele Seiten dieser immense Funktionsumfang nicht benötigt wird. Diese Komplexität führt zu einigen Fallstricken bei der Installation und Konfiguration, die das direkte Loslegen mit dem Plugin erschweren.

Viele Seiten kommen sicher ohne Versionsmanagement und Baumstrukturen der Seiten aus, so dass man sich die Verwendung von acts_as_tree und acts_as_versioned und somit wertvollen RAM sparen könnte. Auch werden mehrere Markup-Parser geladen (RedCloth, Liquid), die nicht jeder verwenden möchte.

Man sollte daher prüfen, ob alle Funktionen tatsächlich benötigt werden. Bei einigen meiner Projekte werden ich jedenfalls bei meiner eigenen, schlankeren CMS-Lösung bleiben.