Widget zur Anzeige von Flaggen zur Sprachauswahl im Menü und in der Fußzeile

Nachdem ich mich dazu entschlossen hatte die WordPress-Multisite-Funktion für meinen mehrsprachigen Blog zu verwenden (siehe dieser Artikel), wollte ich Flaggen zur Sprachwahl im Menü und in der Fußzeile anzeigen.

Dabei hat sich herausgestellt, dass insbesondere die Einbindung von Bildern auf der rechten Seite des (standardmäßig schwarzen) Menübereichs im Design “Twenty Eleven” nicht gerade einfach ist. Daher entschied ich mich dazu, einfach ein kleines Widget zu erstellen, das die Flaggen in einem DIV anzeigt, welches über dem gesamten anderen Inhalt platziert ist und so ganz einfach mit relativen Koordinaten direkt aus dem Admin-Widget-Interface positioniert werden kann.

Folgende Einstellungen können somit im Admin-Bereich getroffen werden:

Flags-Widget (Admin)

  • Positionsabstand der Flagge (links): Der relative Abstand der X-Koordinate des DIVs.
  • Positionsabstand der Flagge (oben): Der relative Abstand der Y-Koordinate des DIVs.
  • Icon-URL der Flagge (en): Die Icon-URL der englischen Flagge (natürlich zurvor hochgeladen).
  • Icon-URL der Flagge (de): Die Icon-URL der deutschen Flagge (natürlich zurvor hochgeladen).

Selbstverständlich kann das problemlos mit weiteren oder anderen Sprachen erweitert werden.

Und hier ist der Quelltext des Widgets:

<?php
/**
 * Flags_Widget Class
 */
class Flags_Widget extends WP_Widget {
	/** constructor */
	function Flags_Widget() {
		parent::WP_Widget(false, $name = 'Flags_Widget');
	}

	/** @see WP_Widget::widget */
	function widget($args, $instance) {
		extract($args);
		?>
			<div style="position: relative;">
				<div style="left: <?php echo $instance['flags_position_left']; ?>px; top: <?php echo $instance['flags_position_top']; ?>px; position: absolute; z-index: 10000 !important;">
					<?php echo '<a href="/en/"><img src="' . $instance['flag_en'] . '" width="20" height="16" title="English" alt="English" />'; ?></a>
					<?php echo '<a href="/de/"><img src="' . $instance['flag_de'] . '" width="20" height="16" title="Deutsch" alt="Deutsch" /></a>'; ?>
				</div>
			</div>
		<?php
	}

	/** @see WP_Widget::update */
	function update($new_instance, $old_instance) {
		$instance = $old_instance;
		$instance['flags_position_left'] = strip_tags($new_instance['flags_position_left']);
		if (!is_numeric($instance['flags_position_left'])) $instance['flags_position_left'] = '0';
		$instance['flags_position_top'] = strip_tags($new_instance['flags_position_top']);
		if (!is_numeric($instance['flags_position_top'])) $instance['flags_position_top'] = '0';
		$instance['flag_en'] = strip_tags($new_instance['flag_en']);
		$instance['flag_de'] = strip_tags($new_instance['flag_de']);
		return $instance;
	}

	/** @see WP_Widget::form */
	function form($instance) {
		$flags_position_left = esc_attr($instance['flags_position_left']);
		if ($flags_position_left == '') $flags_position_left = '0';
		$flags_position_top = esc_attr($instance['flags_position_top']);
		if ($flags_position_top == '') $flags_position_top = '0';
		$flag_en = esc_attr($instance['flag_en']);
		$flag_de = esc_attr($instance['flag_de']);
		?>
			<p>
				<label for="<?php echo $this->get_field_id('flags_position_left'); ?>"><?php _e('Flag position offset (left):'); ?></label>
				<input class="widefat" id="<?php echo $this->get_field_id('flags_position_left'); ?>"
					name="<?php echo $this->get_field_name('flags_position_left'); ?>" type="text" value="<?php echo $flags_position_left; ?>" />
				<label for="<?php echo $this->get_field_id('flags_position_top'); ?>"><?php _e('Flag position offset (top):'); ?></label>
				<input class="widefat" id="<?php echo $this->get_field_id('flags_position_top'); ?>"
					name="<?php echo $this->get_field_name('flags_position_top'); ?>" type="text" value="<?php echo $flags_position_top; ?>" />
				<label for="<?php echo $this->get_field_id('flag_en'); ?>"><?php _e('Flag icon URL (en):'); ?></label>
				<input class="widefat" id="<?php echo $this->get_field_id('flag_en'); ?>"
					name="<?php echo $this->get_field_name('flag_en'); ?>" type="text" value="<?php echo $flag_en; ?>" />
				<label for="<?php echo $this->get_field_id('flag_de'); ?>"><?php _e('Flag icon URL (de):'); ?></label>
				<input class="widefat" id="<?php echo $this->get_field_id('flag_de'); ?>"
					name="<?php echo $this->get_field_name('flag_de'); ?>" type="text" value="<?php echo $flag_de; ?>" />
			</p>
		<?php
	}
} // class Flags_Widget
add_action('widgets_init', create_function('', 'return register_widget("Flags_Widget");'));
?>

