In diesem zweiten Teil zeige ich wie man bspw. Bootstrap-Dateien, die man joomlakonform eingebunden / geladen hat mit eigenen updatesicher überschreiben kann. Beispielsweise um Joomla 3 von Bootstrap 2 auf 3 aufzurüsten oder das Laden von Bootstrap aus dem Core zu verhindern, indem man einfach leere Override-Dateien anlegt. Wer weiterdenkt. . .

Einleitung

In Teil 1 wurde gezeigt, dass nicht nur das Template, sondern auch diverse Erweiterungen z.B. Bootstrap oder andere Bibliotheken aus dem /media/jui/-Verzeichnis laden können. Soweit diese Erweiterungen das joomlakonform mit JHtml-Methoden machen, kann man mit untiger Overridetechnik erreichen, dass stattdessen ALLE diese Erweiterungen die Dateien aus dem eigenen Template-Ordner abholen, ob nun mit anderem Inhalt oder leer (um sie "fies" totzuschalten).

Es gibt auch Hacks wie man solche "unerwünschten" Dateien aus dem Head entfernen kann, bevor dieser gerendert wird. Das ist hier nicht Thema, verwende ich auch nie, da man nahezu alles mit Joomlamitteln hinbekommt. Eines dieser Mittel stelle ich für Weiterdenker vor.

Vorbereitungen

Siehe "Vorbereitungen" im Teil 1 des Tutorials: Joomla 3 Templates verstehen - Der Template HEAD Teil 1.

Template-Grundgerüst des Teils 2

Schon in Teil 1 des Tutorials hatten wir die Datei index.php des Testtemplates stark reduziert, da wir uns vornehmlich auf den HEAD-Tag des Templates konzentrieren wollen. Wir beginnen auch Teil 2 mit einem minimalistischen Jooomla-3.4.1-Template, das zuerst Bootstrap 2.3.2 joomlakonform einbindet (JavaScript-Dateien in Zeile 8 und CSS-Dateien in Zeile 5), sowie eine template.js (Zeile 11) und template.css (Zeile 12) unseres Templates Protostartest. Die joomlakonforme Inkludierung ermöglicht uns in weiteren Schritten das Umstellen auf Bootstrap 3 via Overrides.

Die template.css im Ordner templates/protostartest/css/ habe ich komplett geleert, da sie eine Kopie vom originalen Protostar ist und alle Bootstrap-CSS-Anweisungen enthält. Sie ist in großen Teilen eine Kopie der CSS-Dateien, die wir im Code unten per JHtml::_('bootstrap.loadCss'); laden. Das würde spätestens, wenn wir auf Bootstrap 3 umswitchen zu Konflikten führen, da BS3 in großen und bei einigen wichtigen Anweisungen nicht abwärtskompatibel ist. Die BS2-Anweisungen der template.css würden oft stören, die Seite zerlegen.

<?php
defined('_JEXEC') or die;

// Lade Bootstrap-CSS aus dem Core.
JHtml::_('bootstrap.loadCss');

// Lade Bootstrap-JS aus dem Core und zugleich JQuery.
JHtml::_('bootstrap.framework');

// Lade JS und CSS unseres Templates.
JHtml::_('script', 'templates/protostartest/js/template.js');
JHtml::_('stylesheet', 'templates/protostartest/css/template.css');
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xml:lang="<?php echo $this->language; ?>"
      lang="<?php echo $this->language; ?>"
      dir="<?php echo $this->direction; ?>">
<head>
  <jdoc:include type="head" />
</head>
<body>

</body>
</html>

Das Ergebnis im Seitenquelltext des Frontends sieht dann so aus (das /joomla34/ ist spezifisch für meine Testinstallation; wegdenken!):

...
<head>
  <base href="http://localhost/joomla34/" />
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <meta name="generator" content="Joomla! - Open Source Content Management" />
  <title>Home</title>
  <link href="http://localhost/joomla34/index.php" rel="canonical" />
  <link href="/joomla34/templates/protostartest/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
  <link rel="stylesheet" href="/joomla34/media/jui/css/bootstrap.min.css" type="text/css" />
  <link rel="stylesheet" href="/joomla34/media/jui/css/bootstrap-responsive.min.css" type="text/css" />
  <link rel="stylesheet" href="/joomla34/media/jui/css/bootstrap-extended.css" type="text/css" />
  <link rel="stylesheet" href="/joomla34/templates/protostartest/css/template.css" type="text/css" />
  <script src="/joomla34/media/jui/js/jquery.min.js" type="text/javascript"></script>
  <script src="/joomla34/media/jui/js/jquery-noconflict.js" type="text/javascript"></script>
  <script src="/joomla34/media/jui/js/jquery-migrate.min.js" type="text/javascript"></script>
  <script src="/joomla34/media/jui/js/bootstrap.min.js" type="text/javascript"></script>
  <script src="/joomla34/templates/protostartest/js/template.js" type="text/javascript"></script>

</head>
....

Joomla lädt für BS drei Stück CSS-Dateien (Zeilen 9-11), die JavaScript-Bibliothek JQuery gleich mit, da BS sie zwingend benötigt, egal ob Version 2 oder 3, und danach die JavaScriptdatei für BS selbst (Zeile 16).

Leider sind ein großer Teil der Dateien schwer lesbar, wenn man mal auf einen der Links im Quelltext klickt. Sie sind minifiziert, meist erkennbar an dem .min. im Dateinamen. Es gibt keine praktikable Variante unserer JHtml-Zeilen, die das verhindern würden. Für einzelne schafft man das mal, für alle in einem Rutsch nicht. Probier selbst. Vielleicht findest du den Stein der Weisen. Was man machen kann, um sie unminifiziert geladen zu bekommen, ist in der Joomla-Konfiguration den Debug-Modus zu aktivieren. Das spare ich mir aber hier. Probiers aus und du siehst warum. Zu viel zusätzlicher "Kram" wird in den Quelltext der Seite geladen, obwohl wir noch keine Modulposition innerhalb des BODY eingerichtet haben.

Ein Blick in die Core-Ordner /media/jui/js/ oder /media/jui/css/ und du siehst, dass dort zu nahezu jeder minifizierten Datei auch eine unminifizierte vorliegt, wenn man mal den Code sichten will.

Im Unterschied zu Plugins die es dafür gibt, minifiziert also Joomla nicht on-the-fly, sondern ruft eben explizit die min-Version ab. Das gilt es zu beachten, auch, wenn wir später Overrides verwenden, die exakt wie die Originaldateien benannt sein müssen.

Der Override

Bootstrap-Javascript

JQuery wird man in den seltensten Fällen überschreiben müssen/wollen. Zwar wird in vielen Tutaorials der Eindruck erweckt, aber die Version die Joomla bei hat und auch regelmäßig aktualisiert, ist ausreichend. Die zusätzlich geladene jquery-migrate.min.js kümmert sich um Kompatibilität mit veraltetem JQuery-Code. Viel zu oft probieren Leute ihren veralteten Slider durch Einbinden von veraltetem JQuery zu reparieren, noch dazu mit LINK und SCRIPT-Tags direkt in der index.php. Das ist ein Weg in's JavaScript-Chaos und füllt Foren... Der Override für JQuery funktioniert analog zu folgendem Vorgehen, bei dem wir Bootstrap2- durch Bootstrap3-Bibliotheken ersetzen.

Erstelle eine Datei (und Ordner), also einen Template-Override für die Bootstrap-Javascript

/templates/protostartest/js/jui/bootstrap.min.js

Tippe in die Datei:

alert("hallo");

und lade dein Template im Frontend.

hallo.jpg

Unser Override wurde also statt der Originaldatei geladen. Überzeuge dich im Seitenquelltext:

<script src="/joomla34/templates/protostartest/js/jui/bootstrap.min.js" type="text/javascript"></script>

Und noch mal erwähnt: Ändere den Dateinamen (ohne min)

/templates/protostartest/js/jui/bootstrap.js

Kein Override im Seitenquelltext, da falscher Dateiname.

Aktiviere den Debugmodus in der Joomla-Konfiguration. Und voilà, im Seitenquelltext die Override-Datei ohne min

<script src="/joomla34/templates/protostartest/js/jui/bootstrap.js" type="text/javascript"></script>

Debugmodus wieder ausschalten und Datei wieder zurückbenennen.

Bootstrap-CSS

Funktioniert genauso wie mit JS, nur, dass du deine Override-Dateien im Ordner

/templates/protostartest/css/jui/

anlegst. Z.B. die bootstrap.min.css.

Hinweis:

Die Zeile

JHtml::_('bootstrap.loadCss');

wird sehr selten im Joomla-Core verwendet. Man könnte also auf die Idee kommen, da sie lästigerweise 3 Dateien lädt, was man vielleicht gar nicht benötigt, die eigene Bootstrap-CSS auf eigene Art und Weise einzusetzen. Ich bevorzuge es, alle 3 Dateien als Overrides anzulegen und lieber die eine oder andere leer zu lassen.

Man kann auch mit folgender Variante herumspielen, um nur 1 Datei zu laden

JHtml::_('stylesheet', 'jui/bootstrap.min.css', array(), true);

Seit Joomla 3.7 lautet die Zeile so:

JHtml::_('stylesheet', 'jui/bootstrap.min.css', array('relative' => true));

Man darf halt nie vergessen, dass vielleicht irgendeine Erweiterung doch die Zeile

JHtml::_('bootstrap.loadCss');

verwendet oder andere Variationen, die einem Bootstrap-2-Zeugs einschleppen, weil man keinen leeren Override angelegt hat.

Klar, schön ist das nicht... Aber vornehmliches Ziel ist ja, nichts doppelt zu laden, nicht versehentlich kollidierende Versionen von bspw. JQuery und Bootstrap zu laden, was absoluter Seitenkiller ist. Mit ein bisschen Kreativität packt man halt andere Inhalte rein, die nicht unbedingt zum Dateinamen passen. Mir egal.

Und sollte es sich in den nächsten 20 Jahren endlich bei den Erweiterungsprogrammierern rumgesprochen haben, dass man seine Joomla-Erweiterung so programmiert, dass Benutzer und andere Programmierer die Chance haben joomlakonform Overrides zu verwenden... Juhu! Wie im Teil 1 und auch oben zu sehen, zu testen, ist schon ein magisches true im Aufruf eine echte Erleichterung für Overrider.

Jetzt aber mal richtig

Auf http://getbootstrap.com/getting-started/ laden wir das Paket "Bootstrap" herunter und entpacken es. Das Paket enthält un- und minifizierte Dateien und heißt zum Zeitpunkt des Tutorials "bootstrap-3.3.4-dist". Hier die Kopie der originalen ZIP, wie ich gerade heruntergeladen habe:

Eingeworfen: Die LESS-Versionen, die ich mittlerweile viel praktischer finde, v.a., weil man sich hier ein passendes Paket selbst zusammenstellen kann: http://getbootstrap.com/customize/ sind mir für dieses Tutorial zu aufwendig zu erklären. Vielleicht später mal. (Nebenbei, auch Joomla arbeitet mit LESS-Dateien aus dem /media/-Ordner als Basis, die für die Joomla-Realeases aber zu CSS kompiliert werden. Wenn man's kann, kann man sein Template aber auch mit Bootstrap-2-LESS-Dateien aus dem Joomla-Core versorgen. Allerdings höhere Weihen, wenn man dann auch noch mit Overrides arbeiten will, um Konflikte zu vermeiden.)

Wir legen 3 Ordner an in unserem Template, falls noch nicht geschehen

  1. /templates/protostartest/css/fonts/ (nicht(!) im Unterordner /jui/)
  2. /templates/protostartest/css/jui/
  3. /templates/protostartest/js/jui/

In den 1. Ordner kopieren wir den Inhalt des Ordners /fonts/ aus dem entpackten BS-Paket.

In den 2. Ordner alle CSS-Dateien (*.css).

In den 3. Ordner alle JavaScriptdateien (*.js). (Die npm.js braucht man nicht).

Wir laden unsere Seite im Frontend neu, werfen einen Blick in den Quellcode und sehen, dass wir für ein pures Botstrap 3 noch 2 leere CSS-Dateien anlegen müssen

  1. /templates/protostartest/css/jui/bootstrap-responsive.min.css
  2. /templates/protostartest/css/jui/bootstrap-extended.css

Und das Ergebnis sieht dann so aus (ich habe ein paar Stellen gekürzt, wegen Ausdruck):

...
<head>
    <base href="http://localhost/joomla34/" />
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <meta name="generator" content="Joomla! - Open Source Content Management" />
  <title>Home</title>
 <link href="http://localhost/joomla34/index.php" rel="canonical" />
 <link href="/joomla34/templates/protostartest/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
 <link href="/joomla34/templates/protostartest/css/jui/bootstrap.min.css" type="text/css" />
 <link href="/joomla34/templates/protostartest/css/jui/bootstrap-responsive.min.css" type="text/css" />
 <link href="/joomla34/templates/protostartest/css/jui/bootstrap-extended.css" type="text/css" />
 <link href="/joomla34/templates/protostartest/css/template.css" type="text/css" />
  <script src="/joomla34/media/jui/js/jquery.min.js" type="text/javascript"></script>
  <script src="/joomla34/media/jui/js/jquery-noconflict.js" type="text/javascript"></script>
  <script src="/joomla34/media/jui/js/jquery-migrate.min.js" type="text/javascript"></script>
  <script src="/joomla34/templates/protostartest/js/jui/bootstrap.min.js" type="text/javascript"></script>
  <script src="/joomla34/templates/protostartest/js/template.js" type="text/javascript"></script>

</head>
...

Beispielseiten

Auf http://getbootstrap.com/getting-started/#examples findet man ein paar Template-Beispiele, natürlich nicht tricky Joomla, sondern pures HTML.

Bootstrap starter template

http://getbootstrap.com/examples/starter-template/

Geh in den Seitenquelltext dieser Seite. Du siehst, dass eine weitere CSS-Datei dabei ist, die starter-template.css. Klicke im Seitenquelltext auf den Link und kopiere den Inhalt in deine eben noch leere /templates/protostartest/css/template.css.

Dann kopierst du alles HTML zwischen <body> und </body>, außer den 3 JavaScript-Verweisen am Ende in deinen Protostartest-Template-BODY.

<body>

    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Project name</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">Home</a></li>
            <li><a href="#about">About</a></li>
            <li><a href="#contact">Contact</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>

    <div class="container">

      <div class="starter-template">
        <h1>Bootstrap starter template</h1>
        <p class="lead">Use this document as a way to quickly start any new project.<br> All you get is this text and a mostly barebones HTML document.</p>
      </div>

    </div><!-- /.container -->
</body>

Im Firefox > Extras > Web-Entwickler > Bildschirmgröße testen kannst du responsives Verhalten prüfen.

Theme example

http://getbootstrap.com/examples/theme/

Blick in Quelltext offenbart dir, dass hier die bootstrap-theme.min.css eingebunden wird. Die haben wir vorher schon in unsere BS3-Override-Ordner des Templates kopiert, da im Paket dabei.

Erst mal die template.css wieder leeren, damit uns nicht in die Quere kommt.

Jetzt kannst du entweder die bootstrap-theme.min.css umbenennen in bootstrap-responsive.min.css oder bootstrap-extended.css, weil wir die ja eh nicht nutzen und bei uns bisher leer waren

oder

fügst in deinem Template-Head folgende Zeile hinzu, damit die bootstrap-theme.min.css zusätzlich geladen wird

JHtml::_('stylesheet', 'templates/protostartest/css/jui/bootstrap-theme.min.css');

Es würde aber auch gehen, was ich bevorzugen würde, da wir unsere bootstrap-theme.min.css in einem Overrideordner haben (obwohl wir gar keine solche Datei in /media/jui/css/ haben(!))

JHtml::_('stylesheet', 'jui/bootstrap-theme.min.css', array(), true);

Seit Joomla 3.7. lautet die Zeile so:

JHtml::_('stylesheet', 'jui/bootstrap-theme.min.css', array('relative' => true));

Und dann fehlt dir noch die theme.css, die du im Original findest, die du wieder in deine template.css kopierts wie oben im ersten Beispiel.

Abschließend wieder den BODY-Inhalt in dein Protostartest und wieder ohne die JavaScript-Verweise am Ende...

Nachreichungen

Das mit den minifizierten Dateien kann lästig sein. Gerade, wenn man noch am Forschen ist. Natürlich kann eine Datei mit .min. im Namen auch unminifizierten Inhalt haben. Ist ja nur eine Name.

Es ist nicht empfohlen an den Original-Bootstrap-Dateien INHALTLICH was zu verändern, schon wegen erschwerter Updates. Das sollte man immer in einer weiteren CSS-Datei (template.css) machen.

Ein Folgetutorial ist (bestenfalls) in Planung. Momentan arbeiten wir an einem Templateprojekt (quälen uns damit) bei dem wir eine feine Plugin-Idee aufgegriffen haben, mit dem man, wenn man weiterentwickelt, keine der o.g. Overrides im Template selbst braucht, sondern für mehrere eigene Templates verwendbar in eigenem /media/-Unterverzeichnis. Früher oder später wird bzgl. Bootstrap aber auch Joomla nachrüsten. Kann man sicher sein.

Danke, Re:Later, für Veröffentlichung auf meiner Webseite!