MODx Revolution: mehrere Websites aus einer einzigen Installation heraus betreiben

Veröffentlicht am 5. August 2010

Ich werkele regelmäßig für eine Agentur, deren Kunde ganze Breitseiten an Öffentlichkeitsarbeit in die Welt hinauspumpt. Dafür reicht natürlich eine einzige Website nicht, sondern da wollen gleich ganze Netzwerke befüllt werden. Da aber jeweils die gleichen Redakteure an den Seiten arbeiten, wäre es natürlich schön und effizient, wenn die Verwaltung dieses ganzen Netzwerks über ein gemeinsames Interface möglich wäre. Mit MODx Revolution ist die Umsetzung von so etwas zum Glück geradezu trivial.

Schritt 1: Kontext anlegen

MODx Revolution bietet die Möglichkeit, Sets von Systemeinstellungen anzulegen, die die eigentlichen Systemeinstellungen punktuell überschreiben. Das ist für uns wichtig, weil die verschiedenen Websites unterschiedliche Titel haben sollen und unter unterschiedlichen Domains laufen, sich also in einigen wenigen Dingen von der Grundkonfiguration unterscheiden. Ein solches Set von abweichenden Systemeinstellungen heißt in MODx „Kontext“ und kann unter System → Kontexte angelegt werden. Die zu dort einzutragenden Einstellungen sind für eine eigene Seite in der Regel mindestens die folgenden:

  • site_start und base_url: Startseite und Basis-Adresse
  • site_name: Titel der Seite
  • http_host und base_url: Host und Pfad der jeweiligen Seite

Dazu ist es ratsam, auch für angepasste Fehlerseiten u.Ä. zu sorgen, wobei die Keys dieser Einstellungen einfach aus den Systemsettings ermittelt werden können. Und das ist auch schon alles, was man im MODx-Manager selbst einrichten muss. Der neue Kontext sollte im links im Ressourcenbaum erscheinen und kann bereits mit Seiten befüllt werden.

Schritt 2: Dateien und Domains

Nun ist noch dafür zu sorgen, dass der neu angelegte Kontext beim Aufruf über die neue Domain auch verwendet wird. Das wird mit einem ganz simplen Hack gemacht: einfach die Dateien config.core.php, index.php und .htaccess aus dem Modx-Hauptverzeichnis in ein eigenes Unterverzeichnis kopieren und die Domain oder Subdomain der neuen Seite auf dieses Verzeichnis zeigen lassen. Dann die index.php öffnen und gegen Ende der Datei eine Zeile finden, die so oder ähnlich aussieht:

$modx->initialize('web');

Das, was hier als Parameter an initialize() übergeben wird, ist der Name des zu verwendenden Kontexts – standardmäßig web. Das tauschen wir einfach gegen den Namen unseres neuen Kontexts aus … und das war es dann auch schon! Nochmal zusammengefasst:

  1. Ein Set von abweichenden Systemeinstellungen für die neue Seite anlegen
  2. Drei Dateien kopieren und eine Zeile anpassen, damit die neuen Einstellungen verwendet werden

Ruft man jetzt die Domain der neuen Seite auf (die in das neue Verzeichnis mit den kopierten Dateien zeigt), wird der gewünschte Kontext initalisiert – mit all seinen Einstellungen, Ressourcen und Rechten für Redakteure.

Fertig!

Natürlich braucht es im Detail noch hier und da ein paar Feinjustierungen, aber prinzipiell sind diese beiden Schritte alles, was man machen muss, um mehrere Websites mit einer einzigen MODx-Installation zu betreiben. Nutzen kann das man dies nicht nur für größere Netzwerke, sondern zum Beispiel auch für verschiedene Sprachversionen einer Seite. Mit dem Rechtesystem ist es auch möglich, bestimmte Redakteure nur bestimmte Kontext-Bereiche mit Seiten befüllen zu lassen.

Im übrigen: das gesamte Backend von MODx Revolution ist mit genau dieser Technik umgesetzt – wer es nicht glaubt, kann ja mal den Kontext-Key mgr unter die Lupe nehmen und nachsehen, welche drei Dateien denn da im Manager-Verzeichnis liegen.

Probleme, Lösungen und Tipps

Ein etwas ekliger Aspekt solcher Seiten ist das Kampf mit den URLs verlinkter Ressourcen (Bilder, PDFs etc) in Kombination mit einem WYSIWYG-Editor. Ich nehme zwar an, dass man das alles innerhalb von MODx konfigurieren kann, aber was auch nicht verkehrt ist, ist der Weg über Symlinks oder mod_rewrite – einfach für alle Domains eigene Ressourcenverzeichnisse simulieren, die nichts als Verweise oder Redirects auf einen großen gemeinsames Ressourcenpool sind. Lieber zwei Zeilen in die .htaccess schreiben als groß in der Konfiguration herumfummeln!