Ich wollte es so einfach wie möglich halten und daher ist alles zusammen in einer Datei. Ansonsten sollte man natürlich zumindest die CSS-Styles in eine externe Style-Sheet-Datei packen.

Nur Ausschnitt anstatt des gesamten Artikels anzeigen

Standardmäßig werden in dem Theme “Twenty Eleven” von WordPress (außer bei den Suchergebnissen) überall die gesamten Artikel angezeigt. Das gefällt mir jedoch gar nicht: Wenn ich auf eine Kategorie oder ein Schlagwort klicken, möchte ich einen Überblick bekommen, welche Artikel hier zugeordnet sind. Ich kann dann immer noch auf einen klicken, wenn ich diesen vollständig lesen möchte.

Daher wollte ich nur Ausschnitte der Artikel auf den folgenden Seiten anzeigen lassen:

  • Suchergebnisseiten (was bereits standardmäßig der Fall ist)
  • Startseite des Blogs
  • Kategorie-Seiten
  • Schlagwort-Seiten
  • Datum-basierte Archiv-Seiten (die ich zurzeit überhaupt nicht nutze)

Um das zu erreichen, muss man lediglich im Theme die Zeile in der Datei “content.php”

<?php if ( is_search() ) : // Only display Excerpts for Search ?>

mit dieser ersetzen:

<?php if ( is_home() || is_tag() || is_category() || is_date() || is_search() ) : ?>

Das war’s. Nun finde zumindest ich, dass es für den Benutzer besser aussieht und die Suchmaschinen haben sicherlich auch nichts dagegen (Stichwort: “duplicate content”). ;-)

Mehrsprachiger Blog mit WordPress: qTranslate, WPML oder Multisite-Funktion

Als ich diesen Blog auf eine neue Plattform brachte, wollte ich sichergehen, dass dieser von Anfang Mehrsprachigkeit unterstützt.

Enttäuscht stellte ich fest, dass WordPress noch immer von Hause aus keine Möglichkeit für mehrsprachige Blogs mitbringt. Das kann ich überhaupt nicht nachvollziehen, da offenbar sehr viele Leute genau dieses Problem haben: Wie bekommt man den WordPress-Blog mehrsprachig.

Während ich nach einer Lösung suchte, fand ich grundsätzlich drei sinnvolle Optionen:

  • Plug-In qTranslate
  • Plug-In WPML
  • Die Multisite-Funktion von WordPress selbst

qTranslate

Als ich dieses Plug-In testete, sah ich recht schnell, dass es keine Übersetzung von Slugs (URL-Variante des Namens) für Artikel, Seiten, Kategorien und Schlagwörter unterstützt. Somit ist dieses Plug-In meiner Meinung nach nutzlos, da ohne eine Slug-Übersetzung die Suchmaschinenoptimierung praktisch unmöglich ist.

Offensichtlich hat der ursprüngliche Plug-In-Entwicklung bisher keine Lust oder Zeit gehabt diese Funktion zu implementieren, aber obwohl es inzwischen andere Leute gibt, die sich mit diesem Problem beschäftigen (siehe dieser Forum-Beitrag (Englisch)), wollte ich nun kein derart unvollständiges Plug-In nutzen.

WPML

