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 :-)
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 ;) …
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.
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.
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.
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:
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~');
?>
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.
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-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.
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.
Den Intel ASL Compiler installieren
mt:~# apt-get update
mt:~# apt-get install iasl
Die DSDT-Tabelle in eine Datei schreiben
mt:~# cat /proc/acpi/dsdt > dsdt.dat
Die Datei dekompilieren und diese mit einem Texteditor öffnen
mt:~# iasl -d dsdt.dat
mt:~# nano dsdt.dat
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
}
Datei speichern und wieder kompilieren
mt:~# iasl -tc -f dsdt.dsl
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 /
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).