Jens Brauer

Blog

Umstieg von Wordpress auf Pelican

Vor kurzem habe ich endlich mal wieder Zeit gefunden, mich um die Homepage zu kümmern. Einige Dinge, wie die Twitter Timeline auf der Startseite sahen einfach nicht mehr zeitgemäß aus und funktionierten zum Teil auch nicht mehr. Weiterhin war die Website sehr langsam. Selbst mit schneller VDSL Leitung dauerte der Seitenaufruf relativ lange. Schuld war wohl vor allem die Datenbank. Mein Webspace Anbieter ist eher im günstigen Preissegment angeordnet, der Zugriff auf die MySQL Datenbank via Wordpress war deshalb vllt. nicht ganz so schnell wie er sein könnte.

Grund genug sich einmal mit statischen Website Generatoren auseinanderzusetzen, um komplett auf die Datenbank verzichten zu können. Denn: Wordpress als Blogsystem ist zwar sehr mächtig, viele Funktionen benötige ich aber gar nicht. Meine Wahl fiel auf Pelican, ein in Python geschriebener statischer Seitengenerator.

Seiten und Blogposts werden hierbei in Markdown geschrieben. Pelican ist via Plugins erweiterbar, welche auch relativ einfach selber in Python geschrieben werden können. Themes können via Jinja Templates kreiert werden, dazu später mehr...

Von Wordpress zu Pelican : Import

Zuerst müssen alle Beitraäge und Seiten aus Wordpress exportiert werden. Dazu kann man unter Wordpress im Einstellungsmenü alle Beiträge + Kommentare als XML Datei speichern. Diese können nun mit pelican-import wieder importiert werden. Dieser funktioniert leider nicht ganz so gut, wie man erwarten würde. Besser geht es mit ExitWp, einem Python Skript, welches aus allen Beiträgen der XML Datei eine eigene Markdown Datei erstellt. ExitWp ist allerdings für den statischen Seitengenerator Jekyll erstellt worden. Mit ein paar kleinen Änderungen lassen sich aber auch Markdown Dateien im Pelican gewünschten Format erstellen:

out.write('---\n')      
if len(yaml_header) > 0:                    
    out.write(toyaml(yaml_header))                       
if len(tax_out) > 0:                     
    out.write(toyaml(tax_out))           
out.write('---\n\n')

muss geändert werden in:

if len(yaml_header) > 0:   
     out.write(toyaml(yaml_header))                
if len(tax_out) > 0:             
    for tax_type, tax_values in tax_out.items():
        if tax_type == 'categories':
            tax_type = 'category'
        out.write("%s: %s\n" % (tax_type, ', '.join(tax_values)))
out.write('\n')

Außerdem haben einige Beiträge nach der Konvertierung im Titel Anführungszeichen: 'Titel' statt Titel. Unter Linux lässt sich das mit einem find und sed Befehl beheben wie hier beschrieben. Unter Windows habe ich das fnr - Find and Replace Tool benutzt, im Kommandozeilenmodus:

fnr.exe --cl --dir "exitwp-master\build\jekyll\WEBSITE\_posts" --fileMask "*.*" --excludeFileMask "*.dll, *.exe" --includeSubDirectories --useRegEx --find "Title: '(.*)'" --replace "Title: $1"

Ähnliche Kommandos kann man verwenden um zum Beispiel [gallery] tags von Wordpress zu ersetzen.

Syntax Highlighting

Eine Vorteil von Pelican ist, dass Code-Beispiele direkt beim erstellen der HTML Seiten per Pygments in entsprechenden HTML Code umgewandelt werden und nur noch das entsprechende Pygments-Stylesheet eingebunden werden muss.

Standardmäßig werden auch von exitwp Code-Beispiele in Markdown entsprechend eingerückt, damit Markdown es als Code erkennt. Hat man zwei voneinander getrennte Code-Blöcke direkt aufeinanderfolgend, wird das von Markdown jedoch teilweise nicht richtig erkannt. Daher benutze ich die "fenced Code blocks" aus der Markdown Extra Extension. Um das in ExitWp zu berücksichtigen, müssen in der html2text.py für den pre Tag folgende Änderungen gemacht werden:

if tag == "pre":
    if start:
        if has_key(attrs, 'lang'):
            #self.o('    \n    :::'+attrs['lang'])
            self.o('\n~~~~~~\n:::'+attrs['lang'])
        self.startpre = 1
        self.pre = 1
    else:
        self.pre = 0
        self.o('\n~~~~~~\n')
    self.p()

und

if self.pre:
    bq = '' 
    #bq += "    " 
    data = data.replace("\n", "\n"+bq)