Auf den ersten Blick sah WPML wie eine gute Alternative aus. Es ist zwar nicht (mehr) kostenlos, aber ich habe nichts dagegen ein paar Dollar für ein gutes Plug-In zu bezahlen.

Jedoch sprechen folgende Gründe gegen eine Nutzung, weswegen ich die Rückerstattung meines Geldes (was innerhalb 30 Tagen möglich ist) beantragt habe:

  1. Ich möchte sämtliche Sprachen (inklusive der Standardsprache) in einem Unterverzeichnis haben und das wird von WPML nicht unterstützt.
    Die in diesem Forum geschilderte Hilfslösung (Englisch) ist mir ein bisschen zu provisorisch (man weiß nie, welche Probleme man später mit solchen “Hacks” haben wird).
  2. Es ist unpraktisch, dass WPML es nicht erlaubt Kategorien und Schlagwörter mit denselben Namen und Slugs für verschiedene Sprachen zu haben. Wenn die verschiedenen Sprachen in Unterverzeichnissen (oder sogar Sub-Domains) platziert sind, gibt es keinen Grund, dass die Namen und Slugs sprachübergreifend eindeutig sein müssen.
  3. In WPML gibt es einen Bug, dass Artikel Ihre Übersetzungszuordnung zueinander verlieren. Bisher wurde keine Erklärung oder Lösung hierfür angeboten. (Englisch)

Aber ich möchte hinzufügen, dass die Rückerstattung des Geldes, wie von dem Unternehmen versprochen, sehr schnell (innerhalb weniger Stunden) erfolgt ist; so kann jeder WPML selbst gefahrlos testen.

WordPress Multisite

Logischerweise gibt es nun nicht mehr viele weitere Optionen. Somit bleibt nur diese.

Natürlich gibt es auch dabei einen Nachteil: Übersetzte Artikel sind nicht direkt miteinander verbunden und somit kann der Leser nicht einfach zu einer anderen Sprache des Artikels wechseln. Aber vielleicht erstelle ich dafür selbst noch ein Plug-In, um das zu korrigieren.

In jedem Fall ist man bei dieser Lösung nicht auf irgendwelche fremden Plug-Ins für mehrsprachige Blogs angewiesen.

Hier erkläre ich wie Sie bei Verwendung von WordPress Multisite dennoch Flaggen zur Sprachauswahl anzeigen können.

Und welche Variante verwenden Sie für Ihren mehrsprachigen Blog?

Intel Black Belt Status als AppUp-Entwickler

Heute wurde ich von der deutschen Community-Managerin Monika Lischke von Intels AppUp-Entwicklerprogramm informiert, dass ich den Intel Black Belt Status (Englisch) verliehen bekomme!

Das freut mich sehr, da einer der vielen mit dieser Auszeichnung verbundenen Vorzüge eine Einladung zum diesjährigen Intel Developer Forum (IDF) (Englisch) in San Francisco ist. :-)

Sind Sie auch im Intel-AppUp-Entwicklerprogramm aktiv?

Dotclear als Alternative zu WordPress

Während ich nach einer guten, neuen Plattform für meinen Blog suchte, war die erste Blog-Software, auf die man trifft, natürlich WordPress. Da ich aber mit den Funktionen von WordPress hinsichtlich mehrsprachiger Blogs nicht so glücklich war (siehe dieser andere Post), suchte ich nach einer besseren Lösung.

Dann traf ich auf Dotclear (Englisch), das auf den ersten Blick nach einer interessanten Alternative aussah:

  • Es sieht schlicht und einfach aus.
  • Es ist in PHP geschrieben (da ich selbst auch in PHP entwickle, ist das für mich wichtig, falls es nötig sein sollte selbst einmal etwas hinzuzufügen oder anzupassen).
  • Es sollte einfach möglich sein mehr als eine Sprache für den Blog zu verwenden (was ja der Grund ist, weswegen ich mit WordPress unzufrieden bin).

Daher startete ich einen Versuch und installierte es auf meinem Test-Server, was ohne Probleme oder Fehler funktionierte.

Direkt nach dem ersten Login wollte ich einen Blick in die Dokumentation und die Plug-In-Beschreibungen werden, um zu sehen, welche Plug-Ins für dieses System verfügbar sind. Dann war ich jedoch ziemlich erschrocken: Sämtliche Plug-In-Beschreibungen sowie ein Teil der Dokumentation scheinen nur auf Französisch zur Verfügung zu stehen!

