<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>toscho.design&#187; PHP</title>
	<atom:link href="http://toscho.de/thema/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://toscho.de</link>
	<description>Redaktion und schwer geprüftes Webdesign aus Halle (Saale)</description>
	<lastBuildDate>Sat, 07 Jan 2012 14:55:02 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>daily</sy:updatePeriod>
	<sy:updateFrequency>4</sy:updateFrequency>
	
		<item>
		<title>WordPress: Headergrafik per Plugin ausblenden</title>
		<link>http://toscho.de/2011/wordpress-headergrafik-per-plugin-ausblenden/</link>
		<comments>http://toscho.de/2011/wordpress-headergrafik-per-plugin-ausblenden/#comments</comments>
		<pubDate>Sat, 30 Jul 2011 05:02:18 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1805</guid>
		<description><![CDATA[Ein Header-Image aus einem bestehendem Theme entfernen: Hier zeige ich den Weg über ein Plugin als Alternative zum Child-Theme.]]></description>
			<content:encoded><![CDATA[<p>Seit Version 2.9 kann man in <a href="http://toscho.de/angebote/wordpress/themes/">WordPress-Themes</a> die internen Funktionen für eine eigene Kopfgrafik nutzen mit der Funktion <code><a href="http://codex.wordpress.org/Function_Reference/add_custom_image_header">add_custom_image_header()</a></code>. Jetzt bekommt der Nutzer des Themes im Backend unter <em>Design/Kopfzeile</em> eine nette kleine Bildverwaltung. Leider fehlt dort die Option, das Bild komplett wegzulassen.</p>
<p>Gute Themes bieten dafür eine Option an, TwentyTen und auch TwentyEleven leider nicht. Die nachträgliche Entfernung ist umständlich, wenn man kein Child-Theme erstellen möchte.</p>
<p>Deshalb habe ich ein kleines Plugin geschrieben, das sowohl das Bild im Frontend entfernt als auch den Menu-Eintrag im Backend.</p>
<p class="downloadlink"><a href="https://gist.github.com/1115203">Plugin Remove Header Image</a></p>
<p>Wie üblich – es gibt ein mindestens zwei Haken: Wenn im Theme nicht geprüft wird, ob überhaupt ein Bild vorhanden ist, ehe der Container dafür ausgegeben wird, bekommt man eine leere Fläche. Das ist dann eben ein Schrott-Theme. Davon gibt es leider zu viele.<br />
Und die Seite im Backend ist immer noch erreichbar, wenn man die URL dahin kennt. Bilder kann man aber nicht mehr hochladen.</p>
<p>Als Beispiel für den Einsatz in der Praxis sei das <a href="http://drehlog.de/">Videoblog Drehlog</a> genannt. Dort blogge ich mit ein paar Freunden ab und zu … tja … Videos.</p>
<p><a href="http://drehlog.de/"><img src="http://toscho.de/wp-content/uploads/2011/07/drehlog-300x300.png" alt="Screenshot Drehlog" width="300" height="300" class="aligncenter size-medium wp-image-1806" /></a></p>
<p>Irgendwie werde ich das Gefühl nicht los, einen leichteren Weg übersehen zu haben … sei’s drum.</p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2011/wordpress-headergrafik-per-plugin-ausblenden/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>WordPress: Internet Explorer ohne CSS-Hacks ansprechen</title>
		<link>http://toscho.de/2010/wordpress-internet-explorer-ohne-css-hacks-ansprechen/</link>
		<comments>http://toscho.de/2010/wordpress-internet-explorer-ohne-css-hacks-ansprechen/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 07:43:50 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Browser]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Markup]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Trickkiste]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1731</guid>
		<description><![CDATA[Wie man jede Version des Internet Explorers einfach mit einem Klassennamen ansprechen kann. Extra Code für WordPress-Themes inklusive.]]></description>
			<content:encoded><![CDATA[<p><img src="http://toscho.de/wp-content/uploads/2010/09/ie-150.png" alt="" title="ie-150" width="150" height="150" class="alignright size-full wp-image-1732" />Den Internet Explorer betrachten die meisten Webentwickler zu Recht als chronische Krankheit. Neben anderen Browsern sieht auch die kommende Version 9 <a href="http://www.findmebyip.com/litmus">eher bedrückend</a> aus. Ehe wir diesem Browser keine Extrawurst mehr braten müssen, wird noch viel Zeit vergehen.</p>
<p>Um den IE im Stylesheet gesondert anzusprechen, brauchen wir weder Hacks im CSS noch eine zusätzliche Datei oder gar (pfui!) eine serverseitige Browserweiche. Wir müssen nur das Element <code>&lt;html&gt;</code> über <a href="http://msdn.microsoft.com/en-us/library/ms537512(VS.85).aspx" lang="en" hreflang="en">Conditional Comments</a> anpassen. Diese Idee <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/" hreflang="en">hatte Paul Irish schon 2008</a>.</p>
<p>Ich habe das neulich in einem WordPress-Theme eingesetzt und mag es so sehr, daß ich künftig all meine Themes damit ausrüsten werde.<br />
Ein wenig umständlich: Die Sprachattribute werden in WordPress mit der Funktion <a href="http://codex.wordpress.org/Function_Reference/language_attributes"><code>language_attributes()</code></a> erzeugt – und die hat ein fest eingebautes <code>echo</code>, das man nicht abschalten kann. Ich will nun nicht drei Meter Code in der <code>header.php</code> stehen haben, deshalb habe ich mir zwei kleine Funktionen gebaut. Die Funktion <code>get_language_attributes()</code> ist obendrein etwas schlanker als das Original, und sie gibt das Attribut <code>dir</code> nur aus, wenn der Text von rechts nach links läuft. Andernfalls ist es an dieser Stelle überflüssig.</p>
<p>Doch zum Code, er gehört in die <code>functions.php</code>:</p>
<div class="php-code">
<pre class="notranslate php"><span class='openclose'>&lt;?php
</span><i class='comment'>/**
 * html5 start tag + language attribute + conditional tags for IE Win
 * @link   <a href="http://paulirish.com/?p=88">http://paulirish.com/?p=88</a>
 * @param  bool $print
 * @return void|string
 */</i>
<span class='internal'>function</span> htmlstart(<var>$print</var> <span class='operator'>=</span> <span class='internal'>TRUE</span>)
{
    <var>$out</var>  <span class='operator'>=</span> <span class='string'>&#039;&lt;!Doctype html&gt;&#039;</span>;
    <var>$lang</var> <span class='operator'>=</span> get_language_attributes();
    <var>$ies</var>  <span class='operator'>=</span> <span class='internal'>array</span> (
        6 <span class='operator'>=&gt;</span> <span class='string'>&#039;lte6 lte7 lte8&#039;</span>
    ,   7 <span class='operator'>=&gt;</span> <span class='string'>&#039;lte7 lte8&#039;</span>
    ,   8 <span class='operator'>=&gt;</span> <span class='string'>&#039;lte8&#039;</span>
    ,   9 <span class='operator'>=&gt;</span> <span class='string'>&#039;&#039;</span>
    );

    <span class='internal'>foreach</span> ( <var>$ies</var> <span class='internal'>as</span> <var>$n</var> <span class='operator'>=&gt;</span> <var>$class</var> )
    {
        <var>$out</var> <span class='operator'>.=</span> &quot;<span class='string'>&lt;!--[if IE </span><var>$n</var><span class='string'>]&gt;&lt;html </span><var>$lang</var><span class='string'> class=&#039;ie ie</span><var>$n</var><span class='string'> </span><var>$class</var><span class='string'> lte9&#039;&gt;&lt;![endif]--&gt;</span>&quot;;
    }

    <var>$out</var> <span class='operator'>.=</span> &quot;<span class='string'>&lt;!--[if !IE]&gt;&lt;!--&gt;&lt;html </span><var>$lang</var><span class='string'>&gt;&lt;!--&lt;![endif]--&gt;</span>&quot;;

    <span class='internal'>if</span> ( <span class='operator'>!</span> <var>$print</var> )
    {
        <span class='internal'>return</span> <var>$out</var>;
    }

    <span class='internal'>print</span> <var>$out</var>;
}

<span class='internal'>if</span> ( <span class='operator'>!</span> <a href='http://php.net/function_exists'>function_exists</a>(<span class='string'>&#039;get_language_attributes&#039;</span>) )
{
    <i class='comment'>/**
     * Returns the language attributes.
     *
     * Unobstrusive copy from the core.
     * Requires WP 3.0+
     *
     * @param string $doctype The type of html document (xhtml|html).
     */</i>
    <span class='internal'>function</span> get_language_attributes(<var>$doctype</var> <span class='operator'>=</span> <span class='string'>&#039;html&#039;</span>) {
        <var>$output</var> <span class='operator'>=</span> is_rtl() <span class='operator'>?</span> <span class='string'>&#039;dir=&quot;rtl&quot;&#039;</span> <span class='operator'>:</span> <span class='string'>&#039;&#039;</span>;

        <span class='internal'>if</span> ( <var>$lang</var> <span class='operator'>=</span> get_bloginfo(<span class='string'>&#039;language&#039;</span>) )
        {
            <var>$output</var> <span class='operator'>.=</span> ( ( get_option(<span class='string'>&#039;html_type&#039;</span>) <span class='operator'>!=</span> <span class='string'>&#039;text/html&#039;</span>
                <span class='operator'>||</span> <var>$doctype</var> <span class='operator'>==</span> <span class='string'>&#039;xhtml&#039;</span> )
                <span class='operator'>?</span> <span class='string'>&#039; xml:&#039;</span> <span class='operator'>:</span> <span class='string'>&#039;&#039;</span>) <span class='operator'>.</span> <span class='string'>&#039;lang=&quot;&#039;</span> <span class='operator'>.</span> <var>$lang</var> <span class='operator'>.</span> <span class='string'>&#039;&quot;&#039;</span>;
        }

        <span class='internal'>return</span> apply_filters(<span class='string'>&#039;language_attributes&#039;</span>, <var>$output</var>);
    }
}</pre>
</div>
<p>Im Theme rufen wir die Funktion dort auf, wo früher die Doctype-Deklaration und das Start-Tag standen.<br />
Die Ausgabe sieht (hier aufgehübscht) etwa so aus:</p>
<pre class="notranslate html">&lt;!Doctype html&gt;
&lt;!--[if IE 6]&gt;
    &lt;html lang=<code class="string">"de-DE"</code> class=<code class="string">'ie ie6 lte6 lte7 lte8 lte9'</code>&gt;
&lt;![endif]--&gt;
&lt;!--[if IE 7]&gt;
    &lt;html lang=<code class="string">"de-DE"</code> class=<code class="string">'ie ie7 lte7 lte8 lte9'</code>&gt;
&lt;![endif]--&gt;
&lt;!--[if IE 8]&gt;
    &lt;html lang=<code class="string">"de-DE"</code> class=<code class="string">'ie ie8 lte8 lte9'</code>&gt;
&lt;![endif]--&gt;
&lt;!--[if IE 9]&gt;
    &lt;html lang=<code class="string">"de-DE"</code> class=<code class="string">'ie ie9 lte9'</code>&gt;
&lt;![endif]--&gt;
&lt;!--[if !IE]&gt;&lt;!--&gt;
    &lt;html lang=<code class="string">"de-DE"</code>&gt;
&lt;!--&lt;![endif]--&gt;</pre>
<p>Nein, das ist kein sehr schönes Markup mehr. Aber so richtig schlimmes auch nicht. Obendrein validiert es.</p>
<p>Im Stylesheet können wir den Internet Explorer jetzt ganz einfach mit der passenden Klasse ansprechen:</p>
<pre class="notranslate">.ie8
{
    top:        10px;
}
.lte7
{
    top:        15px;
}</pre>
<p>Das kann ich mir viel besser merken als Kommentarhacks oder Spielereien mit ungültigen Selektoren und Eigenschaften.</p>
<p>Mehrere Internet Explorer auf einem Windows kann man sich mit der <a href="http://utilu.com/IECollection/" lang='en' hreflang='en'>Utilo IE Collection</a> einrichten. Zum Testen der Conditional Comments habe ich im Labor eine kleine Seite eingerichtet: <a href="http://labs.toscho.de/test/conditional-comments/">CC-Test</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/wordpress-internet-explorer-ohne-css-hacks-ansprechen/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>WordPress: Sprache der Ausgabe einstellen</title>
		<link>http://toscho.de/2010/wordpress-sprache-der-ausgabe-einstellen/</link>
		<comments>http://toscho.de/2010/wordpress-sprache-der-ausgabe-einstellen/#comments</comments>
		<pubDate>Mon, 02 Aug 2010 17:00:52 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Markup]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Sprache]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1707</guid>
		<description><![CDATA[Wie man die <i lang="en">Language-Tags</i> in WordPress an die tatsächlich verwendete Sprache anpaßt. Hintergründe, Links und Beispielcode inklusive.]]></description>
			<content:encoded><![CDATA[<!--TOC-->
<h2>Meine Sprache</h2>
<p>Ich bin kein viel versprechendes Talent. Aber ein vielversprechendes … nun, lassen wir das. Will sagen: Mich hat die <a href="http://www.schriftdeutsch.de/ortr-rat.htm">Reform der deutschen Rechtschreibung im Jahre 1996</a> nicht überzeugt. Die Reformen der Reform ebensowenig. Deshalb halte ich mich heute überwiegend an die <em>klassische</em> Orthographie, die seit dem letzten amtlichen Eingriff 1901 ganz allmählich durch den allgemeinen Sprachgebrauch entwickelt wurde.<br />
Und gerade weil ich den Gedanken einer <em>organischen</em> Entwicklung so mag, halte ich mich nicht immer genau an die Regeln von 1995: Ich übertrete sie, wenn mein Sprachgefühl mir dazu rät.</p>
<p>Im Großen aber muß ich meine Sprache für Maschinen als <a hreflang="en" href="http://www.iana.org/assignments/lang-tags/de-DE-1901"><code>de-DE-1901</code></a> kennzeichnen — der <a hreflang="en" lang="en" title="Request for comments 3066" href="ftp://ftp.rfc-editor.org/in-notes/rfc3066.txt">RFC 3066</a> verlangt es so.</p>
<p class="wideimg"><img src="http://toscho.de/wp-content/uploads/2010/08/language-tags-500.png" alt="" width="500" height="282" class="alignnone size-full wp-image-1708" /></p>
<h2>Sprachausgabe in WordPress</h2>
<p>In WordPress wird die Sprache des Blogs in der Datei <code>wp-config.php</code> angegeben:</p>
<pre class="notranslate">define (<code class="string">'WPLANG'</code>, <code class="string">'de_DE'</code>);</pre>
<p>Dann holt sich das CMS automagisch die <a href="http://wordpress-deutschland.org/download/sprachdatei/">passende Sprachdatei</a> namens <samp>de_DE.mo</samp>. Deshalb bringt es mir nichts, die präzise Sprache in der <code>wp-config.php</code> zu setzen: Eine Datei <samp>de_DE_1901.mo</samp> existiert ja leider nicht, und ich möchte auch nicht nach jeder Aktualisierung den Dateinamen hinterherrennen müssen.</p>
<p>Macht nichts.</p>
<p>In der Ausgabe für den Leser, im <i lang="en">Frontend</i> also, wird die Sprache nur an zwei Stellen angegeben: Im <code>lang</code>-Attribut des Elementes <code>html</code>:</p>
<pre class="notranslate">&lt;html lang=<code class="string">"de-DE-1901"</code>&gt;</pre>
<p>Und im Feed, beispielsweise in der Datei <code>/wp-includes/feed-atom.php</code>:</p>
<pre class="notranslate">xml:lang="&lt;?php echo get_option(<code class="string">'rss_language'</code>); ?&gt;"</pre>
<p>Im Theme kann man diese Angabe entweder konkret in den Code schreiben oder die Funktion <a hreflang="en" href="http://codex.wordpress.org/Function_Reference/language_attributes"><code>language_attributes()</code></a> verwenden:</p>
<pre class="notranslate">&lt;html &lt;?php language_attributes(); ?&gt;&gt;</pre>
<p>Diese Funktion gibt die Schreibrichtung und die Sprache aus. Da <code>ltr</code> der <a href="http://www.w3.org/TR/html401/struct/dirlang.html#h-8.2.2" hreflang="en">Standardwert für das Attribut <code>dir</code></a> ist, kann das hier weggefiltert werden.</p>
<p>Die beiden Filter, die wir ansprechen müssen, lauten <code class="string">'language_attributes'</code> und <code class="string">'pre_option_rss_language'</code>.</p>
<h2>Code zum Anpassen</h2>
<p>Ich habe mir dafür eine kleine Klasse geschrieben, die ich in der functions.php des Themes einfach per <a href="http://php.net/require"><code>require</code></a> aufrufe:</p>
<p class="downloadlink"><a href="http://gist.github.com/raw/504854/4aeaa5c3bce59206401f1a6b5a92c69d906a2afa/class.Toscho_Language_Filter.php">Download class.Toscho_Language_Filter.php</a></p>
<div class="php-code">
<pre class="notranslate php"><span class='openclose'>&lt;?php
</span><i class='comment'>/**
 * Adjust the public visible language declarations.
 *
 * @author &quot;Thomas Scholz&quot; <a href="http://toscho.de">http://toscho.de</a>
 * @version 1.0
 */</i>
<span class='internal'>class</span> Toscho_Language_Filter
{
    <i class='comment'>/**
     * @var string
     */</i>
    <span class='internal'>public</span> <span class='internal'>static</span> <var>$lang</var> <span class='operator'>=</span> <span class='string'>&#039;de&#039;</span>;

    <i class='comment'>/**
     * Pseudo constructor.
     *
     * @param  string $lang The language according to …
     * @link   <a href="http://www.evertype.com/standards/iso639/iana-lang-assignments.html">http://www.evertype.com/standards/iso639/iana-lang-assignments.html</a>
     * @return void
     */</i>
    <span class='internal'>public</span> <span class='internal'>static</span> <span class='internal'>function</span> setup(<var>$lang</var> <span class='operator'>=</span> <span class='string'>&#039;de-DE-1901&#039;</span>)
    {
        self<span class='operator'>::</span><var>$lang</var> <span class='operator'>=</span> <var>$lang</var>;

        add_filter(
            <span class='string'>&#039;language_attributes&#039;</span>
        ,   <span class='internal'>array</span> ( <span class='constant'>__CLASS__</span>, <span class='string'>&#039;html&#039;</span> )
        );
        add_filter(
            <span class='string'>&#039;pre_option_rss_language&#039;</span>
        ,   <span class='internal'>array</span> ( <span class='constant'>__CLASS__</span>, <span class='string'>&#039;get_lang&#039;</span> )
        );
    }

    <i class='comment'>/**
     * Returns the language string.
     * @return string
     */</i>
    <span class='internal'>public</span> <span class='internal'>static</span> <span class='internal'>function</span> get_lang()
    {
        <span class='internal'>return</span> self<span class='operator'>::</span><var>$lang</var>;
    }

    <i class='comment'>/**
     * Output for language_attributes().
     * We drop the &#039;dir&#039; attribute.
     *
     * @return string
     */</i>
    <span class='internal'>public</span> <span class='internal'>static</span> <span class='internal'>function</span> html()
    {
        <span class='internal'>return</span> <span class='string'>&#039;lang=&quot;&#039;</span> <span class='operator'>.</span> self<span class='operator'>::</span><var>$lang</var> <span class='operator'>.</span> <span class='string'>&#039;&quot;&#039;</span>;
    }

}
<i class='comment'>// Adjust this to your needs.
</i>Toscho_Language_Filter<span class='operator'>::</span>setup(<span class='string'>&#039;de-DE-1901&#039;</span>);</pre>
</div>
<p>Wer mag, kann die Funktion <code>setup()</code> auch mit einer eigenen Kreation aufrufen. Dann muß man ein <code>-x-</code> davorsetzen, wie Ian Hickson das in den <a hreflang="en" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/">Spezifikationen zu HTML5</a> macht: <code>lang=<code class="string">"en-US-x-hixie"</code></code>.<br />
Über den Nutzen möchte ich lieber nicht diskutieren.</p>
<h2>Mehr davon</h2>
<ul>
<li><a href="http://toscho.de/2010/wordpress-dashboard-approved-nicht-genehmigt/">WordPress-Dashboard: ›Approved‹ nicht ›Genehmigt‹</a></li>
<li><a href="http://toscho.de/2010/wordpress-auszug-zeichenzahl/">WordPress: Auszug mit bestimmter Zeichenzahl</a></li>
<li><a href="http://toscho.de/2009/php-funktion-genitiv/">PHP-Funktion Genitiv</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/wordpress-sprache-der-ausgabe-einstellen/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>WordPress als CMS: Hilfreiche Plugins</title>
		<link>http://toscho.de/2010/wordpress-cms-plugins/</link>
		<comments>http://toscho.de/2010/wordpress-cms-plugins/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 08:44:42 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[e-mail]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1697</guid>
		<description><![CDATA[Eine Auswahl nützlicher kleiner Plugins. Screenshots, Hinweise zur Deinstallation und Urteile zum Code inbegriffen.]]></description>
			<content:encoded><![CDATA[<!--TOC-->
<p>Es gibt noch mehr als Fußball, ja! Nämlich … WordPress … ähm.<br />
<a href="http://blogwiese.de/blog/5283/plugin-parade-2010">Cindy bittet</a>, man möge seine Plugins vorstellen. Da mach ich mal mit.<br />
Bei dieser Auswahl habe ich mich an zwei Punkten orientiert: Die Plugins sollten noch nicht allzu bekannt sein und den Einsatz <a href='/2010/wordpress-cms/'>WordPress’ als CMS</a> unterstützen. Wer also mit mehreren Autoren arbeitet oder einfach deutlich mehr als ein Blog braucht, findet hier hoffentlich etwas Neues.</p>
<h2>Cleverness To-Do List</h2>
<p><a rel="author" href='http://cleverness.org'>Cindy M. Kendrick</a> · <a href='http://cleverness.org/plugins/to-do-list/'>Pluginseite</a> · <a href="http://wordpress.org/extend/plugins/cleverness-to-do-list/">Download</a></p>
<p>Dieses Plugin zeigt offene Aufgaben in einem Dashboard-Widget und auf einer eigenen Seite unter »Werkzeuge«:</p>
<p><img src="http://toscho.de/wp-content/uploads/2010/06/todolist-dashboard-widget.png" alt="Todolist-Dashboard-Widget" width="423" height="182" class="size-full wp-image-1698" /></p>
<p>Man kann jede Aufgabe einer bestimmten Person zuweisen, die dann per E-Mail informiert wird. Obendrein läßt sich jeder Punkt mit einer Priorität versehen, damit oben steht, was brennt. Die Optionen sind eingedeutscht und mit hilfreichen Links versehen. Vielleicht ein bißchen voll.</p>
<p>Der Code … stinkt. Er verpestet den globalen Namensraum mit Variablen wie <var>$action</var>, <var>$priority</var> oder <var>$id</var>. Meine Güte.<br />
Teste das Plugin erst lokal mit allen anderen Plugins, die du verwendest.</p>
<p>Das Plugin räumt sauber auf: Es entsorgt die Optionen und die Aufgabentabelle <code><var>$wpdb-&gt;prefix</var> . 'todolist'</code> bei der Deinstallation.</p>
<p>Projektmanagement en miniature. Hat fast alles, was ich mir in diesem Rahmen wünsche; nur Markup würde ich gerne noch in der Beschreibung zulassen.</p>
<h2>Simply Show IDs</h2>
<p><a rel="author" href="http://sivel.net/">Matt Martz</a> · <a href="http://sivel.net/wordpress/simply-show-ids/">Pluginseite</a> · <a href="http://wordpress.org/extend/plugins/simply-show-ids/">Download</a></p>
<p><img src="http://toscho.de/wp-content/uploads/2010/06/simply-show-ids.png" alt="Simply show IDs" width="148" height="360" class="alignright size-full wp-image-1699 border" /></p>
<p>Jeder Beitrag, jeder Nutzer und jede Kategorie hat in der Datenbank eine eindeutige Nummer, <a href="http://toscho.de/2010/wordpress-id-anhand-titel-herausfinden/">die ID</a>. Diese Nummer braucht man beispielsweise für <code>wp_list_pages()</code> oder den <a href="http://toscho.de/2010/wordpress-shortlinks-reloaded/">Shortlink</a>. Das Plugin fügt den Listen im Backend eine (abschaltbare) Spalte hinzu, in der die Nummer steht. </p>
<p>Prozeduraler Code, aber nur ein paar Funktionen mit dem Präfix <code>ssid_</code>.</p>
<p>Das dürfte WordPress ruhig gleich von Haus aus mitbringen. Ich würde die Spalte gerne einfacher für normale Autoren abschalten können.</p>
<h2>WP Mail from</h2>
<p>Tristan Aston · <a href="http://wordpress.org/extend/plugins/wp-mailfrom/">Download</a></p>
<p>Wenn WordPress eine Mail verschickt, dann vom frei erfundenen Konto wordpress@<var>$hostname</var> aus. Manche Server verweigern jedoch den Versand von nicht existierenden Konten, und auch sonst möchte man vielleicht lieber eine korrekte Adresse verwenden.</p>
<p>Das Plugin bietet die Option, Namen und Adresse zu ändern. Beide Werte werden in separaten Optionen – <code>site_mail_from_email</code> und <code>site_mail_from_name</code> – gespeichert und bei der Deinstallation <em>nicht aufgeräumt</em>.</p>
<p class="wideimg"><img src="http://toscho.de/wp-content/uploads/2010/06/mailfrom-options.png" alt="" title="Mailfrom-Optionen" width="468" height="206" class="size-full wp-image-1700 border" /></p>
<p>Der Code ist prozedural, die Funktionsnamen finde ich nicht ausreichend gegen Kollisionen gesichert: <code>site_mail_from()</code> schreit nach Ärger. </p>
<p>So nützlich und so schlampig … das werde ich mal neu fassen und in mein Standard-Mega-Plugin einbauen.</p>
<h2>Bulk Password Reset</h2>
<p><a rel="author" href="http://rubenwoudsma.nl/">Ruben Woudsma</a> · <a href="http://rubenwoudsma.nl/bulk-password-reset/">Pluginseite</a> · <a href="http://wordpress.org/extend/plugins/bulk-password-reset/">Download</a></p>
<p>Hiermit kann man die Passwörter aller Nutzer einer Gruppe zurücksetzen. Sehr hilfreich, wenn man ein <a href="http://toscho.de/2009/website-gehackt/">gehacktes Blog repariert</a> oder vielen Nutzern auf einen Ruck den Zugang erlauben möchte.</p>
<p><a href="http://toscho.de/wp-content/uploads/2010/06/bulk-password-reset-optionen.png"><img src="http://toscho.de/wp-content/uploads/2010/06/bulk-password-reset-optionen-300x179.png" alt="Bulk-Password-Reset-Optionen" width="300" height="179" class="alignnone size-medium wp-image-1701 border" /></a></p>
<p>Die Optionsseite sieht sehr unbeholfen aus; hier kann man die zu versendende E-Mail anpassen oder ganz verbieten. Ich empfehle dringend, vorher das Plugin <em>WP Mail from</em> zu installieren, damit Antworten der betroffenen Nutzer an eine reale Adresse gehen.<br />
Die Option – immerhin nur ein Array – heißt <code>bpr_options</code>. Die muß man leider manuell löschen, denn das Plugin <em>räumt beim Deinstallieren nicht auf</em>.</p>
<p>Objektorientierter Code, wirft aber Notizen. <abbr title="Objekt-orientierte Programmierung">OOP</abbr> allein ist eben auch kein Wundermittel.</p>
<p>In manchen Situationen einfach unersetzbar. Die Optionsseite sollte jedem angehenden Pluginautor als warnendes Beispiel dienen: So bitte nicht!</p>
<h2>Custom Post Templates</h2>
<p><a rel="author" href="http://www.simonwheatley.co.uk/">Simon Wheatley</a> · <a href="http://www.simonwheatley.co.uk/wordpress/custom-post-template/">Pluginseite</a> · <a href="http://wordpress.org/extend/plugins/custom-post-template/">Download</a></p>
<p>Für Seiten oder spezielle Archive kennt WordPress schon lange <a href="/2010/wordpress-alle-artikel-auflisten/">eigene Templates</a>; für Posts jedoch braucht man dieses Plugin.<br />
Ein Template wird durch folgenden Eintrag am Dateianfang gekennzeichnet:</p>
<pre class="notranslate">/*
Template Name Posts: Jungtiere
*/</pre>
<p><img src="http://toscho.de/wp-content/uploads/2010/06/post-template.png" alt="Custom Post Template" width="287" height="185" class="alignright size-full wp-image-1702" /></p>
<p>Dann bekommt man beim Schreiben eines Artikels ein Auswahlfeld wie bei den Seiten.</p>
<p>Zusätzlich stellt das Plugin noch eine Funktion <code style="white-space:normal">is_post_template(<var>$template</var> = '')</code> bereit.</p>
<p>Der Code ist sehr sauber, bis auf die is-Funktion objektorientiert. Optionen müssen bei der Deinstallation nicht aufgeräumt werden, denn das Plugin speichert keine. Das zugeordnete Template wird in einem Meta-Key namens <code>custom_post_template</code> gespeichert, und der bleibt erhalten.</p>
<p><strong>Ich will das im Core haben.</strong> Es ist nicht einzusehen, warum ein Blogsystem hier Seiten bevorzugt. Der Code könnte einen Tick besser dokumentiert werden … ansonsten ist er die reine Freude.</p>
<h2>Vice Versa </h2>
<p><a rel="author" href="http://jasonlau.biz/">Jason Lau</a> · <a href="http://jasonlau.biz/home/wordpress/convert-pages-to-posts-vice-versa">Pluginseite</a> · <a href="http://wordpress.org/extend/plugins/vice-versa/">Download</a></p>
<p><a href="http://toscho.de/wp-content/uploads/2010/06/vice-versa-optionen.png"><img src="http://toscho.de/wp-content/uploads/2010/06/vice-versa-optionen-208x300.png" alt="Vice-Versa-Optionen" width="208" height="300" class="alignright size-medium wp-image-1703" /></a></p>
<p>Mit diesem Plugin kann man eine Seite in einen Artikel wandeln und umgekehrt – daher der Name. Irre praktisch, wenn man Inhalte aus einer statischen Seite in WordPress integriert und der Kunde sich mehrmals umentscheidet. Man kann auch Elternseiten und -kategorien auswählen. Warum der Autor seine Seite unter den »Einstellungen« aufgehängt hat und nicht unter »Werkzeuge«, bleibt sein Geheimnis. Nun, jedes Kunstwerk birgt ein Rätsel …</p>
<p>Der Code freilich treibt einem die Tränen in die Augen: <code>eregi()</code>, massenhaft Inline-Styles, die der Optionsseite gar nicht gut tun, <code>echo</code>-Orgien … das geht besser. Immerhin werden keine dauerhaften Optionen gesetzt; eine Deinstallation verläuft also schmerzlos.</p>
<p>Die Funktion könnte man auch per Datenbankabfrage direkt übernehmen, aber ich bin im Nachhinein doch dankbar, daß ich das nicht tun mußte. Ich wünsche mir hierfür noch die Umwandlung mehrere Einträge auf einen Ruck.</p>
<hr />
<p>Insgesamt habe ich mit allen hier vorgestellten Plugins gute Erfahrungen gemacht. Besonders <em>Simply Show IDs</em> und <em>Custom Post Templates</em> füllen offensichtliche Lücken. Hätte ich ein echtes Mitspracherecht, so würde ich sie sofort in den Core einbauen – und dafür <a href="http://core.trac.wordpress.org/ticket/13583">anderen Schrott</a> entsorgen.</p>
<p>Leider merkt man auch, daß im <a href="http://wordpress.org/extend/plugins/">Pluginverzeichnis</a> niemand darauf achtet, ob ein <a href="http://toscho.de/2010/wordpress-tutorial-ein-framebreaker-plugin-schreiben/">Plugin sauber geschrieben</a> wurde. Hier ist vielleicht auch die API zu locker. Ein <a href="http://toscho.de/2010/wordpress-tutorial-eigenes-widget-schreiben/">Widget</a> muß einer festen OO-Struktur folgen; ein Plugin jedoch kann jeder schreiben wie er will. Und genau das passiert auch.</p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/wordpress-cms-plugins/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>WordPress-Tutorial: Eigenes Widget schreiben</title>
		<link>http://toscho.de/2010/wordpress-tutorial-eigenes-widget-schreiben/</link>
		<comments>http://toscho.de/2010/wordpress-tutorial-eigenes-widget-schreiben/#comments</comments>
		<pubDate>Fri, 04 Jun 2010 13:45:14 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1693</guid>
		<description><![CDATA[Kleines Lehrstück am konkreten Beispiel eines Widgets, das eine Einschränkung der letzten Posts auf bestimmte Kategorien erlaubt.]]></description>
			<content:encoded><![CDATA[<p><img src="http://toscho.de/wp-content/uploads/2010/06/wp-widget-150.png" alt="" width="150" height="150" class="alignleft size-full wp-image-1694" /></p>
<p>Widgets liegen in der WordPress-Architektur irgendwo zwischen Theme und Plugin: Die eigene Funktionalität und das Aussehen sind meistens eng an vorhandenen Code gebunden, doch können sie auch ganz eigenständig erzeugt werden.<br />
Sie lassen sich in Sidebars einbetten; man kann sie aber auch »manuell« im Theme aufrufen mit der Funktion <code><a href="http://codex.wordpress.org/Template_Tags/the_widget">the_widget()</a></code>.</p>
<p>Die <a href="http://codex.wordpress.org/Widgets_API">Widgets-API</a> ist die einzige, die objektorientiertes Arbeiten <em>erzwingt</em> – deshalb eignet sie sich gut zum Lernen und gefahrlosen Ausprobieren, finde ich.<br />
Themes und Plugins hingegen dürfen komplett prozedural geschrieben werden. Werden sie leider oft auch.</p>
<p>Ein Widget muß die <code><a href="http://core.trac.wordpress.org/browser/trunk/wp-includes/widgets.php">Klasse WP_Widget</a></code> erweitern. Ein Konstruktor wird für den Aufruf gebraucht und eine Funktion <code>widget()</code> für die Ausgabe. Um den Speicherfresser <code>create_function()</code> zu umgehen, packe ich noch eine Funktion <code>register()</code> dazu. Das sieht im einfachsten Falle so aus:</p>
<table class="php-code">
<tr>
<td>
<pre class='line-numbers'><a id='mw1' href='#mw1'>1</a>
<a id='mw2' href='#mw2'>2</a>
<a id='mw3' href='#mw3'>3</a>
<a id='mw4' href='#mw4'>4</a>
<a id='mw5' href='#mw5'>5</a>
<a id='mw6' href='#mw6'>6</a>
<a id='mw7' href='#mw7'>7</a>
<a id='mw8' href='#mw8'>8</a>
<a id='mw9' href='#mw9'>9</a>
<a id='mw10' href='#mw10'>10</a>
<a id='mw11' href='#mw11'>11</a>
<a id='mw12' href='#mw12'>12</a>
<a id='mw13' href='#mw13'>13</a>
<a id='mw14' href='#mw14'>14</a>
<a id='mw15' href='#mw15'>15</a>
<a id='mw16' href='#mw16'>16</a>
<a id='mw17' href='#mw17'>17</a>
<a id='mw18' href='#mw18'>18</a>
<a id='mw19' href='#mw19'>19</a>
<a id='mw20' href='#mw20'>20</a>
<a id='mw21' href='#mw21'>21</a>
<a id='mw22' href='#mw22'>22</a>
</pre>
</td>
<td>
<pre class="notranslate php"><span class='openclose'>&lt;?php
</span>add_action(
    <span class='string'>&#039;widgets_init&#039;</span>
,   <span class='internal'>array</span> (<span class='string'>&#039;Toscho_Mini_Widget&#039;</span>, <span class='string'>&#039;register&#039;</span> )
);
<span class='internal'>class</span> Toscho_Mini_Widget <span class='internal'>extends</span> WP_Widget
{
    <span class='internal'>function</span> Toscho_Mini_Widget()
    {
        <var>$this</var><span class='operator'>-&gt;</span>WP_Widget(<span class='constant'>__CLASS__</span>, <span class='constant'>__CLASS__</span>);
    }

    <span class='internal'>function</span> widget(<var>$args</var>, <var>$instance</var>)
    {
        <span class='internal'>print</span> <span class='string'>&#039;Juhu, hat geklappt!&#039;</span>;
    }

    <span class='internal'>function</span> register()
    {
        register_widget(<span class='constant'>__CLASS__</span>);
    }
}</pre>
</td>
</tr>
</table>
<p>Hier müffelt es noch schlimm nach PHP 4. Wenn der Konstruktor nicht wie die Klasse heißt, läuft der Speicher aus … das müssen wir vorerst wohl hinnehmen.</p>
<p>Das Beispiel oben kann im Backend aktiviert werden, wenn es im Theme eingebunden wird <em>und</em> wenn das Theme mindestens eine <a href="http://codex.wordpress.org/Function_Reference/register_sidebar">Sidebar registriert</a> hat.</p>
<p>Es tut natürlich noch nicht viel.</p>
<p><a href="http://toscho.de/wp-content/uploads/2010/06/widget-restricted-recent-posts.png"><img src="http://toscho.de/wp-content/uploads/2010/06/widget-restricted-recent-posts-225x300.png" alt="Screenshot Eingabemaske" title="Eingabemaske in voller Größe ansehen" width="225" height="300" class="alignright size-medium wp-image-1695 border" /></a></p>
<p>Im nächsten Schritt sehen wir uns mal ein Beispiel an, das wir tatsächlich einsetzen könnten: Wir wollen die letzten Posts auflisten, dabei aber bestimmte Kategorien ausschließen oder zulassen.</p>
<p>Da können wir uns bei der Klasse <code>WP_Widget_Recent_Posts</code> einigen Code abgucken. Die liegt WordPress schon bei in der <a href="http://core.trac.wordpress.org/browser/trunk/wp-includes/default-widgets.php">default-widgets.php</a>.</p>
<p>Wir brauchen zusätzlich noch eine Eingabemaske für die Kategorien, und wir müssen den <a href="http://codex.wordpress.org/Function_Reference/WP_Query">Query</a> erweitern. Die nötigen Argumente finden wir in der Dokumentation zu <code><a href="http://codex.wordpress.org/Template_Tags/query_posts">query_posts()</a></code>.</p>
<p>Die beiden letzten Funktionen stammen nicht aus der Elternklasse, sondern ich habe sie eingebaut, um den Rest des Codes lesbar zu halten.</p>
<p>Live läuft genau dieses Widget gerade auf der Website der <a href="http://ig-bkh.de/">Interessengemeinschaft Britisch Kurzhaar-Katzen</a> links in der Sidebar; hier werden die <a href="http://ig-bkh.de/thema/jungtiere/">Jungtiermeldungen</a> ausgeklammert, weil sie schon sehr prominent auf der Startseite präsentiert werden.</p>
<table class="php-code">
<tr>
<td>
<pre class='line-numbers'><a id='ex11' href='#ex11'>1</a>
<a id='ex12' href='#ex12'>2</a>
<a id='ex13' href='#ex13'>3</a>
<a id='ex14' href='#ex14'>4</a>
<a id='ex15' href='#ex15'>5</a>
<a id='ex16' href='#ex16'>6</a>
<a id='ex17' href='#ex17'>7</a>
<a id='ex18' href='#ex18'>8</a>
<a id='ex19' href='#ex19'>9</a>
<a id='ex110' href='#ex110'>10</a>
<a id='ex111' href='#ex111'>11</a>
<a id='ex112' href='#ex112'>12</a>
<a id='ex113' href='#ex113'>13</a>
<a id='ex114' href='#ex114'>14</a>
<a id='ex115' href='#ex115'>15</a>
<a id='ex116' href='#ex116'>16</a>
<a id='ex117' href='#ex117'>17</a>
<a id='ex118' href='#ex118'>18</a>
<a id='ex119' href='#ex119'>19</a>
<a id='ex120' href='#ex120'>20</a>
<a id='ex121' href='#ex121'>21</a>
<a id='ex122' href='#ex122'>22</a>
<a id='ex123' href='#ex123'>23</a>
<a id='ex124' href='#ex124'>24</a>
<a id='ex125' href='#ex125'>25</a>
<a id='ex126' href='#ex126'>26</a>
<a id='ex127' href='#ex127'>27</a>
<a id='ex128' href='#ex128'>28</a>
<a id='ex129' href='#ex129'>29</a>
<a id='ex130' href='#ex130'>30</a>
<a id='ex131' href='#ex131'>31</a>
<a id='ex132' href='#ex132'>32</a>
<a id='ex133' href='#ex133'>33</a>
<a id='ex134' href='#ex134'>34</a>
<a id='ex135' href='#ex135'>35</a>
<a id='ex136' href='#ex136'>36</a>
<a id='ex137' href='#ex137'>37</a>
<a id='ex138' href='#ex138'>38</a>
<a id='ex139' href='#ex139'>39</a>
<a id='ex140' href='#ex140'>40</a>
<a id='ex141' href='#ex141'>41</a>
<a id='ex142' href='#ex142'>42</a>
<a id='ex143' href='#ex143'>43</a>
<a id='ex144' href='#ex144'>44</a>
<a id='ex145' href='#ex145'>45</a>
<a id='ex146' href='#ex146'>46</a>
<a id='ex147' href='#ex147'>47</a>
<a id='ex148' href='#ex148'>48</a>
<a id='ex149' href='#ex149'>49</a>
<a id='ex150' href='#ex150'>50</a>
<a id='ex151' href='#ex151'>51</a>
<a id='ex152' href='#ex152'>52</a>
<a id='ex153' href='#ex153'>53</a>
<a id='ex154' href='#ex154'>54</a>
<a id='ex155' href='#ex155'>55</a>
<a id='ex156' href='#ex156'>56</a>
<a id='ex157' href='#ex157'>57</a>
<a id='ex158' href='#ex158'>58</a>
<a id='ex159' href='#ex159'>59</a>
<a id='ex160' href='#ex160'>60</a>
<a id='ex161' href='#ex161'>61</a>
<a id='ex162' href='#ex162'>62</a>
<a id='ex163' href='#ex163'>63</a>
<a id='ex164' href='#ex164'>64</a>
<a id='ex165' href='#ex165'>65</a>
<a id='ex166' href='#ex166'>66</a>
<a id='ex167' href='#ex167'>67</a>
<a id='ex168' href='#ex168'>68</a>
<a id='ex169' href='#ex169'>69</a>
<a id='ex170' href='#ex170'>70</a>
<a id='ex171' href='#ex171'>71</a>
<a id='ex172' href='#ex172'>72</a>
<a id='ex173' href='#ex173'>73</a>
<a id='ex174' href='#ex174'>74</a>
<a id='ex175' href='#ex175'>75</a>
<a id='ex176' href='#ex176'>76</a>
<a id='ex177' href='#ex177'>77</a>
<a id='ex178' href='#ex178'>78</a>
<a id='ex179' href='#ex179'>79</a>
<a id='ex180' href='#ex180'>80</a>
<a id='ex181' href='#ex181'>81</a>
<a id='ex182' href='#ex182'>82</a>
<a id='ex183' href='#ex183'>83</a>
<a id='ex184' href='#ex184'>84</a>
<a id='ex185' href='#ex185'>85</a>
<a id='ex186' href='#ex186'>86</a>
<a id='ex187' href='#ex187'>87</a>
<a id='ex188' href='#ex188'>88</a>
<a id='ex189' href='#ex189'>89</a>
<a id='ex190' href='#ex190'>90</a>
<a id='ex191' href='#ex191'>91</a>
<a id='ex192' href='#ex192'>92</a>
<a id='ex193' href='#ex193'>93</a>
<a id='ex194' href='#ex194'>94</a>
<a id='ex195' href='#ex195'>95</a>
<a id='ex196' href='#ex196'>96</a>
<a id='ex197' href='#ex197'>97</a>
<a id='ex198' href='#ex198'>98</a>
<a id='ex199' href='#ex199'>99</a>
<a id='ex1100' href='#ex1100'>100</a>
<a id='ex1101' href='#ex1101'>101</a>
<a id='ex1102' href='#ex1102'>102</a>
<a id='ex1103' href='#ex1103'>103</a>
<a id='ex1104' href='#ex1104'>104</a>
<a id='ex1105' href='#ex1105'>105</a>
<a id='ex1106' href='#ex1106'>106</a>
<a id='ex1107' href='#ex1107'>107</a>
<a id='ex1108' href='#ex1108'>108</a>
<a id='ex1109' href='#ex1109'>109</a>
<a id='ex1110' href='#ex1110'>110</a>
<a id='ex1111' href='#ex1111'>111</a>
<a id='ex1112' href='#ex1112'>112</a>
<a id='ex1113' href='#ex1113'>113</a>
<a id='ex1114' href='#ex1114'>114</a>
<a id='ex1115' href='#ex1115'>115</a>
<a id='ex1116' href='#ex1116'>116</a>
<a id='ex1117' href='#ex1117'>117</a>
<a id='ex1118' href='#ex1118'>118</a>
<a id='ex1119' href='#ex1119'>119</a>
<a id='ex1120' href='#ex1120'>120</a>
<a id='ex1121' href='#ex1121'>121</a>
<a id='ex1122' href='#ex1122'>122</a>
<a id='ex1123' href='#ex1123'>123</a>
<a id='ex1124' href='#ex1124'>124</a>
<a id='ex1125' href='#ex1125'>125</a>
<a id='ex1126' href='#ex1126'>126</a>
<a id='ex1127' href='#ex1127'>127</a>
<a id='ex1128' href='#ex1128'>128</a>
<a id='ex1129' href='#ex1129'>129</a>
<a id='ex1130' href='#ex1130'>130</a>
<a id='ex1131' href='#ex1131'>131</a>
<a id='ex1132' href='#ex1132'>132</a>
<a id='ex1133' href='#ex1133'>133</a>
<a id='ex1134' href='#ex1134'>134</a>
<a id='ex1135' href='#ex1135'>135</a>
<a id='ex1136' href='#ex1136'>136</a>
<a id='ex1137' href='#ex1137'>137</a>
<a id='ex1138' href='#ex1138'>138</a>
<a id='ex1139' href='#ex1139'>139</a>
<a id='ex1140' href='#ex1140'>140</a>
<a id='ex1141' href='#ex1141'>141</a>
<a id='ex1142' href='#ex1142'>142</a>
<a id='ex1143' href='#ex1143'>143</a>
<a id='ex1144' href='#ex1144'>144</a>
<a id='ex1145' href='#ex1145'>145</a>
<a id='ex1146' href='#ex1146'>146</a>
<a id='ex1147' href='#ex1147'>147</a>
<a id='ex1148' href='#ex1148'>148</a>
<a id='ex1149' href='#ex1149'>149</a>
<a id='ex1150' href='#ex1150'>150</a>
<a id='ex1151' href='#ex1151'>151</a>
<a id='ex1152' href='#ex1152'>152</a>
<a id='ex1153' href='#ex1153'>153</a>
<a id='ex1154' href='#ex1154'>154</a>
<a id='ex1155' href='#ex1155'>155</a>
<a id='ex1156' href='#ex1156'>156</a>
<a id='ex1157' href='#ex1157'>157</a>
<a id='ex1158' href='#ex1158'>158</a>
<a id='ex1159' href='#ex1159'>159</a>
<a id='ex1160' href='#ex1160'>160</a>
<a id='ex1161' href='#ex1161'>161</a>
<a id='ex1162' href='#ex1162'>162</a>
<a id='ex1163' href='#ex1163'>163</a>
<a id='ex1164' href='#ex1164'>164</a>
<a id='ex1165' href='#ex1165'>165</a>
<a id='ex1166' href='#ex1166'>166</a>
<a id='ex1167' href='#ex1167'>167</a>
<a id='ex1168' href='#ex1168'>168</a>
<a id='ex1169' href='#ex1169'>169</a>
<a id='ex1170' href='#ex1170'>170</a>
<a id='ex1171' href='#ex1171'>171</a>
<a id='ex1172' href='#ex1172'>172</a>
<a id='ex1173' href='#ex1173'>173</a>
<a id='ex1174' href='#ex1174'>174</a>
<a id='ex1175' href='#ex1175'>175</a>
<a id='ex1176' href='#ex1176'>176</a>
<a id='ex1177' href='#ex1177'>177</a>
<a id='ex1178' href='#ex1178'>178</a>
<a id='ex1179' href='#ex1179'>179</a>
<a id='ex1180' href='#ex1180'>180</a>
<a id='ex1181' href='#ex1181'>181</a>
<a id='ex1182' href='#ex1182'>182</a>
<a id='ex1183' href='#ex1183'>183</a>
<a id='ex1184' href='#ex1184'>184</a>
<a id='ex1185' href='#ex1185'>185</a>
<a id='ex1186' href='#ex1186'>186</a>
<a id='ex1187' href='#ex1187'>187</a>
<a id='ex1188' href='#ex1188'>188</a>
<a id='ex1189' href='#ex1189'>189</a>
<a id='ex1190' href='#ex1190'>190</a>
<a id='ex1191' href='#ex1191'>191</a>
<a id='ex1192' href='#ex1192'>192</a>
<a id='ex1193' href='#ex1193'>193</a>
<a id='ex1194' href='#ex1194'>194</a>
<a id='ex1195' href='#ex1195'>195</a>
<a id='ex1196' href='#ex1196'>196</a>
<a id='ex1197' href='#ex1197'>197</a>
<a id='ex1198' href='#ex1198'>198</a>
<a id='ex1199' href='#ex1199'>199</a>
<a id='ex1200' href='#ex1200'>200</a>
<a id='ex1201' href='#ex1201'>201</a>
<a id='ex1202' href='#ex1202'>202</a>
<a id='ex1203' href='#ex1203'>203</a>
<a id='ex1204' href='#ex1204'>204</a>
<a id='ex1205' href='#ex1205'>205</a>
<a id='ex1206' href='#ex1206'>206</a>
<a id='ex1207' href='#ex1207'>207</a>
<a id='ex1208' href='#ex1208'>208</a>
<a id='ex1209' href='#ex1209'>209</a>
<a id='ex1210' href='#ex1210'>210</a>
<a id='ex1211' href='#ex1211'>211</a>
<a id='ex1212' href='#ex1212'>212</a>
<a id='ex1213' href='#ex1213'>213</a>
<a id='ex1214' href='#ex1214'>214</a>
<a id='ex1215' href='#ex1215'>215</a>
<a id='ex1216' href='#ex1216'>216</a>
<a id='ex1217' href='#ex1217'>217</a>
<a id='ex1218' href='#ex1218'>218</a>
<a id='ex1219' href='#ex1219'>219</a>
<a id='ex1220' href='#ex1220'>220</a>
<a id='ex1221' href='#ex1221'>221</a>
<a id='ex1222' href='#ex1222'>222</a>
<a id='ex1223' href='#ex1223'>223</a>
<a id='ex1224' href='#ex1224'>224</a>
<a id='ex1225' href='#ex1225'>225</a>
<a id='ex1226' href='#ex1226'>226</a>
<a id='ex1227' href='#ex1227'>227</a>
<a id='ex1228' href='#ex1228'>228</a>
<a id='ex1229' href='#ex1229'>229</a>
<a id='ex1230' href='#ex1230'>230</a>
<a id='ex1231' href='#ex1231'>231</a>
<a id='ex1232' href='#ex1232'>232</a>
<a id='ex1233' href='#ex1233'>233</a>
<a id='ex1234' href='#ex1234'>234</a>
<a id='ex1235' href='#ex1235'>235</a>
<a id='ex1236' href='#ex1236'>236</a>
<a id='ex1237' href='#ex1237'>237</a>
<a id='ex1238' href='#ex1238'>238</a>
<a id='ex1239' href='#ex1239'>239</a>
<a id='ex1240' href='#ex1240'>240</a>
<a id='ex1241' href='#ex1241'>241</a>
<a id='ex1242' href='#ex1242'>242</a>
<a id='ex1243' href='#ex1243'>243</a>
<a id='ex1244' href='#ex1244'>244</a>
<a id='ex1245' href='#ex1245'>245</a>
<a id='ex1246' href='#ex1246'>246</a>
<a id='ex1247' href='#ex1247'>247</a>
<a id='ex1248' href='#ex1248'>248</a>
<a id='ex1249' href='#ex1249'>249</a>
<a id='ex1250' href='#ex1250'>250</a>
<a id='ex1251' href='#ex1251'>251</a>
<a id='ex1252' href='#ex1252'>252</a>
<a id='ex1253' href='#ex1253'>253</a>
<a id='ex1254' href='#ex1254'>254</a>
<a id='ex1255' href='#ex1255'>255</a>
<a id='ex1256' href='#ex1256'>256</a>
<a id='ex1257' href='#ex1257'>257</a>
<a id='ex1258' href='#ex1258'>258</a>
<a id='ex1259' href='#ex1259'>259</a>
<a id='ex1260' href='#ex1260'>260</a>
<a id='ex1261' href='#ex1261'>261</a>
<a id='ex1262' href='#ex1262'>262</a>
<a id='ex1263' href='#ex1263'>263</a>
<a id='ex1264' href='#ex1264'>264</a>
<a id='ex1265' href='#ex1265'>265</a>
<a id='ex1266' href='#ex1266'>266</a>
<a id='ex1267' href='#ex1267'>267</a>
<a id='ex1268' href='#ex1268'>268</a>
<a id='ex1269' href='#ex1269'>269</a>
<a id='ex1270' href='#ex1270'>270</a>
<a id='ex1271' href='#ex1271'>271</a>
<a id='ex1272' href='#ex1272'>272</a>
<a id='ex1273' href='#ex1273'>273</a>
<a id='ex1274' href='#ex1274'>274</a>
<a id='ex1275' href='#ex1275'>275</a>
<a id='ex1276' href='#ex1276'>276</a>
<a id='ex1277' href='#ex1277'>277</a>
<a id='ex1278' href='#ex1278'>278</a>
<a id='ex1279' href='#ex1279'>279</a>
<a id='ex1280' href='#ex1280'>280</a>
<a id='ex1281' href='#ex1281'>281</a>
<a id='ex1282' href='#ex1282'>282</a>
<a id='ex1283' href='#ex1283'>283</a>
<a id='ex1284' href='#ex1284'>284</a>
<a id='ex1285' href='#ex1285'>285</a>
<a id='ex1286' href='#ex1286'>286</a>
<a id='ex1287' href='#ex1287'>287</a>
<a id='ex1288' href='#ex1288'>288</a>
<a id='ex1289' href='#ex1289'>289</a>
<a id='ex1290' href='#ex1290'>290</a>
<a id='ex1291' href='#ex1291'>291</a>
<a id='ex1292' href='#ex1292'>292</a>
<a id='ex1293' href='#ex1293'>293</a>
<a id='ex1294' href='#ex1294'>294</a>
<a id='ex1295' href='#ex1295'>295</a>
<a id='ex1296' href='#ex1296'>296</a>
<a id='ex1297' href='#ex1297'>297</a>
<a id='ex1298' href='#ex1298'>298</a>
<a id='ex1299' href='#ex1299'>299</a>
</pre>
</td>
<td>
<pre class="notranslate php"><span class='openclose'>&lt;?php
</span>add_action(
    <span class='string'>&#039;widgets_init&#039;</span>
,   <span class='internal'>array</span> (<span class='string'>&#039;Restricted_Latest_Posts_Widget&#039;</span>, <span class='string'>&#039;register&#039;</span> )
);
<i class='comment'>/**
 * Restricted Recent Posts widget class.
 *
 * Restricts the list of recent posts to selected categories.
 * Derivate of the default widget.
 *
 * @todo Select post types
 * @todo Select taxonomy
 */</i>
<span class='internal'>class</span> Restricted_Latest_Posts_Widget <span class='internal'>extends</span> WP_Widget
{
    <i class='comment'>// Adjust this to your needs.
</i>    <span class='internal'>var</span>
        <var>$max_posts</var> <span class='operator'>=</span> 50
    ,   <var>$wid_name</var>  <span class='operator'>=</span> <span class='string'>&#039;widget_restricted_recent_posts&#039;</span>;

    <i class='comment'>/**
     * Constructor.
     */</i>
    <span class='internal'>function</span> Restricted_Latest_Posts_Widget()
    {
        <var>$widget_ops</var> <span class='operator'>=</span> <span class='internal'>array</span>(
            <span class='string'>&#039;classname&#039;</span>   <span class='operator'>=&gt;</span> <var>$this</var><span class='operator'>-&gt;</span>wid_name
        ,   <span class='string'>&#039;description&#039;</span> <span class='operator'>=&gt;</span> <span class='string'>&#039;Letzte Beiträge per Kategorie ausgewählt.
                                Mit Komma trennen.&#039;</span>
        );
        <var>$this</var><span class='operator'>-&gt;</span>WP_Widget(
            <span class='string'>&#039;restricted-recent-posts&#039;</span>
        ,   <span class='string'>&#039;Restricted Recent Posts&#039;</span>
        ,   <var>$widget_ops</var>
        );
        <var>$this</var><span class='operator'>-&gt;</span>alt_option_name <span class='operator'>=</span> <var>$this</var><span class='operator'>-&gt;</span>wid_name;

        add_action( <span class='string'>&#039;save_post&#039;</span>,
            <span class='internal'>array</span>(&amp;<var>$this</var>, <span class='string'>&#039;flush_widget_cache&#039;</span>) );
        add_action( <span class='string'>&#039;deleted_post&#039;</span>,
            <span class='internal'>array</span>(&amp;<var>$this</var>, <span class='string'>&#039;flush_widget_cache&#039;</span>) );
        add_action( <span class='string'>&#039;switch_theme&#039;</span>,
            <span class='internal'>array</span>(&amp;<var>$this</var>, <span class='string'>&#039;flush_widget_cache&#039;</span>) );
    }

    <i class='comment'>/**
     * Called statically to register the widget.
     *
     * @return void.
     */</i>
    <span class='internal'>function</span> register()
    {
        register_widget(<span class='constant'>__CLASS__</span>);
    }

    <span class='internal'>function</span> widget(<var>$args</var>, <var>$instance</var>)
    {
        <var>$cache</var> <span class='operator'>=</span> wp_cache_get(<var>$this</var><span class='operator'>-&gt;</span>wid_name, <span class='string'>&#039;widget&#039;</span>);

        <span class='internal'>if</span> ( <span class='operator'>!</span> <a href='http://php.net/is_array'>is_array</a>(<var>$cache</var>) )
        {
            <var>$cache</var> <span class='operator'>=</span> <span class='internal'>array</span>();
        }

        <span class='internal'>if</span> ( <span class='internal'>isset</span> ( <var>$cache</var>[ <var>$args</var>[<span class='string'>&#039;widget_id&#039;</span>] ] ) )
        {
            <span class='internal'>echo</span> <var>$cache</var>[ <var>$args</var>[<span class='string'>&#039;widget_id&#039;</span>] ];
            <span class='internal'>return</span>;
        }

        <a href='http://php.net/ob_start'>ob_start</a>();
        <a href='http://php.net/extract'>extract</a>(<var>$args</var>);

        <var>$title</var>        <span class='operator'>=</span> <span class='internal'>empty</span> ( <var>$instance</var>[<span class='string'>&#039;title&#039;</span>] )
                        <span class='operator'>?</span> <span class='string'>&#039;Restricted Recent Posts&#039;</span>
                        <span class='operator'>:</span> <var>$instance</var>[<span class='string'>&#039;title&#039;</span>];
        <var>$title</var>        <span class='operator'>=</span> apply_filters(<span class='string'>&#039;widget_title&#039;</span>, <var>$title</var>);

        <var>$number</var>       <span class='operator'>=</span> <var>$this</var><span class='operator'>-&gt;</span>sanitize_number(<var>$instance</var>[<span class='string'>&#039;number&#039;</span>]);

        <var>$include_cats</var> <span class='operator'>=</span> <a href='http://php.net/trim'>trim</a>(<var>$instance</var>[<span class='string'>&#039;include_cats&#039;</span>]);
        <var>$exclude_cats</var> <span class='operator'>=</span> <a href='http://php.net/trim'>trim</a>(<var>$instance</var>[<span class='string'>&#039;exclude_cats&#039;</span>]);

        <var>$query_args</var>   <span class='operator'>=</span> <span class='internal'>array</span>(
            <span class='string'>&#039;showposts&#039;</span>        <span class='operator'>=&gt;</span> <var>$number</var>
        ,   <span class='string'>&#039;nopaging&#039;</span>         <span class='operator'>=&gt;</span> 0
        ,   <span class='string'>&#039;post_status&#039;</span>      <span class='operator'>=&gt;</span> <span class='string'>&#039;publish&#039;</span>
        ,   <span class='string'>&#039;caller_get_posts&#039;</span> <span class='operator'>=&gt;</span> 1
        );

        <span class='internal'>if</span> ( <span class='operator'>!</span> <span class='internal'>empty</span> ( <var>$include_cats</var> ) )
        {
            <var>$query_args</var>[<span class='string'>&#039;category__in&#039;</span>]
                <span class='operator'>=</span> <var>$this</var><span class='operator'>-&gt;</span>catlist_to_array(<var>$include_cats</var>);
        }
        <span class='internal'>elseif</span> ( <span class='operator'>!</span> <span class='internal'>empty</span> ( <var>$exclude_cats</var> ) )
        {
            <var>$query_args</var>[<span class='string'>&#039;category__not_in&#039;</span>]
                <span class='operator'>=</span> <var>$this</var><span class='operator'>-&gt;</span>catlist_to_array(<var>$exclude_cats</var>);
        }

        <var>$r</var> <span class='operator'>=</span> <span class='internal'>new</span> WP_Query(<var>$query_args</var>);

        <span class='internal'>if</span> ( <var>$r</var><span class='operator'>-&gt;</span>have_posts() )
        {
            <span class='internal'>print</span> <var>$before_widget</var>
                <span class='operator'>.</span> ( <var>$title</var>
                        <span class='operator'>?</span> <var>$before_title</var> <span class='operator'>.</span> <var>$title</var> <span class='operator'>.</span> <var>$after_title</var> <span class='operator'>:</span> <span class='string'>&#039;&#039;</span>
                    )
                <span class='operator'>.</span> <span class='string'>&#039;&lt;ul&gt;&#039;</span>;

            <span class='internal'>while</span> ( <var>$r</var><span class='operator'>-&gt;</span>have_posts() )
            {
                <var>$r</var><span class='operator'>-&gt;</span>the_post();

                <span class='internal'>print</span> <span class='string'>&#039;&lt;li&gt;&lt;a href=&quot;&#039;</span> <span class='operator'>.</span> get_permalink() <span class='operator'>.</span> <span class='string'>&#039;&quot;&gt;&#039;</span>
                    <span class='operator'>.</span> get_the_title() <span class='operator'>.</span> <span class='string'>&#039;&lt;/a&gt;&lt;/li&gt;&#039;</span>;
            }

            <span class='internal'>print</span> &quot;<span class='string'>&lt;/ul&gt;</span><var>$after_widget</var>&quot;;

            <i class='comment'>// Restore global post data stomped by the_post().
</i>            wp_reset_query();
        }

        <var>$cache</var>[ <var>$args</var>[<span class='string'>&#039;widget_id&#039;</span>] ] <span class='operator'>=</span> <a href='http://php.net/ob_get_flush'>ob_get_flush</a>();

        wp_cache_add(<var>$this</var><span class='operator'>-&gt;</span>wid_name, <var>$cache</var>, <span class='string'>&#039;widget&#039;</span>);
    }

    <span class='internal'>function</span> update( <var>$new_instance</var>, <var>$old_instance</var> )
    {
        <var>$instance</var>                 <span class='operator'>=</span> <var>$old_instance</var>;
        <var>$instance</var>[<span class='string'>&#039;title&#039;</span>]        <span class='operator'>=</span> <a href='http://php.net/strip_tags'>strip_tags</a>(<var>$new_instance</var>[<span class='string'>&#039;title&#039;</span>]);
        <var>$instance</var>[<span class='string'>&#039;number&#039;</span>]       <span class='operator'>=</span>
                <var>$this</var><span class='operator'>-&gt;</span>sanitize_number(<var>$new_instance</var>[<span class='string'>&#039;number&#039;</span>]);
        <var>$instance</var>[<span class='string'>&#039;exclude_cats&#039;</span>] <span class='operator'>=</span> <var>$new_instance</var>[<span class='string'>&#039;exclude_cats&#039;</span>];
        <var>$instance</var>[<span class='string'>&#039;include_cats&#039;</span>] <span class='operator'>=</span> <var>$new_instance</var>[<span class='string'>&#039;include_cats&#039;</span>];

        <var>$this</var><span class='operator'>-&gt;</span>flush_widget_cache();

        <var>$alloptions</var> <span class='operator'>=</span> wp_cache_get( <span class='string'>&#039;alloptions&#039;</span>, <span class='string'>&#039;options&#039;</span> );

        <span class='internal'>if</span> ( <span class='internal'>isset</span> ( <var>$alloptions</var>[<var>$this</var><span class='operator'>-&gt;</span>wid_name] ) )
        {
            delete_option(<var>$this</var><span class='operator'>-&gt;</span>wid_name);
        }

        <span class='internal'>return</span> <var>$instance</var>;
    }

    <span class='internal'>function</span> flush_widget_cache()
    {
        wp_cache_delete(<var>$this</var><span class='operator'>-&gt;</span>wid_name, <span class='string'>&#039;widget&#039;</span>);
    }

    <span class='internal'>function</span> form( <var>$instance</var> )
    {
        <var>$title</var> <span class='operator'>=</span> <span class='internal'>isset</span> ( <var>$instance</var>[<span class='string'>&#039;title&#039;</span>] )
                <span class='operator'>?</span> esc_attr(<var>$instance</var>[<span class='string'>&#039;title&#039;</span>]) <span class='operator'>:</span> <span class='string'>&#039;&#039;</span>;

        <span class='internal'>if</span> (   <span class='operator'>!</span> <span class='internal'>isset</span> ( <var>$instance</var>[<span class='string'>&#039;number&#039;</span>])
            <span class='operator'>||</span> <span class='operator'>!</span> <var>$number</var> <span class='operator'>=</span> (int) <var>$instance</var>[<span class='string'>&#039;number&#039;</span>]
        )
        {
            <var>$number</var> <span class='operator'>=</span> 5;
        }

        <var>$incats</var> <span class='operator'>=</span> <span class='internal'>isset</span> ( <var>$instance</var>[<span class='string'>&#039;include_cats&#039;</span>] )
            <span class='operator'>?</span> esc_attr(<var>$instance</var>[<span class='string'>&#039;include_cats&#039;</span>]) <span class='operator'>:</span> <span class='string'>&#039;&#039;</span>;
        <var>$excats</var> <span class='operator'>=</span> <span class='internal'>isset</span> ( <var>$instance</var>[<span class='string'>&#039;exclude_cats&#039;</span>] )
            <span class='operator'>?</span> esc_attr(<var>$instance</var>[<span class='string'>&#039;exclude_cats&#039;</span>]) <span class='operator'>:</span> <span class='string'>&#039;&#039;</span>;
        <span class='openclose'>?&gt;
</span>        &lt;p&gt;
            &lt;label for=&quot;<span class='openclose'>&lt;?php
</span>                <span class='internal'>echo</span> <var>$this</var><span class='operator'>-&gt;</span>get_field_id(<span class='string'>&#039;title&#039;</span>);
            <span class='openclose'>?&gt;</span>&quot;&gt;
                <span class='openclose'>&lt;?php
</span>                    _e(<span class='string'>&#039;Title:&#039;</span>);
                <span class='openclose'>?&gt;
</span>            &lt;/label&gt;
            &lt;input class=&quot;widefat&quot;
                id=&quot;<span class='openclose'>&lt;?php
</span>                    <span class='internal'>echo</span> <var>$this</var><span class='operator'>-&gt;</span>get_field_id(<span class='string'>&#039;title&#039;</span>);
                <span class='openclose'>?&gt;</span>&quot;
                name=&quot;<span class='openclose'>&lt;?php
</span>                    <span class='internal'>echo</span> <var>$this</var><span class='operator'>-&gt;</span>get_field_name(<span class='string'>&#039;title&#039;</span>);
                <span class='openclose'>?&gt;</span>&quot;
                type=&quot;text&quot;
                value=&quot;<span class='openclose'>&lt;?php
</span>                    <span class='internal'>echo</span> <var>$title</var>;
                <span class='openclose'>?&gt;</span>&quot;
            /&gt;
        &lt;/p&gt;

        &lt;p&gt;
            &lt;label for=&quot;<span class='openclose'>&lt;?php
</span>                <span class='internal'>echo</span> <var>$this</var><span class='operator'>-&gt;</span>get_field_id(<span class='string'>&#039;number&#039;</span>);
            <span class='openclose'>?&gt;</span>&quot;&gt;
                Artikelmenge
            &lt;/label&gt;
            &lt;input id=&quot;<span class='openclose'>&lt;?php
</span>                <span class='internal'>echo</span> <var>$this</var><span class='operator'>-&gt;</span>get_field_id(<span class='string'>&#039;number&#039;</span>);
            <span class='openclose'>?&gt;</span>&quot;
                name=&quot;<span class='openclose'>&lt;?php
</span>                    <span class='internal'>echo</span> <var>$this</var><span class='operator'>-&gt;</span>get_field_name(<span class='string'>&#039;number&#039;</span>);
                <span class='openclose'>?&gt;</span>&quot;
                type=&quot;text&quot;
                value=&quot;<span class='openclose'>&lt;?php
</span>                    <span class='internal'>echo</span> <var>$number</var>;
                <span class='openclose'>?&gt;</span>&quot;
                size=&quot;3&quot; /&gt;
            &lt;small&gt;(maximal <span class='openclose'>&lt;?php
</span>                <span class='internal'>print</span> <var>$this</var><span class='operator'>-&gt;</span>max_posts;
            <span class='openclose'>?&gt;</span>)&lt;/small&gt;
        &lt;/p&gt;

        &lt;p&gt;
            &lt;label for=&quot;<span class='openclose'>&lt;?php
</span>                <span class='internal'>echo</span> <var>$this</var><span class='operator'>-&gt;</span>get_field_id(<span class='string'>&#039;include_cats&#039;</span>);
            <span class='openclose'>?&gt;</span>&quot;&gt;
                Auf Kategorien beschränken:
            &lt;/label&gt;
            &lt;input id=&quot;<span class='openclose'>&lt;?php
</span>                <span class='internal'>echo</span> <var>$this</var><span class='operator'>-&gt;</span>get_field_id(<span class='string'>&#039;include_cats&#039;</span>);
            <span class='openclose'>?&gt;</span>&quot;
                name=&quot;<span class='openclose'>&lt;?php
</span>                    <span class='internal'>echo</span> <var>$this</var><span class='operator'>-&gt;</span>get_field_name(<span class='string'>&#039;include_cats&#039;</span>);
                <span class='openclose'>?&gt;</span>&quot;
                type=&quot;text&quot;
                value=&quot;<span class='openclose'>&lt;?php
</span>                    <span class='internal'>echo</span> <var>$incats</var>;
                <span class='openclose'>?&gt;</span>&quot;
                size=&quot;10&quot;
            /&gt;
            &lt;br /&gt;&lt;strong&gt;oder&lt;/strong&gt;&lt;br /&gt;
            &lt;label for=&quot;<span class='openclose'>&lt;?php
</span>                <span class='internal'>echo</span> <var>$this</var><span class='operator'>-&gt;</span>get_field_id(<span class='string'>&#039;exclude_cats&#039;</span>);
            <span class='openclose'>?&gt;</span>&quot;&gt;
                Kategorien ausschließen:
            &lt;/label&gt;
            &lt;input id=&quot;<span class='openclose'>&lt;?php
</span>                <span class='internal'>echo</span> <var>$this</var><span class='operator'>-&gt;</span>get_field_id(<span class='string'>&#039;exclude_cats&#039;</span>);
            <span class='openclose'>?&gt;</span>&quot;
                name=&quot;<span class='openclose'>&lt;?php
</span>                    <span class='internal'>echo</span> <var>$this</var><span class='operator'>-&gt;</span>get_field_name(<span class='string'>&#039;exclude_cats&#039;</span>);
                <span class='openclose'>?&gt;</span>&quot;
                type=&quot;text&quot;
                value=&quot;<span class='openclose'>&lt;?php
</span>                    <span class='internal'>echo</span> <var>$excats</var>;
                <span class='openclose'>?&gt;</span>&quot;
                size=&quot;10&quot;
            /&gt;
        &lt;/p&gt;
        <span class='openclose'>&lt;?php
</span>    }

    <i class='comment'>/**
     * Guarantee a number between 1 and max_posts.
     *
     * @return int
     */</i>
    <span class='internal'>function</span> sanitize_number(<var>$nr</var>)
    {
        <var>$nr</var> <span class='operator'>=</span> (int) <var>$nr</var>;

        <span class='internal'>if</span> ( <var>$nr</var> &gt; <var>$this</var><span class='operator'>-&gt;</span>max_posts )
        {
            <span class='internal'>return</span> <var>$this</var><span class='operator'>-&gt;</span>max_posts;
        }

        <span class='internal'>if</span> ( 0 <span class='operator'>==</span> <var>$nr</var> )
        {
            <span class='internal'>return</span> 1;
        }

        <span class='internal'>return</span> <var>$nr</var>;
    }

    <i class='comment'>/**
     * Used by widget() to fill the category parameter.
     *
     * @param string $catlist
     * @return array
     */</i>
    <span class='internal'>function</span> catlist_to_array(<var>$catlist</var>)
    {
        <var>$tmp_cats</var> <span class='operator'>=</span> <a href='http://php.net/explode'>explode</a>(<span class='string'>&#039;,&#039;</span>, <var>$catlist</var>);
        <var>$new_cats</var> <span class='operator'>=</span> <span class='internal'>array</span> ();

        <span class='internal'>foreach</span> ( <var>$tmp_cats</var> <span class='internal'>as</span> <var>$cat</var> )
        {
            <var>$new_cats</var>[] <span class='operator'>=</span> (int) <a href='http://php.net/trim'>trim</a>(<var>$cat</var>);
        }

        <span class='internal'>return</span> <var>$new_cats</var>;
    }
}</pre>
</td>
</tr>
</table>
<p>Zwei mögliche Erweiterungen habe ich im Kopf angedeutet. Wer will es versuchen?</p>
<p>Eine sehr viel umfangreichere Erweiterung der WordPress-internen Widgets liefert <a href="http://justintadlock.com/archives/2008/12/09/widgets-reloaded-wordpress-plugin">Justin Tadlocks Plugin Widgets Reloaded</a>. Sehr praktisch – und von dem sauberen Code kann man eine Menge lernen.</p>
<p>Siehe auch:</p>
<ul>
<li><a href="http://toscho.de/2010/wordpress-tutorial-ein-framebreaker-plugin-schreiben/">WordPress-Tutorial: Ein Framebreaker-Plugin schreiben</a></li>
<li><a href="http://toscho.de/2010/wordpress-alle-artikel-auflisten/">WordPress: Alle Artikel auflisten</a></li>
<li><a href="http://toscho.de/2009/wordpress-parallele-widgets/">WordPress: Parallele Widgets</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/wordpress-tutorial-eigenes-widget-schreiben/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>WordPress: ID anhand des Titels herausfinden</title>
		<link>http://toscho.de/2010/wordpress-id-anhand-titel-herausfinden/</link>
		<comments>http://toscho.de/2010/wordpress-id-anhand-titel-herausfinden/#comments</comments>
		<pubDate>Tue, 25 May 2010 13:31:25 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1683</guid>
		<description><![CDATA[Ein kleiner Helfer, mit dem sich die WordPress-Funktionen leichter bestücken lassen.]]></description>
			<content:encoded><![CDATA[<p><img src="http://toscho.de/wp-content/uploads/2010/05/wp-id-150.png" alt="" width="150" height="150" class="alignleft size-full wp-image-1684" style="margin-top:-5px" /></p>
<p>Viele Template-Funktionen in WordPress erwarten eine ID als Argument – <a href="http://codex.wordpress.org/Template_Tags/wp_list_pages">wp_list_pages()</a> beispielsweise schließt damit einzelne Seiten aus.<br />
Damit ich nun nicht immer suchen muß, habe ich mir einen kleinen Helfer in die Template-Tools gesetzt. Auszug:</p>
<table class="php-code" style="clear:left">
<tr>
<td>
<pre class='line-numbers'><a id='ex11' href='#ex11'>1</a>
<a id='ex12' href='#ex12'>2</a>
<a id='ex13' href='#ex13'>3</a>
<a id='ex14' href='#ex14'>4</a>
<a id='ex15' href='#ex15'>5</a>
<a id='ex16' href='#ex16'>6</a>
<a id='ex17' href='#ex17'>7</a>
<a id='ex18' href='#ex18'>8</a>
<a id='ex19' href='#ex19'>9</a>
<a id='ex110' href='#ex110'>10</a>
<a id='ex111' href='#ex111'>11</a>
<a id='ex112' href='#ex112'>12</a>
<a id='ex113' href='#ex113'>13</a>
<a id='ex114' href='#ex114'>14</a>
<a id='ex115' href='#ex115'>15</a>
<a id='ex116' href='#ex116'>16</a>
<a id='ex117' href='#ex117'>17</a>
<a id='ex118' href='#ex118'>18</a>
<a id='ex119' href='#ex119'>19</a>
<a id='ex120' href='#ex120'>20</a>
<a id='ex121' href='#ex121'>21</a>
<a id='ex122' href='#ex122'>22</a>
<a id='ex123' href='#ex123'>23</a>
<a id='ex124' href='#ex124'>24</a>
<a id='ex125' href='#ex125'>25</a>
<a id='ex126' href='#ex126'>26</a>
<a id='ex127' href='#ex127'>27</a>
<a id='ex128' href='#ex128'>28</a>
<a id='ex129' href='#ex129'>29</a>
<a id='ex130' href='#ex130'>30</a>
<a id='ex131' href='#ex131'>31</a>
<a id='ex132' href='#ex132'>32</a>
<a id='ex133' href='#ex133'>33</a>
<a id='ex134' href='#ex134'>34</a>
<a id='ex135' href='#ex135'>35</a>
<a id='ex136' href='#ex136'>36</a>
<a id='ex137' href='#ex137'>37</a>
<a id='ex138' href='#ex138'>38</a>
<a id='ex139' href='#ex139'>39</a>
<a id='ex140' href='#ex140'>40</a>
<a id='ex141' href='#ex141'>41</a>
<a id='ex142' href='#ex142'>42</a>
<a id='ex143' href='#ex143'>43</a>
<a id='ex144' href='#ex144'>44</a>
<a id='ex145' href='#ex145'>45</a>
<a id='ex146' href='#ex146'>46</a>
<a id='ex147' href='#ex147'>47</a>
<a id='ex148' href='#ex148'>48</a>
<a id='ex149' href='#ex149'>49</a>
<a id='ex150' href='#ex150'>50</a>
<a id='ex151' href='#ex151'>51</a>
<a id='ex152' href='#ex152'>52</a>
<a id='ex153' href='#ex153'>53</a>
<a id='ex154' href='#ex154'>54</a>
<a id='ex155' href='#ex155'>55</a>
<a id='ex156' href='#ex156'>56</a>
<a id='ex157' href='#ex157'>57</a>
<a id='ex158' href='#ex158'>58</a>
<a id='ex159' href='#ex159'>59</a>
<a id='ex160' href='#ex160'>60</a>
<a id='ex161' href='#ex161'>61</a>
<a id='ex162' href='#ex162'>62</a>
<a id='ex163' href='#ex163'>63</a>
<a id='ex164' href='#ex164'>64</a>
<a id='ex165' href='#ex165'>65</a>
<a id='ex166' href='#ex166'>66</a>
<a id='ex167' href='#ex167'>67</a>
<a id='ex168' href='#ex168'>68</a>
<a id='ex169' href='#ex169'>69</a>
<a id='ex170' href='#ex170'>70</a>
<a id='ex171' href='#ex171'>71</a>
<a id='ex172' href='#ex172'>72</a>
<a id='ex173' href='#ex173'>73</a>
<a id='ex174' href='#ex174'>74</a>
<a id='ex175' href='#ex175'>75</a>
<a id='ex176' href='#ex176'>76</a>
</pre>
</td>
<td>
<pre class="notranslate php"><span class='openclose'>&lt;?php
</span><i class='comment'>/**
 * Toscho’s Template Tools
 *
 * Helpers for WordPress templates.
 *
 * @author  Thomas Scholz &lt;info@toscho.de&gt;
 * @version 1.1
 *
 */</i>
<span class='internal'>class</span> TTT
{
    <i class='comment'>/**
     * Retrieves a post/page/custom-type/taxonomy ID by its title.
     *
     * Returns only the first result. If you search for a post title
     * that you have used more than once, restrict the type.
     * Or don’t use this function. :)
     * Simple usage:
     * $page_start_id = TTT::id_by_title(&#039;Start&#039;);
     *
     * To get the ID of a taxonomy (category, tag, custom) set $tax
     * to the name of this taxonomy.
     * Example:
     * $cat_css_id = TTT::id_by_title(&#039;CSS&#039;, 0, &#039;category&#039;);
     *
     * The result is cached internally to save db queries.
     *
     * @param  string      $title
     * @param  string      $type Restrict the type.
     * @param  string|bool $tax Taxonomy to search for.
     * @return int         ID or -1 on failure
     */</i>
    <span class='internal'>static</span> <span class='internal'>function</span> id_by_title(<var>$title</var>, <var>$type</var> <span class='operator'>=</span> <span class='string'>&#039;any&#039;</span>, <var>$tax</var> <span class='operator'>=</span> <span class='internal'>FALSE</span>)
    {
        <span class='internal'>static</span> <var>$cache</var> <span class='operator'>=</span> <span class='internal'>array</span> ();

        <var>$title</var> <span class='operator'>=</span> <a href='http://php.net/mysql_real_escape_string'>mysql_real_escape_string</a>( <a href='http://php.net/trim'>trim</a>(<var>$title</var>, <span class='string'>&#039;&quot;\&#039;&#039;</span>) );

        <i class='comment'>// Unique index for the cache.
</i>        <var>$index</var> <span class='operator'>=</span> &quot;<var>$title</var><span class='string'>-</span><var>$type</var><span class='string'>-</span>&quot; <span class='operator'>.</span> ( <var>$tax</var> <span class='operator'>?</span> <var>$tax</var> <span class='operator'>:</span> 0 );

        <span class='internal'>if</span> ( <span class='internal'>isset</span> ( <var>$cache</var>[<var>$index</var>] ) )
        {
            <span class='internal'>return</span> <var>$cache</var>[<var>$index</var>];
        }

        <span class='internal'>if</span> ( <var>$tax</var> )
        {
            <var>$taxonomy</var>      <span class='operator'>=</span> get_term_by(<span class='string'>&#039;name&#039;</span>, <var>$title</var>, <var>$tax</var>);
            <var>$cache</var>[<var>$index</var>] <span class='operator'>=</span> <var>$taxonomy</var> <span class='operator'>?</span> <var>$taxonomy</var><span class='operator'>-&gt;</span>term_id <span class='operator'>:</span> <span class='operator'>-</span>1;

            <span class='internal'>return</span> <var>$cache</var>[<var>$index</var>];
        }

        <var>$type_sql</var> <span class='operator'>=</span> <span class='string'>&#039;any&#039;</span> <span class='operator'>==</span> <var>$type</var>
            <span class='operator'>?</span> <span class='string'>&#039;&#039;</span>
            <span class='operator'>:</span> <span class='string'>&quot;AND post_type = &#039;&quot;</span>
                <span class='operator'>.</span> <a href='http://php.net/mysql_real_escape_string'>mysql_real_escape_string</a>(<var>$type</var>) <span class='operator'>.</span> <span class='string'>&quot;&#039;&quot;</span>;

        <span class='internal'>global</span> <var>$wpdb</var>;

        <var>$query</var> <span class='operator'>=</span> &quot;<span class='string'>SELECT ID FROM </span><var>$wpdb</var><span class='operator'>-&gt;</span>posts<span class='string'>
            WHERE (
                    post_status = &#039;publish&#039;
                AND post_title = &#039;</span><var>$title</var><span class='string'>&#039;
                </span><var>$type_sql</var><span class='string'>
            )
            LIMIT 1</span>&quot;;

        <var>$result</var> <span class='operator'>=</span> <var>$wpdb</var><span class='operator'>-&gt;</span>get_results(<var>$query</var>);
        <var>$cache</var>[<var>$index</var>] <span class='operator'>=</span> <span class='internal'>empty</span> ( <var>$result</var> ) <span class='operator'>?</span> <span class='operator'>-</span>1 <span class='operator'>:</span> (int) <var>$result</var>[0]<span class='operator'>-&gt;</span>ID;

        <span class='internal'>return</span> <var>$cache</var>[<var>$index</var>];
    }
}</pre>
</td>
</tr>
</table>
<p>Im praktischen Einsatz sieht das dann so aus:</p>
<table class="php-code">
<tr>
<td>
<pre class='line-numbers'><a id='ey11' href='#ey11'>1</a>
<a id='ey12' href='#ey12'>2</a>
<a id='ey13' href='#ey13'>3</a>
<a id='ey14' href='#ey14'>4</a>
<a id='ey15' href='#ey15'>5</a>
<a id='ey16' href='#ey16'>6</a>
<a id='ey17' href='#ey17'>7</a>
<a id='ey18' href='#ey18'>8</a>
<a id='ey19' href='#ey19'>9</a>
<a id='ey20' href='#ey20'>10</a>
</pre>
</td>
<td>
<pre class="notranslate php"><span class='openclose'>&lt;?php
</span>wp_list_pages(
    <span class='internal'>array</span> (
        <span class='string'>&#039;sort_column&#039;</span>   <span class='operator'>=&gt;</span>  <span class='string'>&#039;menu_order&#039;</span>,
        <span class='string'>&#039;depth&#039;</span>         <span class='operator'>=&gt;</span>  1,
        <span class='string'>&#039;title_li&#039;</span>      <span class='operator'>=&gt;</span>  <span class='string'>&#039;&#039;</span>,
        <span class='string'>&#039;exclude&#039;</span>       <span class='operator'>=&gt;</span>  TTT<span class='operator'>::</span>id_by_title(<span class='string'>&#039;Start&#039;</span>)
    )
);
<span class='openclose'>?&gt;</span></pre>
</td>
</tr>
</table>
<p>Vorsicht: Wenn man einen Titel mehrmals verwendet hat, liefert die Funktion eventuell nicht die ID zurück, die man sich erhofft hat.</p>
<p>Im Backend findet man die meisten IDs übrigens am besten mit Hilfe dieses ungeheuer nützlichen Plugins: <a href="http://wordpress.org/extend/plugins/simply-show-ids/">Simply Show IDs</a>. </p>
<p>Mehr solches Zeug:</p>
<ul>
<li><a href="http://toscho.de/2010/wordpress-auszug-zeichenzahl/">Auszug mit bestimmter Zeichenzahl</a></li>
<li><a href="http://toscho.de/2010/wordpress-alle-artikel-auflisten/">Alle Artikel auflisten</a></li>
<li><a href="http://toscho.de/2009/wordpress-administrator-php-herausfinden/">Administrator mit PHP herausfinden</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/wordpress-id-anhand-titel-herausfinden/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress: Moderationslinks für Kommentare</title>
		<link>http://toscho.de/2010/wordpress-moderationslinks-fuer-kommentare/</link>
		<comments>http://toscho.de/2010/wordpress-moderationslinks-fuer-kommentare/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 20:58:09 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Interna]]></category>
		<category><![CDATA[Markup]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1671</guid>
		<description><![CDATA[Wie man jeden Kommentar um Links ergänzt, die beim Verwalten helfen. Mit vollständigem PHP- und CSS-Code.]]></description>
			<content:encoded><![CDATA[<p>Trotz des <a href="http://toscho.de/2010/spam-verhindern-akismet-htaccess/">Antispam-Plugins</a> schlüpft auch hier manchmal ein Müllkommentar durch den Filter, oder ich vertippe mich … für diese Fälle bietet WordPress an, Kommentare zu bearbeiten, als Spam zu markieren oder ganz zu löschen. Im Backend.</p>
<p>Das ist mir ein wenig zu umständlich; deshalb habe ich in meiner Klasse ›XWP‹, die zusätzliche Templatetags erzeugt, folgenden kleinen Schnipsel eingebaut, den ich <a href="http://yoast.com/wordpress-functions-supercharge-theme/" hreflang="en">von Joost de Valk abgeguckt</a> habe:</p>
<pre class="notranslate">    <i>/* Generates comment moderation links.
     *
     * @author Joost de Valk
     * @link   <a href="http://yoast.com/wordpress-functions-supercharge-theme/">http://yoast.com/wordpress-functions-supercharge-theme/</a>
     * @param  int <var>$id</var> Comment id - use get_comment_ID()
     * @return void
     */</i>
    public static function delete_comment_link(<var>$id</var>)
    {
        if ( ! <a href="http://codex.wordpress.org/Roles_and_Capabilities#moderate_comments">current_user_can</a>('<code class="string">moderate_comments</code>') )
        {
            return;
        }

        global <var>$post</var>;

        <var>$redirect</var> = get_permalink( <var>$post</var>-&gt;ID );

        <var>$links</var> = array (
            '<code class="string">delete</code>'  =&gt; '<code class="string">cdc</code>',
            '<code class="string">spam</code>' =&gt; '<code class="string">cdc&amp;dt=spam</code>',
            '<code class="string">edit</code>' =&gt; '<code class="string">editcomment</code>'
        );

        <var>$return</var> = '<code class="string">&lt;span class="comment_admin"&gt;</code>';

        foreach ( <var>$links</var> as <var>$name</var> =&gt; <var>$param</var> )
        {
            <var>$return</var> .= "<code class="string">&lt;a href='</code>"
                    . admin_url("<code class="string">comment.php?c=<var>$id</var>&amp;action=<var>$param</var>&amp;redirect_to=<var>$redirect</var></code>")
                    . "<code class="string">'&gt;<var>$name</var>&lt;/a&gt;</code>";
        }

        print <var>$return</var> . '<code class="string">&lt;/span&gt;</code>';

        return;
    }</pre>
<p>In der <code>comments.php</code> rufe ich die Funktion innerhalb des Kommentarloops auf:</p>
<pre class="notranslate">XWP::delete_comment_link( get_comment_ID() );</pre>
<p>Das erzeugt etwa dieses <a href="http://toscho.de/thema/markup/">Markup</a>:</p>
<pre class="notranslate">&lt;span class="<code class="string">comment_admin</code>"&gt;
  &lt;a href='<code class="string">/wp-admin/comment.php?c=905&amp;action=cdc&amp;redirect_to=/2010/beispiel/</code>'
     &gt;delete&lt;/a&gt;
  &lt;a href='<code class="string">/wp-admin/comment.php?c=905&amp;action=cdc&amp;dt=spam&amp;redirect_to=/2010/beispiel/</code>'
     &gt;spam&lt;/a&gt;
  &lt;a href='<code class="string">/wp-admin/comment.php?c=905&amp;action=editcomment&amp;redirect_to=/2010/beispiel/</code>'
     &gt;edit&lt;/a&gt;
&lt;/span&gt;</pre>
<p>Mit ein wenig <a href="http://toscho.de/thema/css/">CSS</a> aufgepeppt …</p>
<pre class="notranslate">.comment_admin
    {
        float:              right;
        font:               .9em/1 Calibri;
        text-align:         center;
    }
.comment_admin a
    {
        color:              #444;
        background:         #f9f9f9;
        text-decoration:    none;
        border:             1px solid #bbb;
        border-radius:      4px;
        box-shadow:         0 2px 3px rgba(0,0,0,0.2);
        display:            inline-block;
        width:              3em;
        margin:             4px;
        padding:            4px 15px;
    }
#content .comment_admin a:hover
    {
        background:         #666;
        color:              #fff;
        border:             1px solid #222;
    }</pre>
<p>… sieht das Ergebnis dann so aus:</p>
<p><img src="http://toscho.de/wp-content/uploads/2010/04/comment-moderation.png" alt="" title="comment moderation" width="280" height="123" class="alignnone size-full wp-image-1672 border" /></p>
<p>Nach einem Klick landet man in der Bearbeitungsmaske im Backend, <em>dann erst</em> wird der Kommentar per Knopfdruck gelöscht oder als Spam markiert.</p>
<p>Mehr so’n Zeug:</p>
<ul>
<li><a href="http://toscho.de/2009/wordpress-administrator-php-herausfinden/">Administrator mit PHP herausfinden</a></li>
<li><a href="http://toscho.de/2009/wordpress-moderationsfalle-offenlegen/">Moderationsfalle offenlegen</a></li>
<li><a href="http://toscho.de/2009/no-no-no-nofollow/">No no no nofollow</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/wordpress-moderationslinks-fuer-kommentare/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Designlinks 12</title>
		<link>http://toscho.de/2010/designlinks-12/</link>
		<comments>http://toscho.de/2010/designlinks-12/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 10:19:33 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[Browser]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[Zeichen]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1669</guid>
		<description><![CDATA[Eine Katze, die gerne duscht, langsame Referenzen, schlanke User-Agent-Strings, fette Zeichenreferenzen, ein enorm flexibles Stylesheet und ein Malprogramm.]]></description>
			<content:encoded><![CDATA[<p>Wird mal wieder Zeit. Aber zuerst entspannen wir uns ein bißchen:</p>
<p class="wp-caption-text"><object type="application/x-shockwave-flash" data="http://www.collegehumor.com/moogaloop/moogaloop.swf?clip_id=1920326&#038;fullscreen=1" width="480" height="360" ><param name="allowfullscreen" value="true"/><param name="wmode" value="transparent"/><param name="allowScriptAccess" value="always"/><param name="movie" quality="best" value="http://www.collegehumor.com/moogaloop/moogaloop.swf?clip_id=1920326&#038;fullscreen=1"/><embed src="http://www.collegehumor.com/moogaloop/moogaloop.swf?clip_id=1920326&#038;fullscreen=1" type="application/x-shockwave-flash" wmode="transparent"  width="480" height="360"  allowScriptAccess="always"></embed></object><br />
Quelle: <a href="http://www.collegehumor.com/video:1920326" hreflang="en">CollegeHumor</a>.</p>
<p>›<a href="http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html" hreflang="en" lang="en">Do not use PHP references</a>‹, empfiehlt Johannes Schlüter, denn Referenzen kosten Tempo, Übersicht und Flexibilität. Ob seiner klaren und verständlichen Darstellung dieses kniffligen Themas möchte ich den Artikel jetzt schon in die Liste der zehn besten dieses Jahres rücken.</p>
<p>Nicholas C. Zakas: <a href="http://www.nczonline.net/blog/2010/01/12/history-of-the-user-agent-string/" hreflang="en" lang="en">History of the user-agent string</a>. Warum die UA-Strings heute oft so sonderbar aussehen. Die neue <a href="http://blogs.msdn.com/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx" hreflang="en">Kennung des IE 9</a> lautet:</p>
<pre class="notranslate">Mozilla/5.0 (compatible, MSIE 9.0; Windows NT 6.1; Trident/5.0)</pre>
<p>Anhängsel irgendwelcher Zusatzsoftware werden nicht mehr eingebaut; damit schrumpft die <a href="http://www.useragentstring.com/_uas_Internet%20Explorer_version_8.0.php" hreflang="en">Liste der möglichen Kennungen</a> gewaltig – was es Proxys erheblich erleichtert, gespeicherte Versionen einer Webseite auszuliefern. Das erklärt Billy Hoffman gut in: ›<a href="http://zoompf.com/blog/2010/03/the-big-performance-improvement-in-ie9-no-one-is-talking-about" hreflang="en" lang="en">The Big Performance Improvement in IE9 No One is Talking About</a>‹. Er rät auch dazu, die <a href="http://toscho.de/2010/gzip-pro-und-kontra/">gzip-komprimierte</a> Version <em>nur noch</em> anhand des Accept-Headers zu versenden und den User-Agent zu ignorieren, damit beispielsweise ein Safari-Nutzer die Version bekommt, die der Firefox-Nutzer zuvor in den Proxy gehievt hat.</p>
<p>Man kann <a href="http://toscho.de/2008/zeichenkodierung-begriffe/#toc-maskierung-entity-und-zeichenreferenz">dezimale Zeichenreferenzen</a> mit beliebig vielen führenden Nullen versehen. So läßt sich das <samp>A</samp> als <code>&amp;#65;</code> schreiben oder als <code>&amp;#000000000000000000000000000000065;</code><br />
›hakre‹ hat mal ausprobiert, wie weit man damit gehen kann: ›<a href="http://hakre.wordpress.com/2010/02/25/html-entity-boundaries-zero-padding/" hreflang="en" lang="en">HTML Entity Boundaries – Zero Padding</a>‹.<br />
Ein Experiment, dessen praktischer Nutzen sicher weit unter seinem Unterhaltungswert liegt. Doch zeigt es, wie weit die Entwickler vorausdenken und wo sie die Grenze ziehen zwischen ›das versuche ich noch‹ und ›das wird zu langsam‹. Wenig überraschend frißt Firefox die meisten Nullen – bis zum Erstickungstod.</p>
<p>Anne van Kesteren hat auch ein Experiment mit gewaltigem Geekpotential hingestellt: <a href="http://annevankesteren.nl/test/contenteditable-style.htm" lang="en">Live style sheet editing!</a><br />
Und da muß ich einfach mal den Quelltext zitieren:</p>
<pre class="notranslate">&lt;!doctype html&gt;
&lt;html&gt;
 &lt;head&gt;
  &lt;title&gt;Live style sheet editing!&lt;/title&gt;
  &lt;style style="<code class="string">white-space:pre <i>/* hack for Opera */</i></code>" contenteditable=""&gt;
html {
margin:.2em;
font-size:2em;
color:lime;
background:purple
}
head, title, style
{
display:block
}
body {
display:none
}
  &lt;/style&gt;
 &lt;/head&gt;
 &lt;body&gt;<i>&lt;!-- nothing is needed here --&gt;</i>&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Zum Schluß noch ein Link für die Freunde der Maus: <a href="http://mrdoob.com/projects/harmony/">Harmony</a>, ein Zeichenprogramm in Javascript und Canvas. Das macht wirklich Freude.</p>
<p><img src="http://toscho.de/wp-content/uploads/2010/04/harmony-toscho.png" alt="Harmony. Ein Experiment." width="485" height="330" class="alignnone size-full wp-image-1670 border" /></p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/designlinks-12/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>WordPress-Plugin: Backend Style Enhancements</title>
		<link>http://toscho.de/2010/wordpress-plugin-backend-style-enhancements/</link>
		<comments>http://toscho.de/2010/wordpress-plugin-backend-style-enhancements/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 13:16:12 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Webdesign]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1660</guid>
		<description><![CDATA[Beispiel für ein Plugin, das das Layout des Backends ändert. Mit ausführlich kommentiertem und verlinktem Quellcode und natürlich einem Download.]]></description>
			<content:encoded><![CDATA[<p>Zwar läßt sich das WordPress-Backend ganz gut per <a href="http://toscho.de/2010/css-mein-userstylesheet/">Userstylesheet</a> über den Selektor <code>body.wp-admin</code> ansprechen – doch technisch unbedarften Leuten hilft das eher wenig. Für eine Freundin, die ebenso wie ich eine Navigation lieber rechts oder oben sieht, habe ich deshalb mal fix ein kleines Plugin erstellt.</p>
<p>Es ist ganz einfach, spricht aber ein paar Dinge an, die ich im <a href="http://toscho.de/2010/wordpress-tutorial-ein-framebreaker-plugin-schreiben/">Framebreaker-Tutorial</a> nicht berührt habe. So mag es sich vielleicht als Lehrstück eignen. Ich verkneife mir heute einen langen Text; stattdessen habe ich alles ausführlich kommentiert und verlinkt.</p>
<p class="wideimg"><img src="http://toscho.de/wp-content/uploads/2010/04/backend-enhancements.png" alt="Screenshot Backend Enhancements" width="500" height="391" class="alignnone size-full wp-image-1661" /></p>
<p>Das Stylesheet selbst setzt die Navigation nach rechts, gibt Links bei <code>:hover</code> einen Unterstrich und entsorgt <i>Lucida Grande</i> und <i>Verdana,</i> die ich beide nicht mehr sehen mag. Außerdem repariert es ein paar Breitenangaben – die Entwickler konnten sich wohl nicht vorstellen, daß jemand 14px als <a href="http://toscho.de/2009/mythos-font-size-62dot5-prozent/">Mindestschriftgröße</a> setzt. Das muß man leider als Massenpsychose diagnostizieren.</p>
<p>Im Ganzen sei es bitte nur als <em>Beispiel</em> dafür gesehen, was man ändern kann.</p>
<pre class="notranslate">&lt;?php
<i>/*
Plugin Name: Backend Style Enhancements
Plugin URI:  http://toscho.de/p1660
Description: Some minor fixes for the WP backend.
Version:     1.0
Author:      Thomas Scholz
Author URI:  <a href="http://toscho.de">http://toscho.de</a>
Created:     22.04.2010
*/</i>

<i>/**
 * We need just the constructor.
 */</i>
new Toscho_Backend_Style;

<i>/**
 * Adds a stylesheet to the WordPress backend.
 *
 * @version 1.0
 */</i>
class Toscho_Backend_Style
{
    <i id="query_arg">/**
     * The address for our stylesheet.
     * Should match [0-9a-z-].
     *
     * @see #<a href="#add_query_arg">add_query_arg()</a>
     * @see #<a href="#print_link_element">print_link_element()</a>
     * @var string
     */</i>
    protected <var>$query_arg</var> = '<code class="string">tbecss</code>';

    <i>/**
     * Constructor
     */</i>
    public function __construct()
    {
        <i>/* Register the query argument. */</i>
        <a href="http://codex.wordpress.org/Function_Reference/add_filter">add_filter</a>('<code class="string">query_vars</code>', array ( <var>$this</var>, '<a href="#add_query_arg"><code class="string">add_query_arg</code></a>') );

        <i>/* What should happen, if we find the query? */</i>
        <a href="http://codex.wordpress.org/Function_Reference/add_action">add_action</a>('<code class="string">template_redirect</code>', array ( <var>$this</var>, '<a href="#print_css"><code class="string">print_css</code></a>') );

        <i>/* Like wp_head, just for the backend. */</i>
        add_action('<code class="string">admin_head</code>', array ( <var>$this</var>, '<a href="#print_link_element"><code class="string">print_link_element</code></a>') );

        <i>/* Since this plugin isn’t listed on
         * http://wordpress.org/extend/plugins/
         * we won’t waste the user’s time.
         */</i>
        add_filter('<code class="string">http_request_args</code>',
            array ( <var>$this</var>, '<a href="#prevent_plugin_upgrade_check"><code class="string">prevent_plugin_upgrade_check</code></a>' ), 5, 2);

        return;
    }

    <i id="add_query_arg">/**
     * Registers the query arg in WordPress
     *
     * @param  array <var>$vars</var> Already registered query args.
     * @return array
     */</i>
    public function add_query_arg( array <var>$vars</var> )
    {
        return <a href="http://php.net/array-merge">array_merge</a>( <var>$vars</var>, array ( <var>$this</var>-&gt;<a href="#query_arg">query_arg</a> ) );
    }

    <i id="print_css">/**
     * Prints the CSS content.
     *
     * @return void
     */</i>
    public function print_css()
    {
        if ( ! isset ( <var>$_GET</var>[<var>$this</var>-&gt;<a href="#query_arg">query_arg</a>] ) )
        {
            return;
        }

        <i>// Don’t waste time in wp-includes/template-loader.php</i>
        define('<code class="string">WP_USE_THEMES</code>', FALSE);

        <a href="http://php.net/header">header</a>('<code class="string">Content-Type: text/css;charset=utf-8</code>', TRUE);

?&gt;<code style="color:#059">@charset "utf-8";
.wrap a:hover
{
    text-decoration:    underline       !important;
}
.wrap a.button:hover
{
    text-decoration:    none            !important;
}
body,
td,
input,
select,
#adminmenu *
{
    font-family:        Calibri         !important;
}
textarea, [type="text"]
{
    font-family:        Consolas        !important;
}
body,
#wpbody,
.form-table .pre
{
    color:              #000            !important;
}
td
{
    vertical-align:     top             !important;
    line-height:        1.4             !important;
}
#adminmenu
{
    float:              right           !important;
    margin:             5px -150px 0 0 !important;
}
#adminmenu .wp-submenu li
{
    width:              151px           !important;
}
#wpbody-content
{
    float:              right           !important;
    width:              100%;
}
#wpbody
{
    margin-left:        0               !important;
    margin-right:       170px           !important;

}</code>
&lt;?php
        <i>/* Ugly, yes. But if we just return, WP will
         * proceed and append the default page. */</i>
        exit;
    }

    <i id="print_link_element">/**
     * Prints the link element into the admin head.
     *
     * @return void
     */</i>
    public function print_link_element()
    {
        <var>$url</var> = <a href="http://codex.wordpress.org/Function_Reference/get_option">get_option</a>('<code class="string">siteurl</code>') . '/?' . <var>$this</var>-&gt;<a href="#query_arg">query_arg</a>;
        print "<code class="string">&lt;link rel='stylesheet' href='<var>$url</var>' /&gt;</code>";

        return;
    }

    <i id="prevent_plugin_upgrade_check">/**
     * Blocks update checks for this plugin.
     *
     * @author Mark Jaquith <a href="http://markjaquith.wordpress.com">http://markjaquith.wordpress.com</a>
     * @see    <a href="http://wp.me/p56-65">http://wp.me/p56-65</a>
     * @param  array <var>$r</var> Request information
     * @param  string <var>$url</var>
     * @return array
     */</i>
    public function prevent_plugin_upgrade_check(<var>$r</var>, <var>$url</var>)
    {
        if ( 0 !== <a href="http://php.net/strpos">strpos</a>(<var>$url</var>,
             '<code class="string">http://api.wordpress.org/plugins/update-check</code>') )
        { <i>// Not a plugin update request. Bail immediately.</i>
            return <var>$r</var>;
        }

        <var>$plugins</var> = <a href="http://php.net/unserialize">unserialize</a>( <var>$r</var>['<code class="string">body</code>']['<code class="string">plugins</code>'] );
        <var>$p_base</var>  = <a href="http://codex.wordpress.org/Function_Reference/plugin_basename">plugin_basename</a>( __FILE__ );

        unset (
            <var>$plugins</var>-&gt;plugins[<var>$p_base</var>],
            <var>$plugins</var>-&gt;active[<a href="http://php.net/array_search">array_search</a>(<var>$p_base</var>, <var>$plugins</var>-&gt;active)]
        );

        <var>$r</var>['<code class="string">body</code>']['<code class="string">plugins</code>'] = <a href="http://php.net/serialize">serialize</a>(<var>$plugins</var>);

        return <var>$r</var>;
    }
}</pre>
<p>Als Lohn für das <del datetime="2010-04-22T23:06:17+00:00">geduldige Lesen</del> schnelle Herunterscrollen:</p>
<p class="downloadlink"><a href="http://f.toscho.de/php-skripte/backend-style.zip">Download Plugin Backend Style Enhancements</a></p>
<p>Meine Kommentare ersetzen natürlich nicht eure Fragen. Also stellt sie bitte!</p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/wordpress-plugin-backend-style-enhancements/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP und Google-Maps: Latitude und Longitude finden</title>
		<link>http://toscho.de/2010/php-google-maps-latitude-longitude-finden/</link>
		<comments>http://toscho.de/2010/php-google-maps-latitude-longitude-finden/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 20:04:19 +0000</pubDate>
		<dc:creator>Thomas Scholz</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Suchmaschinen]]></category>
		<category><![CDATA[Webdesign]]></category>

		<guid isPermaLink="false">http://toscho.de/?p=1657</guid>
		<description><![CDATA[Wie man serverseitig Breiten- und Längengrade herausfindet und welche Fallen die Google-API hier eingebaut hat.]]></description>
			<content:encoded><![CDATA[<p>Gerade sitze ich an einem Projekt, für das ich etwa 300 <a href="http://code.google.com/intl/de/apis/maps/documentation/staticmaps/">statische Google-Karten</a> erzeugen will. </p>
<div id="attachment_1658" class="wp-caption alignright" style="width: 210px"><img src="http://toscho.de/wp-content/uploads/2010/04/staticmap-not-found.png" alt="Google Staticmap: Not found" width="200" height="184" class="size-full wp-image-1658" /><p class="wp-caption-text">Nichts gefunden</p></div>
<p>Hierzu habe ich ebenso viele Adressen zur Hand, die ich einfach der API übergeben könnte, auf daß Google selbst die passende Position finde. Problem: Wenn nichts gefunden wird, erfahre ich das im Script nicht, sondern erst beim Ansehen des Bildes.</p>
<p>Da gebe ich doch lieber <em>kein</em> Bild aus.</p>
<p>Also muß ich erst prüfen, ob Google einen Ort auf der Karte finden kann, indem ich die Ortsangabe in Breiten- und Längengrade (Latitude und Longitude) umwandeln lasse. Danke an <a href="http://fabian-beiner.de/">Fabian Beiner</a> für den Tipp dazu. Meine Googlekompetenz schien gestern so eingebrochen zu sein, daß ich <a href="http://code.google.com/intl/de/apis/maps/documentation/services.html#Geocoding_Direct">das</a> nicht selbst herausfinden konnte …</p>
<pre class="notranslate"><i>/**
 * Gets the coordinates (latitude and longitude) for a place.
 * Keeps the image URI short.
 * Thanks to Fabian Beiner - http://fabian-beiner.de/ - for the tip.
 *
 * @param  string $place
 * @return string|bool
 */</i>
function coords_by_name(<var>$place</var>)
{
    <var>$place</var>   = urlencode(<var>$place</var>);
    <var>$url</var>     = "<code class="string">http://maps.google.com/maps/geo?output=xml&amp;q=<var>$place</var></code>";

    <var>$content</var> = file_get_contents(<var>$url</var>);

    <i>// Kein Ergebnis</i>
    if ( FALSE == strpos(<var>$content</var>, 'Placemark') )
    {
        return FALSE;
    }

    <var>$xml</var>     = new SimpleXMLElement(<var>$content</var>);

    return <var>$xml</var>->Response->Placemark->Point->coordinates[0];
}</pre>
<p>Das Ergebnis sieht im Erfolgsfall so aus: <code>"11.9658140,51.4821660,0"</code>.</p>
<p>Für die statische Karte brauchen wir die letzte Angabe – <code>,0</code> – nicht; obendrein akzeptiert die API nur Angaben mit einer Genauigkeit von sechs Dezimalstellen, nicht sieben. Und wir brauchen die beiden Angaben in umgekehrter Reihenfolge für den Mittelpunkt der Karte. Da hat wohl jemand lange nachgedacht und dann Mist gebaut …</p>
<p>Deshalb habe ich mir einen kleinen Helfer geschrieben:</p>
<pre class="notranslate"><i>/**
 * Fixes latitude longitude coordinates.
 *
 * @param  string $s
 * @return bool
 */</i>
function fix_coords(<var>$s</var>)
{
    <var>$found</var> = (bool) preg_match(
        "<code class="string">~^(-?\d{1,2}\.\d{0,6})\d?,(-?\d{1,2}\.\d{0,6})\d?~</code>",
        <var>$s</var>, <var>$match</var>
    );

    if ( ! <var>$found</var> )
    {
        return FALSE;
    }

    return <var>$match</var>[2] . ',' . <var>$match</var>[1];
}</pre>
<p>Das gibt uns <code>"11.965814,51.482166"</code> aus, und damit können wir eine vernünftige Karte bauen.</p>
<p>Aber Achtung: Die Positionen der Marker muß man in umgekehrter Reihenfolge angeben!</p>
<p>Den aktuellen Zwischenstand habe ich eben mal auf GitHub hochgeladen: <a href="http://github.com/toscho/Static-Google-Map">class.Google_Static_Map</a>. Der Code wurde mir dann doch ein bißchen zu lang für einen Blogbeitrag. Dort gibt es auch einen Bugtracker für eure Hinweise oder Vorschläge, und wer Code beitragen oder einen Fork anlegen möchte, ist dazu herzlich eingeladen.</p>
]]></content:encoded>
			<wfw:commentRss>http://toscho.de/2010/php-google-maps-latitude-longitude-finden/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Database Caching using disk: basic
Object Caching 622/756 objects using disk: basic

Served from: toscho.de @ 2012-02-04 12:22:36 -->
