Eigenen JavaScript-Code in das WordPress-Backend einbinden

Beim letzten Projekt benötigte ich JavaScript-Code, um das Backend ein wenig zu modifizieren. Hier will ich kurz anhand eines Beispiels festhalten, wie ich das realisiert habe.
Konkret ging es darum, dass ich im Backend ein Feld hatte, welches den Farbcode eines Elements im DOM bestimmen sollte. Der User sollte dazu aus einer vorgegebenen Liste mit Farbwerten einen auswählen und das DOM-Element sollte mittels Inline-CSS die entsprechende Hintergrundfarbe annehmen:

Normale Select-Option-HTML-Liste

Diese Liste wurde via Backend durch das (absolut empfehlenswerte!) Plugin Types eingepflegt und die Option-Values enthielten den CSS-kompatiblen Farbcode:

Da die Farbwerte jedoch teils recht nah beieinanderlagen, wollte ich die Select-Liste mit der entsprechenden Hintergrundfarbe unterlegen, so dass der User im Backend sieht, welchen Farbton er auswählt.
Das Plugin generiert folgenden HTML-Code für die Select-Liste:

<select id="wpcf-select-pagecolor-1178946369" name="wpcf[pagecolor]" class="wpcf-form-select form-select select">
	<option value="white" class="wpcf-form-option form-option option">Weiß</option>
	<option value="#cc3f14" class="wpcf-form-option form-option option">Rotorange</option>
	<option value="red" class="wpcf-form-option form-option option">Rot</option>
	<option value="#ffd900" class="wpcf-form-option form-option option">Dunkelgelb</option>
	<option value="#6f0" class="wpcf-form-option form-option option">Leuchtend Hellgrün</option>
	<option value="#24ff21" class="wpcf-form-option form-option option">Hellgrün</option>
	<option value="#0580ff" class="wpcf-form-option form-option option">Hellblau</option>
	<option value="#b2ffff" class="wpcf-form-option form-option option">Helltürkis</option>
	<option value="#ba87ff" class="wpcf-form-option form-option option">Hellviolett</option>
	<option value="#f200c2" class="wpcf-form-option form-option option">Pink</option>
</select>

 

Das Ergebnis sollte so aussehen:

Eingefärbte HTML-Select-Option-Liste

Dazu wollte ich mittels jQuery die value’s der option-Tags auslesen, also die Werte, die ich via Types CSS-kompatibel im Backend vorher eingepflegt hatte.

Folgender Code half hier aus:

<!--?php 
function custom_admin_js() {
	$script = '<script type="text/javascript"-->// &lt; ![CDATA['; 	$script .= ' 	jQuery(document).ready( function(){ 		var setBackground = function(){ 			jQuery("select[name=\"wpcf[pagecolor]\"]").css("background-color",  				jQuery("select[name=\"wpcf[pagecolor]\"]").find("option:selected").val() 			)}; 		setBackground(); 		jQuery("select[name=\"wpcf[pagecolor]\"]").find("option").each(function(){ 			jQuery(this).css("background-color", jQuery(this).val()); 		}); 		jQuery("select[name=\"wpcf[pagecolor]\"]").on("change",setBackground); 	}); 	'; 	$script .= ' // ]]&gt;';
	echo $script;
}
add_action('admin_head', 'custom_admin_js');
?&gt;

Wichtig hier ist der add_action – Aufruf, der als 2. Parameter den Namen der Funktion bekommt, die obenstehend deklariert ist und den JavaScript-Code enthält. Dort kann natürlich auch jeder andere Code stehen.

In meinem Fall benötigte ich den obenstehenden jQuery-Code, welcher hier nochmal genauer erläutert wird:

jQuery(document).ready( function(){
	//save background-color setting function for select-element into variable
	var setBackground = function(){
		jQuery("select[name=\"wpcf[pagecolor]\"]").css("background-color", 
			jQuery("select[name=\"wpcf[pagecolor]\"]").find("option:selected").val()
		)};
 
	//call the function to set the background color of the select-element
	setBackground();
 
	//set background-color for all option-tags
	jQuery("select[name=\"wpcf[pagecolor]\"]").find("option").each(function(){
		jQuery(this).css("background-color", jQuery(this).val());
	});
 
	//bind change-event to select-element
	jQuery("select[name=\"wpcf[pagecolor]\"]").on("change",setBackground);
});

Als jQuery-Selector konnte ich auf keine ID zugreifen, da die ID vom Types-Plugin generiert wurde und in jeder Installation anders wäre, daher nutzte ich folgenden Selektor:

select[name="wpcf[pagecolor]"]

Dieser war für meine Zwecke ausreichend, da er eindeutig war. In der Variable setBackground speichere ich mir eine Funktion, die das in der Select-Liste selektierte Option-Tag ausliest und den value-Wert als Hintergrundfarbe des Select-Elements setzt. Danach rufe ich die Funktion auch gleich auf, um den Wert zu setzen. Als rein anonyme Funktion kann ich sie jedoch nicht nutzen, da ich auch bei Farbwechsel den neu ausgewählten Wert setzen wollte. Dazu dient die letzte Zeile, in welcher der Event-Handler „onchange“ die Funktion „setBackground()“ bei Wechsel des Option-Elements aufruft. Wichtig hierbei ist, dass die Funktion ohne () übergeben wird, da hier nur die Referenz auf die Funktion notwendig ist. Würde man die Klammern mit übergeben, würde die Funktion direkt an dieser Stelle im Code ausgeführt werden und nicht erst bei Aufruf des Change-Events.

Das wars dann auch schon!
Anregungen, Kommentare und Verbesserungsvorschläge sind erwünscht! 🙂

Joomla Layout und View-Layout einer Komponente deaktivieren

Soeben hatte ich das Problem, dass ich die Ausgabe in einer selbst entwickelten Komponente bei Joomla deaktivieren wollte, da ich als Ausgabeformat JSON haben wollte oder gegebenenfalls auch XML oder vielleicht sogar nur Text, plain ASCII. Ich habe schon lange nichts mehr mit Joomla gemacht, musste mich also erstmal wieder an das CMS gewöhnen und hab dabei erfreut festgestellt, dass Joomla ja nach MVC-Architektur aufgebaut ist! Da ich in den letzten größeren Projekten hauptsächlich mit Zend gearbeitet hatte, kam mir das nur entgegen. Aber zum eigentlichen Problem:
Nach Recherche fand ich in der Joomla-Doku über Generating JSON output folgende Zeilen, die helfen sollen:

< ?php
//Daten, die später als JSON zurück- bzw. ausgegeben werden sollen.
$data = array('some data');
 
// Lade das Document-Objekt.
$document =& JFactory::getDocument();
 
// Setze MIME Typ für JSON Ausgabe.
$document->setMimeEncoding('application/json');
 
// Dem Header "sagen", dass es sich um eine Datei handelt, die heruntergeladen werden soll. Dateiendung *.json
JResponse::setHeader('Content-Disposition','attachment;filename="'.$view->getName().'.json"');
 
// Ausgabe der Daten JSON-encoded durch die native PHP-Funktion json_encode.
echo json_encode($data);
?>

Da ich die Daten nicht als Datei benötigt habe, sondern die Ausgabe im Browser sehen wollte, hab ich die Zeile, wo der Header für eine Datei gesetzt wird, auskommentiert. Was ich bei vielen Dokus vermisse, ist der Ort, wo dieser Code eingebaut werden soll. Neulinge wissen meist nicht, wohin der Code gehört. Weiterhin kommt dazu, dass es stets mehrere Lösungen gibt, saubere und unsaubere ;). Für mich klang alles nach View, da es ja um die Ausgabe im Browser ging, daher hab ich den Code in die view.html.php der View der Komponente gepackt. Die Datei liegt unter

com_KOMPONENTENNAME/views/KOMPONENTENNAME/view.html.php

Sie repräsentiert die View der Komponente und lädt das Default-Template unter

com_KOMPONENTENNAME/views/KOMPONENTENNAME/tmpl/default.php

aber das nur am Rande erwähnt. Die Ausgabe jedoch entsprach nicht meinem Wunsch: Es kam der Quelltext vollständig zurück mit html, head, title, meta, body und sonstigen HTML-Tags. Nach weiterer Suche traf ich auf einen Beitrag von 2009 zum Verbergen des Administrator- oder Frontend – Layout – Templates:

JRequest::setVar('tmpl', 'component');

Laut Angabe soll diese Zeile im Controller eingebaut werden. Sie bewirkt, dass das Layout nur den Inhalt der View anzeigt, ohne von einem Template umrahmt bzw. gewrappt zu werden. Ich habe die Zeile direkt hinter die MIME-Anweisung in die View gepackt. Neuladen hat gezeigt, dass jetzt die Menüstruktur der gesamten Seite nicht mehr da war, sondern nur noch der Inhalt der View! … und leider noch die html, head, title, meta- und body-Tags. Zu XML- oder JSON-Output hatte ich nun nichts brauchbares mehr gefunden außer viele Fragen, wie das denn nun geht, also hab ich mein Suchquery geändert und nach Verwendung mit AJAX gesucht, da man dabei meist auch nur einen bestimmten Datensatz abfragen will ohne das Layout oder anderen Quelltext. Ebenso kann die Antwort dort ja auch JSON sein und mit AJAX weiterverarbeitet werden. Und siehe da, ich wurde fündig bei stackoverflow (wo auch sonst) in einer Antwort mit 0 „likes“:

//after $this->display($tpl);
global $mainframe;
$mainframe->close();

Dies war die Lösung. Nun nochmal im Gesamtzusammenhang der Code, der mir JSON als Ausgabe in einer View in der Joomla-Komponente ermöglicht hat:

< ?php
//-- No direct access
defined('_JEXEC') || die('=;)');
jimport('joomla.application.component.view');
class KOMPONENTENNAMEViewKOMPONENTENNAME extends JView
{
    public function display($tpl = null)
    {
		// Get the document object.
		$document =& JFactory::getDocument(); 
		// Set the MIME type for JSON output.
		$document->setMimeEncoding('application/json');
		//Deaktiviert das Template und nutzt nur das Template 
		//der Komponente
		JRequest::setVar('tmpl', 'component');   	
 
		/* Datenverarbeitung aller Daten, beispielsweise ein  
		* Datensatz aus der Datenbank, welcher als Array 
		* zurückgegeben wird. Beispielcode:
		* $model = &$this->getModel();
		* $data = $model->getData();
		* echo json_encode( $data ); 
	    */
 
        parent::display($tpl);
		//Deaktivierung der gesamten Layout-Komponente, 
		//die für html, head, meta und body-Tags zuständig ist
		global $mainframe;
		$mainframe->close();
    }//function
}//class
?>

Der auskommentierte Teil in der Mitte steht für den Part, in welchem die Daten geladen werden, welche später JSON-encoded ausgegeben werden sollen.

Ich hoffe, der Code hilft noch vielen weiteren, die wie ich ewig danach gesucht haben!
Ich bin kein Joomla-Experte und freue mich daher sehr über Verbesserungsvorschläge und Anmerkungen! Die Lösung funktioniert zwar, aber ist sie auch sauber?

PHP-Support für Projekte, die mit Eclipse und SVN ausgecheckt wurden

Checkt man ein Projekt via SVN mit Eclipse aus, hat man das nette Syntax-Highlighting, die Auto-Vervollständigung und das Anzeigen der Dokumentation bei Mouseover über einer Funktion leider nicht mehr.

Das Problem ist jedoch einfach gelöst:
Rechten Mausklick auf das Projekt in der PHP-Ansicht, „Configure –> Add PHP Support“ und schon ist alles wieder wie gewohnt! 598MZJK8US6B

Tutorial: Zend 1.11.2 installieren mit XAMPP und MySQL und Eclipse als Entwicklungsumgebung

Teil 1: Einrichten des lokalen Webservers

Dieses Tutorial richtet sich an Anfänger, daher sind hier viele Schritte vielleicht etwas zu ausführlich beschrieben, für jemanden, der mit XAMPP oder anderen Webservern bereits vertraut ist.

Es gibt ja viele Tutorials zur Installation von Zend, jedoch sind die meisten nicht aktuell, unvollständig, für andere Betriebssysteme als ich es gebraucht hätte oder die angeleiteten Schritte funktionierten nicht. Daher schreibe ich hier meine Vorgehensweise zur Installation von Zend in der derzeit aktuellsten Version (Stand: 10.01.2011) 1.11.2. Ich nutze als Betriebssystem Windows XP, daher nutze ich zur Simulation meines Webservers XAMPP. Wer noch keinen Webserver installiert hat, lade sich XAMPP für Windows herunter. Für Linux-Benutzer gibt es das mittlerweile gleichnamige XAMPP-Paket. Früher gab es LAMPP für Linux und WAMPP für Windows, jedoch sind die Versionen gleich. Für Mac-User empfiehlt sich MAMPP. Die folgende Vorgehensweise funktioniert natürlich auch für andere Betriebssysteme wie Windows Vista, Windows 7 oder ältere Windows-Betriebssysteme.

1. Schritt: Download von XAMPP

XAMPP gibt es für Windows in verschiedenen Versionen: XAMPP und XAMPP Lite, jede Version als *.zip-Archiv oder als *.exe-Datei mit Installer. Ich bevorzuge den Download des *.zip-Archivs von XAMPP, es reicht jedoch auch das XAMPP Lite Paket, da es alle für dieses Tutorial notwendigen Komponenten enthält: PHP und MySQL.

Zu den Unterschieden beider Varianten sei soviel gesagt: XAMPP enthält das PEAR-Paket, welches unter anderem ebenfalls die Dateien für Zend enthält. Dies kann unter Umständen und bei falscher Konfiguration zu Problemen führen. Weitere Unterschiede werden hier nicht erläutert.

1.1 Installation von XAMPP

Die Installation ist schnell gemacht: Das heruntergeladene Archiv muss entpackt werden in ein beliebiges Verzeichnis. Für Windows Vista Nutzer sei gesagt, dass es nicht unter „C:\Programme\“ installiert bzw. kopiert werden sollte, da unter Vista die entsprechenden und notwendigen Schreibrechte fehlen. Ich entpacke die Dateien in „E:\xampp\“. Wenn ich das Verzeichnis jetzt öffne, sollte folgende Ordnerstruktur vorhanden sein:

Ordnerstruktur von XAMPP nach dem Entpacken
Xampp Installation Schritt 1: Entpacken

Als nächstes starte ich die xampp_setup.bat – Datei, diese konfiguriert XAMPP. Die nachfolgende Bildergalerie zeigt die Schritte im Detail:

Alle von mir ausgeführten Schritte sind dort mit „y“ für „Ja“ oder „n“ für „Nein“ ausgeführt worden. Im letzten Schritt habe ich mit „1“ das Xampp Control Panel gestartet und mit „x“ die Konsole beendet. Nun starte ich den Apache Webserver und die MySQL-Datenbank und teste, ob meine Installation funktioniert. Im Xampp Control Panel sollte neben „Apache“ und „MySql“ jeweils grün unterlegt „Running“ stehen. Zum Test drücke ich bei beiden auf „Admin“. Daraufhin startet der als Standardbrowser festgelegte Browser mit „http://localhost/xampp/splash.php“ und fragt nach der Sprache. Ein Klick auf „Deutsch“ leitet mich zu „http://localhost/xampp/“ weiter und zeigt mir, dass XAMPP erfolgreich installiert wurde.

1.2 Mögliche Fehlermeldungen

Sollte stattdessen „Die Webseite kann nicht angezeigt werden.“ (Internet Explorer), „Fehler: Verbindung fehlgeschlagen“ oder „Ups! Google Chrome konnte keine Verbindung zu localhost herstellen.“  oder ähnliche Fehlermeldungen auftauchen, läuft der Apache Webserver nicht.

1.3 Mögliche Gründe

Eine Firewall oder ein Programm blockt notwendige Ports. Dies lässt sich durch den „Port-Check“-Button im Xampp Control Panel testen oder durch Starten der xampp-portcheck.exe im Installationsverzeichnis, bei mir „E:\xampp\“. Folgender Screenshot gäbe Aufschluss darüber:

XAMPP Apache startet nicht: xampp-portcheck.exe ausführen
XAMPP Apache startet nicht: xampp-portcheck.exe ausführen

Hier blockiert ein Programm den vom Apache benötigten Port 80, daher erscheint beim Aufruf von http://localhost/ oder http://127.0.0.1/ eine andere Seite als die erwartete. Nach Beendigung des für PC-Fernsteuerung der -Fernwartung übrigens sehr zu empfehlenden Programms TeamViewer starte ich den Apache Webserver erneut. Ein weiteres Programm, was den Port 80 gerne benutzt ist Skype. Startet Skype, bevor der Webserver gestartet wird, blockiert es Port 80. Startet es danach, nimmt es automatisch einen anderen Port.

Damit ist die Installation des lokalen Webservers abgeschlossen. Innerhalb des Ordners „E:\xampp\htdocs\“ können jetzt PHP-Scripte abgelegt werden und mit „http://localhost/“ oder „http://127.0.0.1/“ aufgerufen werden. Es empfiehlt sich in jedem Fall für Anfänger, sich die Sicherheitshinweise durchzulesen, da die Standard-Konfiguration von XAMPP so gut wie nie der Konfiguration eines echten Webservers entspricht und somit auch für den realen Betrieb eines Webservers nicht geeignet und vor allem nicht gedacht ist. XAMPP dient nur als Entwicklungsumgebung.

 

Anmerkung (08.04.2011): Das Tutorial ist noch lange nicht komplett! Es folgen noch Kapitel zur Konfiguration von virtuellen Hosts, zur Installation und Konfiguration von Eclipse und zur Installation und Verwendung von Zend. Dies bedarf jedoch Zeit, die jedoch sehr rar gesät ist ;).

Kurznotiz: Session Handling in PHP

Bin gerade darüber gestolpert, dass man bei der Nutzung von Sessions in PHP Klassendefinitionen VOR der Eröffnung einer Session laden sollte:

Zitat aus http://static.zend.com/topics/0200-T-WP-1107-R1-EN-PHP-is-not-Java-Seesions-in-PHP.pdf:

–  Load class definitions before session_start() is done, otherwise objects stored in the session cannot be unserialized correctly.

Gut zu wissen! Weiterlesen schadet auch nicht!