Skip to main content
Joomla 5 - Tutorial / Skript

Tutorial: "Dark Mode"-Switcher Modul für Joomla 5 erstellen (Backend)

| Dev-Blog

Joomla 5.0 wurde am 17.10.2023 veröffentlicht. Mit "Dark Mode" Unterstützung fürs Backend.
Wer zwischen "Dark-" und "Light-Mode" umschalten möchte, hat allerdings nur die Möglichkeit dies generell über die Browser-Einstellungen zu tun. Eigentlich.😉

TL;DR Wir haben ein kleines Skript geschrieben, dass einen "Dark- / Light-Mode Switcher" im Backend anzeigt. Damit lässt sich sehr einfach ein eigenes Backend-Modul erstellen, dass einen Button einblendet mit dem man auf jeder Seite mit einem Klick zwischen dunkel und hell hin- und herschalten kann. Direkt zur Anleitung.

👉 In English please! 🇺🇸 🇬🇧

Don't speak German, but creating a Dark/Light Mode switch button for Joomla 5 sounds interesting to you?

Scroll down to the bottom and find out how to do it.

Worum geht's?

Joomla 5.0 ist da - mit Dark Mode im Administrator Bereich

Bei unserer ersten Installation von Joomla! 5 (damals noch die Beta-Version) fiel uns besonders eine Neuerung sofort ins Auge: Dark-Mode (Dunkel Modus) im Backend (Administrator Bereich / Atum Template) 😃.
Der anfänglichen Freude über das neue Erscheinungsbild folgte allerdings nach kurzer Zeit etwas Ernüchterung. Der Dark Mode scheint noch nicht so ganz ausgereift. Auf dem Dashboard erscheinen die Notification-Buttons doch etwas grell, ebenso die Bereiche, in denen ein Editor (z.B. TinyMCE) zum Einsatz kommt. Richtig schlecht lesbar wurde es allerdings, wenn als Editor der CodeMirror verwendet wird:

CodeMirror
CodeMirror Editor in Joomla 5 (Darkmode). Die helle Schrift ist auf dem grellen Hintergrund nur schwer lesbar.

Wie lässt sich der Darkmode in Joomla deaktivieren?

So lässt es sich natürlich schlecht arbeiten...
Sicherlich ließe sich manche Farbeinstellung per CSS nachbessern, aber wir wollten lieber generell wieder auf den hellen Modus (Light-Mode) umschalten. Also im Backend auf die Suche nach einem Schalter gemacht... Aber Fehlanzeige... Weder in der Konfiguration, beim Template, noch sonst wo ließ sich eine Einstellung hierzu finden.

Meme

Des Rätsels Lösung:

Joomla passt sich den Browser Einstellungen bzgl. dem „Erscheinungsbild von Websites“ (hell/dunkel) an.
D.h. der Darkmode lässt sich momentan nur per Browser-Einstellungen (also übergreifend für alle Websites) umstellen.

Damit hatten wir zwar eine Lösung gefunden, aber so richtig befriedigend ist das auch nicht. Schließlich möchten wir den Darkmode schon ganz gerne für andere Websites behalten (wie z.B. auf GitHub, wo die dunkle Optik sehr viel angenehmer ist als die helle).

Nach etwas Recherche im Joomla "Rabbit Hole", div. GitHub-Diskussionen und Joomla-Gruppen bei Facebook etc. wurde klar, dass

  1. viele andere User die gleichen Fragen bzgl. "Darkmode deaktivieren" haben
  2. irgendwann wohl eine Art Umschalter in Joomla kommen soll (in einer der nächsten Versionen), Details aber noch diskutiert werden

Unsere (temporäre) Lösung: Ein "Dark Mode Switcher" per JavaScript

Kurzerhand haben wir deshalb selbst ein kleines "Dark Mode Switcher"-Skript entwickelt. (Temporär, weil das ganze mehr als kurzfristige Lösung gedacht ist. Wenn Joomla irgendwann mit einer neuen Lösung kommt, wird das Ganze ggf. obsolet. 🤷🏻‍♂️)
Angefangen mit einem kleinen JavaScript (inspiriert durch diesen Artikel), das erstmal nur von Dark- auf Light-Mode umstellen sollte, ist der Code dann immer weiter angewachsen. Es kam ein Toggle-Button zum Umschalten des Modus (hell/dunkel) auf der aktuellen Seite hinzu und später auch noch die Speicherung des gewählten Toggle-Zustands im Local Storage des Browsers.

Im Folgenden die Anleitung und das Skript, mit dem ihr euer eigenes Backend Modul erstellen könnt:

🌓 DarkMode-Switcher Backend Modul erstellen - so geht's

Achtung: Vorher bitte unbedingt den Editor (zumindest temporär) auf CodeMirror umstellen! (TinyMCE o.ä. könnten beim Speichern evtl. den Code zerstören.)

