Wieder zum Indianer zurück

Posted on in General, Server

Im Laufe einer Servererweiterung bin ich von Lighttpd wieder auf Apache zurück. Nicht dass ich mit Lighty nicht zufrieden gewesen wäre (v.A. in Bezug auf Geschwindigkeit, Speicherauslastung und einfacher Konfiguration), aber der Apache kann einfach mehr, speziell wenn es um DAV und SVN geht. Hab jetzt Apache mit PHP über mod-fcgid laufen und dazu endlich meines eigenes SVN-Repository + Trac :-)

Rezepte

Posted on in Cooking, General

Da ich gerne koche, habe ich mich entschlossen, hier ab und zu mal ein paar Rezepte aufzuschreiben. Ich koche eher nach Lust und Laune als nach Rezept, es kann also leicht sein, dass die Mengenangaben nicht immer ganz genau sind und man ein bisschen probieren muss :grin:. Im Moment fehlt mir so etwas wie eine Kamera, daher gibt es vorerst keine Fotos. Ich werde mich aber bemühen, dies schleunigst nachzuholen ;) …

Und es geht schon los: Pute in Ananas-Curry-Sauce

mafflog in neuer Version online

Posted on in General

Nachdem das mafflog einige Zeit bei einem Freehoster auf WordPress aufgebaut war, habe ich mich endlich überwunden und die Seite von Grund auf neu aufgezogen. Sie läuft nun auf meinem Server unter MODx und es macht jede Menge Spaß, daran zu arbeiten ;-) Es fehlt noch dies und das, im Großen und Ganzen ist die Seite aber (bis auf den mangelnden Inhalt) meiner Ansicht nach vorzeigbar. Na dann mal sehen was die Zukunft bringt und ob ich öfter dazu komme, etwas mehr Inhalt zu spendieren.

PHP Class: StylesheetParser

Posted on in Development, Projects

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;
}

4: 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 .= "\n\n /* -- 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

Posted on in Development, Web

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.

Sound unter Linux auf meinem Toshiba P100

Posted on in How-Tos, Linux

Update: Dieses Tutorial hat sich mittlerweile erübrigt. Sound läuft out-of-the-box in Ubuntu 8.04 (Hardy Heron).

Achtung: Diese Anleitung funktioniert nur bis Ubuntu Feisty (7.04). Auf Ubuntu Gutsy (7.10) funktioniert das Ganze aufgrund eines Bugs im verwendeten Kernel nicht. Siehe auch: https://bugs.launchpad.net/…/136469.

Update: Im Bugtracker für das Problem wurde endlich eine Lösung geposted, die bei mir einwandfrei funktioniert. Werde in Kürze hier eine neue Anleitung online stellen. Siehe: https://bugs.launchpad.net/…/136469/comments/238

Nachdem ich auf meinem Toshiba P100-351 Ubuntu installiert hatte, ging in Richtung Sound gar nichts, obwohl das System den richtigen Treiber eingebunden hatte (snd-hda-intel). Nach einiger Recherche habe ich herausgefunden, dass das Problem an einem etwas schiefgeratenen BIOS seitens Toshiba liegt. Durch folgende 2 Forumthreads habe ich es dann doch hinbekommen:

Im folgenden was ich gemacht habe (steht in den Threads auch schon drin, aber als kleine Übersicht). Getestet habe ich auf openSuse 10.2 und Ubuntu Feisty, immer mit BIOS-Version 2.40. Wie es mit anderen BIOS-Versionen aussieht und ob die Vorgehensweise dort brauchbar ist, weiß ich nicht. Hinweis: ihr benötigt root-Rechte für die nachfolgenden Schritte.

  1. Den Intel ASL Compiler installieren
    mt:~# apt-get update
    mt:~# apt-get install iasl
  2. Die DSDT-Tabelle in eine Datei schreiben
    mt:~# cat /proc/acpi/dsdt > dsdt.dat
  3. Die Datei dekompilieren und diese mit einem Texteditor öffnen
    mt:~# iasl -d dsdt.dat
    mt:~# nano dsdt.dat
  4. Die Datei wie folgt anpassen: Im String Name (_HID, "*PNP0C14") den Stern entfernen. Dann nach Linux suchen, die if-else Struktur auskommentieren und Store (0x07D6, OSYS) // Fake Windows 2006 vor der letzten geschweiften Klammer der Struktur einfügen. Der Teil mit der if-else Struktur müsste dann so aussehen:
    Scope (_SB)
         {
             Method (_INI, 0, NotSerialized)
             {
                 If (DTSE)
                 {
                     TRAP (0x47)
                 } 
    
                 Store (0x07D0, OSYS)
     //             If (CondRefOf (_OSI, Local0))
     //             {
     //                 If (_OSI ("Linux"))
     //                 {
     //                     Store (0x03E8, OSYS)
     //                 }
     //                 Else
     //                 {
     //                     Store (0x07D1, OSYS)
     //                     If (_OSI ("Windows 2001 SP2"))
     //                     {
     //                         Store (0x07D2, OSYS)
     //                     } 
    
     //                     If (_OSI ("Windows 2001.1"))
     //                     {
     //                         Store (0x07D3, OSYS)
     //                     } 
    
     //                     If (_OSI ("Windows 2001.1 SP1"))
     //                     {
     //                         Store (0x07D4, OSYS)
     //                     } 
    
     //                     If (_OSI ("Windows 2006"))
     //                     {
     //                         Store (0x07D6, OSYS)
     //                     } 
    
     //                     If (LAnd (MPEN, LEqual (OSYS, 0x07D1)))
     //                     {
     //                         TRAP (0x3D)
     //                     }
     //                 }
     //             }
              Store (0x07D6, OSYS)  // Fake Windows 2006
             }
  5. Datei speichern und wieder kompilieren
    mt:~# iasl -tc -f dsdt.dsl
  6. Der Befehl spuckt wahrscheinlich einige Fehler aus, aber am Ende solltet ihr eine fertige DSDT.aml bekommen. Diese kopieren wir nun nach /
    mt:~# cp DSDT.aml /
  7. Als nächstes benötigen wir ein Script, das die initrd mit der neuen DSDT patcht. Ihr kopiert das Script am besten nach /boot, wo ihr auch gleich ein Backup der aktuellen initrd machen könnt (solltet).
    mt:~# cd /boot
    mt:~# wget http://gaugusch.at/acpi-dsdt-initrd-patches/initrd-add-dsdt
    mt:~# cp initrd.img-$(uname -r) initrd.img-$(uname -r).original
  8. Jetzt können wir die initrd patchen
    mt:~# sh initrd-add-dsdt initrd.img-$(uname -r) /DSDT.aml
  9. Nun könnt ihr versuchen, das System neu zu starten um zu sehen, ob alles geklappt hat.

Das sollte es gewesen sein. Ich hatte nach diesen Schritten auf beiden getesteten Distributionen Sound. Viel Glück