Skip to content

Dokuwiki als "Multisite"-Installation

DokuWiki ist für mich derzeit und schon länger die generische Antwort auf die Frage nach einem Wiki, nicht nur für Dokumentationszwecke, und auch für die Frage nach einem (simplen) CMS.

Ich installiere DokuWiki dabei (wie die meisten Webapplikationen) nicht als Debian-Paket, sondern direkt vom Erzeuger; zum einen, weil ich gerne eine aktuelle Version habe, zum anderen, weil ich dann (wie bei anderen Webseiten) frei entscheiden kann, wo die Dateien liegen sollen - und das ist in der Regel nicht dort, wo Debian sie ablegen würde, insbesondere, wenn es mehr als einen Nutzer mit Webseiten geben soll - und nicht zuletzt, weil das trivial funktioniert. Das führt dazu, dass ich Updates von Hand durchführen muss, und das kann dann schon etwas nervig werden, wenn es mehrere Hosts und mehrere Wikis betrifft.

Daher überlege ich schon länger, wie ich - zumindest bei Installationen auf demselben Host - den Aufwand (und, natürlich, auch den Platzverbrauch) minimieren kann. Die offenkundige Lösung ist eine “Farm”- oder “Multisite”-Installation, bei der der Code nur einmal vorhanden ist, aber jedes Wiki seine eigenen Konfiguration und natürlich seinen eigenen Speicherplatz für Inhalte hat. DokuWiki unterstützt das prinzipiell, aber die nächste Frage ist ja immer, wie gut das auch tatsächlich funktioniert: stabil, flexibel und vor allem ohne krude Hacks.

Nachdem ich mich diese Woche damit beschäftigt habe, kann ich sagen: es funktioniert gut. Die Flexibilität bleibt erhalten, Hacks braucht man nicht, weil die aktuellen DokuWiki-Versionen eine “Multisite”-Installation unterstützen, und stabil wirkt es bisher auch.

Der offensichtliche Vorteil liegt darin, dass man für beliebig viele Wikis nur einmal den Code für das Wiki selbst - und den für Plugins und Templates - installieren, updaten und pflegen muss. Der offensichtliche Nachteil liegt darin, dass alle Plugins und Templates im “Master”-Wiki installiert werden müssen und in den einzelnen Wikis nicht nachinstalliert werden können, und dass sich alle Wikis in Unterverzeichnissen unter einem “Stammverzeichnis” befinden müssen, deren Namen identisch mit der URL des Wikis sind.

"Dokuwiki als "Multisite"-Installation" vollständig lesen

Blogs und Editoren

Wer ein Blog betreibt, kennt vermutlich die Frage danach, welcher Editor für die Einträge am sinnvollsten verwendet werden sollte.

Meine erste Blogengine, sunlog, bot meiner Erinnerung nach bloß ein Eingabefeld, in das man entweder HTML eingeben oder darauf setzen konnte, dass der ansonsten nicht weiter bearbeitete Text schon irgendwie ausgegeben werden würde.

Nach dem Umstieg auf Serendipity habe ich auch erst einmal den Standard-Editor verwendet, wozu braucht man schließlich WYSIWYG, wenn man HTML beherrscht? Das war auf die Dauer dann aber doch eher anstrengend: um jeden Absatz herum <p>...</p> schreiben, Hervorhebungen korrekt mit <strong>...</strong> einbauen, Links von Hand setzen … Das macht keinen wirklichen Spaß. Und der Einbau von Bildern ist von Hand auch eher eine Strafe als ein Vergnügen.