Schritte:

  1. Im Joomla 5 Backend unter Inhalt -> Administrator Module ein neues Modul vom Typ Eigenes Modul erstellen
  2. Als Titel könnt ihr z.B. "🌓 Dark Mode Switcher" nehmen.
    (Das 🌓-Emoji wird von Joomla mitgespeichert. Nettes Gimmick, um das Modul später in der Modulliste schneller wieder zu finden, wenn ihr es z.B. mal wieder deaktivieren wollt.)
  3. Titel anzeigen könnt ihr deaktivieren
  4. Als Position (Anzeigeposition des Moduls im Backend) empfehle ich unbedingt die Position [status] zu wählen!
    (Der Switch-Button funktioniert am besten oben in der Status-Leiste, da diese auf nahezu jeder Unterseite angezeigt und somit unser Skript überall ausgeführt wird.)
  5. Zugriffsebene könnt ihr auf Special stellen. Und im Reiter Optionen könnt ihr Inhalt vorbereiten -> deaktivieren (wird nicht benötigt)
  6. Im Hauptfeld des Moduls muss nun folgender Code eingefügt werden:
    Wie oben erwähnt, vorher den Editor auf CodeMirror umstellen!
<button type="button" class="header-item-content dms-button" style="border: none;">
  <span class="header-item-icon">
    <span style="margin: 3px; font-size: 1.2rem; transition: all .6s ease;">🌓</span>
  </span>
  <span class="header-item-text">Dark Mode Switcher</span>
</button>

<script>
  (() => {
    'use strict';
  
    // Run script only once
    if (typeof window.jDarkMode !== "undefined") return;
  
    // Initial settings
    let darkMode = window.jDarkMode = (getDarkModeLocalStorage() === "true");
    setDarkModeLocalStorage(darkMode);
    // Update the first visible "Dark Mode Switcher" button to avoid flickering
    updateButton(document.querySelector("button.dms-button"), darkMode);
    updateMode(darkMode);
  
    function updateButton(btn, darkMode) {
      const icon = btn.querySelector(".header-item-icon > span");
      const text = btn.querySelector(".header-item-text");
      if (darkMode) {
        icon.innerHTML = "🌙";
        icon.style.backgroundColor = "rgb(31, 48, 71)";
        text.innerHTML = "&nbsp;Dark Mode";
      } else {
        icon.innerHTML = "☀️";
        icon.style.backgroundColor = "transparent";
        text.innerHTML = "Light Mode";
      }
    }
  
    function updateMode(darkMode) {
      for (const sheet of document.styleSheets) {
        //if (sheet.href && sheet.href.includes("atum/css/template")) {
        for (let i = sheet.cssRules.length - 1; i >= 0; i--) {
          let rule = sheet.cssRules[i].media;
          if (typeof rule !== "undefined" && rule.mediaText.includes("prefers-color-scheme")) {
            if (darkMode) {
              if (!rule.mediaText.includes("(prefers-color-scheme: light)")) rule.appendMedium("(prefers-color-scheme: light)");
              if (!rule.mediaText.includes("(prefers-color-scheme: dark)")) rule.appendMedium("(prefers-color-scheme: dark)");
              if (rule.mediaText.includes("original")) rule.deleteMedium("original-prefers-color-scheme");
            } else { //else if (!darkMode) {
              rule.appendMedium("original-prefers-color-scheme");
              if (rule.mediaText.includes("light")) rule.deleteMedium("(prefers-color-scheme: light)");
              if (rule.mediaText.includes("dark")) rule.deleteMedium("(prefers-color-scheme: dark)");
            } /*else {
              rule.appendMedium("(prefers-color-scheme: dark)");
              if (rule.mediaText.includes("light")) rule.deleteMedium("(prefers-color-scheme: light)");
              if (rule.mediaText.includes("original")) rule.deleteMedium("original-prefers-color-scheme");        
            }*/
          }
        }
        //}
      }
    }
  
    // Sets localStorage state
    function setDarkModeLocalStorage(state) {
      localStorage.setItem("jDarkMode", state);
    }
  
    // Gets localStorage state
    function getDarkModeLocalStorage() {
      return localStorage.getItem("jDarkMode");
    }
  
    // Update all "Dark Mode Switcher" buttons after DOMContentLoaded
    document.addEventListener('DOMContentLoaded', () => {
      const dmsBtns = document.querySelectorAll("button.dms-button");
      dmsBtns.forEach((dmsBtn) => {
        updateButton(dmsBtn, darkMode);
        // Set eventListeners for all "dark-mode"-toggle-buttons on click and set localStorage
        dmsBtn.addEventListener("click", () => {
          let darkMode = window.jDarkMode = (getDarkModeLocalStorage() === "false");
          setDarkModeLocalStorage(darkMode);
          dmsBtns.forEach((dmsBtn) => updateButton(dmsBtn, darkMode));
          updateMode(darkMode);
        });
      });
    });
  
  })();
</script>

Den oben angezeigten Code einfach markieren, kopieren und in euer Modul einfügen.

Das war's.

Anschließend muss das Modul nur noch gespeichert werden und dann sollte auch schon euer neuer ☀️Light- / 🌙Dark-Mode Toggle-Button oben in der Status-Leiste erscheinen (bzw. in der mobilen Version unten, versteckt hinter den drei Punkten ...).


English Video Tutorial on how to build the Dark Mode Switch

The great Tim "Hey there Joomla Fans, I'm a Joomla Fan too" Davis from Basic Joomla Tutorials published a YouTube video on 11/14/2023 explaining how to build the Dark Mode Switcher module in Joomla 5. All you need is our code snippet from above and Tim shows in his video all the steps how to embed it:


Webdesign, Webentwicklung & SEO

Teilen: