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.

Userabhängige Toolbar im CK-Editor in Pimcore

Pimcore verwendet als WYSIWYG-Editor den CK-Editor, ein in JavaScript implementierter Editor der sehr viele Möglichkeiten bietet, einen Text direkt im Browser zu bearbeiten.
Da es oft keine gute Idee ist, den User einen Text mit allen Möglichkeiten bearbeiten zu lassen, bietet der Editor die Möglichkeit, die Toolbar selbst zu definieren.

Mit ein wenig Geschick lässt sich dies sogar Userabhängig bewerkstelligen, so daß beispielsweise ein Admin-User die vollständige Toolbar sieht, ein normaler User aber nur eine eingeschränkte.
Die Information, welcher User gerade eingeloggt ist, lässt sich dem pimcore.globalmanager mit der Methode get(“user”) entlocken.

Ein kleines Script, dass die Konfiguration dann Userabhängig gestaltet, könnte dann so aussehen:

CKEDITOR.editorConfig = function( config ) {
  var user = pimcore.globalmanager.get("user");

  if (!user.admin) {
    config.toolbar = [
      [ 'Source', '-', 'NewPage', 'Preview', '-', 'Templates' ],
      [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ],
      '/',
      [ 'Bold', 'Italic' ]
    ];
  }
};

Dieses Stück Code kann man zum Beispiel in pimcore/static/js/lib/ckeditor/config.js ablegen.

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.

PHPStorm Filewatcher für LessCss

Für CSS gibt es eine Anzahl von Präprozessoren, die einem den Umgang mit dieser deklarativen Sprache erleichtern. So werden geschachtelte Definitionen, Variablen, Mathematik und Makros ermöglicht.

Einer dieser kleinen Helfer, den wir gerne einsetzen ist Less, die Sprache für „Less CSS“

Der Vorgang ist, unabhängig vom verwendeten Dialekt, immer gleich:

  1. Erweitertes CSS schreiben
  2. Verarbeiten lassen
  3. dem Browser übermitteln

Gebräuchlich sind hierfür nun zwei Methoden;

  1. Dem Browser direkt die Rohdaten übermitteln und selbst übersetzen lassen, zum Beispiel mit less.js
  2. Die .less Datei vom Server übersetzen lassen und als fertiges CSS ausliefern, zum Beispiel mit lessphp

Letzteres wird zum Beispiel von Pimcore mit einem Outputfilter realisiert; hierbei wird der HTML-Sourcecode nach einem <link rel=”stylesheet/less” type=”text/css” href=”BLAHFASEL.less”> durchsucht, gefundene Links auf die .less-Quelldateien an lessphp übergeben, der Link auf das Resultat „umgebogen“ und das angepasste HTML schlussendlich an den Browser übergeben.

Seit PHPStorm Version 6 gibt es nun eine dritte Möglichkeit, die noch früher ansetzt: das .less wird direkt von der IDE zu CSS übersetzt.

Filewatcher

Es gibt für diese IDE nun sogenannte Filewatcher, also Hintergrundprozesse, die Aufgaben für definierte Files ausführen, sobald sich diese verändern. Dies eröffnet eine ganze Reihe von Möglichkeiten, eine davon ist es, ein .less File direkt nach dem Abspeichern in ein CSS übersetzen zu lassen. Dadurch wird dieser einmalige Task sofort und vom Rechner des Entwicklers erledigt, und weder Webserver noch Browser müssen sich damit jemals wieder mit LessCss beschäftigen.

Darüber hinaus zeigt der Prozess sofort auf, wenn Fehler beim Übersetzen aufgetreten sind, das erleichtert die Erkennung von Fehlern.

less.js installieren um lesscss zu verarbeiten

Der Präprozessor für .less–Files muss als Befehl für die Kommandozeile vorliegen. Hier könnte man zum Beispiel less.php im CLI-Modus von PHP ausführen lassen, ich habe mich der Einfachheit halber aber für die Node.js Variante entschieden.

Zuerst muss natürlich node.js installiert sein. Unter Gentoo erreicht man das mit einem einfachen Befehl:

