Weblizards sponsern die Website für den Verein “Carsharing Kaufbeuren e.V.”

carsharing-kf“Aller Anfang ist schwer” – aus diesem Grund haben wir dem Verein Carsharing Kaufbeuren eine neue Website gesponsort.

Was ist Carsharing?

Wer selbst ein Auto hat, kann ganz einfach nachrechnen wie viele Minuten er es am Tag benötigt.

Spreche ich zum Beispiel von mir, benötige ich mein Auto nur etwa 30 Minuten jeden Tag. Ich könnte das Auto daher 23,5 Stunden jemand bzw. mehreren Anderen zur Verfügung stellen.

Carsharing möchte genau diesen Standzeiten den Kampf ansagen und stellt PKW an bestimmten Orten zur Verfügung, die dann über ein Buchungssystem reserviert werden können. Bezahlt wird dann je gefahrenem Kilometer. Alles in allem eine tolle Geschichte, weshalb wir diese hiermit unterstützen wollten.

Ausführlich kann das ganze auf der Website www.carsharing-kf.de nachgelesen werden.

Technisch wurde die Seite mit TYPO3 realisiert.

Wir wünschen dem Carsharing Verein eine guten Start.

HTML Entities im Pimcore Navigation Plugin bzw. der Zend Navigation

Bildschirmfoto 2013-04-09 um 11.25.49
Ausgefallene Menü´s machen es manchmal notwendig direkt im Pimcore Navigationstitel HTML-Entities einzutragen.

<span style="font-size: 2em;">AD</span>
VERTISING

Grundsätzlich werden die HTML-Entities aber von der Zend Navigation escaped.

1. Möglichkeit (etwas unschön)

Das ganze kann ganz einfach umgangen werden, indem man in seinem Controller folgenden Befehl vor seine Navigation schreibt:

$this->view->setEscape('trim');

Bedenklich an dieser Einstellung ist, dass ich mit diesem Befehl die gesamte View-Verarbeitung umstelle und damit höchst wahrscheinlich andere Probleme schaffe.

2. & solide Möglichkeit

Die Anpassung des Zend_View_Helper_Navigation bzw. diesen zu überladen.

Schaut man sich in der Klasse Zend_View_Helper_Navigation (zu finden in /pimcore/lib/Zend/View/Helper/Navigation/Menu.php) die Funktion htmlify (Zend_Navigation_Page $page) mal genauer an, sieht man hier im letzten Teil –> $this->view->escape($label) – welcher für das excapen des Menü´s verantwortlich ist.

Diesen Teil müssen wir nun mit unserem angepassten Teil überladen.

Hierzu habe ich mir im Ordner /website/views/helpers/ eine neue Datei MeinMenu.php angelegt, welche mit Extends obige Klasse erweitert.

class Website_Helper_RobertsMenu extends Zend_View_Helper_Navigation_Menu {

  public function htmlify(Zend_Navigation_Page $page) {
    // get label and title for translating
        $label = $page->getLabel();
        $title = $page->getTitle();

        // translate label and title?
        if ($this->getUseTranslator() && $t = $this->getTranslator()) {
            if (is_string($label) && !empty($label)) {
                $label = $t->translate($label);
            }
            if (is_string($title) && !empty($title)) {
                $title = $t->translate($title);
            }
        }

        // get attribs for element
        $attribs = array(
            'id'     => $page->getId(),
            'title'  => $title,
            'class'  => $page->getClass()
        );

        // does page have a href?
        if ($href = $page->getHref()) {
            $element              = 'a';
            $attribs['href']      = $href;
            $attribs['target']    = $page->getTarget();
            $attribs['accesskey'] = $page->getAccessKey();
        } else {
            $element = 'span';
        }

        // Add custom HTML attributes
        $attribs = array_merge($attribs, $page->getCustomHtmlAttribs());

//        return '<' . $element . $this->_htmlAttribs($attribs) . '>'
//             . $this->view->escape($label)
//             . '';

        return '<' . $element . $this->_htmlAttribs($attribs) . '>'
             . $label
             . '';
  }

  public function RobertsMenu(Zend_Navigation_Container $container = null) {
return $this->menu($container);
  }

}

Wie man sieht escaped MeinMenu jetzt das Label des Menü´s nicht mehr.

Wichtig – mann muss natürlich noch den Helper im Autoloader anmelden (/website/lib/Website/Controller/Action.php):

$this->view->addHelperPath(PIMCORE_WEBSITE_PATH . '/views/helpers/', 'Website_Helper');

Jetzt noch der Aufruf im View:

echo $this->navigation()->RobertsMenu()->renderMenu($nav, array("maxDepth" => 0));

In Kürze gibt es auch den Link zur gerade in der Entwicklung befindlichen Website.

Mobile Chrome am Desktop über USB debuggen

Wir beschäftigen uns derzeit start mit Responsive Design in HTML mit Media Queries. Insbesondere interessant ist für uns dabei das Verhalten der mobilen Geräte wie Tablets oder Smartphones.

Leider gestaltet sich das Debuggen des HTML/CSS/Javascript sehr viel schwieriger bei mobilen Geräten als am Desktop, da die Konsole, wie sie zum Beispiel Firefox oder Chrome standardmäßig haben, nicht verwendbar ist. Die Nutzung würde sich mangels geeignetem Zeigegerät wie einer Maus und dem geringen Platz am Bildschirm sehr schwierig gestalten.

Debuggen mit Android

Google stellt allerdings für Android-Geräte mit dem USB-Debugging-Modus eine Möglichkeit bereit, den eigenen Browser Chrome anzuzapfen!

Um das nutzen zu können, braucht man nur am Desktop ebenfalls den Chrome-Browser sowie das das Android Software Development Kit (SDK), welches unter http://developer.android.com/sdk/index.html heruntergeladen werden kann. Für uns interessant sind hierbei aber nur die Platform Tools.

USB Debugging aktivieren am mobilen Gerät

Hier aktiviert man das USB-Debugging

Hier aktiviert man das USB-Debuggin


Um auf die Daten des Browsers zugreifen zu können, muss erst das Debugging aktiviert werden. Unter Android 4.x macht man dies in den Systemeinstellungen unter „Entwickleroptionen“ In diesem Menü macht man nun einen Haken bei “USB-Debugging”; fortan startet der Debugging-Modus, wenn das Gerät an USB angeschlossen wird.
Es empfiehlt sich, den Modus nach dem Debugging wieder zu deaktivieren, da sich hier Angriffsflächen für Hackingversuche bieten, wenn das Gerät in falsche Hände gerät.

Wenn man nun das Gerät an USB anschliesst, muss unter Umständen unter Windows noch der ADK (Android Debugging Kit) Treiber installiert werden, Linux kommt ohne weiteres Zutun klar.

Die Verbindung zum Browser des Mobilgeräts herstellen

Als nächstes muss die Verbindung zwischen dem Desktop und dem Browser des Mobilgeräts hergestellt werden. Dies erledigt das adb Programm der Platform-Tools:

$ cd adt-bundle-linux-x86_64/sdk/platform-tools 
$ ./adb forward tcp:9222 localabstract:chrome_devtools_remote

Wenn kein Fehler auftritt, steht nun unter dem Port 9222 des localhost der mobile Browser zur Verfügung.

Den mobilen Browser ansprechen

Der mobile Chrome kann am Desktop debugged werden

Der mobile Chrome kann am Desktop debugged werden

Um den mobilen Browser anzusprechen, ruft man mit dem lokalen Chrome die URL http://localhost:9222 auf. Es erscheint eine Auswahl von aktuell vorhandenen Tabs am entfernten Browser, hier wählt man den Debug-Kandidaten aus.
Es erscheint nun das Entwickler-Fenster, wie man es von Chrome gewohnt ist – nur dass man jetzt die Interna des entfernten Browsers sieht. Die Werkzeuge verhalten sich exakt wie zum lokalen Pendant; wenn man z.B. ein Node im DOM mit dem Mauszeiger überfährt, wird dieses im Browserfenster des Mobilgeräts hervorgehoben.

Gibt es zum Thema „mobiles Debugging“ Fragen oder Anregungen? Wir freuen uns über Eure Kommentare!

Internetmarke als Plugin für Open-/Libreoffice, auch für Linux

Da wir relativ selten Post versenden (eigentlich nur Rechnungen) sind wir in unserem Büro mit Briefmarken meist unterversorgt.
Mit Einführung der Internetmarke hatte sich das geändert, da man sich mit diesem System der Post die Briefmarken selbst drucken und online bezahlen konnte.
Man kann sich hierbei online ein PDF zusammenstellen lassen, dessen Abmessungen für die meisten Etiketten-Bögen schon hinterlegt sind, herunterladen und ausdrucken.
Für Microsoft Word gab es auch ein Plugin, mit dem der Code einer Marke direkt in das Adress-Fenster gedruckt werden könnte, für OpenSource-Software wie Openoffice aber nicht.

Bis jetzt.

Für Libre-/Openoffice gibt es nun ebenfalls ein Plugin, mit dem die Briefe bereits in der Textverarbeitung frankiert werden können.

Die Installation ist einfach – herunterladen, mit dem Extension Manager installieren, Office neu starten und die Zugangsdaten eintragen, fertig.

Die Arbeit mit der auf Etiketten gedruckten Marke war ja schon einfach und komfortabel, mit diesem kleinen Plugin wird es aber noch um einiges einfacher und sinnvoller.

Ich hätte es ja nicht für möglich gehalten, aber ein schwerfälliger Riese wie die Post hat es doch tatsächlich geschafft, auch die OpenSource-Gemeinde zu bedienen.
Man darf die Hoffnung halt nie aufgeben ;)

Internetauftritt des Spritzguss-Spezialisten Polymold online gegangen

Die Internetpräsenz des süddeutschen Spritzguss-Spezialisten Polymold ist nun online gegangen.

Beauftragt durch die Marktoberdorfer Kommunikationsagentur SINN+FARBE haben wir mit dem CMS Pimcore einen Ausgangspunkt für zukünftige Marketingmaßnahmen geschaffen. So wird die Webseite in den nächsten Ausbaustufen ein zentraler Anlaufpunkt für Schulungen, geschützte Kundendaten, Videostreams und vielem mehr.

Die Polymold GmbH & Co. KG ist ein inhabergeführtes Unternehmen mit Sitz zwischen Ammer- und Starberger See, welches bereits seit 1999 am Kunststoffspritzgussbereich etabliert ist. Innovative Lösungsansätze, präzise Umsetzung und höchste Qualität, sind die Merkmale, die das Unternehmen auszeichnen. Polymold beliefert Unternehmen aus den Bereichen Medizintechnik, Elektroindustrie, Kosmetikbranche, Sport- und Fitnessbereich, Automotiveunternehmen und Haushaltsgerätehersteller.

Indicate Models: Eine Umsetzung mit “Liquid Design”

Neuerstelltung der Internetpräsenz für die Münchner Modelagentur “Indicate-Models”.

Hervorstechendes Merkmal ist hier die edle und schlicht gehaltene Gestaltung, welche sich nach dem Prinzip des “Liquid-Design” über jede Seitenbreite erstreckt und dem hohen visuellen Anspruch der Zielgruppe genügt.

Charakteristisch für das Liquid Design ist, dass sich der Seitenaufbau ausschließlich an der Größe des Bildschirms des Besuchers orientiert und nicht in einen festen Rahmen (Viewport) gezwängt ist.

Im Backend müssen die Anwender lediglich neue Models angelegen, diese werden komplett selbständig über die Seiten verteilt.

Durch die Verwendung des mächtigen Open Source Content-Management Framework Pimcore, wurde es der Agentur ermöglicht, sämtliche Models eigenständig mit Hilfe anwenderfreundlicher Eingabeformulare anzulegen und zu pflegen.

Langfristig sollen in diesem Framework über 500 Models verwaltet werden.

Captchas von Zend Forms in individuelle Formulargestaltung integrieren.

