HowTo: Ghost Blog Social Media Links & Icons lokal hinzufügen

HowTo: Ghost Blog Social Media Links & Icons lokal hinzufügen

Ghost bietet im Standard die Möglichkeit, die eigenen SocialMedia-Profile auf X (ehem. Twitter) und Facebook über die allgemeinen Einstellungen dem Blog hinzuzufügen.

Möchte man hingegen seine SocialMedia-Präsenz auf Mastodon, LinkedIn, YouTube oder sonstige auf seinem Blog mit dem entsprechenden Logo verknüpfen, ist etwas Handarbeit erforderlich.

Bei den offiziellen Ghost-Tutorials gibt es dazu auch bereits ein entsprechende Anleitung:

How to add social media icons to your Ghost theme
Expand your social media presence by adding all of your social media network icons to your Ghost theme.

Das dort beschriebene Vorgehen birgt aber aus meiner Sicht einen entscheidenden Nachteil:

Für das Nachladen der SocialMedia-Icons werden Assets von dem externen CDN Cloudflare nachgeladen – Stichwort DSGVO. Wer bzgl. der Problematik rund um externe CDNs etwas mehr erfahren will, ich hatte hier bereits etwas dazu geschrieben.

Im Folgenden möchte ich daher beschreiben, wie man zum einen das CDN los wird, die Schriftart lokal auf dem eigenen Block hostet und das benötigte Code-Snippet für das eigene Theme anpasst.

Hinweis: Eine weitere kleine Herausforderung ist dabei, dass das im Tutorial beschriebene Vorgehen erstmal nur mit dem Ghost-Standard-Theme Source funktioniert und nicht weiter darauf eingegangen wird, wie man es für andere Themes anpasst. Dazu später mehr...

Das grundsätzliche Vorgehen

Das offiziell von Ghost vorgestellte Vorgehen legt zunächst in der primären Navigationsleiste einen externen HTML-Link pro SocialMedia-Profil an. Das im zweiten Schritt hinterlegt CSS-Script ersetzt dann den Text des Links – z. B. Mastodon – durch das entsprechende Icon aus der Schriftart Font Awesome. Dazu werden die Schriftart und das dazugehörige Script von einem CDN extern nachgeladen.

Das Ergebnis sieht auf meinem Blog und für mein Mastodon-Profil am Ende jedenfalls wie folgt aus:


Das Vorgehen im Detail

Hinweis: Wir verwenden zunächst das Ghost Default-Theme Source und stellen erst im zweiten Schritt auf ein individuelles Theme um, da hierfür das CSS-Script angepasst werden muss.

Zunächst müssen wir für jedes Social-Media-Profil das wir verlinken wollen, ein neues Element der Navigationsleiste hinzufügen. Wir wechseln dazu in das entsprechende Menü in den Einstellungen von Ghost:

Wichtig ist dabei, das ihr in der Linken Spalte den korrekten Namen des sozialen Netzwerkes verwendet und nicht etwa "Michaels YouTube Kanal" sondern nur "YouTube". Sonst kann später das CSS-Script den Eintrag nicht korrekt erkennen und den Text-String durch das entsprechende Logo austauschen.

Hinweis: Es ist also zunächst vollkommen korrekt, das in der Navbar der Link zu den Profilen nur als Text auftaucht.

In meinem Fall habe ich hier den Link zu meinem Mastodon-Profil hinzugefügt:

Das CSS-Script erstellen

Im nächsten Schritt müssen wir das entsprechende Script erstellen, welches zum einen den Text des Links ersetzt und die dazu notwendige Schriftart vom CDN nachlädt. Das offizielle Tutorial enthält dazu einen Code-Generator, welches einem für die verlinkten SocialMedia-Plattformen – nach entsprechender Auswahl – das benötigte Code-Snippet erstellt.

Da ich in meinem Fall nur Mastodon verlinke, sieht das Snippet in meinem Fall wie folgt aus:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/brands.min.css" integrity="sha512-DJLNx+VLY4aEiEQFjiawXaiceujj5GA7lIY8CHCIGQCBPfsEG0nGz1edb4Jvw1LR7q031zS5PpPqFuPA8ihlRA==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<style>
    :where(.nav, .gh-head-menu) .nav-mastodon a {
        font-size: 0 !important;
    }

    :where(.nav, .gh-head-menu) .nav-mastodon a::before {
        font-family: "Font Awesome 6 Brands";
        display: inline-block;
        font-size: 20px;
        font-style: normal;
        font-weight: normal;
        font-variant: normal;
        text-rendering: auto;
        -webkit-font-smoothing: antialiased;
    }

    :where(.nav, .gh-head-menu) .nav-mastodon a::before {content: "\f4f6"}
</style>

Die erste Zeile lädt ein CSS-File nach, welches wiederum für das Nachladen der Schriftart zuständig ist. Der zweite Teil ist etwas CSS, welches den Textstring des jeweiligen Links gegen das entsprechende Icon aus der nachgeladenen Schriftart ersetzt. Das originale Tutorial geht ab hier etwas mehr ins Detail, falls da Interesse besteht.

Das Script verwenden