emerge nodejs

Node.js bringt seinen eigenen Paketmanager mit, damit lässt sich dann leicht less.js nachladen und installieren:

npm install -g less

Das war’s, mehr ist nicht zu tun.

Konfiguration des Filewatchers

PHPStorm frägt, ob ein Watcher eingerichtet werden soll

PHPStorm frägt, ob ein Watcher eingerichtet werden soll

PHPStorm erkennt anhand der Filekennung automatisch, ob ein File bearbeitet wird, für den sinnvollerweise ein Watcher eingerichtet werden könnte und schlägt dies dann vor. Mit einem Klick auf “Add watcher” kann man dies nun tun, bei einem Klick auf “Dismiss” verschwindet der Vorschlag – und kehrt auch nie wieder.

Filewatcher Konfiguration

Filewatcher Konfiguration

Wenn man den Vorschlag einmal weggeklickt hat, oder den Filewatcher nachträglich bearbeiten muss, kann man dies in den Einstellungen von PHPStorm erledigen, die man über

File – Settings – Project Settings – File Watchers erreicht.

Man sollte darauf achten, das Immediate file synchronisation und Check file for syntax errors aktiviert ist, der Pfad zum Compiler findet man an der Konsole heraus mit den Kommando

which lessc

Ein Klick auf OK speichert die Einstellungen ab.

Automatisches Hochladen aktivieren

Automatisches Hochladen aktivieren

Wer auf Remote Servern arbeitet, sollte noch das automatische Hochladen der resultierenden CSS-Datei aktivieren, sonst ist es erforderlich, diese jedes Mal per Hand hochzuladen.

Dies kann man unter Tools->Deployment->Options erreichen, wichtig ist es bei „Upload changed files automatically to the default server“ die Einstellung always zu wählen und bei „Upload external changes&ldquot; einen Haken zu machen.

Fortan sieht man beim Abspeichern der .less-Datei im File-Transfer Infofenster von PHPStorm, dass zwei Dateien auf den Server übertragen wurden :)

Hast Du Kommentare, Fragen oder Anregungen zum LESS-Filewatcher? Wir freuen uns über Beiträge in unserem Kommentarbereich!

Objekte erzeugen in Pimcore beschleunigen

Wer in Pimcore schon in der Situation war, viele User-Objekte erzeugen zu müssen (zum Beispiel bei Datenabgleichen mit anderen System) wird festgestellt haben, dass dies eher gemächlich vonstatten geht.

Mit zwei einfachen Maßnahmen kann man dem Prozess gehörig auf die Sprünge helfen.

Den Cache aktivieren

Ist in Pimcore kein Cache konfiguriert, wird per Default der Zend_File_Cache verwendet.
Das ist zwar besser wie nichts, aber immer noch sehr langsam.

Der Cache wird nur dann deaktiviert, wenn man dies explizit mit

Pimcore_Model_Cache::disable();

so setzt.

Es empfiehlt sich daher, den Cache auf eine schnelle Variante wie Memcached oder die MongoDB zu konfigurieren.

Memcache

Memcache ist ultraschnell, da er ausschliesslich im Speicher läuft, hat aber einen Nachteil – alles, was da reingestopft wird, ist global für jeden mit Zugriff auf den Daemon verfügbar. Um hier abgrenzen zu können, setzt Pimcore eine Zwischenschicht zum Taggen ein, und jene Tags werden wiederum in der normalen SQL-Datenbank abgelegt – dieser Umstand macht also den Memcache für Pimcore nicht zu ersten Wahl.

MongoDB

Die MongoDB ist die schnellere Alternative zum Memcache – obwohl sie im Prinzip eigentlich die langsamere wäre, es fehlt aber das Tagging-Handicap.
Die Installation der Datenbank sollte einfach zu bewerkstelligen sein, die meisten Distributionen enthalten sie.

Die Konfiguration in Pimcore erfolgt über die Datei website/var/config/cache.xml. Eine Beispiel-Datei existiert schon in dem Verzeichnis.