In Formulare in Pimcore einfach erstellt hatten wir ja schon erläutert, wie man ein Formular “zu Fuss” programmiert und sich nur bei den benötigten Elementen bedient, um so das Formular ganz individuell ohne den Aufwand eigener Decorator zu erstellen.

Problem bei der Herangehensweise ist aber, dass Captcha Elemente keine renderViewHelper() Methode kennen und nur über render() ausgegeben werden können. Hierbei werden dann die default-Decorators benutzt, die man dann mit eigenen ersetzen müsste.

Um nun alle Elemente des Captchas (Captcha-Bild, Eingabefeld und hidden-field mit “Lösung”) auszugeben muss man die Schritte ausführen, die Zend_Form_Decorator_Captcha_Word mittels render() erledigen würde:

    public function render($content)
    {
        $element = $this->getElement();
        $view    = $element->getView();
        if (null === $view) {
            return $content;
        }

        $name = $element->getFullyQualifiedName();

        $hiddenName = $name . '[id]';
        $textName   = $name . '[input]';

        $label = $element->getDecorator("Label");
        if($label) {
            $label->setOption("id", $element->getId()."-input");
        }

        $placement = $this->getPlacement();
        $separator = $this->getSeparator();

        $hidden = $view->formHidden($hiddenName, $element->getValue(), $element->getAttribs());
        $text   = $view->formText($textName, '', $element->getAttribs());
        switch ($placement) {
            case 'PREPEND':
                $content = $hidden . $separator . $text . $separator . $content;
                break;
            case 'APPEND':
            default:
                $content = $content . $separator . $hidden . $separator . $text;
        }
        return $content;
    }

Interessant sind hier für uns die Codeteile, die sich mit dem Text- und Hiddenfield befassen.
Diese bedienen sich anderen View Helpern, nämlich Zend_View_Helper_FormHidden und Zend_View_Helper_FormText, die nur mit geeigneten Parametern wie dem Feldnamen oder zu vererbenden Attributen versorgt werden müssen.

Hier ein Beispiel, wie man die Darstellung behandeln kann:

<?php
$formbuilder = new Formbuilder_Frontend();
$form = $formbuilder->getForm("kontakt");
$captcha = $form->getElement("captcha");
$name = $captcha->getFullyQualifiedName(); // Der Name des Eingabefelds
$hiddenName = $name . '[id]'; // Der Name des hidden-fields, erweitert als Array
$textName   = $name . '[input]'; // Der Name des text-fields, erweitert als Array
?>

        <tr>
            <td><?php print $form->captcha->renderLabel() ?></td>
            <td>
              <?php print $form->captcha->renderCaptcha() ?><br>
              <?php print $this->formHidden($hiddenName, $captcha->getValue(), $captcha->getAttribs()); ?>
              <?php print $this->formText($textName, '', $captcha->getAttribs());  ?>
              <?php print $form->captcha->renderErrors() ?></td>
        </tr>

Formulare in Pimcore einfach erstellt

Pimcore liefert mit dem unterliegenden Zend Framework und dem Formbuilder-Plugin von Alexandre Delattre eine komfortable Möglichkeit, eigene Formulare zu erstellen und zu behandeln.

Die Zend Forms sind die eierlegende Wollmilchsau, die alles bietet von der Definition der Felder selbst über die Verifizierung der Inhalte und ihrer Bereinigung bis zu Ihrer Verarbeitung – und, nicht zuletzt, ihrer Darstellung im Browser.
Diese Darstellung erfolgt mit dem Strukturmuster der Decorator, jedes Element “weiss”, wie es dargestellt werden sollte und das Formular kann “sich selbst” ausgeben. Das ist sehr angenehm und praktisch, da für einfache Anwendungen keine weitere Schritte unternommen werden müssen als ein <?php print $form; ?>. Hier liegt aber auch die Krux, denn wirklich aufwändige Designs umzusetzen erfordert einen unverhältnismäßig hohen Aufwand zur Definition der oftmals für jedes Element individuellen Decorator.

