AutoThumb WordPress plugin and English posts

I’m proud to announce two first-timers today: my first officially released WordPress plugin and the first page on this blog I wrote in English. It’s kind of a challenge to my English skills, so please correct me if you find any errors — I’m sure you will ;)

The plugin integrates the great phpThumb library into WordPress and therefore allows you to post images in different sizes flexibly.

Here we go: WordPress Plugin: AutoThumb

WordPress Plugin: AutoThumb

After switching my blog to WordPress I needed a simple solution which allowed me to flexibly post images in different sizes without having to hassle with different filenames, paths etc.

The plugin is actually just a port of a plugin/snippet I wrote for MODx a while ago (see here). It scans your content’s source code for <img> tags with width and height attributes and passes them to phpThumb, a great PHP image editing library, which handles the resizing and editing of the image. Additionally, by passing parameters to phpThumb using a query string, it’s possible to edit the image in several ways (take a look at phpThumb’s demos).

The simplest way to get resized images is to specify width/height attibutes in your HTML. Autothumb will use the given values and remove the attributes from your page’s output. When you take a look at the URLs of the following example images, you will see that the <img>-tag’s src-attribute points to a file called image.php in the plugin’s directory. This file takes the image source and several other parameters and passes them to phpThumb, which will generate and output the final image (of course images will be cached).

To prevent evil people playing with the query string and letting your server generate tons of different images, the plugin generates a hash which is a combination of the query string and a secret password you set in phpThumb’s config file. So every call with different parameters (even the same image with different sizes) has another unique hash and it’s not possible to generate new images without knowing the secret password.

read more »

FH Kufstein Raumbelegung Webservice

FH Kufstein Raumbelegung Webservice

Bequemlichkeit kann machmal der Grund für neue Projekte sein. In diesem Fall die Bequemlichkeit, am Notebook immer Auskunft über die Raumbelegung, den Stundenplan und Planänderungen an der FH zu haben, ohne zum Infoscreen laufen zu müssen. Gegen Anfang des 2. Semesters bin ich auf den Online-Raumbelegungsplan der FH gestoßen, welcher die Basis für dieses Projekt bietet. Da ich mich mit dem Plan nicht wirklich anfreunden konnte, habe ich begonnen, ein eigenes System zu entwickeln, das sich auf die Daten aus genanntem Plan stützt.

Das Resultat ist eine auf PHP basierende Applikation, die die Daten des Raumbelegungsplans abruft und in Form eines SOAP-Webservices zur Verfügung stellt. Nachdem der Webservice in der ersten Version auf den schon doch recht angestaubten Libraries NuSOAP und php-html basierte, liegt der zweiten Version mittlerweile das Zend Framework in Version 1.6 und die Weiterentwicklung von php-html, simple_html_dom, zu Grunde. Das Resultat ist besseres Caching mit Zend_Cache, besserer Code und die Möglichkeit, das System flexibel zu erweitern.

Die Grundfunktion des Webservices besteht darin, den HTML-Quellcode des Online-Raumbelegungsplans, zu parsen, die relevanten Daten auszufiltern und diversen Clients als aufbereitete Daten zur Verfügung zu stellen. Der Webservice erlaubt das Filtern der Daten nach Datum, Studiengang, Lektor und Raum und ermöglicht es zusätzlich, Listen von ebendiesen Filterungskriterien auszulesen, um beispielsweise Auswahlfelder in Clientapplikationen damit zu füllen.

Der Webservice (PHP5/Zend_Soap) ist hier zu finden: http://raumbelegung.stud.ailoo.net/service (WSDL)

Desktopclient

Da ein Webservice ohne darauf aufbauende Applikation relativ langweilig ist, habe ich mich daran gemacht, einen Desktopclient in C# zu entwickeln. Da meine C#-Kenntnisse — vor allem was GUI-Applikationen angeht — (noch) relativ bescheiden sind, ist das Programm nicht sonderlich ausgefeilt und teilweise fehleranfällig. Anregungen und Kritik sind natürlich immer willkommen :)

Changelog

  • 0.2.2: Kleinere Bugfixes
  • 0.2.1: Umstellung der Webservice-URL

