Kategorien
Webentwicklung

WordPress Premium Themes — Ein Fazit

Ich habe im letzten Monat für eine Immobilienfirma in Hamburg gearbeitet und dabei auf einem Theme aufgesetzt, welches der Kunde sich gewünscht hat. Ein WordPress-Premium-Theme.

Ich hatte in der Vergangenheit ein paar Projekte mit Themes von Elmastudio umgesetzt, was ich auch nie wirklich als problematisch empfand. Die Themes sind recht ausgereift und überschaubar.

Nun hatte ich einen Kunden, der eine Seite auf Basis eines amerikanischen Premium-Themes erstellt haben wollte. Die Vorleistung, die das Theme liefert, hätte ich in der kurzen Zeit nicht aufholen können. Allerdings weiss ich nach über 10 Jahren Softwareentwicklung, dass in jedem Projekt, in dem ein Framework zum Einsatz kommt (oder man selbst etwas einigermaßen Framework-ähnliches im Zuge dessen entwickelt).

Die Demo des Themes zeigt so einige Dinge, was dabei nicht erwähnt wird: 50% dieser Dinge, die auch beim Kunden die Kaufentscheidung stark beeinflusst hatten, werden von diversen kostenpflichtigen Premium-Plugins nachgeliefert, für die (und nur die) das Theme auch entsprechende Vorbereitungen mitbringt.

Basis des Themes bildet eine Integration von WP-Job-Manager. Soweit so gut. Damit diese Jobs in dem Theme auch facettiert gesucht werden können, muss WP-Facet-Search gekauft und installiert werden (79$). Damit die Jobs dann auch die Tags-Taxonomie von WordPress verwenden können, muss das entsprechende Plugin für 19$ gekauft werden. Slider Integration besteht für das Theme keine.

Um einen Slider auf der Homepage zu integrieren, musste ich ein neues Template erstellen und einige Styles anpassen, damit das überhaupt funktioniert hat.

Für die “widgetized Homepage” die Templates für die Widgets zu überschreiben wäre eigentlicht einfach, wenn man, wie sonst auch im Theme “get_template_part()” verwendet oder die Widget-Functions wenigstens pluggable gemacht hätte. So konnte ich komplette Funktionen inkl integiertem HTML kopieren und damit die Anzahl der Widgets fast verdoppeln.

Einfach war dann hingegen das Erweitern der Jobs-Einträge um neue Felder – das ist aber eher eine Funktion von WP Jobs Manager, nicht vom Theme.

Ach ja: Um mit WP-All-Import neue Einträge in die Datenbank mit den neuen Feldern (oder auch denen, die das Theme schon hinzugefügt hat) zu importieren, wäre auch noch ein Premium Plugin notwendig.

Und SVG-Icons inline mit get_template_part() einzubinden, finde ich wieder eine sehr gute Idee.

Und wenn ein Theme mit Customify kommt: nutzt für eigene Styles und Scripte lieber ein Child theme statt den Funktionen für “Custom CSS” und “Custom Javascript”. Das ist versionierbar, cache-freundlich und deutlich einfacher ausrollbar.

Fazit

Ich bin nicht begeistert von solchen Single-Purpose-Themes. Insbesondere nicht, wenn das Theme umfangreiche Extra-Funktionen mitbringt, die mit dem Wechsel des Themes verloren gehen. Da es in diesem Fall um Immobilien ging, wäre eine Lösung auf Basis von WpCasa vermutlich sinnvoller und nachhaltiger gewesen, da es mittlerweile auf einem (Free) Plugin basiert (auch hier sind kostenpflichtige Erweiterungen vorhanden). Bei einem Relaunch der Seite, die dann mit weniger Zeitdruck erfolgt, werde ich das auch noch mal genauer evaluieren.

Jedenfalls ist meine Erwartung, wenn ich ein solches Single-Purpose-Theme kaufe, dass das ganze wie in den Demos funktioniert und wenn ich dafür etwas nachkaufen muss, dann sollte das in der Demo auch dabeistehen, was noch zusätzlich für die Funktion gekauft werden muss. Für mich als Entwickler ist das nämlich ziemlich besch****, wenn ich alle Nase lang sagen muss “dazu musst Du noch Plugin xy für xx$ nachkaufen”. Mag sein, dass andere das anders machen, ich finde das unschön.

Lernen kann man von den Premium-Themes auf jeden Fall einiges, gutes, und schlechtes.

Kategorien
Webentwicklung Werkzeuge

REST-Api mit dem Caddyserver simulieren

Ja, ich bin ein Fanboy. Ja, der bin ich gerne, wenn das “Produkt” oder Projekt sinnvoll und inspirierend ist. Ich arbeite zum Beispiel in Teams, bei denen jeder Entwickler eigener Herr seiner Maschine ist und ich exakt nichts voraussetzen kann, was jemand auf seinem Rechner installiert hat, wo er es hat und wie es konfiguriert ist.

