Ruby on Rails ist ein Web Application Framework, das die technische Grundlage legt für Webanwendungen. Es besteht aus vielen hilfreichen Bausteinen, die Entwickler unterstützen, von der Gestaltung der Benutzeroberfläche bis hin zur Datenhaltung.
Ein CMS (= Content-Management-System) ist ein System zur Erstellung, Verwaltung und Darstellung von (Web)inhalten. CMS kommen meist als fertige Lösung mit unzähligen Features. Diese beziehen sich sowohl auf die Darstellung der Seite für den End-User als auch auf die Arbeit von Administratoren und Autoren. Über ein Plugin-System sind CMS meist flexibel erweiterbar.
Was, wenn ich beides gleichzeitig haben will, also eine individuell entwickelte Ruby on Rails Anwendung mit CMS-Funktionalität?
Wer ist der Master, das CMS oder die eigene Anwendung?
Es gibt einige CMS-Lösungen für Ruby on Rails. Die spannende Frage ist: wer ist am Ende der Chef im Ring? Habe ich am Ende ein CMS mit einer Art selbstentwickeltem Rails-Plugin oder eine selbst entwickelte Anwendung mit CMS-Funktionalität? Das CMS Refinery gehört beispielsweise zur ersten Gruppe. Gerade wenn der CMS-Teil eher einfach und klein ist und der Fokus mehr auf der individuellen Entwicklung liegt, ist diese Lösung nicht optimal. Daher möchte ich einen Blick auf ComfortableMexicanSofa werfen. Mit ComfortableMexicanSofa schreibe ich eine ganz normale Ruby on Rails Anwendung und spreche die CMS-Funktionalität nur dort an, wo ich sie brauche.
Installation und Erstellen einer Startseite
Wer die nächsten Schritte selbst nachvollziehen möchte, muss folgende Voraussetzungen erfüllen:
- Fit sein auf der Kommandozeile
- Ruby muss installiert sein, ich empfehle rbenv als Ruby-Umgebung
- Das Kommando rails muss verfügbar sein. Das geht über gem install rails.
Zunächst erstelle ich eine neue Rails-Anwendung über
rails new mexisofa
Starte ich nun den Server (Kommando: rails s) erscheint der gewohnte Willkommensbildschirm.
Ich folge nun den ersten Schritten der Installationsanleitung
- ComfortableMexicanSofa in Gemfile einfügen: gem 'comfortable_mexican_sofa'
- Bibliotheken installieren über bundle install
- CMS-Funktionalität installieren über rails generate comfy:cms
- Datenbank migrieren über rake db:migrate
Nachdem ich den lokalen Server erneut gestartet habe und http://localhost:3000/ aufrufe, erscheint nun eine Fehlermeldung.
Rails hat gemerkt, dass nun Routen bestehen und der Startbildschirm ist uns nicht mehr gegönnt. Der Root-Pfad ist weder definiert, noch ist eine CMS-Seite mit diesem Pfad vorhanden. Letzteres werde ich nun ändern. Das Backend von ComfortableMexicanSofa ist aufrufbar über http://localhost:3000/admin/ (Login: "username" und "password"). Zunächst werde ich gebeten eine Site anzulegen. CMS-Seiten befinden sich innerhalb einer Site, so dass mindestens eine Site bestehen muss. Mehrere Sites können sinnvoll sein bei mehrsprachigen Webseiten. Mehr zu Sites ist hier beschrieben.
Ich lege die Site "Default" an
Als nächstes erstelle ich ein einfaches Layout. Auch dieses nenne ich "Default". Ich übernehme die voreingestellten Eigenschaften.
Jetzt fehlt nur noch eine Seite.
Zugegeben, das Ergebnis ist noch ausbaufähig, aber es erscheint nun unter http://localhost:3000/ der eingegebene Text.
App-Layout nutzen
Ein Blick in den Source-Code verrät allerdings, dass der Inhalt gar kein HTML ist.
Hier gibt es zwei Möglichkeiten: Entweder man verwendet als Content des Layouts den vollständigen Rahmen-HTML-Code (inkl. html, head, body etc.) oder man greift auf das von Rails generierte Application-Layout (/app/views/layouts/application.html.erb) zurück. Alle Layouts werden in einem Dropdown auf der Bearbeitungsseite des Layouts angeboten.
Ich setze das Layout auf application. Die Startseite hat sich dadurch optisch kaum verändert, wohl aber der Quellcode.
Der Vorteil eines App-Layout ist, dass er Teil der Codebasis ist und damit komfortabel mit der eigenen IDE bearbeitet werden kann.
Eigene Content-Felder
Beim Erstellen der Seite habe ich ein Feld "Content" befüllt. Content ist in vielen CMS der Begriff für den Hauptinhalt. Hier nicht. Durch die Übernahme der Voreinstellungen habe ich das Feld quasi selbst erstellt. Im Layout habe ich den Ausdruck
{{ cms:page:content:rich_text }}
verwendet. Dieses sogenannte Tag (mehr zu den verfügbaren Tags wird hier beschrieben) enthält den Teil "content". Verwende ich hier andere Begriffe, verändert sich auch die Bearbeitungsmaske meiner Seiten. Ich kann sogar Datentypen für meine Felder definieren.
Die Bearbeitungsmaske enthält nun die neuen Felder. Es gibt kein "Content"-Feld mehr.
Mit diesem Konzept ermöglicht es ComfortableMexicanSofa, sehr spezifisch Inhalte zu definieren. Statt eines großen Inhaltsblocks, wie z.B. in WordPress, gibt es selbst festgelegte Bausteine, die per Layout zu einer Seite zusammengesetzt werden.
Parent Layout und Child Layouts
Mit dem Konzept von Parent- und Child-Layouts lassen sich Layouts spezialisieren. Im Parent-Layout sind dann diejenigen Informationen enthalten, die für alle Child-Layouts gelten, z.B. ein Logo im Kopfbereich, im Child-Layout nur die spezifischen Dinge.
Voraussetzung für die Parent-Child-Beziehung ist die Verwendung des "content"-Bausteins. Am Beispiel eines 2-Spalten-Layouts zeige ich, wie es funktioniert. Im "Default"-Layout füge ich ein H1-Überschrift hinzu sowie ein umgebendes div-Tag.
Das neue Template "2 Columns" besteht aus zwei Bootstrap-Spalten und verweist auf das Default-Template. Das App Layout wird nicht vererbt, es muss explizit gesetzt werden.
Wenn ich nun eine neue Seite anlege und das "2 Columns"-Layout auswähle, bekomme ich Felder aus beiden Layouts: Heading, Column 1 und Column 2.
Das HTML enthält die Inhalte beider Layouts und der Seite und sieht nun so aus:
Parent Pages und Child Pages
Child Pages unterscheiden sich vom Parent-Child-Konzept der Layouts. Die Parent-Child-Beziehung von Seiten ist verantwortlich für die Zusammensetzung von URLs. Die URLs von Child Pages setzen sich aus der URL der Parent-Seite, einem Slash und dem eigenen Slug zusammen, z.B. http://localhost:3000/sitzmoebel/sofas/mexiko für eine Seite Mexiko mit Parent Sofas, die wiederum einen Parent Sitzmöbel hat.
CSS und JavaScript
Beim Anlegen von Layouts stolpert man über die beiden Felder Stylesheet und Javascript. Wenn man hier etwas einträgt, passiert allerdings erst einmal nichts. Erst wenn man die CSS- und JavaScript-Assets einbindet, haben diese Felder einen Effekt.
Die CSS-Datei habe ich über den Ausdruck {{ cms:asset:default:css:html_tag }} angesprochen. Die CSS-Datei wird nun als Asset-Datei via link-Tag eingebunden. Dass das mitten im Body passiert ist nicht ganz sauber. Hier ist entweder der head-Bereich des App-Template anzupassen oder der head-Bereich muss im CMS definiert werden.
Snippets
Snippets sind wiederverwendbare Code-Schnipsel.
Diese könnten per Tag an beliebiger Stelle in Layouts und Pages eingebunden werden.
Das Snippet erscheint nun mehrfach in der Ausgabe.
Dateien
ComfortableMexicanSofa verfügt über eine einfache Medienbibliothek. Bilder werden nicht in verschiedene Formate kleingerechnet wie in anderen CMS.
Versionsverwaltung
Ein weiteres Feature von ComfortableMexicanSofa ist eine Versionsverwaltung. Layouts, Pages und Snippets sind versioniert und ältere Stände können verglichen und wiederhergestellt werden.
ComfortableMexicanSofa kombiniert mit individueller Softwareentwicklung
Die Anwendung, die ComfortableMexicanSofa nutzt, ist primär eine Ruby on Rails Anwendung, mit allem was dazugehört, z.B. Routen, Controller, Datenhaltung usw. In Kombination mit ComfortableMexicanSofa entsteht eine interessante Lösung, denn die Anwendung lässt sich aufteilen in einen Code-lastigen Part, der von einem Softwareentwickler erstellt wird, und einem Text- und Bild-lastigen Part, der von jemand Fachlichem gepflegt werden kann, z.B. jemand aus dem Marketing-Bereich.
Ein Beispiel soll das Zusammenspiel zwischen eigenem Code und CMS verdeutlichen. Ich lege einen HomeController an mit drei Methoden, die über entsprechende Routen angesprochen werden können.
routes.rb
Rails.application.routes.draw do root 'home#index' post '/increase_number', to: 'home#increase_number' post '/decrease_number', to: 'home#decrease_number' ... end
/app/controllers/home_controller.rb
class HomeController < ApplicationController def index @number = session['number'] || 0 render :cms_page => '/' end def increase_number session['number'] = (session['number'] || 0) + 1 redirect_to root_path end def decrease_number session['number'] = (session['number'] || 0) - 1 redirect_to root_path end end
Für die index-Methode gibt es keine erb-Seite im Code. Stattdessen wird die Home-Seite des CMS referenziert.
Im CMS wiederum spreche ich nun den Programmcode an. Das tue ich über ein Partial.
Das Partial definiere ich im Code unter /app/views/home/_number.html.erb:
<p>Number: <%= @number %></p> <p><%= button_to "Increase", action: "increase_number" %></p> <p><%= button_to "Decrease", action: "decrease_number" %></p>
Das Ergebnis ist eine Kombination aus CMS und Programmlogik.
Es gibt zahlreiche weitere Möglichkeiten, wie eigener Code und CMS kombiniert werden können. Mehr über den Zugriff auf das CMS aus dem eigenen Code gibt es hier.
Fazit
Die Kombination aus Ruby on Rails und dem CMS ComfortableMexicanSofa ist eine sehr interessante Lösung, gerade wenn die eigene Anwendung aus Individualentwicklung und einfachem Web-Content besteht. Die Tatsache, dass das Ergebnis eine Rails-Anwendung ist und der eigene Programmcode sich nicht für ein CMS verbiegen muss, gefällt mir sehr.
ComfortableMexicanSofa ist sehr gut dokumentiert. Das Wiki enthält zahlreiche Dokumente. Außerdem gibt es erste Plugins, die den Funktionsumfang erweitern.
Lust auf mehr? Als Experte für Individualentwicklung mit Ruby on Rails kann ich Sie in Ihren Projekten unterstützen. Melden Sie sich gerne bei mir.
Hinterlassen Sie einen Kommentar