Skins durch Klassen erweitern

Ich möchte für den neuen Installer eine Auswahl an guten Skins haben, da man diese ja in Kürze schon bei der Installation auswählen kann. Aus diesem Grund wollte ich mal an Hand des Skins CityNight aufzeigen, was sich auch mit unserem Skin-System schon machen lässt:

CityNight - Skin

CityNight - Skin

Als Basis habe ich hier Bootstrap verwendet. Somit passt er sich auf allen Endgeräten an der Größe des Browsers an. Ein weitere Besonderheit ist, dass man den Text oben im Skin bearbeiten kann. Um diese Bearbeitung zu Realisieren habe ich dem Skin eine Klasse hinzugefügt. Die Möglichkeit besteht schon relativ lange, so dass ihr auch nicht befürchten muss, dass es im alten Stand noch nicht läuft.

Dazu habe ich meine index.php folgendermaßen aufgebaut:

<?php Skin_CityNight_Core::init(); ?>
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="<?PHP echo sys::getFullSkinPath(); ?>bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="<?PHP echo sys::getFullSkinPath(); ?>style.css" rel="stylesheet">
  <link href='http://fonts.googleapis.com/css?family=Oswald' rel='stylesheet' type='text/css'>
  <?PHP sys::includeHeader(); ?>
  </head>

  <body>
    <div class="navbar navbar-fixed-top navbar-inverse" role="navigation">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
        </div>
        <div class="collapse navbar-collapse">
          <?php Skin_CityNight_Core::displayGlobalMenu(); ?>
        </div>
      </div>
    </div>

    <div class="container main">
      <div class="row row-offcanvas row-offcanvas-right">
        <div class="col-xs-13 col-sm-10 col-md-offset-1">
          <div class="jumbotron">
            <h1><?php Skin_CityNight_Core::display_title(); ?></h1>
            <p>
              <?php Skin_CityNight_Core::display_teaser(); ?>
            </p>
          </div>
        </div>

        <div class="col-xs-12 col-sm-8">
          <div id="main_content" class="col-6 col-sm-12 col-lg-11 col-lg-offset-1">
            <?PHP
              sys::includeContent();
            ?>
          </div>
        </div>

        <div class="col-xs-12 col-sm-4 col-lg-3" id="sidebar" role="navigation">
          <div class="list-group">
            <?php Skin_CityNight_Core::displayLocalMenu(); ?>
          </div>
        </div>
      </div>

      <footer>
        <p>
          <a href="http://www.contentlion.de">CMS by ContentLion</a>
        </p>
      </footer>

    </div>
    <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src="<?PHP echo sys::getFullSkinPath(); ?>bootstrap/js/bootstrap.min.js"></script>
    <script>
      $(document).ready(function() {
        $('[data-toggle=offcanvas]').click(function() {
          $('.row-offcanvas').toggleClass('active');
        });
      });
    </script>
  </body>
</html>

Die Hauptfunktionen habe ich zum Großteil als statische Funktionen in die Klasse Skin_CityNight_Core ausgelagert. Da kann ich dann auch komplexere Aktionen ausführen, ohne die index selbst mit zu viel Code zu überlagern.

Die interessantesten Funktionen hier sind Skin_CityNight_Core::display_teaser und Skin_CityNight_Core::init. Durch sie kann man das oben im Screenshot angezeigte “Mich kann man Bearbeiten” bearbeiten. Werfen wir doch als erstes mal einen Blick in die display_teaser-Funktion:

<?php
  class Skin_CityNight_Core
  {
  //... gekürzt...
    public static function display_teaser()
    {
      if(User::Current()->isAdmin() && isset($_GET['edit_header']))
      {
        self::display_admin_header();
      }
      else {
        self::display_user_header();
      }
    }
  //... gekürzt...
  }

Mit dem GET-Parameter “edit_header” kann man angeben, ob der Teaser gerade bearbeitet werden soll oder nicht. Für die Bearbeitung sind Administrationsrechte erforderlich. In der Funktion display_user_header wird der Header dann angezeigt:

<?php
  class Skin_CityNight_Core
  {
    //... gekürzt ...
    private static function display_user_header()
    {
      echo htmlentities(self::get_teaser_content());
      if(user::Current()->isAdmin())
      {
        $url = $_SERVER['REQUEST_URI'];
        if(strpos($url,"?") === false)
        {
          $url .= "?edit_header=1";
        }
        else
        {
          $url .= "&edit_header=1";
        }
        echo  " <a href='".$url."'>".Language::DirectTranslateHtml("EDIT")."</a>";
      }
    }
    //... gekürzt ...
  }

Hier wird zum einen der Inhalt des Teasers ausgegeben und zum anderen ein Bearbeiten-Link, wenn der User die erforderlichen Rechte hat. Ich habe die Funktionen übrigens alle so kurz gehalten, weil Netbeans 7.4 jetzt Warnungen anzeigt, wenn der Inhalt zu lang ist. Wollte mal schauen, ob ich das schaffe ;-)

Weiter zur Funktion get_teaser_content. Sie liefert den Inhalt für den Teaser zurück. Das sieht dann so aus:

<?php
  class Skin_CityNight_Core
  {
    //... gekürzt ...
    private static function get_teaser_content()
    {
      $teaser = Settings::getRootInstance()->specify("skin", "citynight")->get("teaser");
      if(empty($teaser))
      {
        return self::get_default_teaser();
      }
      else
      {
        return $teaser;
      }
    }
    //... gekürzt ...
  }

Der Inhalt des Teasers steht in den Settings. Diese sind auf den Bereich skin/citynight eingeschränkt, so dass die Einstellung wirklich nur für den Skin ist. Zu guter letzt habe ich auch noch die Fukntion get_default_teaser gemacht, die den Standard-Text zurückgibt. Am liebsten würde ich diesen durch die Sprachdateien ersetzten, die gibt es im Skin-System aber leider noch nicht:

<?php
  class Skin_CityNight_Core
  {
    //... gekürzt ...
    private static function get_default_teaser()
    {
      switch(strtolower(trim(Settings::getValue("language"))))
      {
        case "de":
          return "Diesen Text können Sie ändern! Loggen Sie sich einfach als Administrator ein.";
        default:
          return "You can change this text! Just log in as administrator.";
      }
    }
    //... gekürzt ...
  }

Und so wird unser Text schon mal angezeigt.

Um den Text zu bearbeiten brauchen wir auch noch ein Formular:

<?php
  class Skin_CityNight_Core
  {
    //... gekürzt ...
    private static function display_admin_header()
    {
      echo "<form method='POST'>"
          ."<textarea name='skin_citynight_change_teaser' id='skin_citynight_change_teaser'>"
            .htmlentities(self::get_teaser_content())
          ."</textarea>"
          ."<button type='submit'>".Language::DirectTranslateHtml("SAVE")."</button>"
        ."</form>";
    }
    //... gekürzt ...
  }

Jetzt müssen wir den Text nur noch speichern. Das macht die init-Funktion, welche bei mir ganz oben im Skin aufgerufen wird:

<?php
  class Skin_CityNight_Core
  {
    //... gekürzt ...
    public static function init()
    {
      if(User::Current()->isAdmin() && isset($_POST['skin_citynight_change_teaser']))
      {
        Cache::clear();
        Settings::getRootInstance()->specify("skin", "citynight")->set("teaser",$_POST['skin_citynight_change_teaser']);
        Settings::forceReload();
        header("Location: ".str_replace("?edit_header=1","",str_replace("&edit_header=1","",$_SERVER['REQUEST_URI'])));
        exit;
      }
    }
    //... gekürzt ...
  }

Komplexere Skins

Die Skins aus unserer Gallerie sind aktuell oftmal ähnlich aufgebaut. Durch das Benutzen der Klassen kann man die zum Teil im Core noch fehlenden Funktionen nachrüsten. Allerdings sollte das auch nicht übertrieben werden. Sind die Änderungen sehr allgemein, kann man so vielleicht auch einfach ein neues Plugin herausbringen und im Skin prüfen, ob das Plugin installiert ist. Denn einen Skin kann man nicht aktivieren, er ist einfach da. Denn in den Klassen des Skins sollten hauptsächlich kleinere Designanpassungen vorgenommen werden. Das Bearbeiten von Texten/Bildern ist aber so gerade noch ok.

Dieser Beitrag wurde unter Skins veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>