w.org im Seitenquelltext unter WordPress

Auf einer Webseite, welche ich betreibe, fand sich folgende Abhängigkeit im Quelltext der Seite:

<link rel='dns-prefetch' href='//s.w.org' />

Hier wurde ein DNS Prefetch durchgeführt, das bedeutet der Browser angewiesen wird, besagte Domain bereits per DNS aufzulösen, bevor sich eigentlich benötigt wird. Grundsätzlich achte ich darauf das meine Webseiten ohne externe Abhängigkeiten auskommen. Eine Ausnahme ist z.B. der Zählschnipsel der VG Wort, welcher für die Abrechnung entsprechender Texte benötigt wird.

Bei der Ursachenforschung stellte ich fest das WordPress hier Emojis nachlädt, obwohl dies in den Einstellungen in der Sektion Schreiben deaktiviert wurde.

In den Einstellungen kann die automatische Umwandlung von Emojis abgeschaltet werden

Ursächlich für das Problem war ein Unicode-Zeichen, welches in einem Widget der Seite genutzt wurde und dazu führte, dass das entsprechende Zeichen extern als SVG-Datei geladen wird. Die einfachste Lösung ist es das entsprechende Zeichen zu entfernen, allerdings kann dieses Verhalten auch generell abgeschaltet werden. Dazu sind in der Datei functions.php des benutzen Themes folgende Zeilen hinzuzufügen:

add_filter( 'emoji_svg_url', '__return_false' );
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );

Damit ist die automatische Umwandlung von Emojis abgeschaltet und auch der entsprechende DNS Prefetch sollte nicht mehr im Quelltext auftauchen.

Dungeon Scrawl

Für ein Pen & Paper war ich auf der Suche nach einem einfachen Editor zu Erstellung von Karten. Nachdem ich knapp zwei Dutzend Applikationen dafür ausprobiert habe, bin ich schließlich bei Dungeon Scrawl gelandet. Dungeon Scrawl läuft im Browser und dient dem Mappung von Dungeons und anderen Karten. Die Karte kann mit den unterschiedlichsten Werkzeugen erstellt werden und ist in der Theorie unendlich groß.

Dungeon Scrawl mit einem einfachen Dungeon

Neben einfachen Zeichenwerkzeuge existieren komplexere Werkzeuge und Textwerkzeuge. Das Endergebnis kann als ds-Datei, zur späteren Bearbeitung, gespeichert oder in unterschiedliche Formate wie PNG oder SVG exportiert werden. Im Gegensatz zu anderen Werkzeugen ist Dungeon Scrawl angenehm einfach zu bedienen, sodass erste Ergebnisse nicht lange auf sich warten lassen. Zu finden ist das Werkzeug auf der offiziellen Webseite unter dungeonscrawl.com.

Erste Schritte mit Rust

Vor ein paar Tagen wollte ich die Programmiersprache Rust ausprobieren. Bei Rust handelt es sich um eine Sprache, welche syntaktisch stark an C angelehnt ist und besonderes Augenmerk auf Sicherheit legt. Die erste Frage, die sich mir stellte, ist, ob es für Rust, eine vernünftige IDE-Unterstützung existiert. Fündig geworden bin ich bei IntelliJ IDEA, welches nach Installation des Rust-Plugins zur Programmierung in der Sprache genutzt werden kann. Debugging von Rust-Programmen wird aus technischen Gründen nur in der JetBrains IDE CLion unterstützt, sodass hier einige Abstriche gemacht werden müssen. Neben der Rust-Integration für IntelliJ IDEA gibt es ebenfalls ein Plugin für Visual Studio Code, welches hier allerdings nicht weiter behandelt werden soll.

Mit dem passenden Plugin beherrscht IntelliJ IDEA Rust.

Neben der eigentlichen IDE wird Rust benötigt. Dieses kann über die offizielle Seite der Sprache bezogen werden. Nach der Installation kann in der IDE ein erstes Projekt angelegt werden. Anschließend findet sich in einem Ordner mit dem Namen src eine Datei mit dem Namen main.rs:

fn main() {
    println!("Hello, world!");
}

In dieser Datei findet sich ein minimales Hello world-Programm. Das Ausrufezeichen hinter dem println zeigt unter Rust an, das es sich um ein Makro handelt. Damit können Methoden und Makros einfach auseinander gehalten werden. Da ich Hello world-Programme immer etwas sinnfrei finde was das Lernen einer neuen Programmiersprache angeht, wollte ich für den ersten Versuch das Spiel Zahlenraten programmieren. Ziel des Spieles ist es eine Zahl zwischen 0 und 1000 zu erraten, welche der Rechner sich ausgedacht hat. Dazu muss im ersten Schritt eine Variable definiert werden, in welcher die zufällige Zahl gespeichert wird. Grundsätzlich sieht eine Variablendefinition und Deklaration unter Rust wie folgt aus:

let name: Typ = Wert;

Variablen in Rust sind immer Konstanten, wenn sie nicht explizit als veränderlich angegeben werden. Möglich ist dies mit dem Schlüsselwort mut:

let mut name: Typ = Wert;

Die Benennung von Variablen und anderen Elementen folgt in Rust einem bestimmten Schema. So werden Variablen snake_case benannt. Neben der Definition der Variable muss eine zufällige Zahl zwischen 0 und 1000 generiert werden. Dazu dient ein Zufallsgenerator, welcher über ein use eingebunden werden muss:

use rand::Rng;

Anschließend kann die Variable definiert und deklariert werden:

let number: u32 = rand::thread_rng().gen_range(0, 1000);