Vielleicht könnte ich es mit Hilfe meiner schulischen Lateinkenntnisse und Google Translate trotzdem verstehen, aber ich möchte wirklich kein Blog-System verwenden, welches als Hauptsprache nicht Englisch hat.

Obwohl ich muttersprachlich Deutsch spreche, sollte meiner Meinung nach ein größeres Open-Source-Projekt nicht einmal Deutsch als Hauptsprache wählen: Gib es Übersetzungen in anderen Sprache, ist das natürlich super, aber die meisten Leute verstehen nun mal Englisch und daher sollte die Hauptsprache eines Projektes auch Englisch sein! Punkt.

Somit habe ich den Test mit Dotclear abgebrochen und bleibe bei WordPress.

Haben Sie auch bereits positive oder negative Erfahrungen mit Dotclear gemacht?

USB-Audio-Interfaces mit gutem Frequenzgang

Für ein Messsystem benötigte ich ein USB-Audio-Interface mit einem guten Frequenzgang (mindestens bis zu 40 kHz).

Nach einer ersten Recherche im Internet merkte ich schnelle, dass dies nicht so einfach werden würde, da die meisten Hersteller schlicht und ergreifend keine nützlichen Informationen hinsichtlich des Frequenzgangs auf deren Internetseiten stellen. Wenn man hingegen nachfragt, wissen sie mitunter nicht einmal selbst eine definitive Antwort.

Aus diesem Grund habe ich folgende Interfaces zum Testen bestellt:

  • M-Audio FastTrack Pro (ca. 160 €)
  • TASCAM US-122 MKII (ca. 130 €)
  • E-MU 0202 USB (ca. 100 €)
  • ESI Dr. DAC nano (ca. 70 €)

Im Folgenden die Ergebnisse der einzelnen Audio-Interfaces.

M-Audio FastTrack Pro

M-Audio FastTrack Pro

Das Problem mit diesem Interface war, dass es noch immer USB 1.1 verwendet und daher eine Sampling-Rate von 96 kHz nur in eine Richtung (rein oder raus) möglich ist. Das wäre ja noch in Ordnung für mich, da ich es nur für die Ausgabe verwenden möchte, aber was ich auch immer versuchte, ich habe es nicht geschafft das Interface mit einer Sampling-Rate von 96 kHz zum Laufen zu bringen – es hat nur 44.1 kHz akzeptiert. Als Ergebnis war das obere Ende des Frequenzgangs natürlich nur bei etwa 20 kHz. Daher kann ich dieses Interface für meinen Zweck nicht verwenden.

TASCAM US-122 MKII

TASCAM US-122 MKII

Dies war das beste Interface bezogen auf den Frequenzgang in meinem Test: Im Gegensatz zum FastTrack Pro verwendet es USB 2.0 und kann daher problemlos Sampling-Raten bis zu 96 kHz in beide Richtungen gleichzeitig leisten. Der Frequenzgang ist auch sehr gut (20 Hz bis 40 kHz mit +/-1 dB) wie das folgende Diagramm des RightMark Audio Analyzers zeigt:Frequenzgang des TASCAM US-122-MKII

E-MU 0202 USB

E-MU 0202 USB

Was ich auch immer versucht habe, ich bekam dieses Interface nicht richtig zum Laufen: Mein Windows-XP-Computer stürzte mehrfach ab, als ich versuchte die Treiber zum Laufen zu bringen, und über die Windows-7-Beta-Treiber möchte ich erst gar nicht sprechen! Ich kann einfach nicht verstehen warum ein Unternehmen wie Creative (E-MU wurde 1993 von Creative aufgekauft) es nicht schafft zwei Jahre nach der Veröffentlichung des Betriebssystems offizielle (kein Beta!) und funktionierende Windows-7-Treiber bereitzustellen.

ESI Dr. DAC nano

ESI Dr. DAC nano