In der html2text.py kann man zum Beispiel auch am a und img tag einige Änderungen machen, wenn man zum Beipsiel Klassen Attribute und width sowie align und target Attribute übernehmen will. Mit ein paar einfachen Eingriffen alles kein Problem, ein paar Python Kentnisse vorrausgesetzt ;)

Kommentare + Kategorien + Tags

Pelican kann nur mit einer Kategorie per Beitrag umgehen. Hat man unter Wordpress also mehrere Kategorien per Beitrag benutzt, muss man hier per Hand nachbessern, entweder direkt in XML bevor der Benutzung von exitwp oder direkt in den Markdown Dateien. Tags werden einfach in die Metadaten geschrieben:

Author: admin
Comments: true
Date: 2014-10-18 13:53:42+00:00
Slug: umstieg-von-wordpress-auf-pelican
Title: Umstieg von Wordpress auf Pelican
Tags: wordpress, pelican, jinja, google wsk

Kommentare sind in einer statischen Seite allerdings nicht mehr so einfach machbar. Hier hilft DISQUS, ein externer Dienst zum Verwalten von Kommentaren.
Mit der Wordpress XML Datei kann man dort ganz einfach alle seine Kommentare importieren. In Pelican muss nur auf jeder Beitragsseite ein Javascript Code eingebunden werden, mit eurere psersönlichen Disqus ID. Die Kommentare sind mit der URL verbunden. Hat sich im Zuge des Umzugs auf Pelican auch die URL der Beiträge geändert, wie in meinem Fall von www.jens-brauer.de/Beitragstitel/id auf jens-brauer.de/Blog/Beitragstitel/ (ja, mit Trailing Slash ;) und ohne www) muss sichergestellt werden, dass die alte URL auf die neue URL redirected wird, am besten per htacces rewrite_module, zum Beispiel so:

RewriteCond %{REQUEST_URI} !(blog/)
RewriteRule ^([a-zA-Z0-9\-]+)/([0-9]+)/?$ /blog/$1/ [L,R=301] 

Unter eurer Disqus Seite unter "Discussion->Tools" kann dann ein "Redirect Crawler (Advanced)" gestartet werden, um die alten URLs bei Disqus gegen die neuen zu ersetzen.

Theme

Themes können per Jinja Templates erzeugt werden, was das ganze sehr modifierbar macht. Für diese Homepage habe ich mir ein eigenes Theme erstellt, aufbauend auf dem Google Webkit Starter.

Vorteile:
- GULP file für Browsersync, minfying HTML + CSS (NodeJS und Ruby werden benötigt)
- Browsersync: Website auf localhost auf mehreren Geräten gleichzeitig bearbeiten, bei Änderungen am Stylesheet oder ähnliches werden alle Geräte aktualisiert)
- Minify: Leerzeichen, Kommentare etc in HTML, CSS und JS Dateien werden entfernt, was die Dateigröße kleiner macht -> schnellere Ladezeit
- SASS Sytlesheets
- Responsive Framework -> Smartphone optimierte Darstellung

Workflow

  • Alle Beiträge befinden sich als einzelne Markdown Datei im Verzeichnis content
  • Nach Start von Pelican werden diese in HTML Dateien konvertiert und ins output/app/ Verzeichnis kopiert
  • Im output befinden die NodeJs packages sowie das gulp file
  • Per gulp serve lässt sich die Website lokal betrachten + bearbeiten
  • Per gulp wird die Website erstellt und ins output/dist Verzeichnis kopiert, bereit zur Übertragung auf den Server...

Website Änderungen

Abgesehen vom ganzen Design habe ich auch die Startseite angepasst und mit der Über-Mich Seite vereint. Außerdem gibt es jetzt eine TV/Movie Seite, welche meine zuletzt gesehenen Filme+Serien anzeigt.

SEO

Weiterhin habe ich noch die Permalink Struktur geändert, jetzt alle Links ohne www und mit Trailing Slash '/'. Außerdem ist der Titel jeder Seite jetzt 'Seite · Jens Brauer', so kann man auch bei mehreren geöffneten Tabs der gleichen Website noch die jeweilige Seite erkennen. Letztlich wurden noch viele kleine Sachen geändert, wie neues Icon, Favicon + Support für Twitter Cards etc...

Fazit

Es muss nicht immer Wordpress sein, vor allem wenn man sich etwas mit Python auskennt. Aber auch ohne Python Kenntnisse lässt sich mit Pelican sehr schnell ein Blog erstellen. Und die Ladezeit hat sich merklich verbessert, man könnte sagen, es ist jetzt "blazing-fast" ;)
Zum Schluss noch zwei hilfreiche Artikel zum Umstieg: Macdrifter:Von Pelican zu Wordpress und Umstieg von Wordpress auf Jekyll + Verwendung von Github als Host (sehr ähnlich zum Umstieg auf Pelican)

Kommentare