Man kann aber auch den umgekehrten Weg gehen und das Formular “zu Fuss” programmieren und sich nur bei den benötigten Elementen des Formulars bedienen.
Genau das soll in diesem Beispiel geschehen, zusammen mit ein paar anderen Tricks und Kniffen.

Zuerst muss natürlich das Formular im Formbuilder Plugin gestaltet werden. Hierzu fügt man einfach die benötigten Form Elemente zusammen und stattet diese mit sinnvollen Validatoren zur Prüfung erlaubter Eingaben und Filtern zur Entfernung unerwünschter Inhalte aus.

Ist das Formular erstellt und gespeichert, kann man es im Controller seiner View zuweisen:

public function uploadAction () {
  $formbuilder = new Formbuilder_Frontend();
  $form = $formbuilder->getForm("onlinebewerbung");
  $this->view->form = $form;
}

In der View könnte man es nun theoretisch einfach nur ausgeben und die Ausgabe wäre damit erschöpfend behandelt:

<?php print $this->form; ?>

Hier wollen wir aber eingreifen und jedes Feld per Hand in individuellem HTML/PHP-Code ausgeben. Im Wesentlichen besteht ein Element hierfür aus den Komponenten Label, also der Feldbeschriftung, ViewHelper für die Darstellung des eigentlichen Eingabelemenents und dem Error für den Fall, das ein Validator eingreift.

Die Ausgabe erfolgt nun über entsprechende Methoden:

<?php $form = $this->form; ?>
<?php print $form->anrede->renderLabel() ?>  <?php print $form->anrede->renderViewHelper() ?><?php print $form->anrede->renderErrors() ?>

Was am Label nicht per Default dranhängt ist die Anzeige ob die Eingabe eines Feldes erforderlich ist. Der Label-Decorator kennt aber ein “requiredSuffix” mit dem man bestimmen kann, was das Label in diesem Fall rendern soll.

Nun muss man nur noch das ausgefüllte Formular verarbeiten. Dabei bedienen wir uns eines Tricks um die Code-Workflow übersichtlich und gering zu halten.
Wird die Seite einfach nur so (also per GET) aufgerufen, liegt in der Regel keine Wertübermittlung vor und das Formular soll nur ausgegeben werden.
Als action gibt man im form nun die URL des forms an – es ruft sich also selbst auf, vorzugsweise mit einem POST! Diesen POST kann man nun als Signal für die Weiterverarbeitung auswerten; if ($this->getRequest()->isPost()). Das Formular muss nun auf korrekte Eingabgen geprüft werden: if ($form->isValid($_POST)) {.
Bei dieser Prüfung setzt Zend_Form, falls nötig, die entsprechenden Fehlermeldungen. Nur bei erfolgreicher Prüfung verarbeitet man also weiter, kommt die Prüfung mit dem Ergebnis false zurück soll der Code wieder die Darstellung übernehmen – nur mit dem Unterschied, dass das Form mit den notwendigen Fehlermeldungen ausgestattet wurde, die nun mittels renderErrors() im View dargestellt werden.
War die Prüfung dagegen erfolgreich wird die Eingabe geeignet verarbeitet und die Ausführung auf einer Folgeseite mittels _redirect($url) fortgesetzt.

public function uploadAction () {
  $formbuilder = new Formbuilder_Frontend();
  $form = $formbuilder->getForm("onlinebewerbung");

  // Das Formular verarbeiten wenn es per POST übermittelt wurde
  if ($this->getRequest()->isPost()) {

    // Ist die Eingabe valide?
    if ($form->isValid($_POST)) {
      $values = $form->getValues(); // Alles OK, die Werte abholen

      // Hier nun was damit anfangen

      $this->_redirect("/danke"); // Redirect an die Folgeseite
      // Hier kommen wir nun nicht mehr hin!
    }
  }
  // Das Formular wird zum ersten Mal aufgerufen oder die Eingabe war nicht valide

  // Die Elemente, die ausgefüllt werden müssen,
  // mit einem "*" nach dem Label rendern
  foreach ($form->getElements() as $formelement) {
    $decorator = $formelement->getDecorator('label');
    if (is_object($decorator)) {
      $decorator->setOption('requiredSuffix',' *');
    }
  }
  $this->view->form = $form;
}

Ein paar Klippen gilt es vielleicht noch zu umschiffen. Das Element für Fileuploads kennt keine renderLabel() Methode, man kann es nur vollständig (inklusive Label) mit render() ausgeben lassen. Muss man gewisse Designvorgaben umsetzen und z.B. nach dem Label einen “:” ausgeben, kann man den Label-Decorator entsprechend konfigurieren:

foreach ($form as $element) {
  $label = $element->getDecorator("Label");
  if (is_object($label)) $label->setOption("separator", ":"); // nach jedem Label einen : rendern.
}

Auch lassen sich leider Captchas nicht “zerlegen” sondern nur komplett rendern, eigene Umsetzungen sind hier nur schwer möglich – dem widme ich aber noch einen eigenen Blogeintrag :-)

