<?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>W-Shadow.com &#187; Blogging</title>
	<atom:link href="http://w-shadow.com/blog/category/blogging/feed/" rel="self" type="application/rss+xml" />
	<link>http://w-shadow.com</link>
	<description>Slightly Advanced Computer Stuff (and some magic)</description>
	<lastBuildDate>Thu, 02 Sep 2010 11:04:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Automatic Updates For Private And Commercial Plugins</title>
		<link>http://w-shadow.com/blog/2010/09/02/automatic-updates-for-any-plugin/</link>
		<comments>http://w-shadow.com/blog/2010/09/02/automatic-updates-for-any-plugin/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 11:04:00 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[automatic updates]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[update notifications]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress plugins]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=2045</guid>
		<description><![CDATA[Since time immemorial, only plugins hosted in the official WordPress.org plugin directory have supported automatic updates. Now, I&#8217;ve written a PHP library that you can use to add automatic update capabilities to any plugin. Public, private and commercial plugins alike &#8211; all can now enjoy the benefits of automatic update notifications and one-click upgrades. The [...]]]></description>
			<content:encoded><![CDATA[<p>Since <abbr title="December 10th, 2008 - WordPress 2.7">time immemorial</abbr>, only plugins hosted in the official WordPress.org plugin directory have supported automatic updates. Now, I&#8217;ve written a PHP library that you can use to add automatic update capabilities to any plugin. Public, private and commercial plugins alike &#8211; all can now enjoy the benefits of automatic update notifications and one-click upgrades.</p>
<p>The custom update checker integrates closely with the upgrade system already built into WordPress, producing a seamless user experience. Observe : </p>
<div id="attachment_2064" class="wp-caption aligncenter" style="width: 500px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; display: block; margin-right: auto; margin-left: auto;"><a href="http://w-shadow.com/wp-content/uploads/2010/09/external-upgrade-notice.png"><img src="http://w-shadow.com/wp-content/uploads/2010/09/external-upgrade-notice-490x56.png" alt="" title="Upgrade notice generated by an external plugin update" width="490" height="56" class="size-large wp-image-2064" /></a><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">An upgrade notice for a privately hosted plugin.</p></div>
<div id="attachment_2065" class="wp-caption aligncenter" style="width: 500px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; display: block; margin-right: auto; margin-left: auto;"><a href="http://w-shadow.com/wp-content/uploads/2010/09/external-update-plugin-information.png"><img src="http://w-shadow.com/wp-content/uploads/2010/09/external-update-plugin-information-490x290.png" alt="" title="The &quot;Plugin Information&quot; window with placeholder data" width="490" height="290" class="size-large wp-image-2065" /></a><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">The 'Plugin Information' window with placeholder data.</p></div>
<p><em>(Excuse my marketing-speak. It&#8217;s a thing. On with the practicalities of the matter.)</em></p>
<h3>Download</h3>
<ul>
<li><strong><a href="http://w-shadow.com/files/plugin-updates.zip">Client library</a></strong> (requires PHP5 and WP 2.8 or later)</li>
<li><strong><a href="http://w-shadow.com/files/external-update-example/external-update-example.zip">Example plugin</a></strong></li>
<li><strong><a href="http://w-shadow.com/files/external-update-example/info.json">Example metadata file</a></strong></li>
</ul>
<h3>Quick-start Guide</h3>
<p>This section describes the quickest way to get automatic updates working for your plugin. Here&#8217;s what you&#8217;ll need to do: create a metadata file for your plugin, host it somewhere publicly accessible, and tell the update checker where to find it.</p>
<p>Lets start with the metadata. Copy the <a href="http://www.json.org/">JSON</a> code below into a new file and replace the placeholder values with your plugin&#8217;s info.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;name&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;My Cool Plugin&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;slug&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;my-cool-plugin&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;download_url&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;http://example.com/plugins/my-cool-plugin.zip&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;version&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;2.0&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;author&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;John Smith&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;sections&quot;</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;description&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Plugin description here. Basic HTML allowed.&quot;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>(This is the <em>minimal</em> amount data required to make automatic updates work. In most cases, you will probably want to add a couple more fields. See the metadata docs below for details.)</p>
<p>Most of the fields should be pretty self-explanatory, with one possible exception &#8211; the &#8220;slug&#8221;. WordPress expects all plugins that support automatic updates to have a unique textual identifier called the &#8220;slug&#8221;. Normally, slugs are assigned by the official plugin directory. For a private/commercial plugin that&#8217;s hosted elsewhere you&#8217;ll have to make something up. If unsure, just use the plugin&#8217;s file name without the &#8220;.php&#8221; extension (my-cool-plugin/my-cool-plugin.php becomes my-cool-plugin).</p>
<p>Upload the metadata file you just created to your web server. It doesn&#8217;t matter where exactly you put the file or how you name it. The important thing is for its URL to be accessible from wherever someone might install your plugin.</p>
<p>Next, copy the &#8220;update-checker&#8221; directory from the <a href="http://w-shadow.com/files/plugin-updates.zip">client library archive</a> to your plugin&#8217;s directory. Then fire up your favourite code editor and add the following lines to the top of your plugin file:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'plugin-updates/plugin-update-checker.php'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$MyUpdateChecker</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PluginUpdateChecker<span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'http://example.com/path/to/metadata.json'</span><span style="color: #339933;">,</span>
    <span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'your-chosen-slug'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>(If you followed my advice and used the plugin&#8217;s file name as the slug, you can omit the third parameter of the PluginUpdateChecker constructor.)</p>
<p>And that, believe it or not, is it. </p>
<p>The PluginUpdateChecker class will handle the rest. It&#8217;ll check the metadata file every 12 hours and, if it discovers that a new version has been released, twiddle the right bits in the undocumented WP API to make it show up as a standard upgrade notification in the &#8220;Plugins&#8221; tab. Assuming you&#8217;ve set up the download_url correctly, users will be able to install the update with a single click.</p>
<p>The rest of this post will be devoted to a more in-depth discussion of the update checker class and the metadata format.</p>
<h3>The PluginUpdateChecker class</h3>
<p>This class is the core of the update checker. It&#8217;s also the only part of the updater that you should need to deal with unless you decide to  extend the library yourself.</p>
<p><strong>Class constructor</strong></p>
<p>All configuration settings should be specified by passing them to the PluginUpdateChecker constructor. It takes the following parameters :</p>
<ul>
<li><code>$metadataUrl</code> &#8211; The full URL of the plugin&#8217;s metadata file.</li>
<li><code>$pluginFile</code> &#8211; The fully qualified path to the plugin file. In most cases you can simply use the __FILE__ constant here.</li>
<li><code>$slug</code> &#8211; The plugin&#8217;s &#8216;slug&#8217;. If not specified, the filename part of $pluginFile (sans &#8220;.php&#8221;) will be used as the slug.</li>
<li><code>$checkPeriod</code> &#8211; How often to check for updates (in hours). Defaults to checking every 12 hours. Set to zero to disable automatic update checks.</li>
<li><code>$optionName</code> &#8211; Where to store book-keeping info about updates. Defaults to &#8220;external_updates-$slug&#8221;.</li>
</ul>
<p><strong>checkForUpdates()</strong></p>
<p>Manually trigger an update check. This is especially useful when you&#8217;ve disabled automatic checks by setting $checkPeriod (above) to zero. This method takes no parameters and returns nothing.</p>
<p><strong>addQueryArgFilter($callback)</strong></p>
<p>Register a callback for filtering query arguments. Whenever the update checker needs to retrieve the metadata file, it will first run each filter callback and attach the query arguments that they return to the metadata URL. This lets you pass arbitrary data to the server hosting the metadata. For example, commercial plugins could use it to implement some kind of authorization scheme where only users that have the right &#8220;key&#8221; get automatic updates.</p>
<p>The callback function will be passed an associative array of query arguments and should return a modified array. By default, the update checker will add these arguments to the metadata URL:</p>
<ul>
<li><code>installed_version</code> &#8211; set to the currently installed version of the plugin.</li>
<li><code>checking_for_updates</code> &#8211; set to 1 if checking for updates, absent otherwise (i.e. when loading data for the &#8220;Plugin Information&#8221; box).</li>
</ul>
<p>This method takes one parameter &#8211; the callback function.</p>
<p><strong>addHttpRequestArgFilter($callback)</strong></p>
<p>Register a callback for filtering the various options passed to the built-in helper function <a href="http://codex.wordpress.org/HTTP_API#Helper_Functions">wp_remote_get</a> that the update checker uses to periodically download plugin metadata. The callback function should take one argument &#8211; an associative array of arguments &#8211; and return a modified array or arguments. See the WP documentation on wp_remote_get for details about what arguments are available and how they work.</p>
<p>This method takes one parameter &#8211; the callback function.</p>
<p><strong>addResultFilter($callback)</strong></p>
<p>Register a callback for filtering plugin info retrieved from the metadata URL.</p>
<p>The callback function should take two arguments. If the metadata was retrieved successfully, the first argument passed will be an instance of  PluginInfo (see the source for a description of this class). Otherwise, it will be NULL. The second argument will be the corresponding return value of wp_remote_get (see WP docs for details). The callback function should return a new or modified instance of PluginInfo or NULL.</p>
<p>This method takes one parameter &#8211; the callback function.</p>
<h3>Metadata format</h3>
<p>The automatic update system uses a JSON-based file format to describe plugins.  Essentially, the entire file is one big JSON-encoded object (<em>AKA</em> hash-table or associative array). Each field &#8211; or array key &#8211; represents a piece of information about the latest version of the plugin. <a href="https://spreadsheets.google.com/pub?key=0AqP80E74YcUWdEdETXZLcXhjd2w0cHMwX2U1eDlWTHc&amp;authkey=CK7h9toK&amp;hl=en&amp;single=true&amp;gid=0&amp;output=html">The full description of all available fields is here.</a></p>
<p>For the sake of simplicity, both general metadata and update-related information are stored in the same file. If this is undesirable, you can replace the plain JSON file with a script that checks for the presence of the the &#8220;checking_for_updates&#8221; query parameter and emits just the update-related fields if its set to &#8220;1&#8243;.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/09/02/automatic-updates-for-any-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fixing &#8220;Memory Exhausted&#8221; Errors In WP-DBManager</title>
		<link>http://w-shadow.com/blog/2010/08/25/fix-memory-exhausted-error-wp-dbmanager/</link>
		<comments>http://w-shadow.com/blog/2010/08/25/fix-memory-exhausted-error-wp-dbmanager/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 13:30:27 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress plugins]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=2036</guid>
		<description><![CDATA[WP-DBManager is a handy plugin that can, among other things, make periodic database backups and send them to a specified email address. I installed it on this blog months ago and up until a week ago everything was working perfectly. Then one day the backup emails simply stopped coming. What Went Wrong? A quick check [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://wordpress.org/extend/plugins/wp-dbmanager/">WP-DBManager</a> is a handy plugin that can, among other things, make periodic database backups and send them to a specified email address. I installed it on this blog months ago and up until a week ago everything was working perfectly. Then one day the backup emails simply stopped coming.</p>
<h3>What Went Wrong?</h3>
<p>A quick check of the server&#8217;s error_log revealed the problem: the plugin was running out of memory.</p>

<div class="wp_syntax"><div class="code"><pre class="log" style="font-family:monospace;">[19-Aug-2010 15:47:44] PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 11145167 bytes) in /home/foo/public_html/wp-content/plugins/wp-dbmanager/wp-dbmanager.php on line 101
[20-Aug-2010 15:47:49] PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 10929395 bytes) in /home/foo/public_html/wp-content/plugins/wp-dbmanager/wp-dbmanager.php on line 101
[21-Aug-2010 15:47:38] PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 10693507 bytes) in /home/foo/public_html/wp-content/plugins/wp-dbmanager/wp-dbmanager.php on line 101</pre></div></div>

<p>Alas, this was not all that surprising. Due to the way the mail() function works in PHP, WP-DBManager must read the entire backup file into memory before emailing it. Since the database gets bigger and bigger with each new post and comment, it will one day inevitably exceed the maximum amount of memory that PHP scripts are allowed to use and thus crash the plugin.</p>
<p>There are many ways to fix this problem, but most of them will only buy you some time. Increasing PHP memory limit will work in the short-term, but eventually the WP database will grow large enough to exceed the new limit. Similarly, cleaning up the DB &#8211; e.g. by removing old post revisions &#8211; can make it small enough that the backup file fits in the available memory. But that, too, is only a temporary solution.</p>
<h3>The Fix</h3>
<p>Ideally, the plugin shouldn&#8217;t even need to read the entire file into memory. It&#8217;s just the &#8220;convenient&#8221; design of the built-in mail() function that demands this. To solve the &#8220;allowed memory size of XXX bytes exhausted&#8221; problem once and for all, we need to replace mail() with something more flexible.</p>
<p>So, after an hour or two of hacking, I managed to rig WP-DBManager to use the free <a href="http://swiftmailer.org/">Swift Mailer library</a> instead. Among the library&#8217;s many features is the ability to send file attachments of virtually any size without worrying about memory limits. Thus enhanced, the plugin should be able to handle large backups without a hitch.</p>
<p>You can download the fixed version below. I&#8217;ve successfully installed it on my site and the periodic backup emails are rolling in again (yay!). Note, however, that due to the inclusion of the Swift Mailer library the plugin now requires PHP 5.2 or later. Make sure your server has that before trying to install the modified version.</p>
<p><a href="http://w-shadow.com/files/wp-dbmanager-modified.zip"><strong>wp-dbmanager-modified.zip</strong></a><strong> </strong>(190 KB)</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/08/25/fix-memory-exhausted-error-wp-dbmanager/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Broken Link Checker 0.9.5 Alpha</title>
		<link>http://w-shadow.com/blog/2010/07/28/broken-link-checker-095-alpha/</link>
		<comments>http://w-shadow.com/blog/2010/07/28/broken-link-checker-095-alpha/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 10:13:42 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[News and Rants]]></category>
		<category><![CDATA[broken link checker]]></category>
		<category><![CDATA[new features]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[public alpha]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress plugins]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1944</guid>
		<description><![CDATA[There&#8217;s a wicked thunderstorm coming this way, so I&#8217;ll keep this short. The next major release of the Broken Link Checker plugin is nearing completion. Some of the highest voted ideas have been implemented, the user interface has been re-worked and many bugs have been fixed. Interested? Play with the alpha version, check out new [...]]]></description>
			<content:encoded><![CDATA[<p><em>There&#8217;s a wicked thunderstorm coming this way, so I&#8217;ll keep this short.</em></p>
<p>The next major release of the Broken Link Checker plugin is nearing completion. Some of the <a href="http://feedback.w-shadow.com/forums/58400-broken-link-checker">highest voted ideas</a> have been implemented, the user interface has been re-worked and many bugs have been fixed. Interested? <a href="http://downloads.wordpress.org/plugin/broken-link-checker.zip">Play with the alpha version</a>, check out new features before anyone else, submit last-minute feedback. I&#8217;m especially interested in your thoughts about the new interface &#8211; layout, colours, wording.</p>
<h3>What&#8217;s New</h3>
<p>Implemented and available right now :</p>
<ul>
<li>Individually pick the types of content to check for links.</li>
<li>Check drafts, scheduled and private posts.</li>
<li>Colour-coded &#8220;Status&#8221; column in the link table.</li>
<li>Show/hide columns selectively.</li>
<li>&#8220;Compact&#8221; table view &#8211; each row becomes exactly two lines, no text wrapping. Slick.</li>
<li>Select how many links per page to display.</li>
<li>New URL editor.</li>
<li>Tabbed interface for the settings page.</li>
</ul>
<p>Implemented, but not yet public. Probably reserved for a &#8220;Pro&#8221; version :</p>
<ul>
<li>Check embedded YouTube, DailyMotion and Vimeo videos.</li>
<li>Specialized checker algorithms for RapidShare, Mediafire and MegaUpload links.</li>
<li>Custom post type support.</li>
<li>Check plaintext URLs.</li>
</ul>
<h3>Screenshots</h3>
<p>The new &#8220;Broken Links&#8221; page (click to enlarge) :</p>
<p><a href="http://w-shadow.com/wp-content/uploads/2010/07/blc-new-version-screenshot.png"></a><a href="http://w-shadow.com/wp-content/uploads/2010/07/blc-new-version-screenshot1.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-large wp-image-1950" title="Broken Link Checker - new &quot;Broken Links&quot; table" src="http://w-shadow.com/wp-content/uploads/2010/07/blc-new-version-screenshot1-490x301.png" alt="" width="490" height="301" /></a></p>
<p>The new settings page :</p>
<p><a href="http://w-shadow.com/wp-content/uploads/2010/07/blc-new-settings-page.png"></a><a href="http://w-shadow.com/wp-content/uploads/2010/07/blc-new-settings-page1.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-large wp-image-1951" title="Broken Link Checker - tabbed &quot;Settings&quot; page" src="http://w-shadow.com/wp-content/uploads/2010/07/blc-new-settings-page1-490x216.png" alt="" width="490" height="216" /></a></p>
<p>Thoughts?</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/07/28/broken-link-checker-095-alpha/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Add New Buttons Alongside &#8220;Screen Options&#8221; And &#8220;Help&#8221;</title>
		<link>http://w-shadow.com/blog/2010/06/30/add-new-buttons-alongside-screen-options-and-help/</link>
		<comments>http://w-shadow.com/blog/2010/06/30/add-new-buttons-alongside-screen-options-and-help/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 09:31:46 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[screen meta]]></category>
		<category><![CDATA[screen options]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress plugins]]></category>
		<category><![CDATA[wp]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1911</guid>
		<description><![CDATA[Continuing from yesterday&#8217;s post about adding custom settings to the &#8220;Screen Options&#8221; panel in WP, I will now show you how to add your own buttons alongside &#8220;Screen Options&#8221; and &#8220;Help&#8221;. But first, here are a few screenshots &#8211; to whet your appetite, so to speak. Want those neat buttons in your plugin? Read on. [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing from <a href="http://w-shadow.com/blog/2010/06/29/adding-stuff-to-wordpress-screen-options/">yesterday&#8217;s post</a> about adding custom settings to the &#8220;Screen Options&#8221; panel in WP, I will now show you how to add your own buttons alongside &#8220;Screen Options&#8221; and &#8220;Help&#8221;.</p>
<p>But first, here are a few screenshots &#8211; to whet your appetite, so to speak.</p>
<p><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1914" title="An example link" src="http://w-shadow.com/wp-content/uploads/2010/06/example-meta-link-1.png" alt="" width="352" height="87" /><br />
<img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1915" title="Meta buttons can be styled with CSS" src="http://w-shadow.com/wp-content/uploads/2010/06/more-colourful-meta-links-2.png" alt="" width="254" height="47" /><br />
<img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1913" title="Multiple custom links on one page" src="http://w-shadow.com/wp-content/uploads/2010/06/colourful-meta-links-3.png" alt="" width="361" height="50" /></p>
<p>Want those neat buttons in your plugin? Read on.</p>
<h3>Hackety-Hack</h3>
<p>The area that holds the &#8220;Screen Options&#8221; and &#8220;Help&#8221; links is internally known as &#8220;screen meta links&#8221;. There is no official API for adding new links to this area. Fortunately, the DOM structure that represents the buttons is relatively simple, so we can attach an extra button with just a few lines of JavaScript.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#screen-meta-links'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span>
		<span style="color: #3366CC;">'&lt;div id=&quot;my-screen-meta-link-wrap&quot; class=&quot;hide-if-no-js screen-meta-toggle&quot;&gt;'</span> <span style="color: #339933;">+</span>
			<span style="color: #3366CC;">'&lt;a href=&quot;http://example.com/&quot; id=&quot;my-screen-meta-link&quot; class=&quot;show-settings&quot;&gt;Foo&lt;/a&gt;'</span> <span style="color: #339933;">+</span>
		<span style="color: #3366CC;">'&lt;/div&gt;'</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>jQuery<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>You&#8217;ll also need to add some extra CSS to the page to make the new button show up correctly :</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">&lt;style type<span style="color: #00AA00;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span><span style="color: #00AA00;">&gt;</span>
<span style="color: #cc00cc;">#my-screen-meta-link-wrap</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">float</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">right</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">22px</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">6px</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">font-family</span><span style="color: #00AA00;">:</span> <span style="color: #ff0000;">&quot;Lucida Grande&quot;</span><span style="color: #00AA00;">,</span> Verdana<span style="color: #00AA00;">,</span> Arial<span style="color: #00AA00;">,</span> <span style="color: #ff0000;">&quot;Bitstream Vera Sans&quot;</span><span style="color: #00AA00;">,</span> <span style="color: #993333;">sans-serif</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#e3e3e3</span><span style="color: #00AA00;">;</span>
&nbsp;
	border-bottom-left-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">3px</span><span style="color: #00AA00;">;</span>
	border-bottom-right-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">3px</span><span style="color: #00AA00;">;</span>
	-moz-border-radius-bottomleft<span style="color: #00AA00;">:</span> <span style="color: #933;">3px</span><span style="color: #00AA00;">;</span>
	-moz-border-radius-bottomright<span style="color: #00AA00;">:</span> <span style="color: #933;">3px</span><span style="color: #00AA00;">;</span>
	-webkit-border-bottom-left-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">3px</span><span style="color: #00AA00;">;</span>
	-webkit-border-bottom-right-radius<span style="color: #00AA00;">:</span> <span style="color: #933;">3px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #cc00cc;">#my-screen-meta-link-wrap</span> a<span style="color: #6666ff;">.show-settings</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span><span style="color: #cc66cc;">0</span> <span style="color: #933;">6px</span> <span style="color: #cc66cc;">0</span> <span style="color: #933;">6px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&lt;/style<span style="color: #00AA00;">&gt;</span></pre></div></div>

<p>These style will make your button look just like the default ones &#8211; light-grey background and dark-grey text. You can easily modify the CSS to change your button&#8217;s appearance. For example, the green &#8220;Upgrade&#8221; link pictured in one of the above screenshots has the equivalent of these extra styles applied :</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #cc00cc;">#my-screen-meta-link-wrap</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#00C31F</span><span style="color: #00AA00;">;</span> 
<span style="color: #00AA00;">&#125;</span>
<span style="color: #cc00cc;">#my-screen-meta-link-wrap</span> a<span style="color: #6666ff;">.show-settings</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">font-weight</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">bold</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#DEFFD8</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">text-shadow</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #cc00cc;">#my-screen-meta-link-wrap</span> a<span style="color: #6666ff;">.show-settings</span><span style="color: #3333ff;">:hover </span><span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">white</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<h3>No API? Make one.</h3>
<p>Even such a simple hack can get cumbersome if you need to use it more than once or twice. After using it in several plugins, I went ahead and wrote a wrapper script that hides all the JS/CSS machinations behind a simple PHP interface. Here&#8217;s an example plugin that employs my custom API :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">/*
Plugin Name: Screen Meta Links Demo
Plugin URI: http://w-shadow.com/
Description: Demonstrates how to add new links alongside the &quot;Screen Options&quot; and &quot;Help&quot; links on Dashboard pages.
Version: 1.0
Author: Janis Elsts
Author URI: http://w-shadow.com/blog/
*/</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Load the custom button API</span>
<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'screen-meta-links.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Simple example. Adds a screen meta link to example.com </span>
<span style="color: #666666; font-style: italic;">//to the main Dashboard page.</span>
add_screen_meta_link<span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'meta-link-example2'</span><span style="color: #339933;">,</span>  <span style="color: #666666; font-style: italic;">//Link ID. Should be unique.  </span>
	<span style="color: #0000ff;">'Example Link'</span><span style="color: #339933;">,</span>        <span style="color: #666666; font-style: italic;">//Link text.</span>
	<span style="color: #0000ff;">'http://example.com/'</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">//URL</span>
	<span style="color: #0000ff;">'index.php'</span>            <span style="color: #666666; font-style: italic;">//Where to show the link. </span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Advanced example. Demonstrates how to add one link to </span>
<span style="color: #666666; font-style: italic;">//several different pages and how to set link attributes.</span>
add_screen_meta_link<span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'meta-link-example2'</span><span style="color: #339933;">,</span> 
	<span style="color: #0000ff;">'Advanced Link'</span><span style="color: #339933;">,</span> 
	<span style="color: #0000ff;">'http://example.com/'</span><span style="color: #339933;">,</span> 
	<span style="color: #666666; font-style: italic;">//An array of page/screen IDs specifying where to display the link. </span>
	<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'options-general.php'</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">//Settings -&gt; General	</span>
		<span style="color: #0000ff;">'post'</span><span style="color: #339933;">,</span>                <span style="color: #666666; font-style: italic;">//The post editor</span>
		<span style="color: #0000ff;">'page'</span><span style="color: #339933;">,</span>                <span style="color: #666666; font-style: italic;">//The page editor</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> 
	<span style="color: #666666; font-style: italic;">//Additional attributes for the link tag.</span>
	<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'target'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'_blank'</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Open &quot;http://example.com/&quot; in a new window'</span>
	<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>You can <a href="http://w-shadow.com/files/screen-meta-links-demo.zip">download a working example here</a>. The <code>screen-meta-links.php</code> file is included in the archive. Feel free to use it in your own plugins.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/06/30/add-new-buttons-alongside-screen-options-and-help/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Adding Stuff To WordPress &#8220;Screen Options&#8221;</title>
		<link>http://w-shadow.com/blog/2010/06/29/adding-stuff-to-wordpress-screen-options/</link>
		<comments>http://w-shadow.com/blog/2010/06/29/adding-stuff-to-wordpress-screen-options/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 11:33:48 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[filters]]></category>
		<category><![CDATA[hooks]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[screen options]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress plugins]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1893</guid>
		<description><![CDATA[The Screen Options pull-down is the perfect place for those &#8220;rarely used but nice to have&#8221; settings. It&#8217;s unobtrusive and saves screen space. Some plugins could even put all of their settings in this panel and avoid cluttering the Dashboard menu with yet another &#8220;Settings&#8221; page. While Screen Options were already present in older WP [...]]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://w-shadow.com/wp-content/uploads/2010/06/screen-options-button1.png" alt="" title="The &quot;Screen Options&quot; button" width="210" height="85" class="alignright size-full wp-image-1903" />The <em>Screen Options</em> pull-down is the perfect place for those &#8220;rarely used but nice to have&#8221; settings. It&#8217;s unobtrusive and saves screen space. Some plugins could even put all of their settings in this panel and avoid cluttering the Dashboard menu with yet another &#8220;Settings&#8221; page.</p>
<p>While <em>Screen Options</em> were already present in older WP versions, only the latest 3.0 release finally introduced a sane way to add your own content to this panel &#8211; the <code>screen_settings</code> filter. This filter is completely undocumented, so I thought it would be helpful to create a short tutorial on how to use it. Hence this post.</p>
<h3>The screen_settings Filter</h3>
<p>This <code>screen_settings</code> filter is applied to the additional HTML code that is to be appended to the <em>Screen Options</em> box. The callback function attached to this filter will receive two arguments: the current HTML code and an undocumented &#8220;screen object&#8221;. This object represents the current Dashboard screen. It has an &#8220;id&#8221; property which can be used to figure out which page/screen you&#8217;re on and only attach your extra HTML to specific pages.</p>
<p>Note that a &#8220;screen&#8221; is not the same thing as a page or a menu. For example, both the &#8220;Add Post&#8221; and &#8220;Edit Post&#8221; pages are considered to be the same screen. Luckily, in most cases you can (ab)use the <code>convert_to_screen</code> function to convert the page slug to a screen object. You can then compare the converted object&#8217;s and the current screen&#8217;s &#8220;id&#8221; attributes to check what page your script is executing on.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">add_filter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'screen_settings'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'screen_options_demo'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">function</span> screen_options_demo<span style="color: #009900;">&#40;</span><span style="color: #000088;">$current</span><span style="color: #339933;">,</span> <span style="color: #000088;">$screen</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$desired_screen</span> <span style="color: #339933;">=</span> convert_to_screen<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'plugins.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$desired_screen</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$current</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">&quot;Hello WordPress!&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$current</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The above code will append the line &#8220;Hello WordPress!&#8221; to the <em>Screen Options</em> box on the <em>Plugins</em> page.</p>
<p><a href="http://w-shadow.com/wp-content/uploads/2010/06/screen_settings-filter-example1.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  src="http://w-shadow.com/wp-content/uploads/2010/06/screen_settings-filter-example1-490x123.png" alt="" title="screen_settings filter example" width="490" height="123" class="aligncenter size-large wp-image-1904" /></a></p>
<p>For some pages &#8211; e.g. the main Dashboard page and post/page editor &#8211; you&#8217;ll need to figure out the corresponding screen ID by yourself. See the <code>set_current_screen</code> function in <code>/wp-includes/template.php</code> for clues.</p>
<p>If you specify a page that doesn&#8217;t have its own screen options, the <em>Screen Options</em> box will be added automatically and its contents will be set to the HTML code returned by your callback function. You can also compare the screen id against the hook name returned by <code>add_submenu_page</code> and its ilk to display custom screen options on plugin pages. </p>
<h3>A More Convenient Form</h3>
<p>Personally, I think the screen_settings filter is too low-level for most situations. Do you really want your callback to be executed on each and every admin page, and worry about converting between &#8220;pages&#8221; and the undocumented &#8220;screens&#8221;? And then duplicate that code (<em>boo!</em>) in each new plugin where you want to use this WP feature? Also, the extra settings fields added via this filter lack the tasty AJAX autosave feature used by the native screen options fields, which means you&#8217;d have to reimplement that as well.</p>
<p>With that in mind, I wrote a wrapper script that handles all that for you. The script has one public function named <code>add_screen_options_panel</code> which makes adding extra screen options panels as easy as adding extra menus. The function takes these arguments :</p>
<ul>
<li><strong>id</strong> &#8211; the string to use in the &#8216;id&#8217; attribute of the settings panel. Should be unique.</li>
<li><strong>title</strong> &#8211; Title of your new settings panel. Set to an empty string to omit title.</li>
<li><strong>callback</strong> &#8211; Function that fills the panel with the desired content. Should return a string of HTML.</li>
<li><strong>page</strong> &#8211; The page(s) on which to show the panel.  This can be either a string specifying a single page file name (e.g. &#8220;plugins.php&#8221;) or the hook name returned by add_submenu_page (e.g. &#8220;settings_page_my_plugin&#8221;), or an array of page filenames/hook names.</li>
<li><strong>save_callback</strong> &#8211; Optional. The name of the function that will save the settings contained in the panel.</li>
<li><strong>autosave</strong> &#8211; Optional. If set to true, panel contents will be automatically submitted (via AJAX) when the value of any field in the panel changes, and the specified save_callback function will be called with the field values. Defaults to false.</li>
</ul>
<p>Here&#8217;s an example of how this function is used in the latest version of <a href="http://wordpress.org/extend/plugins/raw-html/">my Raw HTML plugin</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'screen-options/screen-options.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Add our panel to the &quot;Screen Options&quot; box</span>
add_screen_options_panel<span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'rawhtml-default-settings'</span><span style="color: #339933;">,</span>       <span style="color: #666666; font-style: italic;">//Panel ID</span>
	<span style="color: #0000ff;">'Raw HTML defaults'</span><span style="color: #339933;">,</span>              <span style="color: #666666; font-style: italic;">//Panel title. </span>
	<span style="color: #0000ff;">'rawhtml_default_settings_panel'</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">//The function that generates panel contents.</span>
	<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'post'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'page'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>            <span style="color: #666666; font-style: italic;">//Pages/screens where the panel is displayed. </span>
	<span style="color: #0000ff;">'rawhtml_save_new_defaults'</span><span style="color: #339933;">,</span>      <span style="color: #666666; font-style: italic;">//The function that gets triggered when settings are submitted/saved.</span>
	<span style="color: #009900; font-weight: bold;">true</span>                              <span style="color: #666666; font-style: italic;">//Auto-submit settings (via AJAX) when they change. </span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* ...more code here...  */</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Generate the &quot;Raw HTML defaults&quot; panel for Screen Options.
 * 
 * @return string
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> rawhtml_default_settings_panel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$defaults</span> <span style="color: #339933;">=</span> rawhtml_get_default_settings<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Output checkboxes </span>
	<span style="color: #000088;">$fields</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'disable_wptexturize'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Disable wptexturize'</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'disable_wpautop'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Disable automatic paragraphs'</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'disable_convert_chars'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Disable convert_chars'</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'disable_convert_smilies'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Disable smilies'</span><span style="color: #339933;">,</span>
	 <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
 	<span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fields</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$field</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$legend</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$esc_field</span> <span style="color: #339933;">=</span> esc_attr<span style="color: #009900;">&#40;</span><span style="color: #000088;">$field</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$output</span> <span style="color: #339933;">.=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'&lt;label for=&quot;rawhtml_default-%s&quot; style=&quot;line-height: 20px;&quot;&gt;
				&lt;input type=&quot;checkbox&quot; name=&quot;rawhtml_default-%s&quot; id=&quot;rawhtml_default-%s&quot;%s&gt;
				%s
			&lt;/label&gt;&lt;br&gt;'</span><span style="color: #339933;">,</span>
			<span style="color: #000088;">$esc_field</span><span style="color: #339933;">,</span>
			<span style="color: #000088;">$esc_field</span><span style="color: #339933;">,</span>
			<span style="color: #000088;">$esc_field</span><span style="color: #339933;">,</span>
			<span style="color: #009900;">&#40;</span><span style="color: #000088;">$defaults</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$field</span><span style="color: #009900;">&#93;</span>?<span style="color: #0000ff;">' checked=&quot;checked&quot;'</span><span style="color: #339933;">:</span><span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
			<span style="color: #000088;">$legend</span>
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$output</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Process the &quot;Raw HTML defaults&quot; form fields and save new settings
 * 
 * @param array $params
 * @return void
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> rawhtml_save_new_defaults<span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">//Get current defaults</span>
	<span style="color: #000088;">$defaults</span> <span style="color: #339933;">=</span> rawhtml_get_default_settings<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Read new values from the submitted form</span>
	<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$defaults</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$field</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$old_value</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'rawhtml_default-'</span><span style="color: #339933;">.</span><span style="color: #000088;">$field</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'rawhtml_default-'</span><span style="color: #339933;">.</span><span style="color: #000088;">$field</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'on'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$defaults</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$field</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$defaults</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$field</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Store the new defaults</span>
	rawhtml_set_default_settings<span style="color: #009900;">&#40;</span><span style="color: #000088;">$defaults</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And here&#8217;s the result :</p>
<p><a href="http://w-shadow.com/wp-content/uploads/2010/06/Raw-HTML-screen-options2.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  src="http://w-shadow.com/wp-content/uploads/2010/06/Raw-HTML-screen-options2-490x239.png" alt="" title="RawHTML screen options" width="490" height="239" class="aligncenter size-large wp-image-1905" /></a></p>
<p>You can <a href="http://w-shadow.com/files/screen-options.zip">download the wrapper script here</a>. To use it in your plugin, just drop the &#8220;screen-options&#8221; folder into your plugin&#8217;s directory and <code>include</code> the screen-options.php file. Then call the <code>add_screen_options_panel</code> function as described above. </p>
<p>Bonus: the file is structured in a way that lets multiple plugins execute it without causing conflicts <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/06/29/adding-stuff-to-wordpress-screen-options/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Feedback Forums For My WP Plugins</title>
		<link>http://w-shadow.com/blog/2010/05/24/feedback-forums-for-my-wp-plugins/</link>
		<comments>http://w-shadow.com/blog/2010/05/24/feedback-forums-for-my-wp-plugins/#comments</comments>
		<pubDate>Mon, 24 May 2010 11:59:33 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[News and Rants]]></category>
		<category><![CDATA[announcement]]></category>
		<category><![CDATA[feature suggestions]]></category>
		<category><![CDATA[forum]]></category>
		<category><![CDATA[user feedback]]></category>
		<category><![CDATA[UserVoice]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress plugins]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1847</guid>
		<description><![CDATA[I&#8217;ve created UserVoice forums for a couple of my most popular WordPress plugins. You can use them to post your ideas and feature suggestions, as well as view suggestions posted by other users and vote/comment on them. Here are the currently available forums : Broken Link Checker forum Admin Menu Editor forum Eclipse Link Cloaker [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve created UserVoice forums for a couple of my most popular WordPress plugins. You can use them to post your ideas and feature suggestions, as well as view suggestions posted by other users and vote/comment on them. Here are the currently available forums :</p>
<ul>
<li><a href="http://feedback.w-shadow.com/forums/58400-broken-link-checker">Broken Link Checker forum</a></li>
<li><a href="http://feedback.w-shadow.com/forums/58572-admin-menu-editor">Admin Menu Editor forum</a></li>
<li><a href="http://feedback.w-shadow.com/forums/58574-eclipse-link-cloaker">Eclipse Link Cloaker forum</a></li>
</ul>
<p>If you use any of these plugins and you think that they could be improved, head over to the corresponding forum and post your idea!</p>
<p>Even if you&#8217;ve already sent me your suggestion using e-mail or blog comments, you should still go to the appropriate forum and post it there. This will give other users the opportunity to vote and comment on them. Suggestions that are supported by multiple users are likely to be implemented much sooner than they would otherwise be <img src='http://w-shadow.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>If this catches on I will eventually create feedback forums for my other WordPress plugins.</p>
<p>On a completely unrelated note, here is a picture of a playful feline :</p>
<p style="text-align: center;"><a href="http://w-shadow.com/wp-content/uploads/2010/05/Cat-with-a-WP-ball.jpg"></a><a href="http://w-shadow.com/wp-content/uploads/2010/05/Cat-with-a-WP-ball-wc.jpg"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-large wp-image-1853" title="Kittens are a memetic hazard." src="http://w-shadow.com/wp-content/uploads/2010/05/Cat-with-a-WP-ball-wc-489x326.jpg" alt="" width="489" height="326" /></a> <em>(Clicken sie das bild to enlarge)</em></p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/05/24/feedback-forums-for-my-wp-plugins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Filter The Whole Page In WordPress</title>
		<link>http://w-shadow.com/blog/2010/05/20/how-to-filter-the-whole-page-in-wordpress/</link>
		<comments>http://w-shadow.com/blog/2010/05/20/how-to-filter-the-whole-page-in-wordpress/#comments</comments>
		<pubDate>Thu, 20 May 2010 13:55:49 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[hook]]></category>
		<category><![CDATA[output buffering]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1827</guid>
		<description><![CDATA[WordPress has numerous hooks for filtering posts, comments, feed items and more, but no built-in filter that would let you intercept and modify an entire page. However, you can do that fairly easily with PHP&#8217;s output buffering functions. Today I&#8217;m going to show you how. Crash-Course In Output Buffering As the name implies, output buffering [...]]]></description>
			<content:encoded><![CDATA[<p>WordPress has numerous hooks for filtering posts, comments, feed items and more, but no built-in filter that would let you intercept and modify an entire page. However, you can do that fairly easily with PHP&#8217;s <a href="http://php.net/manual/en/book.outcontrol.php">output buffering functions</a>. Today I&#8217;m going to show you how.</p>
<h3>Crash-Course In Output Buffering</h3>
<p>As the name implies, output buffering lets you buffer the output of a PHP script.  Once you initialize a buffer using the <a href="http://php.net/manual/en/function.ob-start.php"><code>ob_start()</code> function</a>, any output that would normally be sent to the browser is stored in the buffer instead (exception : HTTP headers are still sent immediately). You can then process the buffer&#8217;s contents and send a modified version to the browser, or discard the buffer entirely if you like. PHP will also automatically <abbr title="send to the browser">flush</abbr> any active buffers at the end of the script&#8217;s execution.</p>
<p>One of the ways to manipulate the output is to create a callback function that takes the current contents of the buffer and returns a new buffer. Then you just pass the function name to <code>ob_start()</code> and it will be automatically called when the buffer is flushed or cleaned. This is the method that we&#8217;ll use to filter WP-generated pages.</p>
<h3>Filtering WordPress Pages</h3>
<p>Enough with theory, lets see some code! Here&#8217;s a simple example plugin that uses output buffering to attach the current URL and page size to each page generated by WordPress :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">/*
Plugin Name: Page Filter Example
Plugin URI: http://w-shadow.com/blog/2010/05/20/how-to-filter-the-whole-page-in-wordpress/
Description: Demonstrates how to filter the entire page in WordPres. 
Version: 1.0
Author: Janis Elsts
Author URI: http://w-shadow.com/
*/</span>
&nbsp;
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Initialize output buffering.
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> ws_set_up_buffer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">//Don't filter Dashboard pages and the feed</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> is_feed<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> is_admin<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #666666; font-style: italic;">//Start buffering. Note that we don't need to</span>
	<span style="color: #666666; font-style: italic;">//explicitly close the buffer - WP will do that</span>
	<span style="color: #666666; font-style: italic;">//for use in the &quot;shutdown&quot; hook.</span>
	<span style="color: #990000;">ob_start</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ws_filter_page'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'wp'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'ws_set_up_buffer'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Buffer callback.
 *
 * @param string $html Current contents of the output buffer.
 * @return string New buffer contents.
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> ws_filter_page<span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">//As an example, lets append the current URI</span>
	<span style="color: #666666; font-style: italic;">//and page size to the generated HTML.</span>
	<span style="color: #000088;">$info</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">&quot;&lt;!-- <span style="color: #000099; font-weight: bold;">\n</span>Page : <span style="color: #009933; font-weight: bold;">%s</span><span style="color: #000099; font-weight: bold;">\n</span>HTML size : <span style="color: #009933; font-weight: bold;">%d</span> bytes<span style="color: #000099; font-weight: bold;">\n</span> --&gt;&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REQUEST_URI'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$html</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$info</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<h3>Tips and Notes</h3>
<p>There are some things to keep in mind when using output buffering to filter WordPress pages.</p>
<ul>
<li>You probably don&#8217;t want to filter <em>each and every</em> page. For example, the Dashboard and the RSS feed should most likely be excluded (unless you&#8217;re specifically targeting them, of course). Use <a href="http://codex.wordpress.org/Conditional_Tags">conditional tags</a> to check whether the current request refers to one of those pages.</li>
<li>Many conditional tags won&#8217;t work properly until after WP has finished parsing the current request. To mitigate this, attach your buffer initialization routine to an action that runs after the query has already been parsed. The &#8220;wp&#8221; action is a good choice.</li>
<li>You don&#8217;t need to explicitly close/flush your output buffer &#8211; WordPress will do that automatically. See <code>wp_ob_end_flush_all()</code> in <code>/wp-includes/functions.php</code>.</li>
<li>Beware of conflicts with optimization-related plugins. To make pages load faster, some of them will set up their own buffer and compress page contents with the gzip algorithm. This can make those pages appear as unreadable gibberish to your script. To avoid that, make sure your buffer is initialized <em>after</em> the other plugin&#8217;s buffer. Some hook priority tweaking may be required.</li>
</ul>
<p>And now you know how to filter the whole WP page <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/05/20/how-to-filter-the-whole-page-in-wordpress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrating WP.org Plugin Ratings Into The Dashboard</title>
		<link>http://w-shadow.com/blog/2010/05/17/integrating-wp-org-plugin-ratings-into-the-dashboard/</link>
		<comments>http://w-shadow.com/blog/2010/05/17/integrating-wp-org-plugin-ratings-into-the-dashboard/#comments</comments>
		<pubDate>Mon, 17 May 2010 12:27:04 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[compatibility]]></category>
		<category><![CDATA[plugin compatibility]]></category>
		<category><![CDATA[ratings]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress plugins]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1820</guid>
		<description><![CDATA[The WordPress.org plugin directory has a neat rating system that lets users rate plugins both on overall quality and on compatibility with specific WP versions. However, its usefulness is stymied by poor integration with WordPress itself. To try to remedy that, I&#8217;ve created a plugin that lets you vote on plugins directly from your Dashboard. [...]]]></description>
			<content:encoded><![CDATA[<p>The WordPress.org plugin directory has a neat rating system that lets users rate plugins both on overall quality and on compatibility with specific WP versions. However, <a href="http://w-shadow.com/blog/2010/03/25/only-2-of-wordpress-plugins-compatible-for-sure/">its usefulness is stymied</a> by poor integration with WordPress itself. To try to remedy that, I&#8217;ve created a plugin that lets you vote on plugins directly from your Dashboard.</p>
<p>Here&#8217;s a screenshot (click to enlarge) : <a href="http://w-shadow.com/wp-content/uploads/2010/05/vote-for-plugins-screenshot.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-large wp-image-1821" title="WordPress.org rating integration" src="http://w-shadow.com/wp-content/uploads/2010/05/vote-for-plugins-screenshot-489x285.png" alt="" width="489" height="285" /></a></p>
<p>To begin, you&#8217;ll need to enter your WordPress.org account credentials in <em>Plugins -&gt; WordPress.org Account</em>. This is necessary because only registered users can vote on plugins in the official plugin directory. When that&#8217;s done, the plugin will add the star rating widget and the &#8220;Works&#8221; and &#8220;Broken&#8221; buttons from the WordPress.org directory to each plugin listed in the &#8220;Installed Plugins&#8221; tab, allowing you to rate and vote on them without leaving the Dashboard.</p>
<p>The plugin will also attempt to retrieve your past ratings from WordPress.org and pre-fill the rating widgets with your current votes.</p>
<h3>Download</h3>
<p><a href="http://w-shadow.com/files/vote-for-plugins.zip"><strong>vote-for-plugins.zip</strong></a> (17 KB)</p>
<p><strong>Requirements</strong></p>
<ul>
<li>PHP 5</li>
<li>WordPress 2.9+</li>
</ul>
<p><strong>Installation</strong></p>
<ol>
<li>Upload and activate.<strong> </strong></li>
<li>Go to <em>Plugins -&gt; WordPress.org Account</em> and enter your WordPress.org user name and password.</li>
<li>Go to <em>Plugins -&gt; Installed Plugins</em> and cast yer&#8217; votes <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ol>
<h3>Known Issues &amp; To Do</h3>
<ul>
<li>When you first install &#8220;Vote For Plugins&#8221; it doesn&#8217;t know which of your plugins are listed in the official directory (and thus can be voted on) and which aren&#8217;t. So it tries to err on the side of optimism and may initially add the rating widgets to some plugins that can&#8217;t actually be rated.</li>
<li>Fetching past ratings takes longer than it should.</li>
<li>Voting on several plugins at a time would be handy.</li>
</ul>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/05/17/integrating-wp-org-plugin-ratings-into-the-dashboard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AdSense Experiment : The Follow-Up</title>
		<link>http://w-shadow.com/blog/2010/04/29/adsense-experiment-the-follow-up/</link>
		<comments>http://w-shadow.com/blog/2010/04/29/adsense-experiment-the-follow-up/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 19:28:15 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Making Money]]></category>
		<category><![CDATA[adsense]]></category>
		<category><![CDATA[AdSense optimization]]></category>
		<category><![CDATA[CTR]]></category>
		<category><![CDATA[eCPM]]></category>
		<category><![CDATA[search engine visitors]]></category>
		<category><![CDATA[stats]]></category>
		<category><![CDATA[traffic sources]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1809</guid>
		<description><![CDATA[Way back in March, I conducted a little AdSense experiment to see which type of visitors (direct, coming from internal or external pages, or arriving from search engines) were most likely to click on ads. It turned out that internal visitors &#8211; that is, people coming from another page on the same site &#8211; were [...]]]></description>
			<content:encoded><![CDATA[<p>Way back in March, I conducted <a href="http://w-shadow.com/blog/2010/03/18/adsense-experiment-results/">a little AdSense experiment</a> to see which type of visitors (direct, coming from internal or external pages, or arriving from search engines) were most likely to click on ads. It turned out that internal visitors &#8211; that is, people coming from another page on the same site &#8211; were the ones most likely to peruse AdSense ads. This result was contrary to the popular assumption that search engine visitors are the most eager ad-clickers.</p>
<p>Does this unconventional conclusion remain true  in the long-term? Today I&#8217;m going to post a follow-up study that discusses just that. The long-term results were&#8230; different.</p>
<h3>Newly Charted</h3>
<p>As of today, the <a href="http://w-shadow.com/blog/2010/03/09/showing-different-ads-to-different-visitors/">visitor segmentation script</a> has collected 52 days&#8217; worth of data. This is five times the duration of the previous experiment (which lasted just over a week), so the results presented below are presumably much more accurate that those I posted <a href="http://w-shadow.com/blog/2010/03/18/adsense-experiment-results/">last time</a>.</p>
<p>Without further ado, here&#8217;s the updated CTR chart :</p>
<p><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1810" title="Follow-up : CTR by Traffic Source" src="http://w-shadow.com/wp-content/uploads/2010/04/Followup-CTR-by-Traffic-Source.png" alt="" width="485" height="445" /></p>
<p style="text-align: center;"><em>Units hidden to comply with AdSense ToS.</em></p>
<p style="text-align: left;">The updated study shows that visitors arriving from external sites (except search engines) are those who yield highest click-through rate. In the previous analysis, this group occupied the second-to-last spot. Internal visitors, who were the previous &#8220;leaders&#8221; &#8211; if one may use that word to describe people very likely to click on Internet ads &#8211; now fall into the second place. Search engine visitors come third. Finally, direct visitors &#8211; i.e. people who arrive via browser bookmarks or by typing in the URL &#8211; are still the least likely to create advertising income.</p>
<p style="text-align: left;">Here&#8217;s a chart comparing the old and new results :</p>
<p style="text-align: center;"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1811" title="CTR comparison" src="http://w-shadow.com/wp-content/uploads/2010/04/Followup-CTR-changes.png" alt="" width="485" height="445" /></p>
<p style="text-align: center;"><em>Darker shades represent the previous results, lighter ones &#8211; updated research.</em></p>
<p style="text-align: left;">Of course, we also need to consider eCPM. eCPM represents the average earnings per 1000 impressions. Again, I can&#8217;t show you the actual numbers due to AdSense rules, but this chart should give you a general idea of the relative financial value of various traffic sources :</p>
<p style="text-align: left;"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1812" title="Follow-up : eCPM by Traffic-Source" src="http://w-shadow.com/wp-content/uploads/2010/04/Followup-eCPM-by-Traffic-Source.png" alt="" width="485" height="445" /></p>
<p style="text-align: left;">Interestingly, this is pretty close to what we saw in the previous study &#8211; internal visitors generate the most valuable clicks. External and search visitors share the second spot, and direct traffic is the least valuable advertising-wise.</p>
<p style="text-align: left;">Here&#8217;s a comparison with the previous results :</p>
<p style="text-align: center;"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1813" title="eCPM changes" src="http://w-shadow.com/wp-content/uploads/2010/04/Followup-eCPM-changes.png" alt="" width="485" height="445" /><em>The past is dark, the present light. Future not shown.</em></p>
<h3>Conclusions<em> </em></h3>
<p>Despite<em> </em>the updated rankings, the overall conclusion is the same one I arrived to last time &#8211; on this site, the CTR of search, external and internal visitors is very close. Showing ads only to one kind of visitors wouldn&#8217;t make much sense.</p>
<p>Likewise, the main take-away for other AdSense users is still this : don&#8217;t rely blindly on stuff you read on a blog somewhere; test any suggested optimization techniques yourself.</p>
<p>I think that the fact that I got slightly different results this time only reinforces the validity of that advice <img src='http://w-shadow.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/04/29/adsense-experiment-the-follow-up/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Broken Link Checker 0.9 &#8211; Almost There</title>
		<link>http://w-shadow.com/blog/2010/04/13/broken-link-checker-9-almost-there/</link>
		<comments>http://w-shadow.com/blog/2010/04/13/broken-link-checker-9-almost-there/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 09:53:06 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[News and Rants]]></category>
		<category><![CDATA[broken link checker]]></category>
		<category><![CDATA[new features]]></category>
		<category><![CDATA[plugin updates]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress plugins]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1798</guid>
		<description><![CDATA[After two weeks of full-time work on Broken Link Checker, I am delighted (and somewhat relieved) to say that the next version of the plugin is almost ready to go. The upcoming release will include many frequently requested features like email notifications, checking comment links, Cron support and better handling of false positives. If you&#8217;re [...]]]></description>
			<content:encoded><![CDATA[<p>After two weeks of full-time work on Broken Link Checker, I am delighted (and somewhat relieved) to say that the next version of the plugin is almost ready to go. The upcoming release will include many frequently requested features like email notifications, checking comment links, Cron support and better handling of false positives.</p>
<p>If you&#8217;re feeling courageous, you can <a href="http://downloads.wordpress.org/plugin/broken-link-checker.zip">download the in-development version</a> and try out the new features right now, bugs and all. The final &amp; reasonably stable version should be ready in a week or so.</p>
<p>You can find a full list of new features and changes below. Any user suggestions <em>not</em> on this list won&#8217;t get implemented for v. 0.9, but they still remain on my to-do/idea list for the plugin, and may well be realized eventually.</p>
<h3>What&#8217;s New</h3>
<p>The big changes :</p>
<ul>
<li>Checking comment links.</li>
<li>Email notifications.</li>
<li>Run the link checker when you&#8217;re not logged in (via Cron).</li>
<li>Recheck selected links via Bulk Actions.</li>
<li>Suspend checking if the server is overloaded.</li>
<li>The confusing &#8220;Discard&#8221; button is gone; replaced by a &#8220;Not broken&#8221; action link.</li>
<li>Better handling of false positives. If you mark a link as &#8220;Not broken&#8221;, the plugin will memorize the server response that made it think the link was broken, and treat the link as working unless/until it gets a <em>different</em> response when it checks that link again.</li>
<li>Support for custom checking algorithms, e.g. for dealing with YouTube and RapidShare links (not implemented yet, but the required scaffolding is there).</li>
</ul>
<p>The minor stuff :</p>
<ul>
<li>Additional icons (from <a href="http://www.famfamfam.com/">FamFamFam</a>) for the link table.</li>
<li>The &#8220;Delete sources&#8221; action asks for confirmation before deleting anything.</li>
<li>Long HTTP headers in the log no longer cause the &#8220;Details&#8221; section to expand ridiculously.</li>
<li>FTP, mailto:, javascript: and other links with unsupported protocols now show up in the &#8220;All links&#8221; table.</li>
<li>The rarely used &#8220;Exclude&#8221; link is gone. You can still exclude links by adding the URL or domain to the exclusion list in settings.</li>
<li>Editing links via the plugin&#8217;s interface creates new post revisions (where applicable), so you can revert the changes if something goes wrong.</li>
<li>Searching by link text now uses simple pattern matching, not full-text search.</li>
<li>Added Czech translation.</li>
<li>Requirements upped to WP 2.9+</li>
</ul>
<h3>To Do</h3>
<p>Things that need to be done before the final release :</p>
<ul>
<li>Test and tweak email notifications.</li>
<li>Test and tweak load limiting.</li>
<li>Update localization files.</li>
<li>Make &#8220;Trash&#8221; links use AJAX, where possible.</li>
<li>Obsess over the wording of error messages.</li>
<li>Code clean-up.</li>
</ul>
<ul></ul>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/04/13/broken-link-checker-9-almost-there/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
	</channel>
</rss>