Anmerkung: Mittlerweile (v.A. durch die Verschmelzung Client/Service und die AJAX-Funktionalität) läuft der Webclient deutlich flüssiger und zuverlässiger als der Desktopclient.

Download

Der Desktopclient als Windows Installer Package (msi).

Webclient

Um den Service nicht nur auf Windows-Clients zu beschränken, gibt es seit kurzem einen Webclient, der ebenfalls in PHP geschrieben ist. Das Layout ist zwar relativ spartanisch, der Client funktioniert aber und erlaubt komfortablere Filterungsmethoden als der Desktopclient. Seit der zweiten Version greift der Webclient nicht mehr über das SOAP-API auf den Service zu, sondern ist voll in den Service integriert und basiert somit ebenfalls auf dem Zend Framework.

Raumbelegung Webclient

Der Plan bietet direkt über die URL diverse Filtermöglichkeiten, hier ein paar Beispiele:

Direkter Link für den Studiengang WI07-VZ für den aktuellen Tag
Andere Filterungsmöglichkeiten
Kombination von Filtern
Der Date-Filter ist recht flexibel (siehe dazu PHP strtotime)
Dies lässt sich natürlich auch mit anderen Filtern kombinieren
Zusätzlich gibt es auch eine Wochenübersicht
Direktaufruf für einen Studiengang
Direktaufruf für eine Kalenderwoche (KW 44, weil der 29.10 in dieser KW liegt)
iCal Wochenübersicht

Changelog

  • 0.2.3: iCal Support für Wochenübersicht
  • 0.2.2: Wochenübersicht hinzugefügt
  • 0.2.1: Erweiterung um AJAX-Funktionen mittels jQuery
  • 0.2: Zweite Version basierend auf Zend Framework
  • 0.1: Erste Version basierend auf altem Service
Lizenz
sämtlicher Code dieses Projekts (ausgenommen der verwendeten Biblotheken, für die die jeweilige Lizenz gilt) unterliegt der GPL (GNU General Public License)
Sourcecode
Alle Komponenten sind im Sourcecode der aktuellen Version über Subversion verfügbar. Da ich für die neue Version ein anderes SCM-System als Subversion verwendet habe und sich das Ganze im Moment noch recht stark in Entwicklung befindet, ist der aktuelle Code bisweilen nicht online verfügbar. Falls jemand interessiert ist, möge er mich kontaktieren. Die letzte Version des Webservice + Client ist hier zu finden: https://github.com/maff/fhkuf-infoscreen
Changelogs
Da die Changelogs mehr oder weniger in Blogposts festgehalten wurden/werden, dient der entsprechende Tag als gute Anlaufstelle.

Wem der Service nützlich ist und eventuell Lust hat, Clients für andere Betriebssysteme zu schreiben oder die bestehenden Clients zu erweitern, dem sei dies ausdrücklich erlaubt ;)

PHP Class: StylesheetParser

Watch out: this post was written (long) before CSS preprocessors like LESS or SASS were cool. Just ignore the PHP class presented here but keep in mind what futuristic ideas I had at that time ;)

Bei größeren Projekten stehe ich immer wieder vor dem Problem, wie ich mein CSS so strukturiere, dass ich 1. den Überblick nicht verliere und 2. möglichst wenig Aufwand habe. Einerseits kann ich ein paar große Dateien verwenden, durch die ich mich dann aber immer durchscrollen/-suchen muss, andererseits kann ich mit vielen kleineren Dateien pro “Sektion” arbeiten. Die muss ich aber auch irgendwie einbinden, was dann wieder zum Verwaltungsaufwand wird, weil ich das, sobald eine neue Datei dazukommt, irgendwo definieren muss.

Aus diesem Grund habe ich mit eine kleine PHP-Klasse namens StylesheetParser geschrieben, die mir genau diese Arbeit abnehmen soll. Ergänzend dazu bietet die Klasse die Möglichkeit, Platzhalter zu definieren, die dann im CSS verwendet werden können. Letzteres ist überaus nützlich, um sich z.B. Farben zu definieren, oder einfach um ein Stylesheet dynamisch zu gestalten, ohne mit PHP und CSS in einer Datei herumfummeln zu müssen.