Als weiteres praktisch-billiges Tool hat sich dieses Gib-Text-anhängig-vom-aktiven-Kontext-aus-Snippet erwiesen:

$contextkey = $modx->resource->_contextKey;
$contexts = array('foo-de', 'foo-en', 'bar-de', 'bar-en');
foreach($contexts as $context){
    if($context == $contextkey && !empty(${$context})){
        return ${$context};
    }
}

Damit kann man in Templates und Chunks flexibel Textbrocken ja nach aktiver Seite und/oder Sprache ausgeben, einfach indem man z.B. aufruft. Dererlei geht zwar auch über Lexicon-System von MODx, aber wenn es auch mal schnell und dreckig sein darf, reicht dieses Snippet.

Zum Abschluss noch drei allgemeine Tipps aus nun schon mehrmonatiger Erfahrung mit solchen Konstruktionen:

  1. Bei der Auswahl der Kontext-Keys bietet es sich an, sie so zu benennen, dass man die Namen in Snippets parsen kann und automatisch festellen lassen kann, zu beispielsweise welcher Seite oder Sprache ein Kontext gehört. Ich mag das Muster seite-sprache, also z.B. foo-de, foo-en, foo-pl, bar-de, bar-en und so weiter
  2. Baut kontext- und sprachagnostische Snippets. Der Aufwand für Ressourcen-Recycling innerhalb einer MODx-Installation liegt bei 0 – wenn man entsprechend geplant hat. Nicht vergessen dass es ja in Revo auch Platzhalter in Chunks gibt!
  3. Nutzt um Himmels Willen Kategorien um Ressourcen zu sortieren! Wenn man mehr als eine Seite in mehreren Sprachen betreiben sollte, ist das die einzige Chance den Durchblick zu bewahren.

Fragen zu HTML5 beantwortet

Veröffentlicht am 2. August 2010

Wenn ich Fragen zu HTML5 via E-Mail oder Twitter erreichen, ist es manchmal schade, dass einige sehr gute Fragen (nebst Antworten) der Allgemeinheit entgehen. Deshalb eröffne ich hier eine kleine Sammlung mit interessanten Fragen und meinen Antworten der letzten paar Wochen zum Buch und zu HTML5. Wenn es sich lohnt wird das eine kleine Artikelserie. Wer mehr Fragen hat: Nur raus damit, egal ob in die Kommentare oder per Mail oder anderweitig!

Warum HTML5?

Ich erkenne nicht so ganz den Vorteil von HTML5, abgesehen vielleicht von Video- und Canvas-Element. Warum sollte ich zu HTML5 migrieren?

Wenn dir HTML5 etwas überflüssig vorkommt, liegt das vermutlich daran, dass du an Websites denkst. Für Websites ist HTML5 aber nicht vorrangig gemacht, sondern für Webapplikationen. Für den neuen Firmenauftritt der Beispielmüller GmbH wird man vermutlich kein HTML5 brauchen (auch wenn es nicht schaden wird), wohl aber für Webapps, die Desktop-Anwendungen Konkurrenz machen sollen. HTML5 hieß nicht umsonst ursprünglich „Web Applications 1.0“. Für den Einsatz von HTML5 für Websites spricht neben den neuen semantischen Elementen und den neuen Features für Formulare vielleicht noch, dass die Syntax ein klein wenig einheitlicher und einfacher ist und Möglichkeiten zur Verkürzung bietet (sofern man denn auf so etwas steht). Man muss aber nicht migrieren – wenn man mit XHTML 1 oder HTML 4 alles machen kann was man möchte, kann man ruhigen Gewissens beim Altbewährten bleiben. Ich empfehle an dieser Stelle einfach mal einen Blick auf drei Dinge, für die man bereits jetzt mit HTML5 (im jedem Browser) anstellen kann.

Wann kommt das E-Book?

Wird es dein Buch auch als PDF oder ePub fürs iPad geben? Ständig eine Bibliothek in Papierform rumschleppen ist sehr lästig.

Ja, eine E-Book-Ausgabe (sowohl PDF als auch ePub) ist geplant und soll laut Verlag "in Kürze" (wann immer das auch genau sein mag) verfügbar sein. Ich werde es ankündigen wenn es soweit ist.

Welches Element für Fat Footers?

Sollte man sog. „Fat Footers“ (also Footer mit viel Inhalt, Linklisten o.Ä.) auch in eine <aside> packen? Oder in einen <footer>? Eine Blog-Sidebar und ein Fat Footer unterscheiden sich ja inhaltlich kaum.

