<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Playground</title>
	
	<link>http://playground.ebiene.de</link>
	<description>Auch Entwickler brauchen Platz zum Spielen</description>
	<lastBuildDate>Mon, 08 Mar 2010 19:50:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/feedburner/Playground" /><feedburner:info uri="feedburner/playground" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>feedburner/Playground</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Tweets kostenfrei und automatisiert mit Backupify online sichern</title>
		<link>http://feedproxy.google.com/~r/feedburner/Playground/~3/otfHxDrQarI/</link>
		<comments>http://playground.ebiene.de/2401/tweets-backupify-backup/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 11:11:02 +0000</pubDate>
		<dc:creator>Sergej Müller</dc:creator>
				<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://playground.ebiene.de/?p=2401</guid>
		<description><![CDATA[Mit Tweets2Delicious wurde vor Zeiten eine praktikable, kompakte Möglichkeit des Twitter-Stream-Exportes vorgestellt, die nach der Inbetriebnahme auf eigenem Server für die zeitlich justierbare Migration der Tweets nach Delicious und somit für die Sicherung der vom Lebensdauer begrenzten 140-Zeiler zuständig war. In diesem Artikel wird ein alternativer, autonomer Weg des Backups gezeigt: Online-Dienst Backupify stellt 2 [...]]]></description>
			<content:encoded><![CDATA[<p>Mit <a href="http://playground.ebiene.de/2321/tweets-delicious-backup/">Tweets2Delicious</a> wurde vor Zeiten eine praktikable, kompakte Möglichkeit des Twitter-Stream-Exportes vorgestellt, die nach der Inbetriebnahme auf eigenem Server für die zeitlich justierbare Migration der Tweets nach <a href="http://delicious.com">Delicious</a> und somit für die Sicherung der vom Lebensdauer begrenzten 140-Zeiler zuständig war. In diesem Artikel wird ein alternativer, autonomer Weg des Backups gezeigt: Online-Dienst <a href="http://www.backupify.com">Backupify</a> stellt 2 GB Speicher kostenlos zur Nutzung bereit und füllt den verfügbaren Reservoir mit Daten aus unterschiedlichsten Quellen. Neben Facebook, WordPress und Basecamp gehört selbstverständlich auch der Datenstrom aus Twitter-Profilen. Ein Sorglos-Paket: Keine umständliche Installation, keine mühsame Einrichtung.<br />
<span id="more-2401"></span><br />
<strong>Tool zum Sichern inklusive</strong><br />
Das technische Konzept von Backupify ist weitgehend unkompliziert, ist im Nu dargelegt: Backupify bietet im Web <em>keinen</em> starren, &#8220;statischen&#8221; Speicherplatz an, Backupify &#8220;verkauft&#8221; zum Dienst passende, für eine sinnvolle Verwendung relevante und auf die Ansprüche der Anwender zugeschnittene Lösungen mit. Zwei GB an Speichervolumen kosten keinen Cent und können eine Vielzahl an transferierten Tweets problemlos aufnehmen und bei <a href="http://aws.amazon.com/s3/">Amazon S3</a>, dem weltweit führenden Spezialisten für Storage-Lösungen aufbewahren.</p>
<p>Praktisch: Nach erstem erfolgreichen Backup des Twitter-Streams erzeugt Backupify zusätzlich zu XML-Formaten ein PDF-Buch mit allen Tweets des Accounts. So steht einer Weiterleitung per E-Mail, einer Aufbewahrung auf lokalem Rechner oder einem Ausdruck auf Papier nichts mehr im Weg.</p>
<p>Für professionelle Anwender macht sich ein &#8211; noch in der Planung befindlicher &#8211; Upgrade des Accounts mit weiterem Speicherpotenzial bezahlt, Überzeugung und Begeisterung zum Online-Service vorausgesetzt.</p>
<p><strong>Backup-Initialisierung für den Twitter-Stream</strong><br />
Nachfolgend werden die Schritte der Einrichtung für das Anlegen eines automatischen Backups für einen Twitter-Profil abgebildet und mit kurzen Notizen versehen. Es ist zu beachten, dass mit der Sicherung erst wenige Tagen nach der Einrichtung angefangen wird.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/03/backupify-social-accounts.png" alt="Backupify Twitter Backup | Einstellungen" title="Backupify Twitter Backup | Einstellungen" class="alignnone size-full wp-image-2406" /><br />
<em>Nach dem Login werden unter &#8220;Settings&#8221; verfügbare Services gelistet</em></p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/03/backupify-twitter-accounts.png" alt="Backupify Twitter Backup | Verifizierung" title="Backupify Twitter Backup | Verifizierung" class="alignnone size-full wp-image-2407" /><br />
<em>&#8220;Manage&#8221; erlaubt eine Verifizierung mit gewünschtem Twitter-Account</em></p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/03/backupify-backup-settings.png" alt="Backupify Twitter Backup | Optionen" title="Backupify Twitter Backup | Optionen" class="alignnone size-full wp-image-2404" /><br />
<em>Sparsam angelegte Optionen werden am Fuß der Seite festgelegt</em></p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/03/backupify-archiv-uebersicht.png" alt="Backupify Twitter Backup | Backup-Archiv" title="Backupify Twitter Backup | Backup-Archiv" class="alignnone size-full wp-image-2403" /><br />
<em>Im Bereich &#8220;Archives&#8221; werden angefertigte Sicherungen als XML angeboten</em></p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/03/backupify-email-status.png" alt="Backupify Twitter Backup | Benachrichtigung" title="Backupify Twitter Backup | Benachrichtigung"" class="alignnone size-full wp-image-2405" /><br />
<em>Auf Wunsch benachrichtigt Backupify über den Status per E-Mail</em></p>
<p><strong>Fazit</strong><br />
Backupify zeigt sehr deutlich und gekonnt, dass Speicher im Web nicht nur mit herkömmlichen Dateien befüllt werden kann &#8211; Digitale Informationen aus Social-Netzwerken und Web 2.0 Diensten wie Flickr sind ebenfalls gegen Datenverlust empfindlich und eignen sich daher mehr als perfekt für das von Backupify konzipierte und umgesetzte Prinzip: Sichere alles, auch deine Aktivitäten im Social-Web.</p>
<img src="http://feeds.feedburner.com/~r/feedburner/Playground/~4/otfHxDrQarI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://playground.ebiene.de/2401/tweets-backupify-backup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://playground.ebiene.de/2401/tweets-backupify-backup/</feedburner:origLink></item>
		<item>
		<title>PHP-Script: Alte WordPress-Trackbacks auf Gültigkeit prüfen</title>
		<link>http://feedproxy.google.com/~r/feedburner/Playground/~3/tfo-_kZB39E/</link>
		<comments>http://playground.ebiene.de/2396/pings-erreichbarkeit-pruefen/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 22:22:19 +0000</pubDate>
		<dc:creator>Sergej Müller</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://playground.ebiene.de/?p=2396</guid>
		<description><![CDATA[Mit Pingbacks und Trackbacks stehen Autoren zwei äußerst praktische Mechanismen zur Verfügung, welche die Kommunikation zwischen den Blogs übernehmen und für automatische Benachrichtigungen über eingehende Links sorgen. Thematische Verweise zum Artikel, auch Backlinks genannt, steigern die Popularität einer Seite und sind nur von Vorteil (zumindest auf den ersten Blick) &#8211; je mehr von der Sorte, [...]]]></description>
			<content:encoded><![CDATA[<p>Mit <a href="http://de.wikipedia.org/wiki/Pingback">Pingbacks</a> und <a href="http://de.wikipedia.org/wiki/Trackback">Trackbacks</a> stehen Autoren zwei äußerst praktische Mechanismen zur Verfügung, welche die Kommunikation zwischen den Blogs übernehmen und für automatische Benachrichtigungen über eingehende Links sorgen. Thematische Verweise zum Artikel, auch Backlinks genannt, steigern die Popularität einer Seite und sind nur von Vorteil (zumindest auf den ersten Blick) &#8211; je mehr von der Sorte, desto besser.<br />
<span id="more-2396"></span><br />
<strong>Schneller weg als man denkt</strong><br />
In der Regel werden eingetroffene Trackbacks mit einem Link zur Quelle versehen und als Kommentar &#8211; bestenfalls <a href="http://digwp.com/2010/02/separate-comments-pingbacks-trackbacks/">separiert</a> &#8211; dargestellt. Soweit nichts Neues an der Materie.</p>
<p>Die aus der Praxis gewonnene Erkenntnis zeigt, dass Artikel mit gesetzten Pingbacks nicht selten über eine sehr kurze Lebensdauer verfügen und im Laufe der Zeit oft und gern offline gehen. Mögliche Gründe dafür: Blog eingestellt, Domain gewechselt, Artikelseiten entfernt etc. Die Folge: Man linkt im Kommentarbereich auf eine Blogseite, die es aktuell gar nicht mehr gibt. Nicht wirklich schön und ruft jeden passionierten Blogger zu Taten auf.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/02/kann-server-nicht-finden.png" alt="Referenzseiten landen im Nirvana" title="Referenzseiten landen im Nirvana" width="474" height="200" class="alignnone size-full wp-image-2398" /><br />
<em>Referenzseiten landen im Nirvana</em></p>
<p><strong>Miese Techniken: Redirects auf Schrott</strong><br />
Unangenehm dreist wird es, wenn scheinbar freundlich und gut gemeinte Referenzseiten mit funktionierenden Pingbacks plötzlich (meist nach einem Zeitfenster von 3 &#8211; 4 Monaten) auf Projekte mit pornographischen Inhalten umgeleitet werden, so dass man als normalsterblicher Blogger unbewusst auf nackte Tatsachen verweist, ohne davon jegliche Kenntnis zu nehmen. Auch Google sieht es nicht gern, wenn eine solide Blogseite mit unseriösen Angeboten verknüpft ist &#8211; Zack, Ranking runter. Da muss sich also etwas ändern!</p>
<p><strong>Kontrolle der existenten Blogverknüpfungen</strong><br />
Nachfolgend stellt sich ein ausführbares PHP-Skript als eine der tauglichen Lösungen vor: Der Code untersucht die in der Datenbank aufbewahrten Trackbacks auf ihre momentane Erreichbarkeit und fahndet im eingelesenen Artikeltext nach dem Link zum Blog. Auf diese Weise können nicht nur &#8220;Leichen&#8221;, sondern auch &#8220;Betrüger&#8221; (= haben den Link zum Blog entfernt oder die Seite umgeleitet) im Nu ausfindig gemacht und aus dem Blog manuell entfernt werden.</p>
<p>Beobachtungen bestätigen: Bei circa 500 Pingbacks innerhalb eines Blogs sind alle 6 Monate grob überschlagen 5 &#8211; 7 % davon nicht mehr brauchbar, weil nicht existent.</p>
<p><strong>Funktionsweise im Schnelldurchlauf</strong><br />
Um an die Auswahl der Pings (= Trackbacks und Pingbacks) heranzukommen, generiert ein SQL-Kommando die Liste mit URLs der Quellen, die wiederum vom Script nach und nach zwecks Check angesteuert werden. Verdächtige Adressen werden eingeblendet, entsprechende Trackbacks können z.B. im Backend in der Kommentaransicht mithilfe der internen (Kommentar-)Suche lokalisiert und bei Bedarf eliminiert werden.</p>
<p><strong>1. Schritt: DB-Export als CSV</strong><br />
Zunächst gehören die Ursprungsadressen der Pings in Form von alleinigen URLs als lesbare Liste exportiert &#8211; sie wird später vom Skript eingelesen. Ein SQL-Befehl gibt den gewünschten Datensatz aus, dieser gehört händisch exportiert. Für das geplante Vorhaben kann ein beliebiger SQL-Client wie das Online-Tool <a href="http://www.phpmyadmin.net/home_page/index.php">phpMyAdmin</a> oder die Desktop-Anwendung <a href="http://www.sequelpro.com/">Sequel Pro</a> angewendet werden. Einen Export als CSV ohne gesonderte Anpassungen schafft nahezu jede SQL-Applikation.</p>
<p>SQL-Statement zur Ausgabe der Ping-URLs:</p>
<pre>
SELECT DISTINCT comment_author_url
  FROM wp_comments
    WHERE comment_type
      IN('trackback','pingback')
</pre>
<p>Für alle Kommentartypen (Kommentare plus Pings):</p>
<pre>
SELECT DISTINCT comment_author_url
  FROM wp_comments
</pre>
<p><em>Hinweis zur Abfrage</em><br />
Weicht der Tabellenname mit Kommentaren vom WordPress-Standard (<em>wp_comments</em>) ab, so ist dieser im Befehl zu korrigieren.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/02/wordpress_export_pings.png" alt="Export der ausgelesenen Daten im CSV-Format" title="Export der ausgelesenen Daten im CSV-Format" width="474" height="200" class="alignnone size-full wp-image-2397" /><br />
<em>Export der ausgelesenen Daten im CSV-Format</em></p>
<p><strong>2. Schritt: PHP-Code anpassen und speichern</strong><br />
Der nachstehende PHP-Code soll kopiert, im Editor eingefügt, in den beiden Zeilen nach dem ersten Kommentar (<em>/* Zuweisung der Werte */</em>) vervollständigt und abschließend als PHP-Datei, also mit der Endung <em>.php</em>, gespeichert werden.</p>
<p>Erläuterung der abzustimmenden Variablen:</p>
<ul>
<li><em>$import_file</em> &#8211; Dateiname der erzeugten CSV-Datei</li>
<li><em>$blog_url</em> &#8211; Blog-Domain, nach der im Artikeltext gesucht wird</li>
</ul>
<p>Quelltext der Minianwendung:</p>
<pre>
&lt;?php
/* Zuweisung der Werte */
$import_file = 'customresult.csv';
$blog_url = 'playground.ebiene.de';

/* Import starten */
echo &quot;Import läuft...\n&quot;;
$lines = file($import_file);

/* Keine Daten? */
if (empty($lines)) {
  die('No data');
}

/* URLs loopen */
foreach ($lines as $line) {
  /* Zeile scannen */
  preg_match('!&quot;http://(.*)&quot;!', $line, $matches);

  /* Keine gültige URL */
  if (empty($matches[1])) {
    continue;
  }

  /* Gültige URL */
  $url = 'http://' .$matches[1];

  /* URL abrufen */
  if (!$output = @file_get_contents($url)) {
    echo 'Unereichbar: '. $url. &quot;\n&quot;;
  }

  /* Blog-URL suchen */
  if (!preg_match('/' .preg_quote($blog_url). '/i', $output)) {
    'Kein Link in: ' .$url. &quot;\n&quot;;
  }
}

die('Fertig!');
?&gt;
</pre>
<p><strong>3. Schritt: Ausführen</strong><br />
Vorab: Die angelegte PHP-Datei und der exportierte Datensatz im CSV-Format befinden sich am gleichen Ort, also physikalisch im identischen Ordner. PHP-File ist ausführbar, CSV lesbar.</p>
<p>Vor dem Start wird der Ordner auf eine unter PHP-laufende Umgebung transferiert: Das kann ein entfernter oder ein lokal eingerichteter Server sein. Eine Initialisierung via <a href="http://de.wikipedia.org/wiki/Bourne-again_shell">Bash</a> bietet sich an. Ein heimischer Server hat den wesentlichen Vorteil, dass dort Ausführungszeiten des Codes bei Bedarf angepasst werden können &#8211; denn je nach Anzahl der zu prüfenden Links kann der zeitintensive Check schon eine Weile dauern. Da heißt es: Kaffee holen.</p>
<p>Kommt es bei der Analyse der Adressen also zum Stop oder Fehlerhinweis, so muss entweder die <a href="http://php.net/manual/en/function.set-time-limit.php">Execution Time</a> nach oben oder die Menge der Einträge innerhalb der CSV-Liste nach unten korrigiert werden.</p>
<p>Das erreichte Resultat: Suspekte Trackback-Quellen kommen als Übersicht zum Vorschein und können &#8211; doppelt hält besser &#8211; nach manueller Kontrolle aus dem Blog entfernt werden. The job is done.</p>
<p><strong>Fazit</strong><br />
Je nach Projektgröße kann die Prüfroutine alle 6 Monate wiederholt werden &#8211; für mehr &#8220;Sauberkeit&#8221; in WordPress.</p>
<img src="http://feeds.feedburner.com/~r/feedburner/Playground/~4/tfo-_kZB39E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://playground.ebiene.de/2396/pings-erreichbarkeit-pruefen/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		<feedburner:origLink>http://playground.ebiene.de/2396/pings-erreichbarkeit-pruefen/</feedburner:origLink></item>
		<item>
		<title>Verteilung der WordPress-Versionen im deutschsprachigen Raum</title>
		<link>http://feedproxy.google.com/~r/feedburner/Playground/~3/mSL68p5ygrM/</link>
		<comments>http://playground.ebiene.de/2392/wordpress-versionen-verteilung/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 20:22:35 +0000</pubDate>
		<dc:creator>Sergej Müller</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://playground.ebiene.de/?p=2392</guid>
		<description><![CDATA[Um die gegenwärtige Population der WordPress-Versionen zu messen und nebenbei die vor einem Jahr gestartete Initiative am Leben zu erhalten, wurden vor wenigen Tagen Tausende an deutschsprachigen Blogs automatisiert eingelesen und auf die Releasenummer analysiert. Resultierende Werte legen die Aktualisierungsbereitschaft, Blindheit für Sicherheitsrisiken, aber auch die Experimentierfreudigkeit der modernen Blogger offen.

Untersucht wurden Blogseiten mit nicht [...]]]></description>
			<content:encoded><![CDATA[<p>Um die gegenwärtige Population der WordPress-Versionen zu messen und nebenbei die vor einem Jahr <a href="http://playground.ebiene.de/2045/deutsche-setzen-auf-wordpress/">gestartete</a> <a href="http://playground.ebiene.de/1941/verbreitung-wordpress-versionen/">Initiative</a> am Leben zu erhalten, wurden vor wenigen Tagen Tausende an deutschsprachigen Blogs automatisiert eingelesen und auf die Releasenummer analysiert. Resultierende Werte legen die Aktualisierungsbereitschaft, Blindheit für Sicherheitsrisiken, aber auch die Experimentierfreudigkeit der modernen Blogger offen.<br />
<span id="more-2392"></span><br />
Untersucht wurden Blogseiten mit nicht <a href="http://playground.ebiene.de/2310/wordpress-version-entfernen/">versteckten</a> bzw. manipulierten Angaben im Metatag <em>generator</em>. WordPress-Installationen mit der laufenden Nummer kleiner 2.6.0 wurden ebenfalls außer Acht gelassen, da eine sehr minimale Abdeckung. Feinkörnig: Die etwas hochwertigere Gruppe an Blogs aus den deutschen <a href="http://lesercharts.de">Lesecharts</a> wurde separiert behandelt und wird im Verlauf der Seite gesondert aufgeführt. Spot ab.</p>
<p><strong>WordPress-Versionen + Anzahl der Blogs</strong></p>
<ul>
<li>[3.0-alpha] => 5</li>
<li>[2.9.2] => 461</li>
<li>[2.9.1] => 440</li>
<li>[2.9.0] => 84</li>
<li>[2.8.6] => 177</li>
<li>[2.8.5] => 66</li>
<li>[2.8.4] => 206</li>
<li>[2.8.3] => 25</li>
<li>[2.8.2] => 20</li>
<li>[2.8.1] => 19</li>
<li>[2.8.0] => 46</li>
<li>[2.7.x] => 252</li>
<li>[2.6.x] => 87</li>
</ul>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/02/wordpress-versionen-chart.png" alt="Verbreitung der WordPress-Upgrades" title="Verbreitung der WordPress-Upgrades" width="474" height="200" class="alignnone size-full wp-image-2393" /><br />
<em>Wie erwartet: Verbreitung nach Erscheinungsdatum</em></p>
<p><strong>WordPress-Versionen + Anzahl der Blogs aus den Lesercharts</strong></p>
<ul>
<li>[2.9.2] => 97</li>
<li>[2.9.1] => 90</li>
<li>[2.9.0] => 17</li>
<li>[2.8.6] => 28</li>
<li>[2.8.5] => 6</li>
<li>[2.8.4] => 27</li>
<li>[2.8.3] => 4</li>
<li>[2.8.2] => 3</li>
<li>[2.8.1] => 2</li>
<li>[2.8.0] => 5</li>
<li>[2.7.x] => 29</li>
<li>[2.6.x] => 9</li>
</ul>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/02/wordpress-versionen-chart2.png" alt="Verbreitung der WordPress-Upgrades der Lesecharts" title="Verbreitung der WordPress-Upgrades der Lesecharts" width="474" height="200" class="alignnone size-full wp-image-2395" /><br />
<em>WordPress 2.9 in der Poleposition der (Lese)Charts</em></p>
<img src="http://feeds.feedburner.com/~r/feedburner/Playground/~4/mSL68p5ygrM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://playground.ebiene.de/2392/wordpress-versionen-verteilung/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://playground.ebiene.de/2392/wordpress-versionen-verteilung/</feedburner:origLink></item>
		<item>
		<title>Interne Links in WordPress-Beiträgen zukunftssicher setzen</title>
		<link>http://feedproxy.google.com/~r/feedburner/Playground/~3/FTALhydz-8s/</link>
		<comments>http://playground.ebiene.de/2388/wordpress-shortcode-links/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 18:27:09 +0000</pubDate>
		<dc:creator>Sergej Müller</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://playground.ebiene.de/?p=2388</guid>
		<description><![CDATA[Das Einfügen von Verlinkungen in den verfassten Beitragstext gestaltet WordPress mehr als komfortabel: Mit Copy &#038; Paste der Internet-Adresse ist das Vorhaben prompt und wirkungsvoll erledigt. Bei Projekten im jungen Stadium des Fortschritts wird erfahrungsgemäß rege und gern experimentiert, optimiert und modifiziert. Im Verlauf der Abstimmung kommt es daher meist zu textlichen Änderungen im Titel [...]]]></description>
			<content:encoded><![CDATA[<p>Das Einfügen von Verlinkungen in den verfassten Beitragstext gestaltet WordPress mehr als komfortabel: Mit Copy &#038; Paste der Internet-Adresse ist das Vorhaben prompt und wirkungsvoll erledigt. Bei Projekten im jungen Stadium des Fortschritts wird erfahrungsgemäß rege und gern experimentiert, optimiert und modifiziert. Im Verlauf der Abstimmung kommt es daher meist zu textlichen Änderungen im Titel und dem Inhalt der Artikel. Aber auch bei Permalinks kann sich die <a href="http://playground.ebiene.de/933/optimaler-permalink-in-wordpress/">Struktur</a> und die Zusammensetzung jederzeit erneuern &#8211; Unordnung ist vorprogrammiert.<br />
<span id="more-2388"></span><br />
<img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/02/wordpress_link_zuweisung.png" alt="Zuweisung eines Links in WordPress" title="Zuweisung eines Links in WordPress" width="474" height="200" class="alignnone size-full wp-image-2391" /><br />
<em>Zuweisung eines Links in WordPress</em></p>
<p><strong>Dynamisches Konzept für Permalinks</strong><br />
Um die bereits gesetzten, aber im Laufe der Website-Entwicklung umgeformten Links nicht per Hand korrigieren bzw. migrieren zu müssen, werden Verknüpfungen zwischen den internen Blogseiten mithilfe eines simplen <a href="http://codex.wordpress.org/Shortcode_API">Shortcode</a> gesetzt und mit jeweiliger ID angesprochen. Die Zweckmäßigkeit der Lösung: Die Artikel-ID bleibt für immer konstant, kann als Referenz der gelinkten Seite also sorglos verwendet werden &#8211; der Hyperlink wird anhand der ID dynamisch ermittelt und ist immer auf dem aktuellsten Stand. Ohne Weiterleitungen, ohne zusätzliche Plugins.</p>
<p><strong>Erweiterung der functions.php im aktuellen Theme</strong></p>
<pre>
add_shortcode(
  'post',
  create_function(
    '$atts, $data',
    'return &quot;&lt;a href=\&quot;&quot; .get_permalink($atts[id]). &quot;\&quot; title=\&quot;&quot; .esc_attr(strip_tags(get_the_title($atts[id]))). &quot;\&quot;&gt;&quot; .$data. &quot;&lt;/a&gt;&quot;;'
  )
);
</pre>
<p><strong>Mögliche Anwendung im Beitrag</strong></p>
<pre>
... Text [post id=9]Verlinkter Blogartikel[/post] Text ...
</pre>
<p><strong>Nennenswerte Vorteile</strong></p>
<ul>
<li>Link (<em>href</em>) und Titel (<em>title</em>) stets up-to-date, da dynamisch geladen.</li>
<li>Keine Migration oder Anpassungen bei URL-Änderung notwendig.</li>
<li>Empfehlenswert für kleine bis mittelgroße Websites mit WordPress als CMS.</li>
<li>Funktioniert bei Beiträgen, statischen Seiten und Anhängen.</li>
</ul>
<p><strong>Nachteile des Shortcodes</strong></p>
<ul>
<li>Erzeugt zwei zusätzliche Datenbankabfragen, da Werte neu gelesen werden.</li>
<li>Umständlich, da die Ziel-ID gefunden und händisch eingefügt werden muss.</li>
<li>Bei der Entfernung des Codes bleiben Shortcode-Einträge sichtbar zurück.</li>
<li>Keine interne Benachrichtigung via Pingback.</li>
</ul>
<p><strong>Voraussetzungen</strong></p>
<ul>
<li>WordPress 2.8</li>
</ul>
<p><strong>Andere Route zum Ziel?</strong><br />
Als Alternative zum vorgestellten Ansatz wären relative Pfadangaben beim Verlinken der Beiträge durchaus denkbar &#8211; nach einem Blogumzug bliebe zumindest die Suchen-Ersetzen-Prozedur auf der Datenbankebene erspart, da sonst die alte Domain im Pfad durch die neue getauscht werden müsste. Wird jedoch die Gliederung der URL im Laufe der Zeit nachträglich korrigiert, so kommt man als Blogger nicht drumherum, &#8220;hart&#8221; gesetzte Links aufwendig zu aktualisieren. Des Weiteren kommen die meisten Feedreader mit relativen Angaben der Links im Artikelinhalt nicht klar &#8211; Contra für die Relativität also.</p>
<p><strong>Fazit</strong><br />
Zusammenfasend lässt sich festhalten, dass die angesprochene Methode zwar geringfügig umständlicher, &#8220;hungriger&#8221; als die von WordPress mitgelieferte Technik ist, dafür aber effizient. Mit einer gesunden Portion Selbstdisziplin kann auf diesem Weg ein internes, pflegeleichtes und vor allen Dingen stabiles Linknetzwerk aufgebaut werden. Ohne Fleiß kein Preis.</p>
<p><strong>P.S.</strong><br />
Übrigens verfolgt Michael Oeser in seinem <a href="http://www.michaeloeser.de/wie-man-in-wordpress-shortcodes-fuer-permalinks-erstellt-37000.html">How-To</a> einen identischen Ansatz.</p>
<img src="http://feeds.feedburner.com/~r/feedburner/Playground/~4/FTALhydz-8s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://playground.ebiene.de/2388/wordpress-shortcode-links/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		<feedburner:origLink>http://playground.ebiene.de/2388/wordpress-shortcode-links/</feedburner:origLink></item>
		<item>
		<title>wpTwitBox Plugin: Werkzeugkasten mit Twitter-Tools auf Basis von Bit.ly</title>
		<link>http://feedproxy.google.com/~r/feedburner/Playground/~3/8vHi86Q4jmw/</link>
		<comments>http://playground.ebiene.de/2375/wptwitbox-wordpress-plugin/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 08:00:40 +0000</pubDate>
		<dc:creator>Sergej Müller</dc:creator>
				<category><![CDATA[Twitter]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://playground.ebiene.de/?p=2375</guid>
		<description><![CDATA[Für immer mehr Blogger wird Twitter zum effektiven und gern genutzten Marketinginstrument: Aktuell verfasste Beiträge sind heutzutage nicht ausschließlich auf Blogseiten und in Form eines RSS-Feeds verfügbar. Der verzögerungsfreie Twitter-Stream informiert ebenfalls über Neuzugänge im Blog. Dabei leisten vielfältige Tools &#8211; Marke &#8220;Eigenbau&#8221; oder Drittanwendungen &#8211; dem Beitragsautor unermüdliche Unterstützung und übernehmen einen Großteil der [...]]]></description>
			<content:encoded><![CDATA[<p>Für immer mehr Blogger wird Twitter zum effektiven und gern genutzten Marketinginstrument: Aktuell verfasste Beiträge sind heutzutage nicht ausschließlich auf Blogseiten und in Form eines RSS-Feeds verfügbar. Der verzögerungsfreie Twitter-Stream informiert ebenfalls über Neuzugänge im Blog. Dabei leisten vielfältige Tools &#8211; Marke &#8220;Eigenbau&#8221; oder Drittanwendungen &#8211; dem Beitragsautor unermüdliche Unterstützung und übernehmen einen Großteil der zeitintensiven Arbeit. Das Plugin <em>wpTwitBox</em> bringt ebenso eine Sammlung an nützlichen Funktionen mit, welche beliebige WordPress Blogs mit klugen Automatismen ausstatten und Verknüpfungen zu <a href="http://twitter.com">Twitter</a> und <a href="http://bit.ly">Bit.ly</a> herstellen.<br />
<span id="more-2375"></span><br />
<strong>Sprungmarken</strong></p>
<ul>
<li><a href="#functionality">Funktionsweise</a></li>
<li><a href="#features">Features</a></li>
<li><a href="#history">Versionsverlauf</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="#download">Download</a></li>
</ul>
<p><strong id="functionality">Funktionsweise</strong><br />
Das kostenlose WordPress Plugin <em>wpTwitBox</em> vereint in sich gängige Funktionen rund um Twitter, welche von Webverfasser kontinuierlich genutzt und eigenen Lesern zugänglich gemacht werden (Stichwort: <em>Twit This</em>). Bei der Programmierung der Erweiterung wurde sehr viel Wert auf die Performance der Software gelegt: WordPress-interne <a href="http://de.wikipedia.org/wiki/Cron">Cronjobs</a> und <a href="http://de.wikipedia.org/wiki/Cache">Caching</a>-Methoden gehören daher zum Lieferumfang. Umfangreich, jedoch mit viel Liebe zum Detail.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/01/wptwitbox_optionen.png" alt="Selbsterklärende wpTwitBox Optionen" title="Selbsterklärende wpTwitBox Optionen" width="474" height="200" class="alignnone size-full wp-image-2377" /><br />
<img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/01/wptwitbox-optionen-2.png" alt="wpTwitBox Optionen" title="wpTwitBox Optionen" width="474" height="200" class="alignnone size-full wp-image-2378" /><br />
<em>Selbsterklärende wpTwitBox Optionen</em></p>
<p><strong id="features">Features</strong><br />
Der Funktionsumfang von <em>wpTwitBox</em> zusammengefasst:</p>
<p><strong>1. Automatische Aktualisierung der Followerzahl</strong><br />
Einmal täglich holt das prompt installierte Plugin die Gesamtzahl der Follower via Twitter API ab und aktualisiert den Counter in der Datenbank. Der passende Begriff hierfür: Caching!</p>
<p>Aus dem Template heraus kann auf die zwischengespeicherte Followerzahl zwecks Ausgabe wie folgt zugegriffen werden (Beispiel siehe Sidebar rechts):</p>
<pre>
&lt;?php if (class_exists('wpTwitBox')) {
  $GLOBALS['wpTwitBox']->the_followers_count();
} ?&gt;
</pre>
<p><em>Pflichtfeld für diese Option</em></p>
<ul>
<li>Twitter Nutzername</li>
</ul>
<p><strong>2. Twitter bei neuen Beiträgen benachrichtigen (Auto Tweet)</strong><br />
Nach der Aktivierung der Checkbox wird <em>wpTwitBox</em> versuchen, einen Tweet mit dem Titel samt Link des soeben veröffentlichen Artikels abzusetzen. Dabei spielt es keine Rolle, ob der Beitrag sofort oder zu einem späteren Zeitpunkt publiziert wurde.</p>
<p>Ist der Beitragstitel zu lang, so wird er vom Plugin passend gekürzt. Der Permalink zum Post wird verständlicherweise in einen kürzeren Bit.ly Link konvertiert. Es ergibt sich das Format: Blogtitel + Bit.ly URL</p>
<p><em>Pflichtfelder für diese Option</em></p>
<ul>
<li>Twitter Nutzername</li>
<li>Twitter Passwort</li>
</ul>
<p><strong>3. Links in den Kommentaren in Bit.ly Links umwandeln</strong><br />
<del datetime="2010-01-20T00:39:49+00:00">SEOs</del> Kommentatoren jonglieren zu gerne mit Links. Nicht selten sind URLs &#8220;meterlang&#8221; und ruinieren das gesamte Layout der Kommentarspalte. Aus ästhetischen Gründen können Verweise nach dem Absenden eines Kommentars in deutlich kürzere, charmantere Bit.ly Links abgeändert werden. Denkbar wäre auch ein simpler Schutz vor Links, die im Laufe der Zeit offline gehen oder umgeleitet werden.</p>
<p>Kleinigkeit am Rande: Ist der umzuwandelnde Link kürzer als der resultierende Bit.ly Link, so nimmt <em>wpTwitBox</em> keine Konvertierung vor, da die gewünschte Länge bereits gegeben ist.</p>
<p><strong>4. Permanentes Caching der Bit.ly Links</strong><br />
<em>wpTwitBox</em> ist in der Lage einen &#8211; pro Artikel eigenständigen &#8211; <em>Twit This Link</em> (auch <em>ReTweet</em> genannt) zu erzeugen und im Template mittels Funktionsaufruf auszugeben. Auch hier übernimmt Bit.ly die Herrschaft über den Link.</p>
<p>Ist das Caching eingeschaltet, so greift die Erweiterung auf den in der Datenbank abgelegten, also gecachten Link zu und umgeht somit ständige Anfragen an den Shortener für die Ermittlung der Kurzversion von Artikel-URLs. Genutzte Caching-Techniken sind geschwinder und eleganter als die mit der Performance verschwenderisch umgehenden Zugriffe auf externe Server. Mehr zum Thema unter <a href="http://playground.ebiene.de/2188/wordpress-tweet-this/">Twitter-Link mit Caching-Funktion</a>.</p>
<p>Im Template kann der von <em>wpTwitBox</em> vorbereitete Twit This Link unkompliziert eingebunden werden:</p>
<pre>
&lt;?php if (class_exists('wpTwitBox')) { ?&gt;
  &lt;a href=&quot;&lt;?php $GLOBALS['wpTwitBox']->the_tweet_link() ?&gt;&quot;&gt;..&lt;/a&gt;
&lt;?php } ?&gt;
</pre>
<p>Funktionsaufruf gibt den (gecachten) Bit.ly Link zurück:</p>
<pre>
&lt;?php if (class_exists('wpTwitBox')) { ?&gt;
  &lt;?php echo $GLOBALS['wpTwitBox']->get_tweet_link() ?&gt;
&lt;?php } ?&gt;
</pre>
<p><strong>5. Shortener J.mp anstatt von Bit.ly nutzen</strong><br />
J.mp ist nichts anderes als Bit.ly &#8211; gleicher Anbieter, absolut identische Daten. Der wahre Unterschied liegt lediglich an der geringeren Zeichenanzahl der Domain: J.mp ist halt 2 Buchstaben kürzer. Auf Wunsch kann J.mp also als Plugin-Shortener verwendet werden.</p>
<p><strong>6. Klicks auf Bit.ly Links protokollieren</strong><br />
Die Optionsfelder für die Eingabe der Bit.ly Zugangsdaten sind nicht umsonst da: Sind diese richtig hinterlassen, nutzt <em>wpTwitBox</em> eine weitere API von Bit.ly und lässt den weltweit beliebten Shortener für diesen bestimmten Nutzer spezifische Links anlegen. Benutzergebundene Links werden automatisch zum Bestandteil der persönlichen Bit.ly History (im eingeloggten Zustand bereits auf der Bit.ly Startseite zu sehen) und geben auf Anhieb Auskunft über die Verbreitung und das Klickverhalten der angelegten Verweise.</p>
<p>Tipp: Einen extra Bit.ly Account anlegen, um wertvolle Statistiken separat und unabhängig von den gewöhnlichen Tweets zu erhalten.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/01/bitly-history.png" alt="Bit.ly History mit Links und Klicks" title="Bit.ly History mit Links und Klicks" width="474" height="200" class="alignnone size-full wp-image-2376" /><br />
<em>Bit.ly History mit Links und Klicks</em></p>
<p><strong>Generelle Hinweise</strong></p>
<ul>
<li>Ab WordPress 2.7</li>
<li>Plugin-Deinstallation löscht alle Optionen und den Cache</li>
<li>Kostenlose Nutzung, GPL</li>
<li>In Deutsch und Englisch verfügbar</li>
</ul>
<p><strong>Geplante Features</strong></p>
<ul>
<li>Tweetbacks</li>
<li>Darstellung eigener Tweets</li>
<li>Validierung der Zugangsdaten</li>
<li>Flexibilität des Textes im ReTweet-Link und Auto Tweet</li>
<li>Vergabe der Hash-Tags</li>
</ul>
<p><strong id="history">Versionsverlauf</strong><br />
Version 0.2 vom 21.01.2010:</p>
<ul>
<li>Transparentes Plugin-Icon</li>
<li>Neue Funktion <em>get_tweet_link</em> liefert den Bit.ly Link des Artikels</li>
<li>Textliche und optische Anpassungen</li>
<li>Fix für Auto Tweets bei geplanten Posts</li>
</ul>
<p>Version 0.1 vom 20.01.2010:</p>
<ul>
<li><em>wpTwitBox</em> goes live</li>
</ul>
<p><strong id="installation">Installation</strong></p>
<ul>
<li>Plugin downloaden</li>
<li>Via FTP oder WordPress-Backend zu den Plugins hochladen</li>
<li>Reiter <em>Plugins</em> aufrufen</li>
<li>Plugin <em>wpTwitBox</em> aktivieren</li>
<li>Einstellungen vornehmen</li>
</ul>
<p><strong id="download">Download</strong><br />
<a href="http://downloads.wordpress.org/plugin/wptwitbox.zip">&rsaquo; WordPress Plugin wpTwitBox &darr;</a></p>
<ul>
<li>Format: ZIP</li>
<li>Version: 0.2</li>
</ul>
<img src="http://feeds.feedburner.com/~r/feedburner/Playground/~4/8vHi86Q4jmw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://playground.ebiene.de/2375/wptwitbox-wordpress-plugin/feed/</wfw:commentRss>
		<slash:comments>68</slash:comments>
		<feedburner:origLink>http://playground.ebiene.de/2375/wptwitbox-wordpress-plugin/</feedburner:origLink></item>
		<item>
		<title>Webseiten-Performance: JavaScript-Dateien mit Google bündeln</title>
		<link>http://feedproxy.google.com/~r/feedburner/Playground/~3/Yx7FBzo8f3c/</link>
		<comments>http://playground.ebiene.de/2362/google-optimiert-javascript/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 05:00:21 +0000</pubDate>
		<dc:creator>Sergej Müller</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://playground.ebiene.de/?p=2362</guid>
		<description><![CDATA[Steigende Anzahl an Interaktionen innerhalb einer Webseite sorgt in der Regel für zusätzliche Stylesheets und JavaScript. Im unglücklichen Fall werden gar Frameworks aka &#8220;Schwergewichte&#8221; herangezogen. Dabei generiert extern ausgelagerter Code je nach Dateimenge weitere Server-Anfragen und verlangsamt den gesamten Ladevorgang. Google&#8217;s Werkzeuge reduzieren die Quantität auf ein Minimum &#8211; Resultat: Einziger Request bei beliebig vielen [...]]]></description>
			<content:encoded><![CDATA[<p>Steigende Anzahl an Interaktionen innerhalb einer Webseite sorgt in der Regel für zusätzliche Stylesheets und JavaScript. Im unglücklichen Fall werden gar Frameworks aka &#8220;Schwergewichte&#8221; herangezogen. Dabei generiert extern ausgelagerter Code je nach Dateimenge weitere Server-Anfragen und verlangsamt den gesamten Ladevorgang. Google&#8217;s Werkzeuge reduzieren die Quantität auf ein Minimum &#8211; Resultat: Einziger Request bei beliebig vielen JS-Dateien.<br />
<span id="more-2362"></span><br />
<strong>JavaScript only</strong><br />
Dieser Artikel fokussiert sich ausschließlich auf die Performance-orientierte Einbindung der JavaScript-Komponenten. Eine gewinnbringende Integration von Stylesheets ins Projekt wird an dieser Stellen nicht behandelt.</p>
<p><strong>Verlangsamte Ausführung durch JavaScript-Dateien</strong><br />
Je nach Komplexität und Funktionsvielfalt einer Website bindet der Entwickler Handvoll an externen JavaScript-Instanzen ins XHTML-Gerüst ein, um Funktionen zur Laufzeit verfügbar und ausführbar zu machen. Ein alltäglicher Prozess.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/01/js_requests.png" alt="Zuviele Requests schaden dem Ladevorgang der Seite" title="Zuviele Requests schaden dem Ladevorgang der Seite" width="474" height="200" class="alignnone size-full wp-image-2363" /><br />
<em>So nicht: Zuviele Requests schaden dem Ladevorgang der Seite</em></p>
<p>Ein Szenario aus dem Alltag: Zwei <a href="http://de.wikipedia.org/wiki/Framework">JavaScript-Frameworks</a> werden geladen, plus ein jQuery-Plugin für die Slideshow, <a href="http://code.google.com/p/swfobject/">SWFObject</a> für die Flash-Einbindung, dazu kommt noch Google Analytics oder anderes Tracking-Tool auf JavaScript-Basis.</p>
<p>An sich nichts, was man nicht braucht. Wenn da nicht die schmerzende Tatsache wäre, dass jede dieser Module (Modul = Datei) den Browser dazu zwingt, sich mit dem Server zu verbinden, um Daten in Form von JavaScript-Zeilen zum Rechner des Nutzers zu transferieren. Das Gewicht der Files und die Anzahl der Bytes ist an dieser Stelle nicht wirklich kritisch (was sein muss, muss sein). Vielmehr ist die Menge der Anfragen als bedenklich zu betrachten, da Browser je nach Typ eingeschränkt parallele Requests bzw. Downloads ausführen können.</p>
<p><strong>Einbettung einer Gesamtdatei mit JS-Code</strong><br />
Je mehr Dateien von der gleichen Domain in eine Seite eingebunden werden (unabhängig vom Typ), desto länger wird im Browser die Warteschlange zum Abarbeiten, um so langsamer ist die Ausgabe. Die Erkenntnis: Idealerweise steckt der komplette JS-Code in nur einer Datei, die einmalig im XHTML referenziert wird &#8211; der Browser stellt dafür nur die einzige Verbindung her und kann nebenbei andere Medien wie z.B. Bilder herunter laden. Bringt einen Performanceschub. </p>
<p>Viele der erfahrenen Entwickler praktizieren diese simple Technik: In der Entwicklungsumgebung aus Gründen der Übersichtlichkeit und der Bequemlichkeit an mehreren Dateien arbeiten. Live kommt lediglich die eine Datei zum Einsatz, die aus den separaten JS-Bibliotheken gewonnen und anschließend minimiert (z.B. mithilfe des <a href="http://compressor.ebiene.de/">JavaScript-Compressor</a>) wurde.</p>
<p><strong>Techniken für die Bündelung der JavaScript-Sourcen</strong><br />
Neben dem händischen Kopiervorgang der Zusammenführung von JS-Fragmenten existieren noch weitere Methoden für das Erzeugen einer zentralen JS-Datei. Eine der bewährten Möglichkeiten ist beispielsweise ein dynamisches <a href="http://rakaz.nl/2006/12/make-your-pages-load-faster-by-combining-and-compressing-javascript-and-css-files.html">Load-Script in PHP</a>, welches Dateinamen als Parameter empfängt und entsprechende JS-Files in kombinierter Form an den Browser ausgibt.</p>
<p>Aber auch Google Labs stellt solch zweckmäßige, installationslose Online-Lösungen öffentlich zur Verfügung, welche weiter unten samt Vorteilen praxisbezogen vorgestellt werden.</p>
<p><strong>1. Google Closure Compiler</strong><br />
<a href="http://closure-compiler.appspot.com/">Closure Compiler</a> ist ein kostenloser Online-Service von Google mit alleiniger Aufgabe, JavaScript-Input komprimiert zu bündeln. Warum <em>bündeln</em>? Das Tool fasst nicht nur die händisch eingefügten JavaScript-Fragmente zusammen, auch gängige Frameworks (jQuery und Prototype zum Beispiel) und extern abgelegte Quellen lassen sich in der Anwendungsoberfläche auswählen bzw. abrufen und fließen so ins Endergebnis mit ein. Nach diesem Prinzip wären die notwendigen Frameworks und der eigene Code in nur einer Datei vereint.</p>
<p>Nach der erfolgreich abgeschlossenen Kompilierung der Rohdaten steht eine Zeichenwüste zum Kopieren und Download bereit.</p>
<p><strong>Pro</strong></p>
<ul>
<li>Zusammenführung mehrerer JS-Dateien (eigene, externe, Frameworks)</li>
<li>Komprimierung der Größe durch Bereinigung des Codes (minify)</li>
</ul>
<p><strong>Contra</strong></p>
<ul>
<li>Entwickler übernimmt das Hosting, Caching, GZIP und <a href="http://playground.ebiene.de/2351/google-app-engine-als-cdn/">CDN</a></li>
</ul>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/01/closure_compiler.png" alt="Eigene JS-Inhalte und bekannte Libs mit Closure Compiler gruppieren" title="Eigene JS-Inhalte und bekannte Libs mit Closure Compiler gruppieren" width="474" height="200" class="alignnone size-full wp-image-2364" /><br />
<em>Eigene JS-Inhalte und bekannte Libs mit Closure Compiler gruppieren</em></p>
<p><strong>2. AJAX API Loader</strong><br />
Seit neustem verfügt Google über einen neuartigen Dienst namens <a href="http://code.google.com/apis/ajax/documentation/#AutoLoading">Autoloader</a>, der mehrere APIs zusammenlegt und in komprimierter Datei zurückgibt. Der Autoloader unterstützt auch GET-Parameter und so werden die zum Laden notwendige Module als URL-Aufruf übergeben, Google fast den Code der APIs in einer Datei zusammen. Der praktische <a href="http://code.google.com/apis/ajax/documentation/autoloader-wizard.html">Wizard</a> hilft bei der Bündelung der APIs und der Generierung der kryptischen Adresse.</p>
<p>Doch die Vielfalt der möglichen Module beschränkt sich nicht unbedingt auf Google APIs: Die oben bereits erwähnten Frameworks können auf die gleiche Weise via URL-Aufruf gruppiert geholt werden &#8211; als Ergänzung eine Übersicht der auf Google verfügbaren Frameworks: <a href="http://code.google.com/apis/ajaxlibs/documentation/">Google AJAX Libraries API</a>. Dazu werden lediglich die Namen und Versionsnummer der gewünschten Module angepasst bzw. ergänzt und als Übergabeparameter definiert. Mehr ist an dieser Stelle nicht notwendig.</p>
<p>In folge dessen können schwergewichtige Bibliotheken (dabei bleibt die Anzahl der Files variabel) mit nur einem Request (welcher jedoch Gold wert ist) ins eigene Projekt inkludiert werden.</p>
<p><strong>Pro</strong></p>
<ul>
<li>Zusammenführung mehrerer Frameworks</li>
<li>Komprimierung der Größe durch Bereinigung des Codes (minify)</li>
<li>GZIP-Komprimierung während der Übertragung</li>
<li>Übergabe korrekter Cache-Header</li>
<li>Anbindung an ein <a href="http://playground.ebiene.de/2351/google-app-engine-als-cdn/">CDN</a></li>
</ul>
<p><strong>Contra</strong></p>
<ul>
<li>Kein eigenes JS möglich, ausschließlich bei Google verfügbare Frameworks</li>
<li>Abhängigkeit von Google</li>
</ul>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2010/01/AJAX_API_Loader.png" alt="Google's Autoloader kann APIs, aber auch Frameworks verbinden" title="Google's Autoloader kann APIs, aber auch Frameworks verbinden" width="474" height="200" class="alignnone size-full wp-image-2365" /><br />
<em>Google&#8217;s Autoloader kann APIs, aber auch Frameworks verbinden</em></p>
<p><strong>Fazit</strong><br />
Aktuell berücksichtigt Google die Geschwindigkeit der Webseiten als einen nicht unerheblichen Ranking-Faktor, gibt den Entwicklern aber auch ausgereifte und kostenfreie Werkzeuge für diesen Zweck in die Hände. Die Zusammenführung der JavaScript-Dateien ist eine wichtige Schraube im mächtigen Motor der Performance-Optimierung und darf daher nicht &#8220;einrosten&#8221;.</p>
<img src="http://feeds.feedburner.com/~r/feedburner/Playground/~4/Yx7FBzo8f3c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://playground.ebiene.de/2362/google-optimiert-javascript/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		<feedburner:origLink>http://playground.ebiene.de/2362/google-optimiert-javascript/</feedburner:origLink></item>
		<item>
		<title>Content Delivery Network (CDN) von Google für eigene Projekte nutzen</title>
		<link>http://feedproxy.google.com/~r/feedburner/Playground/~3/Myw5TQ_vhRw/</link>
		<comments>http://playground.ebiene.de/2351/google-app-engine-als-cdn/#comments</comments>
		<pubDate>Sun, 20 Dec 2009 23:00:26 +0000</pubDate>
		<dc:creator>Sergej Müller</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://playground.ebiene.de/?p=2351</guid>
		<description><![CDATA[Mit App Engine stellt Google jedem ambitionierten Programmierer eine skalierbare Entwicklungsumgebung bereit, die sich in Punkten Performance, Speicher und Bandbreite an die wachsenden Ansprüche der Anwendungen dynamisch anpasst. Ursprünglich für Ausführungen komplexer Java- und Python-Skripte angelegt, kann auf Google App Engine gleicherweise statischer Content geparkt und in eigenen Seiten vorteilhaft eingebunden werden. Mit CDN als [...]]]></description>
			<content:encoded><![CDATA[<p>Mit <a href="http://appengine.google.com">App Engine</a> stellt Google jedem ambitionierten Programmierer eine skalierbare Entwicklungsumgebung bereit, die sich in Punkten <em>Performance</em>, <em>Speicher</em> und <em>Bandbreite</em> an die wachsenden Ansprüche der Anwendungen dynamisch anpasst. Ursprünglich für Ausführungen komplexer Java- und Python-Skripte angelegt, kann auf Google App Engine gleicherweise statischer Content geparkt und in eigenen Seiten vorteilhaft eingebunden werden. Mit CDN als Turbo.<br />
<span id="more-2351"></span><br />
<strong>Länge, die in die Tiefe geht</strong><br />
<a href="http://en.wikipedia.org/wiki/Cloud_computing">Cloud Computing</a> und <a href="http://de.wikipedia.org/wiki/Content_Delivery_Network">CDN</a> &#8211; nie etwas davon gehört? Im Unterschied zu den nahezu unzählig vorhandenen Beiträgen à la &#8220;Nutzen Sie CDN, um Ihre Webseiten zu beschleunigen&#8221; bleibt der Leser nach diesem Artikel nicht unwissend im Regen stehen. Der Bericht geht gleichermaßen auf die praktische Seite der Nutzung eines CDN ein, konkretisiert die Pluspunkte solch eines Netzwerks für den Website-Entwickler und erläutert in einfachen, für Einsteiger verständlichen Schritten die Inbetriebnahme der praktischen Lösung. Legen wir mit Verständnisfragen los.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2009/12/google_app_engine.png" alt="Die Flugzeug-Turbine steht für (Webseiten-)Turbo" title="Die Flugzeug-Turbine steht für (Webseiten-)Turbo" width="474" height="200" class="alignnone size-full wp-image-2355" /><br />
<em>App Engine: Die Flugzeug-Turbine steht für (Webseiten-)Turbo</em></p>
<p><strong>Was ist ein CDN und welche Aufgabe hat es zu erledigen?</strong><br />
<em>CDN</em> steht für <em>Content Delivery Network</em> &#8211; ein intelligent ausgelegter Verbund aus mehreren kontinental zerstreuten Servern bzw. Server-Farmen. Die zu erfüllende Mission: Je nach geografischem Standort der Webseiten-Besucher reagiert der nächstgelegene Server auf die Browser-Anfrage und kann die angeforderten Daten prompter, also zeitsparender ausliefern als der Konkurrent auf gegenüberliegender Welthälfte. So teilen sich die Rechner im Verbund die Last und das Traffic-Aufkommen, sichern aber auch die höchste Erreichbarkeit und die niedrigste Ladezeit der dort gehosteten Webseiten oder statische Objekte. Eine &#8220;Win-Win&#8221;-Situation, sozusagen.</p>
<p>Ein banales Quiz zum Verständnis: Eine durchschnittliche Webseite sendet circa 20 Anfragen an den Server, um für die Darstellung notwendige Informationen zu erhalten. Wann sind die Daten schlagartiger zurück?</p>
<ul>
<li><strong>A.</strong> Wenn sich der zuständige Server &#8220;um die Ecke&#8221; befindet</li>
<li><strong>B.</strong> Wenn die Anfrage um den halben Globus geht</li>
</ul>
<p>Für größere Websites mit internationalem Publikum empfiehlt sich zweifellos ein Hosting-Provider mit angelegtem CDN (z.B. <a href="http://aws.amazon.com/cloudfront/">Amazon CloudFront</a>). Dank der Ortung anhand von IP-Adressen treffen statische Files wie Bilder, CSS oder JavaScript im Browser der Kunden zügiger ein. Was bringt diese Erkenntnis wiederum für den Website- bzw. Shop-Betreiber (Produktbilder sind die besten Kandidaten)?</p>
<ol>
<li>Konsumenten bedanken sich für flüchtiges Laden der Inhalte (und kaufen nachweislich mehr, denn <a href="http://www.konversionskraft.de/cro-serien/konversionskiller-performance.html">jede Sekunde zählt</a>).</li>
<li>Google als Suchmaschine lässt die technische Performance einzelner Pages ins Ranking einfliessen (wer braucht da noch <a href="http://de.wikipedia.org/wiki/Suchmaschinenmarketing">Suchmaschinenmarketing</a>).</li>
</ol>
<p>Handeln ist angesagt!</p>
<p><strong>Google mit eigenem Content Delivery Network</strong><br />
Wie bei der Einleitung oben bereits erwähnt, gehört auch <em>Google App Engine</em> zum kleinen, jedoch sehr feinen Kreis der Anbieter, die ihre Infrastruktur um das Content Delivery Network bereichert haben und gestellte Requests dementsprechend auch IP-bezogen verarbeiten. </p>
<p>Bedauerlicherweise kann Google mit keiner Anbindung an die lokal verfügbaren Server innerhalb Europa dienen (Amazon CloudFront dagegen in den USA, Europa und Asien &#8220;vertreten&#8221;), so dass beispielsweise Anfragen aus Deutschland von den in Amerika ansässigen Webservern entgegengenommen und abgearbeitet werden (<a href="http://whois.domaintools.com/74.125.39.141">einer der Server</a>). Kleiner Wermutstropfen: Die Reaktionszeiten der ausländischen Google-Rechner sind beeindruckend geringfügig, kaum ein deutscher Hoster kann mit solch winzigen Millisekunden konkurrieren. Glück im Unglück, quasi.</p>
<p>Im Übrigen lässt Google eigene Applikationen ebenfalls auf den selben Maschinen hosten bzw. laufen wie die App Engine Anwendungen der Dritthersteller &#8211; <a href="http://playground.ebiene.de/2362/google-optimiert-javascript/">Google Closure Compiler</a> sei als Beispiel genannt. Das kann als Garant für ununterbrochene Stabilität und langfristige Zuverlässigkeit des CDN-Hosters aus Mountain View verstanden werden.</p>
<p><strong>Zusätzlicher Nutzen des Hostings bei Google App Engine</strong><br />
Alleine wegen einem bereitgestellten CDN wäre Google&#8217;s App Engine für deutschsprachige Websites nicht interessant genug gewesen, wenn da im Zusammenhang nicht noch weitere, für Webworker recht spannende Instrumente dabei wären, welche &#8220;die Cloud&#8221; attraktiv gestalten (lassen). Fassen wir weitere Vorteile von Google App Engine ausführlich zusammen:</p>
<p><strong>1. Kostenlose Nutzung des Dienstes</strong><br />
Jede bei Google App Engine angelegte Anwendung (in unserem Fall sind es Projekte mit statischen Inhalten) verfügt über ausreichend CPU, Bandbreite und Speicher. Fünf Millionen Aufrufe pro Monat kosten keinen Cent. Darüber hinaus wird nach CPU-Stunden oder Gigabyte-weise abgerechnet, wobei sich die jeweiligen Einheiten in Cent-Bereichen befinden (dazu die <a href="http://code.google.com/intl/de-DE/appengine/docs/billing.html">Preistabelle</a>). Keine monatlichen Bindungsverträge et cetera.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2009/12/google_app_engine_dashboard.png" alt="Nutzungsstatistik auch für kostenfrei verfügbares Kontingent" title="Nutzungsstatistik auch für kostenfrei verfügbares Kontingent" width="474" height="200" class="alignnone size-full wp-image-2352" /><br />
<em>Nutzungsstatistik auch für kostenfrei verfügbares Kontingent</em></p>
<p><strong>2. Gesonderte, Cookie-freie (Sub)Domain</strong><br />
Je nach Wunsch kann das Projekt bei App Engine mit eigener Domain verknüpft werden, Anfragen an statische Daten werden z.B. auf <em>static.domain.de</em> umgeleitet. Verzichtet man auf die Verknüpfung der eigenen Domain mit angelegtem App Engine Project, so ist die öffentlich erreichbare Subdomain <em>xxx.appspot.com</em> (<em>xxx</em> steht dabei für den Projektnamen) das neue Zuhause der im Webseiten-Quelltext referenzierten Dateien.</p>
<p>Irrelevant wofür sich der Entwickler letztendlich entscheidet (eigene Domain oder doch ohne), in beiden Fällen werden beim Datenabruf &#8211; etwa die Darstellung der Bilder oder Einbindung von CSS &#8211; seitens Google keine Cookies mitgeschickt, gesetzt oder ausgelesen. Frei von jeglichen Cookies für noch weniger Bytes beim Austausch zwischen dem Server und den Clients. </p>
<p>Pluspunkt: Je nach Alter können diverse Browser lediglich eine begrenzte Anzahl an gleichzeitigen Anfragen pro Domain stellen. Kommt eine abweichende Domain bzw. Subdomain als eine weitere Datenquelle ins Spiel, kommt es zwangsläufig plötzlicher bei der Fertigstellung des Ladevorgangs voran.</p>
<p>Beide Punkte (abweichende Domain + keine Cookies) werden von <a href="http://code.google.com/intl/de-DE/speed/page-speed/">Page Speed</a> und <a href="http://developer.yahoo.com/yslow/">Yahoo! YSlow</a> als relevant eingestuft und sollen daher Beachtung finden.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2009/12/yahoo_yslow_cookie_free.png" alt="Analyse-Tools bewerten die Webseiten nach mehreren Kriterien" title="Analyse-Tools bewerten die Webseiten nach mehreren Kriterien" width="474" height="200" class="alignnone size-full wp-image-2353" /><br />
<em>Analyse-Tools bewerten die Webseiten nach mehreren Kriterien</em></p>
<p><strong>3. GZIP-Komprimierung und Caching von Dateien</strong><br />
Komprimierfähige Dateien wie beispielsweise Stylesheets und JavaScript werden von Google in gestraffter Form verschickt und auf der Client-Seite (in diesem Fall ist es der Browser) entpackt. So wird Traffic gespart und die Geschwindigkeit der Datenübertragung zusätzlich gesteigert. Google App Engine erkennt solche Dateien selbsttätig und behandelt sie mit der GZIP-Komprimierung, ohne dass der Administrator des Accounts dafür aktiv werden muss (z.B. Modifizierungen am Server oder an der <em>.htaccess</em>).</p>
<p>Nach wenigen manuellen Korrekturen versieht der App Engine Server den ausgehenden Datenstrom mit korrekten Headern, die nachhaltig und effizient dafür sorgen, dass die im Browser-Cache abgelegten Elemente bis auf Wiederruf dort aufbewahrt und für die Anzeige verwendet werden sollen. Unverzügliche Darstellung im Browserfenster und ökonomische Anfragestellung zum entfernten Server ergeben sich im Endeffekt.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2009/12/cache_header_gzip_app_engine.png" alt="GZIP-Komprimiert und in den Browser-Cache befördert" title="GZIP-Komprimiert und in den Browser-Cache befördert" width="474" height="200" class="alignnone size-full wp-image-2354" /><br />
<em>GZIP-komprimiert und in den Browser-Cache befördert</em></p>
<p><strong>4. Traffic-Einsparung und Server-Schonung</strong><br />
Durch die Auslagerung der statischen Files auf den Google-Server kommt der eigene Server (hoffentlich) zur Ruhe und kann sich um andere Rechenaufgaben wie z.B. die Generierung von dynamischen Inhalten kümmern. Die Praxis bestätigt immer wieder aufs Neue: Nach der Ausgliederung pendelt die Serverlast spürbar zurück.</p>
<p><strong>Live-Beispiel der Implementierung</strong><br />
Um das Hosting der Daten auf bzw. in Google App Engine und die entsprechende Integration der Quelle im XHTML-Gerüst zu demonstrieren, wurden statische Elemente (Stylesheets und Grafiken) meiner Portfolio-Website <a href="http://eBiene.de">eBiene.de</a> auf Google als eigenständiges Projekt ausgelagert. Es ging nicht um die Notwendigkeit, vielmehr um die Machbarkeit der Realisierung.</p>
<p>Wir verlassen an dieser Stellen den theoretischen Part des Artikels. Der praktische Teil spezifiziert, wie Objekte nach Google App Engine übertragen und in die Projektseiten eingebunden werden. Spot ab!</p>
<p><strong>1. Projekt anlegen</strong><br />
Auf der <a href="https://appengine.google.com/">Google App Engine Website</a> gelangt man nach der Registrierung bzw. Anmeldung (Keine Abfrage von Konto- oder Kreditkartendaten, dafür eine kostenfreie Verifizierung per SMS notwendig) auf die Übersichtsseite der gegenwärtigen Projekte. Sind keine Projekte bis dato existent, hat man eine direkte Möglichkeit den Namen für das neue Projekt zu vergeben. Der Projektname mutiert zugleich zur Subdomain von <em>appspot.com</em> (ebienede.appspot.com ist in unserem Beispiel die entsprechende Subdomain). Die systemweite Eindeutigkeit des <em>Application Identifiers</em> hat den bitteren Nachgeschmack, das die Vielzahl der möglichen Namen von anderen Teilnehmern bereits genutzt und somit längt vergeben ist. Kreativität ist also gefragt.</p>
<p>Ist die Applikation erfolgreich angelegt, bekommt Developer die Gelegenheit auf das Projekt-Dashboard zu springen: In der Zusammenfassung werden Statistiken für jegliche Art an Verbrauch chronologisch abgebildet. CPU-Gesamtzeit, verstrichene Bandbreite und so weiter.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2009/12/application-identifier-wird-zur-subdomain-des-proj.png" alt="Application Identifier als Subdomain" title="Application Identifier als Subdomain" width="474" height="200" class="alignnone size-full wp-image-2357" /><br />
<em>Application Identifier wird zur Subdomain des Projektes</em></p>
<p><strong>2. Upload-Client in Betrieb nehmen</strong><br />
Die Nutzung des Dienstes wird durch die fehlende Möglichkeit erschwert, Daten auf die bekannte Weise via lokales FTP-Programm zum Google-Server zu übertragen. Für diesen Zweck existiert u.a. ein Entwickler-Werkzeug in Form einer smarten Anwendung, die einen vorher definierten Ordner samt Inhalt (Verzeichnisse, Files) auf den entfernten Rechner dupliziert: Ein Klick auf <em>Deploy</em> gleicht den Bestand der Datenstruktur ab.</p>
<p>Auf der offiziellen <a href="http://code.google.com/intl/de-DE/appengine/downloads.html">Download-Seite</a> wird Google App Engine SDK für das gewünschte Betriebsystem heruntergeladen und installiert. Im geöffneten Tool-Fenster kann über das Menü eine <em>New Applikation</em> angelegt werden: <em>Application Name</em> ist der eben im Web gewählte <em>Application Identifier</em>, <em>Application Directory</em> ist der Ort auf der heimischen Festplatte, der als Referenz für die Spiegelung der Dateien gelten soll. Port ist 8080, andere Optionen bleiben unberührt.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2009/12/google-app-engine-launcher.png" alt="Google App Engine Launcher" title="Google App Engine Launcher" width="474" height="200" class="alignnone size-full wp-image-2358" /><br />
<em>Lediglich 2 Felder pro Projekt gehören ausgefüllt</em></p>
<p><strong>3. Statische Inhalte in Google App Engine definieren</strong><br />
Die Applikation wird nach dem Klick auf den Button <em>Create</em> als entsprechender Listeneintrag im Client und auf der Festplatte im gleichnamigen Ordner angelegt. Navigiert man dahin, werden dort 3 Standard-Systemdateien vorgefunden:</p>
<ul>
<li>app.yaml</li>
<li>index.yaml</li>
<li>main.py</li>
</ul>
<p>Im Verzeichnis werden nun Unterordner für statische Inhalte erstellt. Exemplarisch: <em>css</em> und <em>img</em>, wo jeweils Stylesheets und Bilder separiert aufbewahrt werden. Neu hinzugefügte Ordner gehören in der Konfigurationsdatei <em>app.yaml</em> als Ordner mit nicht dynamischem Content deklariert. Die Datei <em>app.yaml</em> passen wir nun händisch im Texteditor an &#8211;  nach der Änderung sieht sie wie folgt aus (wobei <em>xxx</em> für den Projektnamen steht):</p>
<pre>
application: xxx
version: 1
runtime: python
api_version: 1

default_expiration: "365d"

handlers:
- url: /css
  static_dir: css

- url: /img
  static_dir: img
</pre>
<p>Der Parameter <em>default_expiration</em> kommuniziert die Tagesanzahl für das Caching, die der Server wiederum an den Browser sendet. Der Wert ist variabel.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2009/12/ordnerstruktur-einer-app-engine-applikation.png" alt="Ordnerstruktur einer App Engine Application" title="Ordnerstruktur einer App Engine Application" width="474" height="200" class="alignnone size-full wp-image-2359" /><br />
<em>Exemplarische Ordnerstruktur einer App Engine Application</em></p>
<p><strong>4. Hochladen und im XHTML einbinden</strong><br />
Befinden sich nun Dateien in den erstellten Ordnern, so können diese via Schaltfläche <em>Deploy</em> auf den Server gespiegelt werden. Im zusätzlich eingeblendeten Fenster zeigt die Anwendung den Ablauf der laufenden Aktion und weist auf eventuelle Fehler hin.</p>
<p>Geglückter Upload sichert die Erreichbarkeit der übertragenen Dateien unter der bekannten Subdomain. Ein Test in der Adresszeile des Browsers genügt als Bestätigung. Fällt die Prüfung positiv aus, kann die Statik im Quelltext der Webseiten referenziert werden. Als Musterbeispiel sei die CSS-Datei meines Portfolios genannt: <a href="http://ebienede.appspot.com/css/global.css">http://ebienede.appspot.com/css/global.css</a>.</p>
<p>Das waren die vier Schritte, die für den Umzug vom traditionellen Hoster auf Google App Engine notwendig waren. Leider erkennt Yslow die Google App Engine Plattform nicht als vollwertigen CDN-Hoster. Das liegt an der Tatsache, dass Google im Analyse-Tool nicht als solcher hinterlegt ist. <a href="http://developer.yahoo.com/yslow/faq.html#faq_cdn">Yahoo! verrät</a>, wie die interne Liste um weitere CDN-Provider erweitert werden kann.</p>
<p><strong>Fazit</strong><br />
Google App Engine ist eine perfekte Alternative zum gewöhlichen Webhoster, wenn es darum geht, statische Medien sinnvoll und gewinnbringend auszulagern. Ob eine Website für diesen Zweck groß genug, die Zielgruppe ausreichend international und die angesprochene Upload-Lösung bequem ist, entscheiden ganz alleine die Projektmacher. Als kostenloser Einstieg ins Cloud Computing ist Google App Engine jedoch wärmstens zu empfehlen.</p>
<img src="http://feeds.feedburner.com/~r/feedburner/Playground/~4/Myw5TQ_vhRw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://playground.ebiene.de/2351/google-app-engine-als-cdn/feed/</wfw:commentRss>
		<slash:comments>43</slash:comments>
		<feedburner:origLink>http://playground.ebiene.de/2351/google-app-engine-als-cdn/</feedburner:origLink></item>
		<item>
		<title>WordPress-Tipp: Query nach benutzerdefinierten Feldern sortieren</title>
		<link>http://feedproxy.google.com/~r/feedburner/Playground/~3/kV7Np5cvND0/</link>
		<comments>http://playground.ebiene.de/2349/wordpress-orderby-customfield/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 19:31:57 +0000</pubDate>
		<dc:creator>Sergej Müller</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://playground.ebiene.de/?p=2349</guid>
		<description><![CDATA[Die Praxis des WordPress-Entwicklers zeigt, dass die gelisteten Beiträge nicht selten nach einem ausdrücklichen, für die gestartete Abfrage relevanten Custom Field (auf Deutsch: Benutzerdefiniertes Feld) geordnet werden sollen. Würde man dafür einen eigenständigen SQL-Statement schreiben wollen, würde dieser recht komplex ausfallen, da für diese Operation mindestens zwei Datenbank-Tabellen (wp_posts und wp_postmeta) mittels JOIN verknüpft werden [...]]]></description>
			<content:encoded><![CDATA[<p>Die Praxis des WordPress-Entwicklers zeigt, dass die gelisteten Beiträge nicht selten nach einem ausdrücklichen, für die gestartete Abfrage relevanten <a href="http://codex.wordpress.org/Custom_Fields">Custom Field</a> (auf Deutsch: Benutzerdefiniertes Feld) geordnet werden sollen. Würde man dafür einen eigenständigen SQL-Statement schreiben wollen, würde dieser recht komplex ausfallen, da für diese Operation mindestens zwei Datenbank-Tabellen (<em>wp_posts</em> und <em>wp_postmeta</em>) mittels JOIN verknüpft werden müssten.<br />
<span id="more-2349"></span><br />
<strong>Ausgabe nach eigenem Feldnamen sortieren</strong><br />
Es geht jedoch deutlich einfacher, wenn die von WordPress zur Verfügung gestellten Template Tags verwendet werden &#8211; in unserem Fall greifen wir auf die WordPress-Funktion <a href="http://codex.wordpress.org/Template_Tags/query_posts">query_posts</a> zurück.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2009/12/custom-field-in-wordpress.png" alt="Custom Field in WordPress" title="Custom Field in WordPress" width="474" height="200" class="alignnone size-full wp-image-2350" /><br />
<em>Manuell angelegtes Feld beim Verfassen eines Beitrages</em></p>
<p>Nachfolgend ist ein Einzeiler als Beispiel-Aufruf abgebildet, der das gewünschte Custom Field <em>my_day</em> in die Query einbezieht, aber auch danach sortieren lässt. Eine knappe, verständliche Code-Zeile mit effektivem Ergebnis.</p>
<pre>
&lt;?php
query_posts('meta_key=my_day&#038;meta_compare=<=&#038;meta_value=20&#038;orderby=meta_value');
?&gt;
</pre>
<img src="http://feeds.feedburner.com/~r/feedburner/Playground/~4/kV7Np5cvND0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://playground.ebiene.de/2349/wordpress-orderby-customfield/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://playground.ebiene.de/2349/wordpress-orderby-customfield/</feedburner:origLink></item>
		<item>
		<title>Performance in WordPress: Selten genutzte Plugins deaktivieren</title>
		<link>http://feedproxy.google.com/~r/feedburner/Playground/~3/LQ2GsnrO6RQ/</link>
		<comments>http://playground.ebiene.de/2347/wordpress-plugins-deaktivieren/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 20:22:50 +0000</pubDate>
		<dc:creator>Sergej Müller</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://playground.ebiene.de/?p=2347</guid>
		<description><![CDATA[Verfügbare WordPress-Plugins sind dafür da, um die Vielfalt der Funktionen &#8211; kombiniert mit hohem Nutzen &#8211; zu erweitern. Die Wenigen der Erweiterungen dienen rein administrativen, dem Besucher der Website verborgenen Zwecken. Sprich, installierte Drittanwendungen werden vom Administrator in unregelmäßigen Zeitabständen händisch ausgeführt, um beispielsweise an die gewünschte Information innerhalb des Admin-Bereichs zu gelangen. Abgeschaltet gehören [...]]]></description>
			<content:encoded><![CDATA[<p>Verfügbare <a href="http://wpcoder.de">WordPress-Plugins</a> sind dafür da, um die Vielfalt der Funktionen &#8211; kombiniert mit hohem Nutzen &#8211; zu erweitern. Die Wenigen der Erweiterungen dienen rein administrativen, dem Besucher der Website verborgenen Zwecken. Sprich, installierte Drittanwendungen werden vom Administrator in unregelmäßigen Zeitabständen händisch ausgeführt, um beispielsweise an die gewünschte Information innerhalb des Admin-Bereichs zu gelangen. Abgeschaltet gehören solche.<br />
<span id="more-2347"></span><br />
<strong>Inaktiv für mehr Nutzen</strong><br />
Erweiterungen, die nicht direkt ins Frontend des Blogs eingebunden werden und keine täglichen Aufgaben im Hintergrund wie z.B. <a href="http://wpantivirus.de">AntiVirus für WordPress</a> zu erledigen haben, sollen während der Nichtnutzung im Backend bis auf Weiteres deaktiviert werden.</p>
<p><img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2009/12/inaktives-plugin-in-wordpress.png" alt="Inaktives Plugin in WordPress" title="Inaktives Plugin in WordPress" width="474" height="200" class="alignnone size-full wp-image-2348" /><br />
<em>Fällt aus der Reihe: Selten genutztes Plugin</em></p>
<p>Das sind die Vorteile, die sich dadurch ergeben:</p>
<ul>
<li><strong>Sinkende Ausführungszeit:</strong><br />
Jedes aktive Plugin wird beim Laden der Webseite (Frontend &#038; Backend) vom System eingescannt und in den Speicher der Applikation eingelesen. Durch die Stilllegung der einzelnen Module minimiert sich die Verarbeitungszeit der Gesamtanwendung, der interne Speicher wird für andere Aufgaben freigehalten.</li>
<li><strong>Erhöhte Sicherheit</strong><br />
Im Betrieb befindliches Plugin bedeutet einen ausführbaren Code, der seinerseits angreifbar sein könnte. Bei abgeschalteten Addons schläft es sich garantiert ruhiger.</li>
</ul>
<p><strong>Beispiel gefällig?</strong><br />
<a href="http://playground.ebiene.de/2340/wordpress-cronjobs-bereinigen/">WP-Crontrol</a> stellt System-weite Cronjobs als Liste dar: Wird erst bei Bedarf aktiviert und anschließend manuell gestartet.</p>
<p><strong>Fazit</strong><br />
Ein winziges, selbstgebautes Plugin mag zwar als Ausnahme durchgehen, die restlichen Kandidaten in der Plugin-Verwaltung sollen kritisch überprüft und je nach Notwendigkeit mit dem Status &#8220;Inaktiv&#8221; versehen werden.</p>
<img src="http://feeds.feedburner.com/~r/feedburner/Playground/~4/LQ2GsnrO6RQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://playground.ebiene.de/2347/wordpress-plugins-deaktivieren/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://playground.ebiene.de/2347/wordpress-plugins-deaktivieren/</feedburner:origLink></item>
		<item>
		<title>Freebie des Monats: PNG-Buttons für deutsche Social-Dienste</title>
		<link>http://feedproxy.google.com/~r/feedburner/Playground/~3/8aPvyjdXalM/</link>
		<comments>http://playground.ebiene.de/2344/german-social-icons/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 15:53:20 +0000</pubDate>
		<dc:creator>Sergej Müller</dc:creator>
				<category><![CDATA[Icons]]></category>

		<guid isPermaLink="false">http://playground.ebiene.de/?p=2344</guid>
		<description><![CDATA[Social Media Icons sind aus dem modernen Web nicht mehr wegzudenken &#8211; große Verlage sind da keine Ausnahme. Entsprechend vielfältig und tief ist das Angebot an frei verfügbaren Schaltflächen, die unter Artikeln Platz finden und mit Twitter, Delicious &#038; Co. verknüpft werden. Für in Deutschland verbreitete Dienste haben solch grafische Buttons bis dato gefehlt &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Social Media Icons sind aus dem modernen Web nicht mehr wegzudenken &#8211; große Verlage sind da keine Ausnahme. Entsprechend vielfältig und tief ist das Angebot an frei verfügbaren Schaltflächen, die unter Artikeln Platz finden und mit Twitter, Delicious &#038; Co. verknüpft werden. Für in Deutschland verbreitete Dienste haben solch grafische Buttons bis dato gefehlt &#8211; diese Lücke schließt das zum kostenfreien Download freigegebene Icon Set mit vier Platzhirschen des Social-Webs.<br />
<span id="more-2344"></span><br />
<img src="http://playground.ebiene.de/wordpress/wp-content/uploads/2009/11/germany-social-icons.png" style="height:284px" alt="German Social Icons: Wikio, YiGG, t3n, Mister Wong" title="German Social Icons: Wikio, YiGG, t3n, Mister Wong"  class="alignnone size-full" /><br />
<em>Social Icons: Wikio, YiGG, t3n, Mister Wong</em></p>
<p><strong>Licence</strong><br />
Available social icons may be used in any projects, whether commercial or private nature. Please refer the ZIP archive with buttons not directly, but I would appreciate a link to this post. Thank you.</p>
<p><strong>Lizenz</strong><br />
Angebotene Social Icons dürfen in jeglichen Projekten zum Einsatz kommen, ganz gleich ob kommerzieller oder privater Natur. Verweist bitte das ZIP-Archiv mit Buttons nicht direkt, vielmehr würde ich mich über einen Link zu diesem Beitrag sehr freuen. Herzlichen Dank.</p>
<p><strong>Download</strong><br />
<a href="http://files.me.com/sergej.mueller/n7luba">&rsaquo; Free Icons deutscher Social-Dienste &darr;</a></p>
<ul>
<li>4 handgezeichnete, transparente PNG Icons <strong>32&#215;32 Pixel</strong></li>
<li>4 handgezeichnete, transparente PNG Icons <strong>64&#215;64 Pixel</strong></li>
</ul>
<img src="http://feeds.feedburner.com/~r/feedburner/Playground/~4/8aPvyjdXalM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://playground.ebiene.de/2344/german-social-icons/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://playground.ebiene.de/2344/german-social-icons/</feedburner:origLink></item>
	</channel>
</rss>