Verwendung

Ich habe meistens diese Verzeichnisstruktur: einen Ordner css, in dem meine PHP-Dateien liegen, die StylesheetParser verwenden. In einem Unterordner liegen dann die eigentlichen CSS-Dateien (in den Beispielen nenne ich den Unterordner res).

1: Stylesheets manuell hinzufügen

Hier wird ein neues Objekt erstellt, manuell ein paar Stylesheets hinzugefügt und das Resultat ausgegeben. Der zweite, optionale Parameter der Methode addStylesheet setzt einen Titel für das Stylesheet, der dann im CSS als Kommentar eingefügt wird.

<?php
// include the class file
require_once('../lib/stylesheetparser.class.inc.php');

// create a new object
$style = new StylesheetParser();

// add some stylesheets
$style->addStylesheet('res/01_reset.css', 'reset HTML');
$style->addStylesheet('res/02_htmlbody.css', 'basic html and body');
$style->addStylesheet('res/03_typo.css', 'typography');
$style->addStylesheet('res/04_layout.css', 'general layouting');
$style->addStylesheet('res/05_mainmenu.css');
$style->addStylesheet('res/05_submenu.css');
$style->addStylesheet('res/06_searchform.css');
$style->addStylesheet('res/06_commentform.css');

// render the result
$style->Render();
?>

2: Stylesheetordner hinzufügen

Nehmen wir an, wir haben die selben 8 Stylesheets wie oben, möchten diese aber nicht manuell einbinden. Sobald ein neues Stylesheet in dem Ordner landet, soll dieses ebenfalls miteingebunden werden. Dafür gibt es die Methode addStylesheetDir. Die Methode hat einen zweiten optionalen Parameter $recursive. Ist dieser auf true gesetzt, werden Unterverzeichnisse ebenfalls miteinbezogen. Die Methode sortiert alle Dateien/Verzeichnisse alphabetisch, es bietet sich hier also an, Dateien je nach Priorität mit einer Nummerierung zu versehen (wie in Beispiel 1).

<?php
// include the class file
require_once('../lib/stylesheetparser.class.inc.php');

// create a new object
$style = new StylesheetParser();

// add a directory to scan for stylesheets
$style->addStylesheetDir('res');

// add another directory to recursively scan for stylesheets
$style->addStylesheetDir('res2', true);

// render the result
$style->Render();
?>

3: Platzhalter

Wie weiter oben angesprochen, bietet die Klasse die Möglichkeit, Platzhalter zu setzen. Damit werden Stylesheets 1. dynamisch, ohne dass man mit Programmcode in den CSS-Dateien arbeiten muss und 2. leichter wartbar, weil man Variablen setzen kann, die dann beliebig oft verwendet und zentral verwaltet werden können.

<?php
// ...

// add placeholder values
$style->addValue('fontcolor', '#333');
$style->addValue('linkcolor', '#ccc');

// add placeholder value depending on request parameter
if(isset($_GET['headerimage']) && !empty($_GET['headerimage']))
{
    $headerimage = $_GET['headerimage'];
}
else
{
    $headerimage = 'default';
}

$headerimage = '../img/headers/'.$headerimage.'.jpg';
$style->addValue('headerimage', $headerimage);

// ...
?>

Alternativ kann man auch mehrere Platzhalter gleichzeitig setzen, indem man ein Array und die Methode addValues verwendet.

<?php
// ...

// add placeholder values
$values = array(
    'fontcolor' => '#333',
    'linkcolor' => '#ccc'
);

$style->addValues($values);

// ...
?>

Diese Platzhalter sind dann in den eingebundenen Stylesheets im Format {{platzhaltername}} verwendbar:

#content p
{
    color: {{fontcolor}};
    ...
}

#content a
{
    color: {{linkcolor}};
    ...
}

/* headerimage from first example */
#header
{
    background: #555 url({{headerimage}}) no-repeat top left;
}

Verhalten beinflussen