Eine funktionierende Version der cache.xml für die MongoDB würde Beispielsweise so aussehen:


    
    
        Core
        
            pricelist_
            99999
            true
        
    
    
        Pimcore_Cache_Backend_Mongodb
        true
        
            pimcore_cache
        
    

Die Datei wird bei jedem Request an Pimcore gesucht, sobald sie vorhanden ist, ist der Cache aktiv.

Den Cache nutzen um Zend_Db_Table zu beschleunigen

Beim Anlegen von vielen Objekten zeigt sich eine kleine, ich will nicht sagen, Unzulänglichkeit, von Zend_Db_Table:

Standardmäßig fragt Zend_Db_Table_Abstract die darunterliegende Datenbank für die Metadaten der Tabelle ab immer wenn diese diese Daten benötigt werden um Tabellenoperationen durchzuführen. Das Tableobjekt holt die Metadaten der Tabelle von der Datenbank indem es die describeTable() Methode des Adapters verwendet.
[...]
In einigen Fällen, speziell wenn viele Table Objekte auf der gleichen Datenbanktabelle instanziert werden kann das Abfragen der Datenbank nach den Metadaten der Tabelle für jede Instanz unerwünscht sein wegen der Geschwindigkeit. In solchen Fällen, können Benutzer davon profitieren das die Metadaten der Tabelle, die von der Datenbank empfangen werden, gecached werden.

Die Kurzfassung: bei jedem Erzeugen eines Daten-Objekts wird die Datenbank gefragt, wie die Daten denn auszusehen haben.
Dieser Vorgang kostet enorm viel Zeit und kann gecached werden mit Zend_Db_Table_Abstract::setDefaultMetadataCache()

Dieser statischen Methode muss einfach nur ein Cache übergeben werden – und einen solchen stellt Pimcore, wie weiter oben beschrieben, zur Verfügung.

Folgende beiden Zeilen aktivieren daher den Metadaten-Cache für Zend_Db_Table:

$cache = Pimcore_Model_Cache::getInstance();
Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);

Die Praxis

Bei einem Kunden war es notwendig, ca 3500 Objekte (mit Assets, es finden also auch Kopiervorgänge auf der Platte statt) zu importieren.
Ohne Cache dauerte dies ca 2 Stunden, mit Cache 15 Minuten, und mit dem Metadaten-Cache nur noch fünf Minuten.

In der Praxis haben diese beiden Maßnahmen uns also enorme Geschwindigkeitssteigerungen gebracht!

EDIT:
Wir haben diese Verbesserung als Issue bei Elements eingereicht: Activate caching Zend table metadata by default.
Die zwei Zeilen sind angemommen worden, ab Version 1.4.10 ist der Cache daher nun im Core von vornherein mit drin :)

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!

Pimcore in Version 1.4.9 erschienen

Es gibt einen neuen Release von Pimcore, diesmal in Version 1.4.9

Neben zahlreichen Bugfixes gibt es auch ein paar Verbesserungen.
Am interessantesten finde ich dabei den Update des CKEditors auf Version 4 und die neue Bounce Mail Inbox.

REST

Was auch neu ist, in den Release Notes aber nicht auftaucht: die REST API, mittels welcher man RESTful mit Pimcore „sprechen“ kann.

Folgende Aktionen lassen sich zum gegenwärtigen Stand damit ausführen:

  • Get Object By ID
  • Delete Object By ID
  • Create a new object
  • Update existing object
  • Get Object Metadata
  • Get Class By ID
  • Get Field Collection Definition By Key
  • Object Brick Definition By Key
  • Get Asset By ID
  • Delete Asset By ID
  • Create New Asset
  • Update Existing Asset
  • Get Document By ID
  • Delete Document By ID
  • Create New Document
  • Update Existing Document
  • Search Assets
  • Search Documents
  • Search Objects
  • Get Asset Count
  • Get Document Count
  • Get Object Count
  • Get User
  • Get KeyValue Definition
  • Get Server Info
  • Override HTTP Method

Die Release Notes