Also bin ich später auf den WYSIWYG-Editor von Serendipity gewechselt; ich glaube, ich habe sogar nacheinander verschiedene solche benutzt. So richtig zufrieden war ich damit aber auch nicht; das daraus generierte HTML erschien teilweise suboptimal, zwischendurch hatte das Gerät aufgrund irgendeiner (vermutlich von mir irrtümlich getroffenen) Einstellung die Neigung, alle Texte per <font>-Tag mit weißem Hintergrund zu hinterlegen und Spielereien dieser Art mehr. Außerdem war es so mit nicht unerheblichem Aufwand verbunden, Einträge in einem Texteditor vorzubereiten und später per copy & paste ins Blog zu übernehmen, bedurfte es dann doch eines zweiten Schrittes, in dem Formatierungen und Links hinzugefügt wurden, wie auch lx4r in einem vergleichbaren Blogbeitrag berichtet. Wenn ich stattdessen direkt im Editor schrieb, ereilte mich gerne ein Missgeschick wie “langen Blogeintrag geschrieben, abgeschickt, mittlerweile aber ausgeloggt” (worauf Serendipity den Beitrag üblicherweise hungrig verspeist und man ihn neu schreiben darf) oder, noch schlimmer, ich komme an eine Tastenkombination, die eine Browseraktion auslöst und dann den Browser den Text verschlucken lässt. Gut, dagegen hilft Lazarus, aber der wahre Jakob ist das trotzdem nicht, ganz abgesehen davon, dass man eben so nicht sinnvoll offline arbeiten (oder auch nur die Annehmlichkeiten eines guten Texteditors nutzen) kann.

Mit dem Relaunch des Blogs habe ich auch dafür eine Lösung gefunden: ich verwende den simplen Standardeditor von Serenditpity zusammen mit dem Markdown-Plugin. Wieder eine für mich sehr hilfreiche Anwendung von Markdown. Jetzt kann ich flüssig Texte schreiben, sie ggf. per copy & paste ins Blog übernehmen und muss mich nie wieder um seltsame Formatierungen kümmern. Passt. Das ist ein Workflow, der Spaß macht.

(Um zu verhindern, dass ältere Einträge durch das Markdown-Plugin zerhackt werden, kann man dieses Plugin für die älteren Einträge - jeweils einzeln pro Eintrag - deaktivieren. Jedenfalls dann, wenn man das Plugin “erweiterte Eigenschaften für Artikel” [serendipity_event_entryproperties] installiert hat. :-))

Geldsenke Amazon

Amazon habe ich als Buchladen kennengelernt, und früher habe ich dort auch (nur) Bücher gekauft. Dann ab und an auch mal Software, v.a. Spiele. Und DVDs. Und später dann Elektronikzeugs, und mittlerweile fast alles.

Das hat natürlich Folgen.

Wer das ungute Gefühl, dass Amazon für einen wesentlichen Teil des Ausgabenbudgets verantwortlich ist, einmal näher quantifizieren möchte, dem kann mit damazon.py geholfen werden.

(Wem - wie mir - pip install requests beautifulsoup4 nichts sagt, außer der Vermutung, dass es sich um entsprechende Bibliotheken handelt, die zunächst installiert werden müssen, dem hilft - wenn er nicht noch einen weiteren Paketmanager zusätzlich zu apt bzw. aptitude (Debian), cpan (Perl), gem (Ruby) und Co. auf dem System begrüßen möchte - unter Debian Wheezy auch die Eingabe von aptitude install python-requests python-bs4 weiter.)

Via @towo.

Markdown: HTML aus Text erzeugen

Der erste längere (Erläuterungs-)Text, den ich zur Veröffentlichung im Netz verfasst habe, war im September 1998 die Header-FAQ, deren erster Entwurf am 18.09.1998 in der Newsgroup de.admin.net-abuse.mail veröffentlicht wurde und die dann seit dem 15.10.1998 unter dem Titel “E-Mail-Header lesen und verstehen” dort über viele Jahre lang monatlich erschien.

Text- und HTML-Version

Natürlich sollte es zu der monatlich geposteten FAQ auch eine Web-Version geben, die bereits im Oktober entstanden war und deren URL im November 1998 das erste Mal in der FAQ genannt wurde. Und natürlich sollte diese Version auch mit allem Annehmlichkeiten, die HTML für Optik und Funktion bietet, also namentlich Formatierungen und Verlinkungen, ausgestattet sein. Das bedeutete dann umgekehrt aber auch, dass zwei völlig getrennte Versionen desselben Textes zu pflegen waren; insbesondere bei größeren Änderungen und Ergänzung keine wirklich gute Idee. Es musste also eine andere Lösung her: die eine Fassung sollte aus der anderen Fassung generiert werden, oder ggf. beide Fassungen aus demselben Rohtext.