Als nächstes müssen wir das Script nun in unseren Ghost-Blog einbauen. Wir gehen dazu wieder in die Einstellungen, wählen die Option Code injection und fügen das Code-Snippet im Bereich Site header hinzu:

Sofern wir alles richtig gemacht haben und – wichtig – das Ghost Default-Theme Source verwenden, sollten wir jetzt das entsprechende SocialMedia-Logo als Link in unserer Navbar sehen:

Wenn wir uns die Details des Blogs mit den Web Developer Tools unseres Browsers anschauen, sehen wir im z. B. im Firefox das jetzt ein externes CDN auftaucht:

Wie Anfangs schon erwähnt, ist das im offiziellen Tutorial beschriebene Vorgehen nicht unbedingt mit allen Themes direkt kompatibel. In meinem Fall verwende ich das Theme Attila und das Ersetzen des Linktextes durch das Icon klappt leider nicht direkt:

Script an ein Custom Theme anpassen

Kümmern wir uns zunächst darum, dass das Code-Snippet auch mit unserem Custom-Theme funktioniert. In meinem Fall verwende ich das kostenlose Ghost-Theme Attila.

Das Problem

Das vom Codegenerator erzeugte Code-Snippet funktioniert für unsere Custom-Theme aller Wahrscheinlichkeit nicht, weil die Themes unterschiedliche Klassenbezeichnungen für die Elemente in der Navbar nutzen.

Der im generierten Code-Snippet dazu relevante Teil lautet :where(.nav, .gh-head-menu) .nav-mastodon a und kommt an drei Stellen vor. Diese müssen wir für unser Custom-Theme entsprechend anpassen.

Korrekten Klassenbezeichner identifizieren

Um den in unserem Custom-Theme verwendeten Klassenbezeichner zu identifizieren, öffnen wir die Web Developer Tools unseres Browser – im Firefox mit der Taste F12 – und laden die Webseite nochmal neu.

Im Bereich Inspector navigieren wir im Body in den Bereich der Navbar und gehen einfach Schritt für Schritt die dort angezeigten Elemente durch, bis wir die den Navbar-Elementen Home, About und Mastodon übergeordnete Klasse gefunden haben.

Im Browser wird praktischerweise direkt aktiv farblich markiert, wo wir uns gerade befinden:

Der im Attila-Theme verwendete Klassenbezeichner lautet also .nav-wrapper und ich passe das CSS-Snippet dementsprechend für mein Attila-Theme wie folgt an:

<style>
    :where(.nav, .nav-wrapper) .nav-mastodon a {
        font-size: 0 !important;
    }

    :where(.nav, .nav-wrapper) .nav-mastodon a::before {
        font-family: "Font Awesome 6 Brands";
        display: inline-block;
        font-size: 20px;
        font-style: normal;
        font-weight: normal;
        font-variant: normal;
        text-rendering: auto;
        -webkit-font-smoothing: antialiased;
    }

    :where(.nav, .nav-wrapper) .nav-mastodon a::before {content: "\f4f6"}
</style>

Wenn ich jetzt die Seite im Browser neu aufrufe, sollte jetzt wieder das Logo des Sozialen Netzwerkes anstatt des Strings zu sehen sein. Sollte das nicht klappen, ggf. den Browsercache leeren oder mit den Developer Tools des Browsers nachschauen, wo es ggf. hängt.

Externes CDN entfernen

Jetzt muss ich nur noch das externe CDN loswerden. Dazu verwende ich ein ähnliches Vorgehen, wie ich bereits in dem Artikel Selfhosted Ghost-Blog die CDNs entziehen vorgestellt hatte.

Zunächst müssen wir dazu die externen Ressourcen (CSS-File und Fonts) identifizieren, lokal herunterladen, in das Theme integrieren und schlussendlich noch das Code-Snippet anpassen.

Theme lokal bereitstellen

Der direktestes und einfachste Weg Ghost die externen Ressourcen zur Verfügung zustellen, ist es diese direkt in unser Theme zu integrieren. Wir laden dazu das aktuell verwendete Theme in den Einstellungen unseres Ghost-Blogs herunter:

Das heruntergeladene ZIP-File entpacken wir schon mal in unserem lokalen Dateisystem für die folgenden Schritte.

Das CSS-File lokal bereitstellen

Die erste Zeile des Code-Snippets gibt uns die URL zu dem CSS-File brands.min.css, welches auf dem CDN von Cloudflare gehostet wird.

<link rel="stylesheet" 
  href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/brands.min.css" 
  integrity="sha512-+oRH6u1nDGSm3hH8poU85YFIVTdSnS2f+texdPGrURaJh8hzmhMiZrQth6l56P4ZQmxeZzd2DqVEMqQoJ8J89A==" 
  crossorigin="anonymous" 
  referrerpolicy="no-referrer" 
/>

Die URL lautet also:

https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/brands.min.css

Ich persönlich bin ein Freund der Shell und habe das CSS-File mit wget heruntergeladen. Alternativ kann man die URL auch im Browser öffnen und das CSS-File anschließend über den Browser speichern.