Ein Footer gehört prinzipiell in ein <footer>-Element, denn genau dafür ist das Element da. Es ist laut Spezifikationen auch explizit für typische Fat-Footer-Inhalte freigegeben (...typically contains information about its section such as who wrote it, links to related documents, copyright data, and the like). Dabei ist das <aside>-Element durchaus ähnlich, allerdings muss man beachten, dass es Sectioning Content ist, sich also auf die Outline auswirkt. Möchte man, dass ein Footer ein eigener Seitenbereich ist? Wahrscheinlich in den meisten Fällen nicht.

Wie rotiere ich Elemente auf einer Canvas?

Wie kann ich in einem canvas mit mehreren Elementen ein einzelnes Element rotieren ohne dass die anderen mitrotieren? Bei meinen Versuchen mit context.rotate() rotiert immer der gesamte Inhalt. Habe schon daran gedacht alle Elemente auf einzelne canvas zu zeichnen und diese per z-index übereinanderzulegen aber ich hoffe, Sie können mir einen einfacheren Weg zeigen.

Die Sache ist ganz einfach: es gibt keine „Elemente“ auf einer Canvas. Eine Canvas ist nur eine Malfläche mit Pixeln und rotiert wird immer nur das unsichtbare Koordinatensystem, an dem die Pixel gezeichnet werden. Mein Vorschlag für das Problem:

  1. context.save()
  2. context.rotate()
  3. „rotiertes“ Element zeichnen
  4. context.restore()
  5. alle anderen Elemente zeichnen

So kommt nur das zu rotierende Element in den Genuss eines gedrehten Koordinatensystems, während alle anderen nach dem Aufruf von context.restore() wieder anhand eines normalen Koordinatensystems gezeichnet werden.

Weitere Fragen?

Eure Fragen zu HTML5 beantworte ich gerne! Einfach eine E-Mail schreiben oder Formspring bemühen und ein bisschen Geduld haben – falls ich gerade unterwegs bin, kann es mit Antwort manchmal etwas dauern, doch früher oder später schreibe ich garantiert zurück.

Hardware-Review: Logitech Wireless Presenter R400

Veröffentlicht am 30. Juli 2010

Logitech Wireless Presenter R400

Wer mir auf Twitter folgt, dem ist sicher nicht entgangen, dass ich diese Woche in München eine HTML5-Schulung gehalten habe. In Vorbereitung hierauf habe ich so manches gelesen und gekauft, unter anderem den Wireless Presenter R400 von Logitech. Dabei handelt es sich um eine Fernbedienung für Präsentationen mit eingebautem Laserpointer. Mein Fazit nach drei Tagen intensiver Dauer-Benutzung: Wer regelmäßig Slides an Leinwände wirft und dabei nicht vor seinem Computer festgenagelt sein will, muss so ein Teil haben.

Der 11cm lange Wireless Presenter R400 hat neben der Taste für den Laserpointer und einem kleinen An/Aus-Schalter an der Seite vier Tasten zur Steuerung von Präsentationen – Slide vor, Slide zurück, Abdunkeln und eine weitere Taste zum Starten der Präsentation. Hinzu kommt eine einfache Batterieanzeige. Der Anschluss an den Computer erfolgt über ein kleines USB-Modul, das im Presenter selbst verstaut wird und das keinerlei Installation bedarf. Mitgeliefert werden eine Bedienungsanleitung, zwei Batterien und eine schicke kleine Kunststofftasche mit Reißverschluss.

Die beigelegte Bedienungsanleitung ist freilich komplett überflüssig, da sich die Tasten selbst erklären und eine Installation wie gesagt nicht nötig ist. Die Reichweite von 15 Metern ist beachtlich und das Gerät liegt perfekt und rutschfest in der Hand, so dass man kreuz und quer durch den Raum toben und trotzdem immer seine Präsentation steuern kann. Sowohl unter Windows wie auch OS X und Linux funktioniert der Presenter ohne Mucken und erledigt zuverlässig seinen Job.

Logitech Wireless Presenter R400 (Detailansicht)

Mein einziger, winziger Kritikpunkt betrifft die Anordnung der Taste zum Abdunkeln, denn diese befindet sich genau unter der Taste für „Slide vor“. Ein Verwechseln der Tasten ist zwar aufgrund ihrer Formgebung ausgeschlossen (die Abdunkeln-Taste ist wesentlich kleiner und die „Slide vor“-Taste hat einen kleine Erhebung) und da die Tasten Vertiefungen haben, wird weitgehend verhindert, dass man abrutscht. Genau das ist mit aber im Eifer des Gefechts zwei mal passiert, was durchaus einer gewissen wurstfingerigkeit meiner Person anzulasten ist. Das Problem ist, dass bei diesem Abrutschen nach unten man dummerweise genau auf die Taste gerät, die durch ein Abdunkeln einen halben Totalschaden hervorruft. Vielleicht wäre es besser gewesen, an dieser Stelle die „Präsentation starten“ zu platzieren und diese so auszulegen, dass sie bei laufenden Präsentationen einfach nichts tut – so wäre ein versehentliches Abwürgen der Präsentation komplett ausgeschlossen.