Dies war das günstigste Interface in meinem kleinen Test und es hat auch nicht besonders viele Funktonen: Es kann einfach nur Audio in Stereo ausgeben – über S/PDIF oder Line-Out -, aber das funktioniert einwandfrei auch bei einer Sampling-Rate von 96 kHz. Der Frequenzgang ist nicht das, was ich als “neutral” bezeichnen würde (es macht den Eindruck als wollte der Hersteller den Bass bewusst etwas verstärken), aber zumindest auch die höheren Frequenzen werden mit einer nicht zu hohen Dämpfung (20 Hz bis 40 kHz mit +2/-3 dB) ausgegeben. Für diesen Test habe ich das Interface TASCAM US-122 MKII als Eingang für den RightMark Audio Analyzer verwendet:Frequenzgang des ESI Dr. DAC nano

Als Ergebnis würde ich das Interface ESI Dr. DAC nano empfehlen, wenn nur Stereo bei 96 kHz ausgegeben werden muss und +2/-3 dB im Frequenzbereich von 20 Hz bis 40 kHz in Ordnung sind. Ansonsten ist bezogen auf den Frequenzgang eindeutig das TASCAM US-122 MKII von den getesteten am besten.

Formel-Parser für .NET

Für ein neues Softwareprojekt war ich auf der Suche nach einem guten Formel-Parser für .NET.

Neben dem Parsen und Auswerten von Formeln mit allen gängigen mathematischen Funktionen (wie Sinus, Cosinus, Logarithmus, …) sollte es auch möglich sein Variablen in den Formeln zu verwenden.

Die beste Lösung, die ich fand, ist diese hier:
http://www.lundin.info/mathparser.asp (Englisch)

Die Verwendung ist sehr einfach; hier ein Beispiel-Code in C#:

// Parser instanziieren
ExpressionParser parser = new ExpressionParser();

// Erstellen einer Hashtable für die Werte
Hashtable h = new Hashtable();

// Variablen und Werte zur Hashtable hinzufügen
h.Add("x", 1.ToString());
h.Add("y", 2.ToString());

// Parsen und Ergebnis holen
double result = parser.Parse("xcos(y)", h);

Und für diejenigen, die Visual Basic .NET bevorzugen:

' Parser instanziieren
Dim parser As New ExpressionParser()

' Erstellen einer Hashtable für die Werte
Dim h As New Hashtable()

' Variablen und Werte zur Hashtable hinzufügen
h.Add("x", 1.ToString())
h.Add("y", 2.ToString())

' Parsen und Ergebnis holen
Dim result As Double
result = parser.Parse("xcos(y)", h)

Es ist wichtig, dass die Werte dabei stets als String zur Hashtable der Variablen hinzugefügt werden. Der Grund dafür ist, dass diese intern einfach in die Formel eingefügt werden, bevor diese geparst wird – entsprechend müssen sie natürlich vom Typ String sein.

Die kostenlose Bibliothek is Open-Source und unter der LGPL lizensiert. Dadurch kann sie auch in kommerziellen Projekten eingesetzt werden, solange sie dynamisch als externe Bibliothek eingebunden wird.

Einfacher Sinus-Generator für .NET

In diesem Artikel möchte ich zeigen, wie man einen einfachen Sinus-Generator in .NET erstellen kann.

Zunächst ein Quelltextausschnitt, danach erkläre ich, was es damit aufsich hat:

const double frequency	= 1000;
const double amplitude	= 20000;
const long sampleRate	= 44100;
const int durationSec	= 5;

long sampleCount = sampleRate * durationSec;

double timeStep = 1.0 / (double)sampleRate;

double time = 0;
int[] values = new int[sampleCount];
for (long i = 0; i < sampleCount; i++) {
	values[i] = (int)(amplitude * Math.Sin(2 * Math.PI * frequency * time));
	time = time + timeStep;
}

Gut, nun also ein paar Erklärungen:

  • Zeilen 1-4: Einige Konstanten, die geändert werden können, um z. B. die Frequenz anzupassen.
    Hinweis: Die Frequenz kann maximal die Hälfte der Abtastrate betragen.
  • Zeile 6: Berechnung der Anzahl an Abtastpunkten.
  • Zeile 8: Berechnung der Zeit zwischen zwei Abtastpunkten.
  • Zeilen 10-11: Ein paar Variablen-Initialisierungen.
  • Zeilen 12-15: Hier wird schlussendlich der Wert für jeden Abtastpunkt berechnet.

Und nun noch der entsprechende Quelltext für Visual Basic .NET:

const frequency as double		= 1000
const amplitude as double		= 20000
const sampleRate As Long		= 44100
const durationSec As Integer	= 5

Dim sampleCount As Long
sampleCount = sampleRate * durationSec

Dim timeStep As Double
timeStep = 1.0 / sampleRate

Dim time As Double = 0
Dim values(0 To sampleCount - 1) As Integer
For i As Long = 0 To sampleCount - 1
	values(i) = amplitude * Math.Sin(2 * Math.PI * frequency * time)
	time = time + timeStep
Next i

Um das Ganze abzuspielen, kann man nun entweden einen API-Aufruf wie PlaySound (von winmm.dll) oder die Lösung dieses super Artikels (Englisch) verwenden.

Haben Sie auch bereits einmal einen Sinus in .NET generieren müssen?

MobileMonday: Vortrag über “Ihre Windows- und MeeGo-Apps in AppUp”

Heute war ein MobileMonday Developer Day (M2D2) in München mit einem Intel AppUp Application Lab: MeeGo Series extended, organisiert und durchgeführt in Kooperation von MobileMonday und Intel mit ungefähr 100 Teilnehmern.

Die Referenten sprachen über Details des Intel AppUp Entwicklerprogramms, die Vorteile der MeeGo-Plattform, die unzähligen Werkzeuge (im Besonderen das MeeGo SDK & Qt), die Binärcode-Validierung und die App-Entwickler-Community.

MobileMonday Intel AppUp Application Lab

Ich war eingeladen dort einen Vortrag zum Thema “Ihre Windows- und MeeGo-Apps in AppUp” zu halten. Downloaden Sie die PowerPoint-Präsentation (Englisch).

Digitale Signatur von Binärdateien unter Windows

Bereits seit vielen Jahren signiere ich sämtliche meiner Binärdateien digital – also Setups oder ausführbare Produktdateien.

Aber weswegen ist die digitale Signatur von Binärdateien so wichtig?

Ist eine Binärdatei digital signiert, kann der Benutzer, der sie ausführen möchte, sicherstellen, dass es sich um die Orginaldatei handelt und diese in keiner Weise verändert wurde. Außerdem zeigt die Windows Vista und Windows 7 Benutzerkontensteuerung dieseBenutzerkontensteuerung von Windows (signiert)

anstatt dieser sehr hässlichen Meldung an:Benutzerkontensteuerung von Windows (nicht signiert)

Davon abgesehen setzen inzwischen auch App-Store-Systeme wie Intel AppUp (Englisch) voraus, dass Ihre Setups digital signiert sind.

Zunächst einmal benötigen Sie ein Code-Signing-Zertifikat. Wenn Sie ein Entwickler im Intel-AppUp-Programm sind, bekommen Sie dieses direkt über die AppUp-Entwickler-Webseite. Ansonsten können Sie hier günstige Comodo-Zertifikate erhalten: http://codesigning.ksoftware.net (Englisch)

Nachdem Sie Ihre Code-Signing-Zertifikat erhalten haben, können Sie diese kleine GUI-Anwendung zum Signieren von binären Dateien (Englisch) verwenden.

Oder, falls Sie keine GUI-Anwendungen mögen oder das Signieren in Ihren Build-Prozess einbinden möchten, können Sie auch eine kleine Batch-Datei wie diese erstellen und die Binärdatei, die Sie signieren möchten, einfach per Drag & Drop auf diese Batch-Datei ziehen (oder als Parameter übergeben):

signtool.exe sign /f "zertifikat.pfx" /p "passwort" /t "http://timestamp.verisign.com/scripts/timstamp.dll" "%1"

Natürlich müssen Sie zertifikat.pfx mit dem Dateinamen Ihres Zertifikats (welches sich zusammen mit der Datei signtool.exe im selben Verzeichnis wie die Batch-Datei befinden sollte) und passwort mit Ihrem Zertifikatspasswort, dass Sie beim Export aus Ihrem Webbrowser gewählt haben,ersetzen. Um die Datei signtool.exe zu erhalten, laden Sie sich das kostenlose Microsoft Windows SDK (Englisch) herunter.

Hier sind einige häufig gestellte Fragen zu Code-Signing-Zertifikaten und digitaler Signatur.

Signieren Sie auch Ihre Binärdatei bereits digital?