In diesem Fall wird ein vorzeichenloser Integer mit 32 Bit Breite als Datentyp definiert. Wird nun versucht das Rust-Programm zu kompilieren, so wird die Fehlermeldung:

error[E0432]: unresolved import `rand`
 --> src\main.rs:1:5
  |
1 | use rand::Rng;
  |     ^^^^ use of undeclared type or module `rand`

error[E0433]: failed to resolve: use of undeclared type or module `rand`
 --> src\main.rs:4:23
  |
4 |     let number: u32 = rand::thread_rng().gen_range(0, 1000);
  |                       ^^^^ use of undeclared type or module `rand`

error: aborting due to 2 previous errors

auftauchen. Grund hierfür ist, dass das genutzte Paket über den Paketmanager von Rust bezogen werden muss. Pakete werden über den Paketmanager Cargo bezogen. Die entsprechenden Pakete des offiziellen Repositorys sind unter crates.io zu finden. In der Datei Cargo.toml müssen die entsprechenden Abhängigkeiten eingebunden werden:

[dependencies]
rand = "0.7.3"
text_io = "0.1.8"

Neben dem Pseudozufallszahlengenerator, wurde gleich noch das Paket text_io eingebunden, welches später für die Eingabe von Text benötigt wird. Dieses Paket stellt hierbei das Makro read zur Verfügung, mit dessen Hilfe eine Eingabe realisiert werden kann:

let user_number: u32 = read!();

Damit sind die Grundlagen für das Spiel Zahlenraten gelegt und der Rest des Quellcodes ergibt praktisch sich von selbst:

use rand::Rng;
use text_io::read;

fn main() {

    let number: u32 = rand::thread_rng().gen_range(0, 1000);

    let mut running = true;

    println!("Ich habe mir eine Zahl zwischen 0 und 1000 ausgedacht.");

    while running {

        println!("Dein Vorschlag: ");
        let user_number: u32 = read!();

        if number > user_number {
            println!("Meine Zahl ist größer.");
        } else if number < user_number {
            println!("Meine Zahl ist kleiner.");
        } else {
            running = false;
        }
    }

    println!("Du hast die Zahl erraten. Es war die {}.", number);
}

Hervorzuheben ist, das unter Rust in if-Statements und Schleifen keine Klammern benötigt werden. Werden diese trotzdem genutzt, so warnt der Compiler entsprechend und bittet die überflüssigen Klammern zu entfernen.

Neben der entsprechenden Dokumentation auf der offiziellen Seite empfiehlt sich das Rust Cookbook als Quelle für die ersten Schritte unter Rust. Wer Rust einfach mal im Browser ausprobieren möchte, kann hierfür den Rust Playground nutzen.

Bookmarklet zum Sortieren von YouTube-Videos nach Dauer

Wird ein YouTube-Kanal geöffnet, so können die Videos in diesem nach der Beliebtheit und dem Datum sortiert werden. Eine Sortierung nach Dauer der Videos ist leider nicht vorgesehen. Abhilfe schafft ein entsprechendes Bookmarklet:

javascript:(function(){l=[].map.call(document.querySelectorAll("span.ytd-thumbnail-overlay-time-status-renderer"),function(e){l=e.innerHTML.trim().split(":").map(function(t){return parseInt(t)}).reduce(function(p,c){return p*60+c});return{a:e.parentElement.parentElement.parentElement,l:l}}).sort(function(a,b){return a.l-b.l});i=document.querySelector("#primary #items");l.forEach(function(o){i.appendChild(o.a.parentElement.parentElement.parentElement)})})()

Zum Anlegen des Bookmarklets muss ein neues Lesezeichen im Browser angelegt werden und der entsprechende JavaScript-Code in das Adressfeld des neuen Lesezeichens kopiert werden.

Nach der Nutzung des Bookmarklets sind die Videos nach Dauer sortiert

Zur Nutzung muss der entsprechende YouTube-Channel im Browser geöffnet sein und alle Videovorschaubilder, welche sortiert werden sollen, müssen geladen sein. Anschließend kann das Bookmarklet benutzt werden und alle Videos sind nach der Nutzung aufsteigend nach ihrer Länge sortiert.

Dark Mode auf Webseiten

In vielen Betriebssystemen wie z.B. macOS oder iOS zog in den letzten Versionen ein sogenannter Dark Mode ein. Bei diesem Modus werden die Elemente des Betriebssystems auf dunklere Farben eingestellt. Damit wird der Nutzer am Abend bzw. in der Dunkelheit nicht mehr so stark geblendet. Wird allerdings bei aktiviertem Dark Mode eine Webseite aufgerufen, welche von Haus aus mit hellen Farben arbeitet, so wird der Nutzer wieder geblendet. Mittlerweile können Webseiten sich allerdings dem gewünschten Farbschema anpassen. Dazu muss im CSS eine entsprechende Media Query definiert werden:

@media (prefers-color-scheme: dark) {
body {
    background-color: rgb(24, 26, 27);
    color: rgb(214, 211, 205);
}
}

Ist nun der Dark Mode im Betriebssystem aktiviert, wird das präferierte Farbschema übermittelt und kann dann CSS entsprechend umgesetzt werden.

seeseekey.net im Dark Mode

Wer die eigene Webseite mit einem dunklen Farbschema sehen möchte, kann dazu die Firefox-Erweiterung Dark Reader nutzen.

Dark Reader
Preis: Kostenlos

Mit dieser Erweiterungen können Webseiten automatisch in ihre dunklen Versionen überführt werden. Für die Entwicklung einer eigenen dunklen Variante können die neuen Farbwerte nun mittels der Entwicklertools des Browsers aus der Ausgabe der Erweiterung extrahiert werden.