Standardmäßig verwendet StylesheetParser die Platzhalter-Trennzeichen {{ und }} und gibt bei Aufruf der Methode Render das Stylesheet mit dem content-type header text/css aus. Dieses Verhalten kann auch beeinflusst werden.

Um die Platzhalter-Trennzeichen zu ändern, gibt es die Methode setDelimiters. Diese erwartet als ersten Parameter das linke Trennzeichen und als zweiten das rechte.

<?php
// ...

// set placeholder delimiters
$style->setDelimiters('[[', ']]');

// ...
?>

Die Methode Render hat einen optionalen Parameter $return, der, sofern er auf true steht, bewirkt, dass das Ergebnis zurückgeliefert und nichts ausgegeben wird. Dies könnte nützlich sein, wenn man die Ergebnisse im Nachhinein nochmal manipulieren möchte.

<?php
// ...

// save results to a variable
$mystyle = $style->Render(true);

// add some additional content
$mystyle .= "nn /* -- end of stylesheet -- */";

// set correct header
header('Content-type: text/css');

// show the results
echo $mystyle;
?>

5. Ausgabe strukturieren oder komprimieren

Standardmäßig wird der Code unkomprimiert ausgegeben und für jede Datei ein Kommentarheader in folgender Form eingefügt:

/* --------------------------------------------------------------

files_screen/02_00_mainmenu.css

-------------------------------------------------------------- */

Dieses Verhalten kann man mit $showSections beeinflussen:

$style->showSections = false;

Neu hinzugekommen ist die Möglichkeit, den Code zu komprimieren (alle Kommentare und Leerzeilen entfernen). Dafür gibt es 3 Variablen:

bool $compressAll
der gesamte Code wird komprimiert
array $compressPatterns
ein Array mit regulären Ausdrücken für die Filenamen, die komprimiert werden sollen
array $nonCompressPatterns
das Gegenteil von $compressPatterns. Wird bevorzugt, sprich der Code der passenden Dateien bleibt trotz $compressAll oder $compressPatterns unkomprimiert

Achtung: die regulären Ausdrücke werden direkt an preg_match übergeben, müssen also gültig sein.

<?php
// compress all
$style->compressAll = true;

// override compress setting for debug files
$style->nonCompressPatterns = array('~^files/debug~');
?>
<?php
// compress framework files
$style->compressPatterns = array('~files/framework~');
?>

Anmerkungen

Die Methode Render setzt, sofern sie nicht mit dem Parameter $return aufgerufen wird den korrekten content-type mittels header(). Es ist daher darauf zu achten, dass vor dem Aufruf der Methode nichts im Script ausgegeben wird, da es sonst mit einem Fehler beendet wird.

StylesheetParser funktioniert nur unter PHP5

Download

Bookmarklets für spotlight.de

Da ich öfter auf spotlight.de unterwegs bin, habe ich mir mit der Zeit einige Bookmarklets angesammelt, um komfortabel HTML-Code zu produzieren. Habe mal eine Vorlage gefunden und diese meinen Bedürfnissen angepasst. Leider weiß ich nicht mehr, woher ich die diese habe, falls sich jemand durch den “Codeklau” gestört fühlt: bitte melden ;)

Die folgenden Bookmarklets werden alle auf den ausgewählten Text in der Textarea angewendet:

  • SL-Code – Ausgewählten Text in ein <code><pre> hüllen
  • SL-A – Link mit dem ausgewählten Text als Linkziel erstellen
  • SL-Acronym – Ausgwählten Text in <acronym> hüllen
  • SL-Kbd – Ausgewählten Text in ein <kbd> hüllen
  • SL-Em – Ausgewählten Text in ein <em> hüllen
  • SL-Strong – Ausgewählten Text in ein <strong> hüllen

Hier noch eine Textarea um die oben stehenden Bookmarklets auszuprobieren (einfach Text in der TA auswählen und auf die Links klicken):

Um die Bookmarklets zu “installieren”, einfach das Linkziel als Lesezeichen speichern (im Firefox rechtsklick auf den Link und “Lesezeichen für diesen Link hinzufügen”). Ich hab sie zur schnellen Erreichbarkeit in der Lesezeichen Symbolleiste in einem Ordner liegen.