Unterm Strich ist festzuhalten, dass wie gesagt der Logitech Wireless Presenter R400 ein Muss ist, wenn man öfter Slides an die Wand zu werfen gedenkt. Wer dererlei auch unter Zeitdruck machen muss, sollte vielleicht auch einen Blick auf die etwas kostenintensivere Deluxe-Variante R800 riskieren – hier ist neben verdoppelter Reichweite (wobei, wer braucht 30 Meter?) auch ein Display mit Timer geboten.

Warum Douglas Crockford HTML5 stoppen will (und warum das schwierig wird)

Veröffentlicht am 13. Juli 2010

We need to reset HTML5 and start over. Dieses Zitat von Douglas Crockford sollte in den vergangen Wochen an den meisten von uns ein- oder zweimal vorbeigescrollt sein. Egal ob auf Konferenzen oder im Interview, der Javascript-Altmeister wird nicht müde, zwar einige Ideen von HTML5 zu loben aber auch ganz klar zu sagen, dass es seiner Meinung nach ein Schritt in die falsche Richtung ist und eine Vollbremsung angebracht sei. Warum ist das so?

Das Problem, das HTML5 löst (nämlich dass bisherige Web-Technologien ein unzureichendes Rüstzeug für Webapps sind) ist laut Crockford nicht das Problem, das dem Web unter den Füßen brennt – vielmehr müsste Sicherheit die Top-Priorität genießen. Heutige Webbrowser machen es nämlich Übeltätern recht einfach: jedes Script, das auf einer Website läuft, darf alles – es darf Cookies setzen und auslesen, es darf die Website selbst verändern, es darf den User bitten sein Passwort einzugeben und vieles mehr. Sobald es einem Angreifer also irgendwie gelingt, einen <script>-Schnipsel irgendwo auf einer Website einzuschleusen (z.B. auf einer Profilseite in einem sozialen Netzwerk), kann er den Browser eines jeden Besuchers dieser Seite übernehmen. Das nennt man Cross-Site-Scripting (XSS).

XSS ist eine der größten Sicherheitslücken des Webs und gleichzeitig auch eins seiner besten Features, denn erst die umfassenden Privilegien für Scripts machen es möglich, Dinge wie Google-Maps, Facebook-Buttons und Flattr-Widgets mit zwei Zeilen HTML (besagten <script>-Schnipseln) einzubauen. Die Scripts dürfen die Seite selbst verändern um ihre Buttons und Bilder zu platzieren, was man ja Google, Facebook und Flattr durchaus gerne erlauben, Datendieben aber gerne untersagen würde. So einfach ist es aber nun eben nicht und HTML5 verändert an diesem Zustand nichts – im Gegenteil, Technologien wie Offline-Speicher eröffnen interessierten Kriminellen neue, attraktive Angriffsziele.

Douglas Crockford vertritt die Auffassung, dass Sicherheit wichtiger als neue HTML-Elemente sei. Seiner Ansicht nach gehört die HTML5-Entwicklung gestoppt bis ein besseres Sicherheitsmodell für den Browser erdacht und implementiert wurde. Danach sollen die Einzelteile von HTML5 Stück für Stück den neuen Sicherheitsvorgaben angepasst und re-implementiert werden. Alles andere verschlimmere nur die XSS-Problematik, die ohne Änderungen am Browser selbst nicht in den Griff zu kriegen sei.

Ich persönlich tu mich mit diesem Ansatz schwer, gleichwohl an der Diagnose, dass XSS ein Problem ist, natürlich nicht zu rütteln ist. Aber man muss auch sehen, dass dass das Kind HTML5 bereits in den Brunnen gefallen und auf dem Weg nach unten mindestens schon zum nervigen Teenager herangewachsen ist. Es ist schwer vorstellbar, dass da noch irgendeine Form von Reset möglich sein soll, zumal bekannt ist, wie lange es dauert, bis sich eine Technologie in wirklich allen Browsern auf breiter Front etabliert hat. Außerdem ist nicht zu vergessen, dass HTML5 ja selbst das Ergebnis eine geplanten Web-Resets, nämlich XHTML 2 ist – das Web ist eben nicht die Bühne für Resets oder Revolutionen, sondern viel mehr ein Ort der graduellen Veränderungsprozesse. Vor diesem Hintergrund habe ich so meine Probleme damit, We need to reset HTML5 and start over als einen ernst gemeinten, konstruktiven Vorschlag anzusehen. XSS reparieren, gerne – aber dafür HTML5 stoppen, das wird schon sehr schwierig.