HTML-Dokumente aus Textdokumenten erzeugen

Da mir das Usenet als Publikationsmedium (damals) deutlich näher lag, hatte ich zuerst den Gedanken, die Webseite - also das HTML-Dokument - zumindest im wesentlichen aus dem Textdokument der geposteten FAQ zu erzeugen. Bei entsprechenden Recherchen stieß ich dann auch auf das Tool AscToHTM, das genau diesem Zweck diente und sich auch insbesondere an FAQ-Autoren richtete. Eine Zeit lang habe ich damit auch gearbeitet (und das erzeuge HTML-Dokument dann quasi mit Header und Footer versehen, um es optisch und organisatorisch - Navigation! - in meine damalige Webseitenstruktur einzubinden), aber so wirklich überzeugend war das nicht. Es bedurfte einiger Kompromisse im Layout des geposteten Textes, um die HTML-Generierung überzeugend hinzubekommen, und der Aufwand war doch vergleichsweise groß.

Textdokumente aus HTML-Dokumenten erzeugen

Daher habe ich mich - theoretisch im übrigen völlig richtig - in der Folge davon überzeugen lassen, dass die Vorgehensweise, aus (letztlich) unstrukturiertem Text strukturierten Text (mit Markup) zu erzeugen, bereits gedanklich verfehlt ist und keinen dauerhaften Erfolg haben könne: HTML enthält gegenüber text/plain zusätzlichen Informationsgehalt, Struktur, Markup eben, und aus der Gestaltung des Rohtextes das Markup zu “erraten”, ist keine brauchbare Lösung. Daher bin ich danach dann eben den umgekehrten Weg gegangen und habe beschlossen, dass nunmehr die Webversion der FAQ das “Master-Dokument” (oder die Quelle) sein sollte und ich den geposteten Text daraus erzeuge. Information und optische Gestaltung zu kürzen sollte ja vergleichsweise trivial sein. — Ganz so war es dann erwartungsgemäß doch nicht, denn auch der gepostete “reine” Text sollte ja einigermaßen apart formatiert sein, mit dem was, man an “Formatierungen” in E-Mail und Usenet so gewohnt ist: Zitate eingeleitet mit “|” am Zeilenfang, Hervorhebungen und Betonungen durch *Sternchen* o.ä. und dieser Dinge mehr. Für den Anfang half dazu html2text, damals in C++ geschrieben, mittlerweile durch den verstorbenen Aaron Swartz auch in PYthon reimplementiert, aber ganz zufrieden war ich mit dem Output noch nicht.

Einiges Experimentieren führte dann zu dem folgenden Workflow:

  1. wget http://th-h.de/faq/$1 -O output.html
  2. html2text -nobs -width 70 -rcfile html2text.rc output.html > output.txt
  3. ./wrap.pl &lt; output.txt > wrapped.txt