Das CSS-File habe ich anschließend in dem Unterordner ./assets/css/ des entpackten Attila-Themes abgelegt. Dabei habe ich in den Dateinamen die Versionsnummer aus der URL übernommen und aus brands.min.css die Datei brands-6.5.2.min.css gemacht.

Die Schriftarten lokal bereitstellen

Wenn man sich das CSS-File brands-6.5.2.min.css – nach dem Einsatz eines Code-Beautifiers – etwas genauer anschaut, findet man relativ weit oben den folgenden Abschnitt:

@font-face {
    font-family: "Font Awesome 6 Brands";
    font-style: normal;
    font-weight: 400;
    font-display: block;
    src: url(../webfonts/fa-brands-400.woff2) format("woff2"), url(../webfonts/fa-brands-400.ttf) format("truetype")
}

Hier sehen wir, dass das CSS die zwei Schriftarten fa-brands-400.woff2 und fa-brands-400.ttf relativ zum eigenen Pfad nachlädt. Aus dieser Information können wir die URLs der Schriftarten auf dem CDN zusammenbauen und die zwei Dateien lokal herunterladen. Dazu verwenden wir entweder wieder wget oder den Webbrowser:

https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/webfonts/fa-brands-400.woff2

https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/webfonts/fa-brands-400.ttf

Nachdem wir die zwei Schriftarten heruntergeladen haben, legen wir diese in dem Unterordner ./assets/font/ unseres entpackten Themes ab.

Pfade im CSS-File anpassen

Bevor wir das erweiterte Theme wieder in Ghost hochladen können, müssen wir jetzt noch die relativen Pfade zu den Schritftdateien im lokal abgelegten CSS-File ./asstets/css/brands-6.5.2.min.css anpassen, damit die Schriftarten später direkt von unserem Blog ausgeliefert werden.

Die kleine Herausforderung dabei ist, dass das CSS-File minified wurde, um möglichst schnell ausgeliefert werden zu können. Das erhöht die Lesbarkeit für uns Menschen leider aber gerade eben nicht.

Zum Glück stehen die gesuchten URLs zu den Schriftdateien sehr weit oben. Wir suchen den Abschnitt

src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf)

und ersetzen dort den relativen Pfads auf dem CDN ../webfonts/, durch den neuen relativen Pfad auf unserem Blog ../font/:

src:url(../font/fa-brands-400.woff2) format("woff2"),url(../font/fa-brands-400.ttf)

Theme hochladen

Das CSS-File und die Schriftarten liegen jetzt lokal vor und die notwendigen relativen Pfade im CSS-File wurden für den neuen Speicherort auf unserem Blog angepasst. Das Theme kann jetzt wieder zu einer ZIP-Datei gepackt werden und die resultierende attila.zip Datei wieder in den Blog hochgeladen und aktiviert werden.

Lokales CSS und Fonts aktivieren

Wir sind aber noch nicht ganz fertig! Aktuell liegen jetzt zwar die Ressourcen lokal in unserem Blog vor, jedoch wird aktuell immer noch das CSS-File und die Schriftarten des CDNs genutzt.

Um das zu ändern, müssen wir noch die URL auf unser lokales CSS-File umbiegen. Und da es sich außerdem nun um eine lokale Ressource handelt, können wir auf die zusätzlichen Konfigurationsparameter verzichten.

So wird aus der ersten Zeile des Code-Snippets,

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/brands.min.css" integrity="sha512-+oRH6u1nDGSm3hH8poU85YFIVTdSnS2f+texdPGrURaJh8hzmhMiZrQth6l56P4ZQmxeZzd2DqVEMqQoJ8J89A==" crossorigin="anonymous" referrerpolicy="no-referrer" />

unter Vernwendung der eigenen Domain, die folgende Zeile:

<link rel="stylesheet" href="https://DEINE-DOMAIN/assets/css/brands-6.5.2.min.css"/>

Das vollständige Snippet sieht bei mir dann wie folgt aus:

<link rel="stylesheet" href="https://thoughtodyssey.net/assets/css/brands-6.5.2.min.css"/>

<style>
    :where(.nav, .nav-wrapper) .nav-mastodon a {
        font-size: 0 !important;
    }

    :where(.nav, .nav-wrapper) .nav-mastodon a::before {
        font-family: "Font Awesome 6 Brands";
        display: inline-block;
        font-size: 20px;
        font-style: normal;
        font-weight: normal;
        font-variant: normal;
        text-rendering: auto;
        -webkit-font-smoothing: antialiased;
    }

    :where(.nav, .nav-wrapper) .nav-mastodon a::before {content: "\f4f6"}
</style>

Und damit sollten wir es haben! Nach einem erneuten Laden, sollte weiterhin das oder die Icons der verlinkten sozialen Medien zu sehen sein.

Mit den Web Developer Tools des Browsers können wir im Bereich Network überprüfen, ob auch wirklich keine externen CDNs mehr nachgeladen werden. Damit uns der Cache hier kein Bein stellt, die Überprüfung mit geleertem Cache oder im Inkognito-Modus des Browsers durchführen.

Ich hoffe die Anleitung war nützlich!