Hier die Releasenotes für Version 1.4.9:
Bug

  • maintenance.php: PHP Warning: Error while sending STMT_CLOSE packet. PID=23365 in Unknown on line 0
  • overwrite hasChilds() in hardlink wrappers respecting children setting in hardlinks
  • outdated classloader map
  • Front end translation not working after clean install
  • Renaming a class results on unknown behavior
  • Not possible to add object named “Service”
  • Cannot create documents in Plugin (There is already an active transaction)
  • 1.4.8: Sql request problem when saving an object with multiple multihref fields
  • RTE RichText Wysiwyg Editor in FieldCollections stops working after reordering
  • Can edit object in “Search, Edit and Export Tab”, but the role is not allow
  • Colon (:) as path separator in /pimcore/cli/classmap_generator.php
  • Assets: Download as zip does not work for root folder
  • Classes can create invalid PHP Files
  • Document_List not autoloading because of bug in function getDocuments()
  • CSV import with cell containing carriage return does not work properly
  • postupdate Script for revision 2209 fails
  • Video-incompatibilities caused by a comma
  • Modal dialog “Please wait” stays there forever if Import Asset from URL is attempted with invalid URL
  • Data in structured table is truncated after 50 characters
  • Ext.form.ComboBox items can not be selected in IE
  • Spelling Mistake – The desired element is currently opend by an other person:
  • Session Error (see Screenshot)
  • Geographical Polygon Selection Editor doesn’t load if polygon present
  • 1.4.8, isValidKey in class Pimcore_Tool doesn’t allow the preset key on fresh installation
  • Deletion of user-/rolefolders containing users/roles doesn’t remove the content.
  • Can’t drop additional editables into areablock after certain number of elements is already added
  • Asset->setParent() and Document->setParent() does not work
  • Deleting cache cleans whole folder inclusive .dummy
  • Implement webservice API for keyvalue data type
  • Document_Service::render() not overwriting passed $params on sucessive calls
  • Drop Locks Table on Install
  • YUICompressor and curilyc
  • Image cropping doesn’t work when no thumbnail config is defined
  • mongodb persist option throws exception (persist parameter is outdated)
  • Do not allow “admin”, “webservice”, “install” and “plugin” as name for documents in the first level (system routes)
  • Reload after plugin uninstall
  • PHP5.4 Bugging
  • rename in document tree breaks path

Verbesserung

  • Option for caching images directly after upload should be present somewhere
  • Thumbnails are resizing gradually in Editmode
  • HTML 5 Video: Automatically add microdata for search engines (poster thumnail, …)
  • In folder view rename buton “Delete” to “Delete folder”
  • Allow to turn off opening the last open tabs in backend on user level
  • Editables: Add “Show in Tree” in contextmenu where items are assigend
  • Pimcore_View parameter is forced to HTTP request rather than abstract
  • Plugin initialisation array index not defined warnings
  • Prepare datatypes for better preview and diff view
  • CKEditor Update (Version 4)
  • Thumbnails: Support for progressive JPEGs
  • Custom metadata on pages
  • Make root nodes in sidebar (“home”) translatable
  • Site-specific robots.txt
  • Site-specific routes: allow same name for routes of different sites
  • new Asset_* should have the type predefined
  • Additional SOAP API Functionality
  • New style editor should be optional
  • Add async attribute to minified JS in JavascriptMinify.php
  • Update Cache after updating Website settings
  • Tag-Manager: Allow to restrict to sites
  • Disabling versions doesn’t work
  • Asset_Image creation very slow because of low-performant $this->clearThumbnails() function

Neue Funktion

  • Bounce Mail Inbox
  • Option to switch between old and new ckeditor
  • Add the ability to recursively create Object/Asset folders
  • Previews for pages (document)

Pimcore Dynamic Dropdown Module in neuer Version

Eines unser Plugins für Pimcore ist in einer neuen Version erschienen.

Es handelt sich hierbei um das Dynamic Dropdown Plugin, das in Objekten ein Dropdown-Eingabeelement zur Verfügung stellt, dessen Inhalte wiederum aus anderen Objekten bzw deren Feldern bestimmt werden.

Was ist neu?

Das Plugin kann nun rekursiv verarbeiten und das Ergebnis sortieren.

Das Plugin kann nun rekursiv verarbeiten und das Ergebnis sortieren.

  • Die Reihenfolge der Elemente kann nun entweder nach ihrer ID oder ihrem Wert sortiert werden, dies ist in der Konfiguration des Eingabelements einstellbar.
  • Die Ordner, in denen die Elemente liegen müssen, können nun rekursiv durchsucht werden. Auch dies ist in der Konfiguration (de-)aktivierbar.
  • Der Bug, der dazu führte daß die Methodennamen erst nach einem Reload der Seite zur Verfügung standen, ist behoben.
  • Das Feld kann nun in der Grid-Ansicht der Objektliste angezeigt werden. Zu beachten ist dabei, daß es sich beim Dynamic Dropdown intern um ein Href handelt, es kann daher nicht nach dieser Spalte sortiert werden.
  • Die eingestellte Breite wird nun berücksichtigt.

Die neue Version kann in der Pimcore-eigenen Pluginverwaltung aktualisiert werden.

Feedback ist, wie immer, ausdrücklich erwünscht :)

Ein Ausblick in die Zukunft

Ein Ausblick auf die neue Eingabe

Ein Ausblick auf die neue Eingabe

Einer unserer Kunden benötigt eine Erweiterung der Eingabeverarbeitung, hierbei ist die Darstellung als zwei Boxen gewünscht wobei die eine die zur Verfügung stehenden Eingaben und die andere die Gewählten darstellen soll. Der Wechsel von der einen Box in die andere soll dabei durch Doppelklick stattfinden.

Pimcore translations im Layout

Pimcore bietet mit seinem internen Übersetzer die Möglichkeit, “feststehende” Begriffe auf Webseiten zu komfortabel zu übersetzen.

Der Aufruf hierfür ist, zum Beispiel in einer View:

print $this->translate("Der zu übersetzende Begriff");

Wir die Webseite einmal aufgerufen nimmt Pimcore den Satz „Der zu übersetzende Begriff“ in die Liste mit auf. Dort kann man dann die Angaben in den gewünschten Sprachen machen, und abhängig von der im Frontend eingestellten Sprache wird dann die betreffende Übersetzung ausgegeben.

Die Sprache stellt man im Frontend ein über den Zend_Registry Eintrag “Locale”:

Zend_Registry::set("language", $language);
$locale = new Zend_Locale($language);
Zend_Registry::set("Zend_Locale", $locale);

Dies funktioniert wunderbar – mit einer Ausnahme: im Layout, bzw. Im Actioncontroller Website_Controller_Action

Alle Angaben, die hier gemacht werden, werden nicht übersetzt, weil der Translator noch nicht initialisiert ist.

Will man also beispielsweise Übersetzungen für ein Javascript bereits inline und global mitgeben:

$this->view->headScript()->captureStart(); ?>
var livesuche = "view->translate("Livesuche") ?>";
view->headScript()->captureEnd();

wird der String „Livesuche“ nicht übersetzt.

Um auch hier schon Übersetzungen zu erreichen, muss der Translator händisch initialisiert werden bevor das erste Mal die translate() Methode aufgerufen wird. Dies erreicht man mit:

      $this->initTranslation();

Pimcore: eine Page in mehreren Navigationen verwenden

Pimcore stellt eine komfortable Möglichkeit zur Verfügung, einer Webseite eine strukturierte Dokumentenhierarchie zu verleihen.
Diese Struktur kann automatisiert ausgelesen und sowohl in eine Navigation für die Webseite selbst als auch in sinnvolle und “sprechende” URLs verarbeitet werden.
So ist die URL zu einer Seite “Impressum” folgerichtig “/impressum”, und falls die Seite in einem Unterverzeichnis steckt dann “/unterverzeichnis/impressum”.