Und wrap.pl, das (daher der Name) vor allem für den Umbruch auf 70 Zeichen pro Zeile unter Beachtung von (nicht zu umbrechenden Zitaten) zuständig war, sah folgendermaßen aus:

  1. #!/usr/bin/perl</p>
  2.  
  3. <p>use Text::Wrap qw(&amp;wrap $columns);
  4. $columns = 70;</p>
  5.  
  6. <p>while (&lt;>) {
  7.  if (/[-\/]$/) {
  8.   ($zeile, $rest) = /(.+\s)(\S+)$/;
  9.   print &#8220;$zeile\n&#8221;;
  10.   JOINLOOP: while (&lt;>) {
  11.    $rest .= $_;
  12.    last JOINLOOP if (/^$/);
  13.   }
  14.   $rest =~ s/\n/ /g;
  15.   $_ = wrap(&#8221;, &#8221;, $rest).&#8221;\n&#8221;;
  16.  };
  17. print $_;
  18.  if (/^[|>:]/) {
  19.   QUOTELOOP: while (&lt;>) {
  20.    chomp;
  21.    if (/^$/) {
  22.     print &#8220;\n&#8221;;
  23.     last QUOTELOOP;
  24.    } elsif (/^[|>:]/) {
  25.     print &#8220;\n$<em>&#8221;;
  26.    } else {
  27.     print $</em>;
  28.    }
  29.   };
  30.  };
  31.  print &#8220;\n&#8221;;
  32. };

Das ließ sich jetzt durchaus automatisieren; andererseits gefiel es mir nicht wirklich, dass die Quelle des Textes nun ein HTML-Dokument war und ich erst längere Konversionsprozesse laufen lassen musste, um zu überprüfen, ob auch die (aus meiner Sicht immer noch primäre) Textfassung ordentlich aussah. Und HTML schreiben ist auch deutlich aufwendiger als “Klartext”, selbst wenn man sich durch geeignete Editoren beim Einfügen der passenden Tags (und deren Schließen!) unterstützen lässt.

Die Lösung?

Am Ende habe ich, glaube ich, einfach wieder beide Texte getrennt gepflegt oder, wahrscheinlicher, die FAQ (erst einige Zeit nicht mehr richtig aktualisiert und dann) gar nicht mehr gepostet; sowohl das Spam-Problem (jedenfalls der Wunsch, Spam nachzuverfolgen und zu melden) als auch das Usenet waren dabei, in die Bedeutungslosigkeit abzurutschen.

"Markdown: HTML aus Text erzeugen" vollständig lesen

Serendipity, Spartacus und Dateirechte

Wie ich schon im Eintrag “Serendipity 2.0-beta” dokumentiert habe, hatte ich anfangs mit meiner Serendipity-Installation das Problem, das alle (über Spartacus) heruntergeladenen Plugins falsche Dateirechte hatten, die Verzeichnisse nämlich 0700 und die Dateien allesamt 0600. Das hatte zur Folge, dass der Webserver auf die Dateien und Verzeichnisse nicht zugreifen und u.a. Grafiken nicht anzeigen konnte, und auch sonst die Funktion der Plugins eingeschränkt war. Stattdessen müssten richtigerweise Rechte von 0755 und 0644 (oder zumindest 0705 und 0604) gesetzt werden.

Nachträglich beheben lässt sich das - im Verzeichnis plugins - ganz einfach so:

  1. find . -type d -perm 700 -exec chmod 755 &#8216;{}&#8217; \;
  2. find . -type f -perm 600 -exec chmod 644 &#8216;{}&#8217; \;

Nachdem ich einen Bug reportet hatte, bekam ich sehr schnell den richtigen Hinweis, dass die Spartacus-Konfiguration entsprechende Einstellungsmöglichkeiten aufweist, was ich übersehen hatte. Im Plugin lassen sich daher die richtigen Rechte vorgeben, und dann funktioniert die Installation auch zukünftig direkt problemlos.

Die Ursache für die zu strikten Rechte war für mich dann nicht auf Anhieb zu finden; die umask des Systems stand nämlich erwartungsgemäß und korrekt auf 0022. Allerdings setzte suphp für PHP dann noch einmal eine eigene umask in /etc/suphp/suphp.conf, und dort steht tatsächlich 0077

Wer also vor demselben Problem steht, sollte an der einen oder der anderen Stelle entsprechend den Schraubenzieher ansetzen.

Keywords: serendipity s9y spartacus plugins apache php suphp permissions too strict wrong

Serendipity 2.0-beta

Mitte April 2014, gerade als ich überlegte - und im Usenet diskutierte -, ob ich für den Relaunch meines Blogs weiter auf Serendipity (s9y) setze oder zu Wordpress wechseln soll, erschien die erste Beta des lange entwickelten Serendipity 2.0, auf die mich zuerst Dirk in seinem Blog aufmerksam machte und über die man kurz danach dann auch in Nur ein Blog lesen konnte.

Also habe ich ein Testblog aufgesetzt und mir das mal angeschaut, und nachdem das ganz gut lief und alles sehr schick aussah für den Relaunch meines Blogs direkt auch auf die Beta-Version gesetzt.

Unter anderem YellowLed und onli haben sehr gute Arbeit geleistet: das Standard-Template 2k11 funktioniert gut und ist sehr schick, und auch die renovierte Backend-Oberfläche kann auf den ersten Blick bereits optisch, aber auch technisch-inhaltlich gefallen. Insgesamt ist bereits die Beta einen Blick wert, und so stabil, wie man das von Serendipity gewohnt ist.

Natürlich gibt es auch noch einige kleine Fehler, Haken und Ösen:

  • Die Vorschaubilder der Templates (jetzt: “Themes”) stecken in riesig großen Rahmen, die zu Scrollorgien führen, weil ein Vorschaubild übergroß ist (mittlerweile behoben).
  • Das Einfügen von Bildern als Thumbmail mit Link auf das große Bild funktioniert mit dem eingebauten Button irritierender Weise nur beim ersten Mal; danach wird kein Link mehr generiert (mittlerweile behoben).
  • Ab und an (konkret insbesondere: beim Filtern bzw. Durchsuchen von Einträgen nach ihrem Inhalt) führt ein Druck auf die Enter-Taste nicht zum erwarteten Ergebnis, sondern zum Aufruf einer ganze anderen Seite (mittlerweile behoben).
  • Kategorien können über die Admin-Oberfläche nicht mehr bearbeitet werden, weil dann eine Namenskollision auftritt (bereits behoben).
  • Das serendipity_event_entrycheck-Plugin versagt schweigend: wenn es eigentlich wegen leerer Titel o.ä. das Speichern verhindern müsste, bestätigt es zumindest bei Entwürfen das erfolgreiche Speichern, verwirft den Eintrag aber (es lebe das Lazarus-Plugin für Firefox!).
  • Der schöne neue Button “Veröffentlichen” im neuen Admin-Dashboard für Entwürfe funktioniert nicht; der Eintrag wird zwar auf “veröffentlicht” gesetzt, erscheint aber nicht im Blog (mittlerweile behoben).
  • Zumindest bei mir hatten alle Plugin-Verzeichnisse und -Dateien zu strikte Zugriffsrechte.
  • Mit HTTPS werden (aufgrund der Protokollangabe in den Links zu CSS- und Javascript-Dateien) Stilinformationen, Icon-Schriften und Javascript nicht korrekt eingebunden.

Das sind jedenfalls die Kleinigkeiten - oder auch Größerigkeiten -, über die ich bisher gestolpert bin, aber: es wird!

Ich habe heute abend dann mal noch Bugreports für alle noch nicht bekannten Probleme eingeworfen (statt des Forums hat Serendipity dankenswerterweise jetzt auch einen Bugtracker in Form von github Issues) und bin sicher, dass wir in einiger Zeit einen Release Candidate und dann eine großartige 2.0-Version von Serendipity haben werden!

Nachtrag vom 19.05.2014 und 22.05.2014:

Das HTTPS-Problem lässt sich dadurch lösen, dass man unter “Konfiguration” (Block “Einstellungen” im Backend) und dort dann im Panel “Pfade” die Option “HTTP-Hostnamen automatisch erkennen” auf “Ja” setzt. Es handelt sich also eher um eine Fehlkonfiguration als einen Fehler. :-)

Und die Einstellungen für die Dateirechte lassen sich im Spartacus-Plugin vorgeben (was ich auch hätte bemerken können). Mit passenden Werten (0644 für Dateien und 0755 für Verzeichnisse) dort funktioniert dann auch alles blendend. - Allerdings sollten leere Eingaben dort einen Fallback auf die umask nach sich ziehen, und die ist korrekt auf 0022 gesetzt. Ganz in Ordnung scheint mir das daher noch nicht zu sein. Allerdings nur die umask des Systems. In der /etc/suphp/suphp.conf ist hingegen standardmäßig, auch unter Debian, eine umask von 0077 gesetzt … was das Problem erklärt. Also kein Fehler in Serendipity, sondern nur etwas, woran man denken sollte.

Nachtrag vom 10.06.2014:

Die meisten gemeldeten Probleme - und noch einige kleinere Baustellen, die mir zwischendurch aufgefallen sind - sind mittlerweile im Entwicklungszweig 2.0 bereits behoben.