gresemonkey – Bytespeicher https://bytespeicher.org Hackspace Erfurt Sat, 09 Jan 2016 18:37:22 +0000 de-DE hourly 1 WordPress erweitern mit [Grease|Tamper]monkey (ohne PHP) https://bytespeicher.org/2016/wordpress-erweitern-mit-greasetampermonkey-ohne-php/ Sat, 09 Jan 2016 09:02:59 +0000 https://bytespeicher.org/?p=1286 WordPress erweitern mit [Grease|Tamper]monkey (ohne PHP) weiterlesen ]]> Unsere Seite hier ist ein WordPress-Blog und ich schreibe seit neuestem die Bytespeicher-Notizen im integrierten Editor im Adminbereich der Seite.
Da wir vorher Input in Pads (Etherpad) sammeln, besteht ein Großteil des Artikelschreibens aus Copy & Paste. Einige Nachbearbeitungsschritte sind aber noch nötig und diese wollen wir automatisieren.

Damit sich das Format zumindest an einige wenige Standards hält, gibt es eine Vorlage dazu.

Die Vorlage und zum Glück auch die Inputgeber verwenden dabei Markdown, eine Formatierungssprache die ähnlich der Wiki- oder Forensyntax Textstrukturierung direkt im Quelltext erlaubt, dabei aber leidlich lesbar bleibt. Etherpad selbst ‚versteht‘ diese Auszeichnungssprache nicht, wir verwenden sie aber schon in Vorbereitung des Kopierens ins WordPress, wo sie am Ende in HTML umgesetzt wird.

Lediglich Links werden, aus historischen und Übersichtsgründen im Pad im Format

* Notiztext
https://link.example.org/detailseite

angegeben und mussten bisher im WordPress-Editor per Button oder händisch in die Form

* Notiztext (<a href=https://link.example.org/detailseite>example.org<\a>)

gebracht werden.

Das hat genervt.

Nun ist das eigentlich ein einfacher Fall für ein Suchen&Ersetzen mittels Regular Expressions, wie sie in jedem besseren Editor zur Verfügung steht.
Nun ist der WordPress-Editor alles andere als einer der ‚besseren‘, man müsste die Funktion also als Plugin nachrüsten, will man den Text nicht in einem zusätzlichen Arbeitsschritt noch durch einen Editor schleifen. Leider ist WordPress selbst und seine Plugins in PHP geschrieben, einer serverseitigen Skriptsprache um die der Autor dieses Textes und verfügbare Hilfskräfte im Bytespeicher jeweils einen großen Bogen machen. Also was tun?

Aber was serverseitig geht, geht auch clientseitig. Browser-Plugins wie Greasemonkey (Firefox-Plugin) und Tampermonkey (Chrome-, Safari-, Opera- und Dolphin-Plugin) erlauben es, eigene Javascriptfunktionen regelbasiert auf Webseiten anzuwenden nachdem sie geladen und bevor sie angezeigt werden.

Dazu sucht man sich das zu manipulierende HTML-Element aus dem DOM-Tree der Webseite, in dem man die Developer-Tools der gängigen Browser nutzt. (In Chrome: Rechtsklick + ‚Inspect element‘). Idealerweise hat das Element eine ID, was die Adressierung einfach macht, z.b. so:

var menu = document.getElementById('ed_toolbar');

Dann kann man sich ein neues Element (z.B. ein Button) erzeugen und in den DOM-Tree an der entsprechenden Stelle einhängen:

newinput = document.createElement("input");
newinput.type = "button";
newinput.className = "ed_button button button-small";
newinput.value = "Fix Links";
newinput.addEventListener('click',replace_text,true);
menu.appendChild(newinput);

Neuer Button in der Menüleiste
Neuer Button in der Menüleiste

Damit haben wir einen Button, der eine Skriptfunktion auslösen kann in die Webseite eingebaut.
Das hilft, wenn es sich bei der Funktion nicht nur um eine dauerhafte Änderung handelt, die beim Laden der Seite ausgeführt werden kann.
Mit der selben Technik holen wir uns den bisherigen Text im Editor ab und formen ihn um.
Vielen Dank an mkzero für die Erarbeitung der Suchen&Ersetzen-Routine, die natürlich nicht ‚mal eben so einfach‘ ist sondern eine Menge Ausnahmen und Sonderbehandlungen abdecken muss.

function replace_text(){
    var i = 0, j = 0,
    lines = document.getElementById('content').innerHTML.split('\n'),
    newdoc = [],
    match = /(?:(http|ftp)(s|):\/\/)([a-z-.]+[a-z]+)/,
    link = /(href="|>)((http|ftp)(s|):\/\/)([a-z-.]+[a-z]+)/,
   //[...]
    for (i = 0; i <= lines.length; i+=1) {
        if (match.test(lines[i]) && !link.test(lines[i]) /*[..]*/ ) {
            if (match.test(lines[i-1]) && !link.test(lines[i-1])) {
                newdoc[j] ='' + lines[i] + '');
                j += 1;
    //[...]
        } else {
            newdoc[j] = lines[i];
            j += 1;
        }
    }
    
    document.getElementById('content').innerHTML = newdoc.join('\n');   
}

Das ganze ist natürlich eigentlich nur für Notizenschreiber nützlich. Wer trotzdem mal in den Code schauen möchte, findet das Skript bei GitHub und im Tampermonkey-Repository.

]]>