Wenn man SPAs entwickelt, kann man natürlich für eine reine Frontend-Entwicklung eine komplette Vagrant-Box aufsetzen. Das ergibt für das Backend-Team einfach mehr Sinn. Da nicht jeder über eine generische Umgebung für den Apachen verfügt und das unter Windows z.B. auch eher suboptimal läuft, war ich total begeistert als ich über den Caddyserver gestolpert bin: “Serve the web like it’s 2016”. Caddy hat Binaries für Windows, Linux und OSX und braucht nur ein ziemlich einfaches Konfig-File.

Damit ist ein zweiter Entwickler ohne viel Stress in der Lage, ein SPA-Projekt zu übernehmen. Er braucht die Entwicklungs-Tools und den Caddyserver. Unsere aktuellen SPA-Projekte haben diese Datei schon von mir verpasst bekommen, in der Regel mit Proxy-Rewrites. die auf die Maschine mit dem Backend zeigen.

Aber man kann in den frühen Phasen des Projekts auch eine API und die entsprechenden REST-Requests mit lokalen JSON-Dateien simulieren, damit kann auch ein Abzug einer API lokal statisch genutzt werden. Das ist z.B. bei der Entwicklung von SPAs mit AngularJS oder EmberJS praktisch.

Ein GET-Request an /api/test/eintest  wird damit auf die Datei /data/get_test_eintest.json umgeleitet. Auch Antworten eines Post-Requests lassen sich mit /data/post_test.json simulieren.

Weitere Doku:

Code für einen lokalen API-Abzug in JSON-Files

:9090
gzip
rewrite /api {
	r ^/(.*?)/(.*?)/(.*?)/(.*?)/(.*?)(/|)$
	to /data/{method}_{1}_{2}_{3}_{4}_{5}.json
}
rewrite /api {
	r ^/(.*?)/(.*?)/(.*?)/(.*?)(/|)$
	to /data/{method}_{1}_{2}_{3}_{4}.json
}
 
rewrite /api {
	r ^/(.*?)/(.*?)/(.*?)(/|)$
	to /data/{method}_{1}_{2}_{3}.json
}
 
rewrite /api {
	r ^/(.*?)/(.*?)(/|)$
	to /data/{method}_{1}_{2}.json
}
 
rewrite /api {
	r ^/(.*?)(/|)$
	to /data/{method}_{1}.json
}

Das ganze kann ich auch gerne noch mal als .htaccess-Datei für den Apachen zur Verfügung stellen.

Kategorien
Webentwicklung Werkzeuge

Websites bauen mit pimcore

phpstorm

Ich bin ja als PHP-Entwickler nicht gerade erfahren, ich mach dann eher das mit dem Frontend. Neuerdings beschlich mich allerdings der dringende Wunsch, mal ein bisschen Abwechslung zu haben und ich habe mich auch mal auf der Entwicklungsseite mal ein bisschen mit pimcore auseinandergesetzt.

Dazu habe ich eine kleine Website gebaut, die über Energydrinks informieren kann. Die Website ist direkt zweisprachig und von Objekten getrieben. Ich will nur mal einen kleinen Einblick geben, wie das ganze anhand der Drink-Darstellung aussieht.

Der Drinks-Controller

<?php

use Website\Controller\Action;
use Pimcore\Model\Object;


class DrinksController extends Action
{

    public function defaultAction()
    {
        $this->enableLayout();

    }

    public function listDrinksByCaffeineAction()
    {
        $this->enableLayout();

        $drinkList = new Object\Drink\Listing();
        $drinkList->setOrderKey("Koffeingehalt");
        $drinkList->setOrder("DESC");

        $this->view->drinks = $drinkList;


    }

    public function drinkDetailAction(){
        $this->enableLayout();

        $drink = Object\Drink::getById($this->getParam('id'));

        $this->view->drink = $drink;

    }

    public function indexAction()
    {
        $this->enableLayout();
    }
}

Hier werden eigentlich nur zwei Views mit passenden Daten gefüllt, die dann z.B. in list-drinks-by-caffeine.php (man beachte die Benamung der Datei im Vergleich mit der Action) angezeigt werden:

<?php
$this->layout()->setLayout('standard');
$lang_prefix = $this->document->getProperty('mainNavStartNode')->getFullPath();
?>


<?php while ($this->block("contentblock")->loop()) { ?>
    <?= $this->wysiwyg("content"); ?>
<?php } ?>