Häufiger hatten wir hier das Problem, dass auf der Webseite mehrere, voneinander getrennte Navigationen gewünscht sind. Diese kann man in Pimcore dann ganz leicht in Unterordnern zusammenfassen und jeden individuell auslesen und in eine Navigation verwandeln. Dies stellt aus Suchmaschinensicht aber nicht das Optimum dar, da mit jedem Unterpfad die Relevanz der Seite sinkt, von der “merkwüdigen” URL wie “/kopfnavigation/impressum” ganz zu schweigen.

Wir haben daher mit Hilfe der Eigenschaften, die in Pimcore jeder Seite vergeben werden können, eine Lösung entwickelt.

Folgende Ausgangssituation:

Es existieren drei Navigationen:

  1. Die Kopfnavigation
  2. Die Linke Navigation
  3. Die Hauptnavigation

Zudem gibt es im Fuß der Seite die Gesamtnavigation in der jeder mögliche Navigationspunkt nochmal aufgeführt ist:

In Pimcore sind diese Seiten in einer flachen Hierarchie untergebracht, um möglichst kurze URLs zu produzieren:

In der Umsetzung bedienen wir uns der Zend_Navigation, welche uns sehr viel Arbeit abnimmt.
Mit dem pimcoreNavigation() View Helper stellt uns Pimcore eine komfortable Möglichkeit zur Verfügung, eine fertige Zend_Navigation aus dem Dokumentenbaum zu erzeugen.
Dies erreicht man durch Aufrufen der Methode getNavigation($currentDocument, $navStartNode) des View Helpers. $currentDocument stellt dabei das Dokument dar, das in der Navigation als “aktiv” markiert werden soll. In unserem Zusammenhang ist das $this->document. Die Variable $navStartNode beschreibt das Dokument, dessen Kinder die einzelnen Links werden. In unserem Fall ist das “/home”.

      $navStartNode = Document::getById(1);
      $gesamte_nav = $this->view->pimcoreNavigation()->getNavigation($this->document, $navStartNode);

Aus dieser Navigation erzeugen wir nun die anderen, wir müssen jeder Seite nur noch die Information mitgeben, in welcher Navigation sie zusätzlich noch erscheinen soll.
Dies erreichen wir mit den Eigenschaften der Seite. Praktisch hierfür ist es, eine vorgefertige Eigenschaft zu definieren, aus der dann nur noch ausgewählt werden muß. Hier ist das eine “select” Eigenschaft mit den Werten “Kopf,Links,Haupt”:

Diese Eigenschaft kann man nun jeder Seite zuweisen:

Diese Information kann nun bequem ausgewertet werden, um die einzelnen Navigationen zu erzeugen.
Hierbei lesen wir jede Zend_Navigation_Page aus der Navigation aus und werten die Eigenschaft “navigation” des Documents der Page aus. Abhängig vom Inhalt wird eine Seite gegebenenfalls einer weiteren Navigation zugewiesen:

      $kopf_nav  = new Zend_Navigation();
      $linke_nav = new Zend_Navigation();
      $haupt_nav = new Zend_Navigation();

      foreach ($gesamte_nav as $page) {
        $newpage = clone $page;
        $nav_property = trim($page->getDocument()->getProperty("navigation"));
        if     ($nav_property == "Kopf")  $kopf_nav->addPage($newpage);
        elseif ($nav_property == "Haupt") $haupt_nav->addPage($newpage);
        elseif ($nav_property == "Links") $linke_nav->addPage($newpage);
      }

      $this->view->gesamte_nav = $gesamte_nav;
      $this->view->kopf_nav    = $kopf_nav;
      $this->view->linke_nav   = $linke_nav;
      $this->view->haupt_nav   = $haupt_nav;

Ganz wichtig hierbei ist es, $page vor der Zuweisung durch addPage() mit dem clone keywords zu kopieren (Zeile 6), da Zend_Navigation_Container der Seite beim addPage()-Vorgang ein neues Parent zuweist und damit der Gesamt-Navigation entziehen würde.

Die so erzeugten Navigationen können im Layout nun bequem ausgegeben werden:

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