Produktionsbetrieb “gefährdet”! ;-)

Nach dem letzen Entkalkungsvorgang hat unser wichtigstes Produktionsmittel den Betrieb eingestellt: der Kaffevollautomat!

Der Kaffee kam nur noch tröpfchenweise, die einhellige Reaktion auf diesen Zustand war bei allen im Büro hier gleich: das beliebte deutsche Schimpfwort das mit “Sch” beginnt.

Allgemeiner Konsens:
Rechner kaputt? “Kein Problem, nehm ich halt den Laptop.”
Kaffeemaschine kaputt? “Das geht gar nicht, so kann ich nicht arbeiten!”

Die Dampfdüse brachte noch einwandfrei Heisswasser, also musste der Fehler irgendwo im Bereich Brüheinheit liegen. Also hab ich die Maschine am Wochenende mit heimgenommen und mal komplett zerlegt und begutachtet.
Anhand der Schlauchkonfiguration im Inneren ließ sich schon erkennen dass beim Entkalken, da das Wasser ja bei diesem Modell, einer Delonghi Magnifica ESAM 3000 B, immer über die Dampfdüse ausgestossen wird, die Brüheinheit nicht beteilligt ist. Dementsprechend sahen die Teile im Inneren des Druckzylinders auch aus:

Matschiger Kalk, wohin man blickt.

Also sowohl Druckzylinder als auch die Brüheinheit komplett zerlegt, freigekratzt, nochmal in heißer Zitronensäure eingeweicht (natürlich ohne O-Ringe) und dann wieder unter Einwirkung von Silikonfett zusammengesetzt.

Resultat: Operation gelungen, Patient lebt, Kaffee schmeckt wieder.

So kann es am Montag wieder weitergehen mit der Arbeit ;-)

Javascript debuggen mit console.log() – verfeinert

Viele wissen ja, dass die meisten Browser eine debugging-Konsole bereitstellen, an die man in seinem Script mittels console.log(“Eine Nachricht”) eine Nachricht schicken kann. Dies eignet sich hervorragend für schnelles Debuggen “zwischendurch”.
Angenehm ist dabei, das ausgegebene Objekte im Log anklickbar und damit inspizierbar sind.

Mit

console.log(this)

bekommt man das aktuelle this zum inspizieren:

Leider geht die Möglichkeit zu inspizieren verloren, wenn man Datentypen mischt, also zum Beispiel Zeichen und Objekte:

console.log("Das aktuelle this: " + this)

ergibt eine Ausgabe in der das Objekt als String repäsentiert wird:

Die Console-API bietet aber zum Glück viel mehr, unter anderem versteht sie eine sprintf-artige Syntax, die es erlaubt, verschiedene Typen zu mischen.
So steht beispielsweise %o für “Objekt”:

console.log("Das aktuelle this: %o",this)

Nun lässt sich das Objekt wieder näher untersuchen:

Aber console bieter noch viel mehr, die Ausgaben lassen sich klassifizieren und dann von der Debug-Konsole des Browsers entsprechend filtern.

Die komplette Übersicht aller Möglichkeiten findet sich auf der Seite des Firebug-Projekts