<table class="table">
    <tr>
        <th><?= $this->translate("Bild"); ?></th>
        <th><?= $this->translate("Koffeingehalt"); ?> / 100ml</th>
        <th><?= $this->translate("Name"); ?></th>
        <th><?= $this->translate("Hersteller"); ?></th>
    </tr>



    <?php
    /** @var  \Pimcore\Model\Object\Drink $drink */
    foreach ($this->drinks as $drink) { ?>

        <tr>
            <td>
                <a href="<?= $this->url(array(
                    "prefix" => $lang_prefix,
                    'id' => $drink->getId()
                ), "drink") ?>">
                    <?php if ($drink->getBild()) { ?>
                        <?= $drink->getBild()->getThumbnail('list')->getHTML() ?>
                    <?php } ?>
                </a>

            </td>

            <td class="col-sm-4">
                <?= $drink->getKoffeingehalt(); ?>

            </td>
            <td class="col-sm-4">


                <a href="<?= $this->url(array(
                    "prefix" => $lang_prefix,
                    'id' => $drink->getId()
                ), "drink") ?>">
                    <?= $drink->getName(); ?>
                </a>
            </td>
            <td class="col-sm-4">

                <a href="<?= $this->url(array(
                    "prefix" => $lang_prefix,
                    'id' => $drink->getHersteller()->getId()
                ), "hersteller") ?>">
                    <?= $drink->getHersteller()->getName(); ?>

                </a>

            </td>
        </tr>

    <?php }; ?>

</table>

Das sieht dann so aus:

Drinks Übersicht
Drinks Übersicht

Für die Abbildung der Detail-Ansicht muss man sich dann ein bisschen mit statischen Routen befassen, die man in pimcore pflegen kann, die sieht dann so aus:

static_routes

Drinks Detail
Drinks Detail

Zusammenfassend kann ich sagen:

Mit dem CMS/PIM-System pimcore und dem Hilfsmittel PHPStorm bekomme ich (PHP nicht so erfahren) recht schnell brauchbare Ergebnisse und kann Seiten, die viele strukturierte Daten darstellen sollen, die untereinander verknüpft sind, schnell und einfach umsetzen.

Das ersetzt sicher keinen PHP-Profi, der 10 Jahre Zend-Erfahrung hat, kann aber ein guter erster Schritt sein, solche Modelle mal anzudenken. Wen das ganze interessiert, kann sich bei pimcore.org weitere Informationen holen, oder mich fragen.

Kategorien
Webentwicklung Werkzeuge

Was sich mit HTTP/2 ändern wird

Tools

Gerrit van Aaken beschrieb neulich den Toolchain-Wahn, der die Aufrüstung im Frontend-Development befallen hat. Einige dieser Toolchains nutze ich auch, zum Beispiel das Precompiling von Frontend-Templates in eine Datei, das kompilieren von mehreren LESS- und CSS-Files in eine einzige Datei. Alles, weil HTTP/1.1 teilweise nur einen Request parallalel verarbeitet. Aktuell ist das sinnvoll und notwendig, um überflüssige Header (Overhead) zu verringern und den Übertragungs-Payload möglich hoch zu halten.

Nachdem die Seitenperfomance immer größeren Stellenwert bei Google Rankings bekommt und Amazon mal durchgerechnet hat, wie dramatisch 100 Millisekunden zwischen Bounce und Conversion unterscheiden können, gehört es nicht nur zum guten Ton, sondern zur Pflicht, solche Dinge in seinen Workflow zu integrieren, wenn eine Internetseite für den Unternehmenserfolg ausschlaggeben sein sollte.

Aber was würde Sich ändern wenn unter anderem:

  1. Header komprimiert würden?
  2. Mehrere Requests parallel laufen könnten?
  3. Was, wenn die Site dem Browser Daten ungefragt rüberschiebt?

Dann wäre vieles (nicht alles) dieser Dinge überflüssig. Am Ende muss man die Rechnung Header vs. Payload neu auslegen, wenn Header komprimiert sind und die Dateien parallel geladen werden können. Zusammenfügen der Stylesheets und Javascript-Dateien wäre weniger wichtig als heute. Teilweise könnte das sogar kontraproduktiv sein.

Damit wird die Übergangszeit von HTTP/1.1 auf HTTP/2 für die Frontend-Developer noch eine sehr spannende Zeit werden. (Wer sich den englischen Wikipedia-Artikel über HTTP/2 durchliest, der wird deutlich besser informiert, wo HTTP/2 herkommt (SPDY von Google) und was es so im einzelnen für Änderungen gibt. Der deutsche Artikel ist da eher kurz angebunden.

Wer heute schon testen will, wie sich HTTP/2 in etwa auswirken könnte, der kann sich mal auf einem Apachen mod_spdy installieren und eine Perfomance-Messung vorher-nachher machen. Firefox und Chrome können in den aktuellen Stable-Versionen SPDY von Hause aus, Opera vermutlich auch und der IE wird mit Version 11 nachziehen.

Seid ihr auf die Zukunft vorbereitet? Habt ihr eure Grunt- / Gulp- / $BUILDTOOL-Chains schon vorbereitet? Macht ihr euch noch Gedanken um die aktuelle Optimierungs-Praktik oder lebt ihr schon mit vielen kleinen Dateien in der Zukunft der Webentwicklung? Werdet ihr verschiedene Versionen für HTTP/1.1 und HTTP/2 erstellen müssen?

Kategorien
Webentwicklung Werkzeuge

Creating a Professional WordPress Development Workflow With Vagrant

Creating a Professional WordPress Development Workflow With Vagrant