<?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>Keighl &#187; Blog</title>
	<atom:link href="http://www.keighl.com/category/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.keighl.com</link>
	<description>I provide creative web solutions for all kinds of people.</description>
	<lastBuildDate>Wed, 14 Apr 2010 15:03:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Switching Visual/HTML Modes With TinyMCE</title>
		<link>http://www.keighl.com/2010/04/switching-visualhtml-modes-with-tinymce/</link>
		<comments>http://www.keighl.com/2010/04/switching-visualhtml-modes-with-tinymce/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 14:59:15 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[rich editor]]></category>
		<category><![CDATA[tinymce]]></category>
		<category><![CDATA[visual html]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wp_tiny_mce]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=1524</guid>
		<description><![CDATA[A simple way to turn the rich-editor on and off in your WordPress plugin, and allow users to edit the HTML.]]></description>
			<content:encoded><![CDATA[<p>One of the greatest parts of the WordPress interface is the flexibility it gives us from within the editing screen. As a user, I can write this post using the rich-editor (<a href="tinymce.moxiecode.com/" target="_blank">TinyMCE</a>), or switch to <em>HTML</em> mode to edit the markup directly. I&#8217;ve received a handful of comments on my previous post regarding <a href="http://www.keighl.com/2010/01/tinymce-in-wordpress-plugins/">TinyMCE in WordPress Plugins</a> asking how to go about incorporating this flexibility into plugins.</p>
<p>TinyMCE has a few built-in methods that allow you to turn the editor on and off; essentially this is all you have to do to switch between the two modes. It is not, however, a second interface. The WordPress editor actually has two rich-editors: one for <em>Visual</em>, and one for <em>HTML</em>. Instead of turning  off TinyMCE, WordPress merely switches the rich-editors. That&#8217;s why you see those nice formatting buttons even through, you&#8217;re in <em>HTML</em> mode. Accomplishing that type of functionality is difficult. You can see the complexity of the custom <code>switchEditors</code> method in <a href="http://core.trac.wordpress.org/browser/trunk/wp-admin/js/editor.dev.js" target="_blank">editor.dev.js</a>.</p>
<p>Too much to cover. For now, I will simply show you how to turn the rich-editor on and off. First, set up a basic TinyMCE editor. This code builds of my other <a href="http://www.keighl.com/2010/01/tinymce-in-wordpress-plugins/">post</a>. There you can find a more complete description of what&#8217;s going on. In short, though, <code>wp_tiny_mce()</code> does all the initialization for you, and queues it on the page. This example could exist on a <a href="http://codex.wordpress.org/Creating_Options_Pages" target="_blank">plugin options page</a>, the profile editor, a <a href="http://codex.wordpress.org/Function_Reference/add_meta_box" target="_blank">post metabox</a>, or really anywhere you want users to rich-edit.</p>
<pre class="brush: php; html-script: true;">
&lt;?php
wp_tiny_mce( false , // true makes the editor &quot;teeny&quot;
	array(
		&quot;editor_selector&quot; =&gt; &quot;foo&quot;,
                &quot;height&quot; =&gt; 150
	)
);
?&gt;

&lt;textarea class=&quot;foo&quot; id=&quot;foo&quot; name=&quot;foo&quot;&gt;&lt;/textarea&gt;
</pre>
<p>Although you must setup the editor for your plugin using <code>wp_tiny_mce()</code>, the regular TinyMCE methods are all available to call from some custom JavaScript. The ones you want to be concerned with are <a href="http://wiki.moxiecode.com/index.php/TinyMCE:Commands" target="_blank"><code>mceAddControl</code></a> and <a href="http://wiki.moxiecode.com/index.php/TinyMCE:Commands" target="_blank"><code>mceRemoveControl</code></a>. If you spent any time digging through editor.dev.js, you would notice that the complex WordPress switcher still uses these methods.</p>
<p>Above the textarea, stick some links that will act as our switchboard:</p>
<pre class="brush: xml;">
&lt;p align=&quot;right&quot;&gt;
	&lt;a class=&quot;button toggleVisual&quot;&gt;Visual&lt;/a&gt;
	&lt;a class=&quot;button toggleHTML&quot;&gt;HTML&lt;/a&gt;
&lt;/p&gt;
&lt;textarea class=&quot;foo&quot; id=&quot;foo&quot; name=&quot;foo&quot;&gt;&lt;/textarea&gt;
</pre>
<p>Now, write some simple jQuery that adds the switching functionality. You could <a href="http://codex.wordpress.org/Function_Reference/wp_enqueue_script">enqueue</a> this as a separate file, or place it with the textarea.</p>
<pre class="brush: jscript;">
jQuery(document).ready(function($) {

	var id = 'foo';

	$('a.toggleVisual').click(
		function() {
			tinyMCE.execCommand('mceAddControl', false, id);
		}
	);

	$('a.toggleHTML').click(
		function() {
			tinyMCE.execCommand('mceRemoveControl', false, id);
		}
	);

});
</pre>
<p>The buttons now add or remove the rich-editor respectively. You will notice that, when in <em>HTML</em> mode, the textarea resolves to a very small box. To combat this problem, simply give it some <code>rows</code> and <code>cols</code> markup, or style it with CSS.</p>
<p>Another route in you could take  is a <strong>single button</strong> that toggles the editor on or off. I use this in my <a href="http://www.keighl.com/plugins/tinymce-signature/">TinyMCE Signature</a> plugin. It&#8217;s not terribly different; just add some logic.</p>
<pre class="brush: jscript;">
jQuery(document).ready(function($) {

	$('a.toggleEditor').click(
		function() {
			id = 'foo';
			if (tinyMCE.get(id)) {
				tinyMCE.execCommand('mceRemoveControl', false, id);	}
			else {
				tinyMCE.execCommand('mceAddControl', false, id);
			}
		}
	);

});
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2010/04/switching-visualhtml-modes-with-tinymce/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Nonce and AJAX</title>
		<link>http://www.keighl.com/2010/04/nonce-and-ajax/</link>
		<comments>http://www.keighl.com/2010/04/nonce-and-ajax/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 04:05:55 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[nonce]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=1505</guid>
		<description><![CDATA[Verify data passed through an AJAX request using the WordPress Nonce system. Not hard!]]></description>
			<content:encoded><![CDATA[<p>In the WordPress plugin API, <a href="http://codex.wordpress.org/WordPress_Nonces" target="_blank">Nonce</a> is a way to verify that data passed to/from a plugin is from a trusted source. <a href="http://markjaquith.wordpress.com/2006/06/02/wordpress-203-nonces/" target="_blank">Mark Jaquith</a> can explain this better than I can:</p>
<blockquote><p>&#8220;A nonce is a <strong>n</strong>umber used <strong>once</strong>, and it  is used for intention verification purposes in WordPress.  Think of it  as a password that changes each time it is used. [...] The idea is simple: we verify that user’s request is intentional by  verifying that the request originates from within the WordPress admin.&#8221;</p></blockquote>
<p>WordPress ships with a handful of convenient functions that help you create and verify Nonces. They are chiefly designed for synchronous use, or where data is passed from one web page to another using an HTTP request. You create a nonce in your initial form using <code>wp_nonce_field()</code> and then verify that nonce is correct in the method that handles the form with <code>check_admin_referer()</code>. It&#8217;s fairly straight forward and well documented.</p>
<p>However, what if you want to secure your AJAX (asynchronous) transaction with Nonce? With a simple glance at the code, an evil-doer could still send some irresponsible data to your plugin. You can approach the problem with the same theoretical mindset as a normal nonce: pass a code, check it, carry on. The main difference here is how we pass the nonce code.</p>
<p>Let&#8217;s imagine we have a very simple bulletin plugin that allows a registered user to type a note and post it without a page refresh. First, set up the basic plugin stuff.</p>
<pre class="brush: php;">
$QuickNotes = new QuickNotes();

class QuickNotes {

	function QuickNotes() {
		add_action('admin_menu', array(&amp;$this, 'add_note_page'));
		add_action(&quot;admin_print_scripts&quot;, array(&amp;$this, 'js_libs'));
		add_action('wp_ajax_quicknotes_add', array(&amp;$this, 'add'));
	}

	function add_note_page() {
		add_theme_page('Quick Notes', 'Quick Notes', 'administrator', 'quick_notes', array(&amp;$this, 'notes'));
	}

	function js_libs() {
		wp_enqueue_script('jquery');
	}

	function notes() {

		if ( function_exists('wp_nonce_field') )
			wp_nonce_field('quicknotes_nonce', 'quicknotes_nonce');

		?&gt;
		&lt;div class=&quot;wrap&quot;&gt;
			&lt;h2&gt;Quick Notes&lt;/h2&gt;
			&lt;ul id=&quot;note_board&quot;&gt;&lt;/ul&gt;
			&lt;p&gt;
				&lt;textarea id=&quot;note&quot;&gt;&lt;/textarea&gt;
				&lt;a class=&quot;button&quot; id=&quot;add_note&quot;&gt;Add Note&lt;/a&gt;
			&lt;/p&gt;
		&lt;/div&gt;
		&lt;?php

	}

	function add() {

	}

}
</pre>
<p>As a quick overview, here&#8217;s what has happened so far:</p>
<ul>
<li>We added an option page under Appearance that returns the &#8216;form&#8217; held in the <code>notes()</code> method.</li>
<li>Queued the <a href="http://jquery.com/" target="_blank">jQuery</a> library (good for AJAXing)</li>
<li>Mapped an AJAX request using <code>wp_ajax_</code> (action =&gt; <code>quicknotes_add()</code>, callback =&gt; <code>add()</code>)
<ul>
<li>This allows us to use a method within our plugin to handle the AJAX request, as opposed to a separate web page.</li>
</ul>
</li>
<li>Created a Nonce to use called <code>quicknotes_nonce</code>.</li>
</ul>
<p>Now let&#8217;s set up the actual AJAX request with jQuery so the user can add the note without a page refresh. Using the <code>$.post</code> method, we&#8217;ll send the values for both the note <em><strong>and</strong></em> the nonce when the &#8216;Add&#8217; button is clicked. Finally, the note is pasted back to note board.</p>
<pre class="brush: jscript;">
function notes() {

	// The Nonce ......... ?&gt;

	&lt;script type=&quot;text/javascript&quot;&gt;

		jQuery(document).ready(function($) {
			$('#add_note').live('click',
				function () {
					note = $(&quot;#note&quot;).val();
					nonce = $(&quot;input#quicknotes_nonce&quot;).val();
					$.post(
						&quot;&lt;?php echo get_option('siteurl'); ?&gt;/wp-admin/admin-ajax.php&quot;,
						{
							action:&quot;quicknotes_add&quot;,
							note : note,
							nonce : nonce
						},
						function (str) {
							$('ul#note_board').html(str);
						}
					);
				}
			);
		});

	&lt;/script&gt;

	&lt;?php  // The Form ..........
}
</pre>
<p>So, the nonce is now being passed as a <code>$_POST</code> parameter just like standard operating procedure. Next, assert the validity of the nonce in the <code>add()</code> method. If the nonce is correct, move on to inserting the note into the database, or just echo it back to the list.</p>
<pre class="brush: php;">
function add() {

	if (!wp_verify_nonce($_POST['nonce'], 'quicknotes_nonce'))
		exit();

	echo '&lt;li&gt;' . $_POST['note'] . '&lt;/li&gt;';
	exit();

}
</pre>
<p>That&#8217;s it! <a href="http://www.keighl.com/wp-content/uploads/quick_notes.php_.zip">Download the entire example. </a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2010/04/nonce-and-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding Custom Link Classes in WordPress</title>
		<link>http://www.keighl.com/2010/03/adding-custom-link-classes-in-wordpress/</link>
		<comments>http://www.keighl.com/2010/03/adding-custom-link-classes-in-wordpress/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 00:32:51 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[hooks]]></category>
		<category><![CDATA[link classes]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[themes]]></category>
		<category><![CDATA[tinymce]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=1479</guid>
		<description><![CDATA[Add special class to the available list under 'Insert/edit Link' button. Good for plugin and theme developers. ]]></description>
			<content:encoded><![CDATA[<p><a class="fancybox" href="http://www.keighl.com/wp-content/uploads/link-box.png"><img class="alignleft size-thumbnail wp-image-1482" title="Insert/edit Link" src="http://www.keighl.com/wp-content/uploads/link-box-150x150.png" alt="" width="150" height="150" /></a>Most AJAX-ing and general-web-awesomeness is driven by CSS selectors. For instance, a lightbox pops up exclusively on links with a class of <code>lightbox</code>. For a plugin or theme developer, if you&#8217;re application requires selectors like this, it&#8217;s best to assume that the users cannot do this on their own. What I mean is this: give them a simple way to add the selector without and hand-coding.</p>
<p>A fine way to do this is via the class setting found under <strong>Insert/edit Link</strong>. Through a plugin or a theme, you can set specific classes from which the user can choose. Use the <code>tiny_mce_before_init</code> hook that WordPress provides. It works by declaring some extra classes that are added to the mega array of TinyMCE settings.</p>
<p>Drop this in your <strong>functions.php</strong> file, or in your plugin:</p>
<pre class="brush: php;">
add_filter('tiny_mce_before_init', 'add_lightbox_classes');

function add_lightbox_classes($initArray) {

	$initArray['theme_advanced_styles'] = &quot;Lightbox=lightbox;iFrame=iframe&quot;;

	return $initArray;

}
</pre>
<p>There is a problem with this, though! By using the <code>tiny_mce_before_init</code> hook you effectively replace the normal ones like: <em>aligncenter, alignleft, etc</em>. If you examine how the normal ones are generated, you&#8217;ll find they are not created through the initArray. They are fed in through another javascript object. If WordPress sees that there is something other than nothing in the <code>theme_advanced_styles</code> key, it replaces everything.</p>
<p>So, if you want to keep the normal ones you need to redo them in your hook function. I should probably submit a core patch that addresses this.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2010/03/adding-custom-link-classes-in-wordpress/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Limiting Dates on Two jQuery Datepickers</title>
		<link>http://www.keighl.com/2010/02/limiting-dates-on-two-jquery-datepickers/</link>
		<comments>http://www.keighl.com/2010/02/limiting-dates-on-two-jquery-datepickers/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 04:53:08 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[datepicker]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jquery ui]]></category>
		<category><![CDATA[minDate]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=1425</guid>
		<description><![CDATA[Using two jQuery UI Datepickers, how to limit the second calendar so the end cannot come before the beginning. ]]></description>
			<content:encoded><![CDATA[<p>I just ran into a scenario where I had two separate jQuery UI datepickers, and needed to have the first calendar limit the date choices of the second. Essentially a start date and end date. It doesn&#8217;t take a degree in relational physics to know that the end cannot come before the beginning; therefore, anything before the date the user chooses in the first calendar needs to be unavailable in the second calendar. </p>
<pre class="brush: jscript;">
jQuery(document).ready(function($) {

	$('#start').datepicker({
		dateFormat: &quot;@&quot;,
		onSelect: function(dateText, inst) {
			dateText = eval(dateText);
			var min = new Date();
			min.setTime(dateText);
			$('#end').datepicker('option', 'minDate', min);
		}

	});

	$('#end').datepicker({
		dateFormat: &quot;@&quot;,
	});

});
</pre>
<p>It&#8217;s as easy as that. </p>
<p>However, if you&#8217;re localizing this script to the island from <em>Lost</em>, I cannot guarantee that start date will be there in the first place.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2010/02/limiting-dates-on-two-jquery-datepickers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Polling WordPress Users on Calendar Functionality</title>
		<link>http://www.keighl.com/2010/01/polling-wordpress-users-on-calendar-functionality/</link>
		<comments>http://www.keighl.com/2010/01/polling-wordpress-users-on-calendar-functionality/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 21:20:54 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[calendar]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=1407</guid>
		<description><![CDATA[In preparation for a new calendar plugin, I need to know how people like their calendars. Let me know!]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m in the process of developing a(nother) events calendar plugin for WordPress. I&#8217;m trying to get a feel for the optimal UX; I realize that people like to go about things in various ways on their WordPress installments, and I want this plugin to be a natural fit into the way a blog is normally operated &#8230; not by some grizzly multi-page addition to the interface.</p>
<p>There are a handle-full of questions I&#8217;m dealing with. The most important, is &#8220;how do users prefer to post events?&#8221; There are two general ways I can imagine a plugin going about this one:</p>
<ul>
<li>Create an event from a specific post</li>
<li>Create a discrete event, separate from the posts &#8230; with the option of linking to a post.</li>
</ul>
<p>The database architecture would be very different <code>foreach()</code> of these scenarios. I think that the second would allow for more control over the calendar itself. For instance, if the calendar features events from all over the place (not your blog), the first scenario would require you to make a post for it anyway. With discrete events, you could feature events without an associated post.</p>
<p>However, a very intimate relationship between events and posts is probably what most users would expect from a &#8216;native&#8217; WordPress event function.</p>
<p>Of course, there could be both &#8230; but that would mean, in theory, two separate ways to go about posting events. It could be a few too many avenues for reaching the same goal. Also, that would be a pain for me to document.</p>
<p>If you&#8217;ve got a second, please tell me what you think.</p>
<script type='text/javascript' language='javascript' charset='utf-8' src='http://s3.polldaddy.com/p/2625505.js'></script><noscript> <a href='http://answers.polldaddy.com/poll/2625505/'>View Poll</a></noscript>
<script type='text/javascript' language='javascript' charset='utf-8' src='http://s3.polldaddy.com/p/2625532.js'></script><noscript> <a href='http://answers.polldaddy.com/poll/2625532/'>View Poll</a></noscript>
<script type='text/javascript' language='javascript' charset='utf-8' src='http://s3.polldaddy.com/p/2625535.js'></script><noscript> <a href='http://answers.polldaddy.com/poll/2625535/'>View Poll</a></noscript>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2010/01/polling-wordpress-users-on-calendar-functionality/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Using Thickbox in WordPress Plugins</title>
		<link>http://www.keighl.com/2010/01/using-thickbox-in-wordpress-plugins/</link>
		<comments>http://www.keighl.com/2010/01/using-thickbox-in-wordpress-plugins/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 18:04:27 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[thickbox]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=1374</guid>
		<description><![CDATA[How to use Thickbox in a WordPress plugin; covers loading Thickbox and using jQuery to make it awesome.  ]]></description>
			<content:encoded><![CDATA[<p>I have a few qualms about the reliance on Thickbox in the WordPress admin interface. As a plugin developer, I use the modal-box method frequently; it&#8217;s great for handling all kinds of data asynchronously &#8230; without page refreshes. They keep your file quantities down, and WordPress users are already familiar with how they work.</p>
<p>However, Thickbox is becoming a little antiquated:</p>
<ul>
<li>It&#8217;s no longer maintained (http://jquery.com/demo/thickbox/)</li>
<li>In the WordPress context, it uses annoying $_GET variables to pass data</li>
</ul>
<p>Now that the <a href="http://wordpress.org/development/2010/01/2010-open-source-design/" target="_blank">WordPress interface is being brought towards a more open source model</a>, I hope this is one of things they change. I&#8217;d like to see more integration of the <a href="http://jqueryui.com/demos/dialog/" target="_blank">jQuery UI Dialog widget</a>.</p>
<p>Regardless, Thickbox is how it works now; so here&#8217;s how to use it in a plugin.</p>
<h3>Concept</h3>
<p>The most frequent use (I&#8217;m saying this with no evidence to support my claim) of any modal box in a plugin is to <em>do something</em> without navigating to another page. For instance, you upload an image through a Thickbox; the page stays current, but an image is uploaded asynchronously through the modal-box.</p>
<p>For this example, let&#8217;s imagine that it is necessary for a user to decide something: black or white? We want them to open a box, decide, and close the box all from the plugin&#8217;s interface.</p>
<h3>General Plugin Setup</h3>
<pre class="brush: php;">
&lt;?php
/*
Plugin Name: Black or White?
Plugin URI: http://www.example.com/
Description: You choose.
Version: 0.1
Author: Kyle Truscott
Author URI: http://www.keighl.com
*/

$BlackOrWhite = new BlackOrWhite();

class BlackOrWhite {

	function BlackOrWhite() {
		add_action('admin_menu', array(&amp;$this, 'add_admin'));
		add_action(&quot;admin_print_scripts&quot;, array(&amp;$this, 'js_libs'));
		add_action(&quot;admin_print_styles&quot;, array(&amp;$this, 'style_libs'));
	}

	function add_admin() {
		add_theme_page('BlackOrWhite', 'BlackOrWhite', 'administrator', 'black-or-white', array(&amp;$this, 'admin_view'));
	}

	function js_libs() {
		wp_enqueue_script('jquery');
		wp_enqueue_script('thickbox');
	}

	function style_libs() {
		wp_enqueue_style('thickbox');
	}

	function admin_view() {}

	function choice() {}

}
?&gt;
</pre>
<p>Fairly normal. In order to use Thickbox, you need to queue both the script and style respectively. WordPress has these pre-registered for us, so all we need to do is tell it to load with <code>wp_enqueue_script()</code> and <code>wp_enqueue_style()</code> from the constructor.</p>
<h3>Calling the Thickbox Dialog</h3>
<p>In order to actually have the modal-box pop up, it is necessary to do so through the <code>href</code> parameter of a link. This is where it gets ugly.</p>
<pre class="brush: php;">
function admin_view() {
	?&gt;
	&lt;div class=&quot;wrap&quot;&gt;
		&lt;h2&gt;Black or White?&lt;/h2&gt;
		&lt;p&gt;
			&lt;a class=&quot;thickbox button&quot; href=&quot;&lt;?php echo get_option('siteurl'); ?&gt;/wp-admin/admin-ajax.php?action=choice&amp;width=150&amp;height=100&quot; title=&quot;Choice&quot;&gt;
				Choice
			&lt;/a&gt;
		&lt;/p&gt;
		&lt;p&gt;
			Your choice: &lt;span class=&quot;your-choice&quot;&gt;&lt;/span&gt;
		&lt;/p&gt;
	&lt;/div&gt;
	&lt;?php
}
</pre>
<p>You need to :</p>
<ul>
<li>Declare &#8220;thickbox&#8221; as one of the link&#8217;s classes (&#8220;button&#8221; is nice too)</li>
<li>Direct the link to: <code>&lt;?php echo get_option('siteurl'); ?&gt;/wp-admin/admin-ajax.php?</code></li>
<li>Give it the following $_GET variables
<ul>
<li><strong>action</strong> &#8211; tells WordPress how to handle the AJAX request, or what stuff to load into the Thickbox</li>
<li><strong>width</strong> &#8211; the dialog&#8217;s width in pixels</li>
<li><strong>height</strong> &#8211; the dialog&#8217;s height in pixels</li>
</ul>
</li>
</ul>
<p>The reason for passing the AJAX request through admin-ajax.php is so we can call one of our plugin functions &#8230; the one for the dialog box content. Back in the constructor, simply tell WordPress to which function it should redirect the AJAX request.</p>
<pre class="brush: php;">
function BlackOrWhite() {
 add_action('admin_menu', array(&amp;$this, 'add_admin'));
 add_action(&quot;admin_print_scripts&quot;, array(&amp;$this, 'js_libs'));
 add_action(&quot;admin_print_styles&quot;, array(&amp;$this, 'style_libs'));

 add_action('wp_ajax_choice', array(&amp;$this, 'choice'));
}
</pre>
<p>Now, when the user clicks &#8220;Choose&#8221;, whatever we have stored in choice() will return within the box.</p>
<h3>In the Thickbox</h3>
<p>So far so good, but there is nothing in the modal-box. We need two buttons: <strong>black </strong>and <strong>white</strong>. The dialog box displays whatever is returned from <code>choice()</code>. Therefore, that&#8217;s where the buttons go.</p>
<pre class="brush: php;">
function choice() {
	?&gt;
	&lt;p&gt;
		&lt;a class=&quot;button choice_button&quot; id=&quot;Black&quot;&gt;Black&lt;/a&gt;
		&lt;a class=&quot;button choice_button&quot; id=&quot;White&quot;&gt;White&lt;/a&gt;
	&lt;/p&gt;
	&lt;?php
	exit();
}
</pre>
<p>Don&#8217;t forget to <code>exit()</code> the function, or you&#8217;ll get an annoying 0 in the Thickbox. We don&#8217;t have any <code>href</code> info for these links, because we&#8217;ll be handling their events via jQuery. The goal here is to only have one page, right?</p>
<h3>Some jQuery</h3>
<pre class="brush: php;">
function admin_view() {
	?&gt;

	&lt;script type=&quot;text/javascript&quot;&gt;
		jQuery(document).ready(function($) {
			$('.choice_button').live('click',
				function () {
					var choice = $(this).attr('id');
					tb_remove();
					$('.your-choice').html(choice);
				}
			);
		});
	&lt;/script&gt;

	&lt;!-- The rest of the admin view ... --&gt;

	&lt;?php
}
</pre>
<p>On the click event of either <code>choice_button</code>, we execute a function that returns the user&#8217;s choice to the main interface.  Use the <code>live()</code> method to bind the event, because the buttons were loaded via AJAX.</p>
<p>Removing the Thickbox is much easier than launching it &#8230; simply call the <code>tb_remove()</code> function.</p>
<h3>Conclusion</h3>
<p>All in all, using the Thickbox in WordPress plugins is not that hard, but it could certainly be easier.</p>
<p>Download the full tutorial code here: <a href="http://www.keighl.com/wp-content/uploads/black-or-white.php_1.zip">Black or White?</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2010/01/using-thickbox-in-wordpress-plugins/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>TinyMCE in WordPress Plugins</title>
		<link>http://www.keighl.com/2010/01/tinymce-in-wordpress-plugins/</link>
		<comments>http://www.keighl.com/2010/01/tinymce-in-wordpress-plugins/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 00:47:33 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[tinymce]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wp_enqueue_script]]></category>
		<category><![CDATA[wp_tiny_mce]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=1293</guid>
		<description><![CDATA[In order to use TinyMCE from a WordPress plugin, use wp_tiny_mce(), and override the defaults. ]]></description>
			<content:encoded><![CDATA[<p>Unlike some of the other JavaScript assets available to plugin developers through <a href="http://codex.wordpress.org/Function_Reference/wp_enqueue_script"><code>wp_enqueue_script()</code></a>, getting <a href="http://tinymce.moxiecode.com/">TinyMCE</a> to function in your plugin is a little different. You would perhaps expect to use it like this:</p>
<pre class="brush: php; html-script: true;">
&lt;?php
add_action(&quot;admin_print_scripts&quot;, &quot;js_libs&quot;);

function js_libs() {
     wp_enqueue_script('tiny_mce');
}
?&gt;
</pre>
<pre class="brush: jscript; html-script: true;">
&lt;script type=&quot;text/javascript&quot;&gt;

	tinyMCE.init({
		mode : &quot;exact&quot;,
		elements: &quot;a_nice_textarea&quot;,
		theme : &quot;simple&quot;
	});

&lt;/script&gt;
</pre>
<pre class="brush: xml;">
&lt;textarea id=&quot;a_nice_textarea&quot; name=&quot;a_nice_textarea&quot;&gt;&lt;/textarea&gt;
</pre>
<p>However, enqueuing the TinyMCE really won&#8217;t get you any results. You need to use the <code>wp_tiny_mce()</code> function, which is not well documented. Essentially, the function pre-constructs the TinyMCE for you, and you override its default options. The main option to override is <code>editor_selector</code> which points TinyMCE at a specific textarea <code><strong>class</strong></code>.</p>
<pre class="brush: php; html-script: true;">
&lt;?php
wp_tiny_mce( false , // true makes the editor &quot;teeny&quot;
	array(
		&quot;editor_selector&quot; =&gt; &quot;a_nice_textarea&quot;
	)
);
?&gt;

&lt;textarea class=&quot;a_nice_textarea&quot; id=&quot;a_nice_textarea&quot; name=&quot;a_nice_textarea&quot;&gt;&lt;/textarea&gt;
</pre>
<p>You can stick this anywhere you want, and it will work (for the most part). All the available configuration options for TinyMCE can be determined by referencing it within the array. WordPress has a bunch of them determined by default for the post content editor; most of them are fine as is.</p>
<pre class="brush: php;">
// TinyMCE init settings
$initArray = array (
	'mode' =&gt; 'none',
	'onpageload' =&gt; 'switchEditors.edInit',
	'width' =&gt; '100%',
	'theme' =&gt; 'advanced',
	'skin' =&gt; 'wp_theme',
	'theme_advanced_buttons1' =&gt; &quot;$mce_buttons&quot;,
	'theme_advanced_buttons2' =&gt; &quot;$mce_buttons_2&quot;,
	'theme_advanced_buttons3' =&gt; &quot;$mce_buttons_3&quot;,
	'theme_advanced_buttons4' =&gt; &quot;$mce_buttons_4&quot;,
	'language' =&gt; &quot;$mce_locale&quot;,
	'spellchecker_languages' =&gt; &quot;$mce_spellchecker_languages&quot;,
	'theme_advanced_toolbar_location' =&gt; 'top',
	'theme_advanced_toolbar_align' =&gt; 'left',
	'theme_advanced_statusbar_location' =&gt; 'bottom',
	'theme_advanced_resizing' =&gt; true,
	'theme_advanced_resize_horizontal' =&gt; false,
	'dialog_type' =&gt; 'modal',
	'relative_urls' =&gt; false,
	'remove_script_host' =&gt; false,
	'convert_urls' =&gt; false,
	'apply_source_formatting' =&gt; false,
	'remove_linebreaks' =&gt; true,
	'paste_convert_middot_lists' =&gt; true,
	'paste_remove_spans' =&gt; true,
	'paste_remove_styles' =&gt; true,
	'gecko_spellcheck' =&gt; true,
	'entities' =&gt; '38,amp,60,lt,62,gt',
	'accessibility_focus' =&gt; true,
	'tab_focus' =&gt; ':prev,:next',
	'content_css' =&gt; &quot;$mce_css&quot;,
	'save_callback' =&gt; 'switchEditors.saveCallback',
	'wpeditimage_disable_captions' =&gt; $no_captions,
	'plugins' =&gt; &quot;$plugins&quot;
);
</pre>
<p>For a closer look at <code>wp_tiny_mce()</code>, <a href="http://core.trac.wordpress.org/browser/trunk/wp-admin/includes/post.php">check out the source</a>.</p>
<p>For incorporating the <em>Visual</em>/<em>HTML</em> mode switcher, and turning TinyMCE on and off, see <a href=" http://www.keighl.com/2010/04/switching-visualhtml-modes-with-tinymce/" target="_self">Switching Visual/HTML Modes With TinyMCE</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2010/01/tinymce-in-wordpress-plugins/feed/</wfw:commentRss>
		<slash:comments>60</slash:comments>
		</item>
		<item>
		<title>ExpressionEngine: Filter Access By Member Join Date</title>
		<link>http://www.keighl.com/2009/11/expressionengine-filter-access-by-member-join-date/</link>
		<comments>http://www.keighl.com/2009/11/expressionengine-filter-access-by-member-join-date/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 16:54:46 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[expression engine]]></category>
		<category><![CDATA[member join date]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=1226</guid>
		<description><![CDATA[Restrict access to data based on a member's join date with ExpressionEngine. Works for all kinds of stuff ... even calendars. ]]></description>
			<content:encoded><![CDATA[<p>Depending on the nature of your content within <a href="http://expressionengine.com/">ExpressionEngine</a>, you may want to discriminate member access to entries based upon when they were registered. For instance, if they pay for the information, you don&#8217;t want them to see backlog entries for free! Unfortunately, EE doesn&#8217;t have an easy global variable for join date; however, a member&#8217;s join date is stored in the database (table <code>exp_members</code>, column <code>join_date</code>), so it is still available for our use.</p>
<p>This process can be done on any template. First, we need to procure the member&#8217;s id number, with which we can filter the database. There is a global variable for this, <code>{member_id}</code>, but it becomes rather unstable when used in conditionals and database queries. I find it easier to simply grab the <code>$SESS</code> data. Make sure the <a href="http://expressionengine.com/docs/templates/php_templates.html">PHP parsing stage is set to <strong>input</strong></a>.</p>
<pre class="brush: php;">
&lt;?php
global $SESS;
$member_id = $SESS-&gt;userdata['member_id'];
?&gt;
</pre>
<p>With this info we can query the database, and use a conditional statement to filter the members&#8217; access. If their join date is after the entry&#8217;s date, we shut them down.</p>
<pre class="brush: php; html-script: true;">
{exp:weblog:entries orderby=&quot;date&quot; sort=&quot;desc&quot; limit=&quot;1&quot;}

	{exp:query sql=&quot;SELECT join_date FROM exp_members WHERE member_id = '&lt;?php echo $member_id; ?&gt;'&quot;}

	    {if {entry_date} &gt; {join_date} }

	        You get what you pay for!

			&lt;!-- EE Entry Data ... --&gt;

	    {if:else}

			Forget about it.

	    {/if}

	{/exp:query}

{/exp:weblog:entries}
</pre>
<h3>Calendar</h3>
<p>The same principles, as applied above, can be used within an AJAX-ified mini-calendar. <a href="http://www.keighl.com/2009/11/expressionengine-dynamic-calendar-using-jquery/">Check out my post on the matter, because the following code builds upon it</a>.</p>
<p>From within the <code>{if_entries}</code> bit of the calendar tag, you can filter the links by the same method of querying the database with the member&#8217;s id. If their join date is after the entry, they don&#8217;t see a link.</p>
<pre class="brush: php; html-script: true;">
&lt;?php

$weblog =  $_POST['weblog'];

if (isset($_POST['month'])) :
	$month = $_POST['month'];
	$year = $_POST['year'];
else :
	$month = date('m');
	$year = date('Y');
endif;

global $SESS;
$member_id = $SESS-&gt;userdata['member_id'];

?&gt;

{exp:weblog:calendar weblog=&quot;&lt;?php echo $weblog;?&gt;&quot; switch=&quot;calendarToday|calendarCell&quot; month=&quot;&lt;?php echo $month; ?&gt;&quot; year=&quot;&lt;?php echo $year; ?&gt;&quot;}
    &lt;table class=&quot;calendar&quot; border=&quot;0&quot; cellpadding=&quot;4&quot; cellspacing=&quot;0&quot;&gt;
    	&lt;tr&gt;
	    	&lt;th class=&quot;calendarHeader&quot;&gt;
		    	&lt;a href=&quot;&quot; alt=&quot;{previous_date format=&quot;%m&quot;}&quot; class=&quot;{previous_date format=&quot;%Y&quot;}&quot;&gt;&amp;lt;&lt;/a&gt;
		    &lt;/th&gt;
	    	&lt;th class=&quot;calendarHeader&quot; colspan=&quot;5&quot;&gt;{date format=&quot;%F %Y&quot;}&lt;/th&gt;
		    &lt;th class=&quot;calendarHeader&quot;&gt;
		    	&lt;a href=&quot;&quot; alt=&quot;{next_date format=&quot;%m&quot;}&quot; class=&quot;{next_date format=&quot;%Y&quot;}&quot;&gt;&amp;gt;&lt;/a&gt;
		    &lt;/th&gt;
		    &lt;/tr&gt;
	    &lt;tr&gt;
	    	{calendar_heading}
		    &lt;td class=&quot;calendarDayHeading&quot;&gt;{lang:weekday_abrev}&lt;/td&gt;
		    {/calendar_heading}
	    &lt;/tr&gt;
	    {calendar_rows }
	    	{row_start}&lt;tr&gt;{/row_start}

				{if entries}
				        {entries}

				            {exp:query sql=&quot;SELECT join_date FROM exp_members WHERE member_id = '&lt;?php echo $member_id; ?&gt;' &quot;}
				                {if {entry_date} &gt; {join_date} }
				                    &lt;td class='{switch} calentry' align='center'&gt;
				                        &lt;a href=&quot;{day_path=&lt;?php echo $weblog;?&gt;/index}&quot;&gt;{day_number}&lt;/a&gt;
				                    &lt;/td&gt;
				                {if:else}
				                    &lt;td class='{switch}' align='center'&gt;
				                        {day_number}
				                    &lt;/td&gt;
				                {/if}

				            {/exp:query}

				        {/entries}
				    {/if}

			    {if blank}
					&lt;td class='calendarBlank'&gt;&amp;nbsp;&lt;/td&gt;
				{/if}
		    {row_end}&lt;/tr&gt;{/row_end}
	    {/calendar_rows}
    &lt;/table&gt;
{/exp:weblog:calendar}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2009/11/expressionengine-filter-access-by-member-join-date/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ExpressionEngine: Dynamic Calendar Using jQuery</title>
		<link>http://www.keighl.com/2009/11/expressionengine-dynamic-calendar-using-jquery/</link>
		<comments>http://www.keighl.com/2009/11/expressionengine-dynamic-calendar-using-jquery/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 15:48:56 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[calendar]]></category>
		<category><![CDATA[expression engine]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=1181</guid>
		<description><![CDATA[Create a dynamic calendar using jQuery for Expression Engine with one template and the $.post() method. Let the people scoll!]]></description>
			<content:encoded><![CDATA[<p><a href="http://expressionengine.com/">ExpressionEngine</a> is a great tool for managing any kind of content. A feature users depend on, regardless of whether the application is a simple blog or otherwise, is a mini-calendar. It enables them to quickly shuffle through archives or posts. Thankfully, EE has a nice built in calendar module known as <a href="http://expressionengine.com/docs/modules/weblog/calendar.html"><code>{exp:weblog:calendar}</code></a>. It&#8217;s great at returning one month&#8217;s worth of links, but cycling through to another month (past or previous) takes the user by default to a respective archive page. Now, the user must shift mental gears, and hunt for the info in a new way; ideally, they should be able to cycle through all the months without leaving the calendar or their current page.</p>
<p>With a little help from <a href="http://jquery.com/">jQuery</a> and AJAX, it&#8217;s not a difficult procedure. Essentially, we will create a separate EE template that dynamically generates a calendar, and load it in to another template passing some <code>$_POST</code> variables. When the users clicks &#8220;Next Month,&#8221; the calendar is regenerated without a page refresh.</p>
<h3>Calendar Template</h3>
<p>First, create a new EE template <code>lib/calendar</code>, or whatever you&#8217;d like to call it. Be sure to set the <a href="http://expressionengine.com/docs/templates/php_templates.html">PHP parsing stage to <strong>input</strong></a>. As you can see, the month, year and weblog parameters for the calendar tag are being dynamically accepted from the <code>$_POST</code> array.</p>
<pre class="brush: php; html-script: true;">

&lt;?php
$weblog =  $_POST['weblog'];
if (isset($_POST['month'])) :
	$month = $_POST['month'];
	$year = $_POST['year'];
else :
	$month = date('m');
	$year = date('Y');
endif;
?&gt;

{exp:weblog:calendar weblog=&quot;&lt;?php echo $weblog;?&gt;&quot; switch=&quot;calendarToday|calendarCell&quot; month=&quot;&lt;?php echo $month; ?&gt;&quot; year=&quot;&lt;?php echo $year; ?&gt;&quot;}
    &lt;table class=&quot;calendar&quot; border=&quot;0&quot; cellpadding=&quot;4&quot; cellspacing=&quot;0&quot;&gt;
    	&lt;tr&gt;
	    	&lt;th class=&quot;calendarHeader&quot;&gt;
		    	&lt;a href=&quot;&quot; alt=&quot;{previous_date format=&quot;%m&quot;}&quot; class=&quot;{previous_date format=&quot;%Y&quot;}&quot;&gt;&amp;lt;&lt;/a&gt;
		    &lt;/th&gt;
	    	&lt;th class=&quot;calendarHeader&quot; colspan=&quot;5&quot;&gt;{date format=&quot;%F %Y&quot;}&lt;/th&gt;
		    &lt;th class=&quot;calendarHeader&quot;&gt;
		    	&lt;a href=&quot;&quot; alt=&quot;{next_date format=&quot;%m&quot;}&quot; class=&quot;{next_date format=&quot;%Y&quot;}&quot;&gt;&amp;gt;&lt;/a&gt;
		    &lt;/th&gt;
		    &lt;/tr&gt;
	    &lt;tr&gt;
	    	{calendar_heading}
		    &lt;td class=&quot;calendarDayHeading&quot;&gt;{lang:weekday_abrev}&lt;/td&gt;
		    {/calendar_heading}
	    &lt;/tr&gt;
	    {calendar_rows }
	    	{row_start}&lt;tr&gt;{/row_start}
		    	{if entries}
			        {entries}
		                &lt;td class='{switch} calentry' align='center'&gt;
		                    &lt;a href=&quot;{day_path=&lt;?php echo $section;?&gt;/index}&quot;&gt;{day_number}&lt;/a&gt;
		                &lt;/td&gt;
			        {/entries}
			    {/if}
			    {if not_entries}
					&lt;td class='{switch}' align='center'&gt;{day_number}&lt;/td&gt;
				{/if}
			    {if blank}
					&lt;td class='calendarBlank'&gt;&amp;nbsp;&lt;/td&gt;
				{/if}
		    {row_end}&lt;/tr&gt;{/row_end}
	    {/calendar_rows}
    &lt;/table&gt;
{/exp:weblog:calendar}
</pre>
<h3>Javascript</h3>
<p>For the user page, where the calendar is to be displayed, first load the jQuery core. Also, create an empty <code>div</code> with an <code>id</code> of &#8220;calendar&#8221; somewhere on the page.</p>
<pre class="brush: xml; light: true;">

&lt;script type=&quot;text/javascript&quot; src=&quot;http://code.jquery.com/jquery-latest.js&quot;&gt;&lt;/script&gt;
</pre>
<p>Create the calendar functions using jQuery&#8217;s <a href="http://docs.jquery.com/Ajax/jQuery.post"><code>$.post</code></a> method to load the calendar. We send it, via post, the data for the specific month/year we&#8217;d like to display. In parallel, jQuery is on the prowl for links embedded in the calendar; clicking on these links trigger the <code>render_calendar()</code> function again, but this time with new month/year data extracted from the prev/next links we set up in <code>lib/calendar</code>. The data is stored as <code>class</code> and <code>alt</code>; you could store them however you want, though.</p>
<pre class="brush: jscript;">
$(document).ready(function(){

	var weblog = &quot;xxxxxx&quot;;
	var month = xx;
	var year = xxxx;

	render_calendar(section,month,year);

	function render_calendar(section,month,year) {
		$.post(
			&quot;{path='lib/calendar'}&quot;,
			{ weblog : weblog, month : month, year : year },
			function(str) {
				$('#calendar').html(str).fadeIn();
			}
		);
	}

	$(&quot;#calendar a&quot;).live(&quot;click&quot;, function(){
		$('#calendar').fadeOut();
		month = $(this).attr('alt');
		year = $(this).attr('class');
		render_calendar(section,month,year);
	});

});
</pre>
<p>And that&#8217;s it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2009/11/expressionengine-dynamic-calendar-using-jquery/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>jQuery Corner Plugin on Floated Elements</title>
		<link>http://www.keighl.com/2009/10/jquery-corner-plugin-on-floated-elements/</link>
		<comments>http://www.keighl.com/2009/10/jquery-corner-plugin-on-floated-elements/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 14:26:04 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[corner plugin]]></category>
		<category><![CDATA[floated elements]]></category>
		<category><![CDATA[ie]]></category>
		<category><![CDATA[ie bugs]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[widths]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=1131</guid>
		<description><![CDATA[The Corner Plugin for jQuery is a great little tool to take away the pain of rounding corners with CSS. [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://malsup.com/jquery/corner/">Corner Plugin</a> for <a href="http://jquery.com/">jQuery</a> is a great little tool to take away the pain of rounding corners with CSS. I use it most frequently for dynamically rounded navigation tabs, a feature that most clients want. As opposed to aligning background-images in CSS2, or wrestling with border-radius in CSS3, with the Corner Plugin you can just command any page element to round itself automatically.</p>
<p>As with all things, though, the evil IE6 makes you look like a fool when Corner breaks everything on your painstakingly crafted layout. I&#8217;ve deduced that the main bug with IE is that when applied to floated elements without specified widths, IE corners them as if their widths were 100% of the parent container. So, if you have an unordered list of menu items that are floated left of right, it will look horrible. Unfortunately, this scenario is the most common implementation of menu tabs where the widths are entirely unpredictable.</p>
<p>The solution I discovered was apparent only after I diagnosed that undeclared widths were the root problem. With a little more jQuery, there&#8217;s an easy fix.</p>
<pre class="brush: jscript;">
$(document).ready(function(){ 

	jQuery.each($('.nav ul li'), function() {
	    var width = $(this).width();
		$(this).css({ width:width });
	});

	$('.nav ul li').corner(&quot;3px&quot;);

});
</pre>
<p>Assuming that <code>.nav ul li</code> is something like your floated list, before applying the rounded corners assign each matched element a width. This bit uses the <code>each()</code> selector to go over each list item, measure its width, and then apply that width with CSS. Now, IE6 has a specified width for each element, and you can stop pulling out your hair follicles.</p>
<p>And this idea extends to many other IE problems &#8230; if things are ugly, give them explicit widths.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2009/10/jquery-corner-plugin-on-floated-elements/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recent Comments Without Plugins</title>
		<link>http://www.keighl.com/2009/09/recent-comments-without-plugins/</link>
		<comments>http://www.keighl.com/2009/09/recent-comments-without-plugins/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 17:33:56 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[comments]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[recent comments]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=1073</guid>
		<description><![CDATA[Here&#8217;s a very simple PHP script to make WordPress regurgitate some recent comments without installing any plugins &#8230; good for [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a very simple PHP script to make WordPress regurgitate some recent comments without installing any plugins &#8230; good for doing something very specific within a template or a footer. Within the <code>foreach</code> statement, you can print the array items however you want (list, div, br, etc.). The <code><a href="http://codex.wordpress.org/Function_Reference/get_comments">get_comments()</a></code> function has a handful of parameters that can restrict the comments retrieved. As opposed to messing around with the <code>wp_list_comments()</code> to make it display correctly, I prefer to do this. </p>
<p>I&#8217;ve only listed the array items that I think are typically important, but there are a few more available; there&#8217;s a full list of them <a href="http://codex.wordpress.org/Database_Description#Table:_wp_comments">here</a>. </p>
<pre class="brush: php;">
&lt;?php
	$comments = get_comments();

	foreach($comments as $comment) :

		if ($comment-&gt;comment_approved == 1) : 

			echo $comment-&gt;comment_ID;
			echo $comment-&gt;comment_post_ID;
			echo $comment-&gt;comment_author;
			echo $comment-&gt;comment_author_email;
			echo $comment-&gt;comment_author_url;
			echo $comment-&gt;comment_date;
			echo $comment-&gt;comment_content;

		endif;

	endforeach;
?&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2009/09/recent-comments-without-plugins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Protected Images in ExpressionEngine</title>
		<link>http://www.keighl.com/2009/08/using-protected-images-expression-engine/</link>
		<comments>http://www.keighl.com/2009/08/using-protected-images-expression-engine/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 15:13:36 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[.htaccess]]></category>
		<category><![CDATA[expression engine]]></category>
		<category><![CDATA[gd]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=953</guid>
		<description><![CDATA[How to display images from within a protected directory, and mask their real path for better security within ExpressionEngine.]]></description>
			<content:encoded><![CDATA[<p>Another <a href="http://expressionengine.com/" target="_blank">ExpressionEngine</a> challenge arose recently involving how to serve up images in a template that are harbored in a directory protected with .htaccess. For this particular client I&#8217;m working with, EE is managing a vast library of images, and only certain members are allowed to see them. The million dollar question was this: How can we deliver images into a members-only template that are .htaccess protected, and at the same time mask the true path of the images? A kind of two tiered security measure.</p>
<p>First of all, we want the images to be rendered on a template that is only visible to members of group-x. This is done easily within EE from the <a href="http://expressionengine.com/docs/cp/templates/template_access.html" target="_blank">Template Access Restriction</a> section of the control panel.</p>
<p>Typically, this would be good enough for protecting sensitive text content, but leaves images still at risk. A real jerk could look at the tag <code>&lt;img src="./images/confidential.png" /&gt;</code> and point all his internet buddies to the path, or take some other stuff he shouldn&#8217;t have his dirty little fingers on. The biggest hole is the simple <code>&lt;img&gt;</code> tag. So, to be safe we can protect the /images/ director with .htaccess &#8230; but now the upstanding citizens of group-x have to authenticate themselves again with credentials outside of EE to view the images. Annoying.</p>
<p>Here&#8217;s what we do. As long you&#8217;ve got an image library on your server (like GD, or ImageMagik), you can hide the real path to the images, and avoid the separate login box. Instead of an absolute or relative path to the image in the <code>src</code> parameter, just send it to a secret script that creates the image.</p>
<pre class="brush: xml; light: true;">&lt;img src=&quot;{path=lib/image}confidential.png/&quot; /&gt;</pre>
<p>This will output something like this when rendered in EE:</p>
<pre class="brush: xml; light: true;">&lt;img src=&quot;http://www.example.com/lib/image/confidential.png/&quot; /&gt;</pre>
<p>What&#8217;s cool in this case is that the image will generated from within this off-site script; the user cannot know the real location of the image. Better yet, because PHP can access protected directories, the user won&#8217;t be prompted to login via .htaccess. And &#8230; (yes there&#8217;s more) if we created the script as its own template in EE, it can be protected just like the main template so only members of group-x will be able to view it. For outsiders, the image will not be generated. It&#8217;s two-tiered protection.</p>
<pre class="brush: php;">
&lt;?php

$image = &quot;{segment_3}&quot;;
$url_path = &quot;{segment_4}&quot;;

switch ($url_path):

	case &quot;image_bin&quot;:
		$path = '../../photos/';
	break;
	case &quot;espionage&quot;:
		$path = '../../state/secrets/';
	break;
	default:
		exit();
endswitch;

if (is_file($path . $image)) {
    $f = $path . $image;
} else {
	exit();
}

header('Content-type: image/png');

$im = @ImageCreateFromJPEG ($f) or // Read JPEG Image
$im = @ImageCreateFromPNG ($f) or // or PNG Image
$im = @ImageCreateFromGIF ($f) or // or GIF Image
$im = false; // If image is not JPEG, PNG, or GIF

if (!$im) {
    readfile ($f);
} else {
    @ImagePNG($im);
}

?&gt;
</pre>
<p>So now, what does this script look like? If you examine the <code>&lt;img&gt;</code> tag above, you&#8217;ll see that the file name (in this case confidential.gif) is actually being sent to the script as a <a href="http://expressionengine.com/docs/templates/globals/url_segments.html" target="_blank">URI Segment Variable</a> &#8230; not as a relative path. The third segment in the URI is the file name. The segments give a lot of extensibility to this process.</p>
<p>For instance, if there were more than one directory that these images are being pulled from, just slap another segment on that represents the path, without giving it away. So, /confidential.png/image_bin/. In this particular case, I went a step further, and assigned a code name for the directory segment, which is then translated privately from within the script in the <code>switch</code>.</p>
<p>The script takes the info from the URI segments, and spits out an image. It&#8217;s that simple.</p>
<p>What&#8217;s beautiful is that, through using this method, you can protect sensitive images through both permitting only certain member groups and hiding the true directories. Oh, and you can still use .htaccess. Now it sounds more like three-tiered security. Sheesh.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2009/08/using-protected-images-expression-engine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Redirecting Members with ExpressionEngine</title>
		<link>http://www.keighl.com/2009/06/redirecting-members-with-expression-engine/</link>
		<comments>http://www.keighl.com/2009/06/redirecting-members-with-expression-engine/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 03:54:31 +0000</pubDate>
		<dc:creator>Keighl</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[expression engine]]></category>
		<category><![CDATA[global variables]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[member groups]]></category>
		<category><![CDATA[redirect]]></category>

		<guid isPermaLink="false">http://www.keighl.com/?p=836</guid>
		<description><![CDATA[A way to redirect member groups to specific templates after they log in with ExpressionEngine. ]]></description>
			<content:encoded><![CDATA[<p>Sometimes simple is better. Actually, simple is almost always better. Especially in web development. This past week, I&#8217;ve been struggling to find a method in <a href="http://expressionengine.com/" target="_blank">ExpressionEngine</a> to redirect member groups to their appropriate templates after logging in.</p>
<p>Here is a little background on what I needed. My client supplies confidential information to subsequent clients. It would be easy to register all their clients as member, and then restrict access to the templates so only members could see them. However, in this case, the company has a handle full of data sets, and its customers subscribe to specific sets; they aren&#8217;t allowed to see the others.</p>
<p>First, it is useful to name associated member groups, weblogs, and templates the same. So if we have four member groups (north, south, east, west), they have each have corresponding weblogs and templates (north, south, east, west). Also, the groups are given access to only their respective templates, which is done through the simple <a href="http://expressionengine.com/docs/cp/templates/template_access.html" target="_blank">Template Access Restriction</a>.</p>
<p>When our members first arrive at the site, they are prompted to login, so we&#8217;ll need a template group specifically for logging them in, <code>{login/index}</code>. This one page will handle everything we need.</p>
<pre class="brush: xml;">
&lt;pre&gt;{exp:member:login_form return=&quot;login/index&quot;}

	&lt;p&gt;&lt;span class=&quot;userpass&quot;&gt;Username&lt;/span&gt;&lt;br/&gt;
	&lt;input type=&quot;text&quot; name=&quot;username&quot;  maxlength=&quot;32&quot; class=&quot;input&quot; /&gt;&lt;/p&gt;

	&lt;p&gt;&lt;span class=&quot;userpass&quot;&gt;Password&lt;/span&gt;&lt;br/&gt;
	&lt;input type=&quot;password&quot; name=&quot;password&quot;  maxlength=&quot;32&quot; class=&quot;input&quot;  /&gt;&lt;/p&gt;

	{if auto_login}
	&lt;p&gt;&lt;input class='checkbox' type='checkbox' name='auto_login' value='1' /&gt; Remember me&lt;/p&gt;
	{/if}

	&lt;p&gt;&lt;input type=&quot;submit&quot; name=&quot;submit&quot; id=&quot;submit&quot; value=&quot;Submit&quot; class=&quot;submit&quot; /&gt;&lt;/p&gt;

	&lt;p&gt;&lt;a href=&quot;{path='member/forgot_password'}&quot;&gt;Forgot your password?&lt;/a&gt;&lt;/p&gt;

{/exp:member:login_form}
</pre>
<p>Notice how the script returns itself to the same template, <code>{login/index}</code>. It doesn&#8217;t really matter where it returns because the bit we are about to add redirects the members after they log in to wherever they need to go &#8230; before the <code>{exp:member:login_form}</code> is queried again. ExpressionEngine gives us a convenient set of global variables that aid our redirections quite nicely. They are <code>{group_id}</code> and <code>{redirect="template/path"}</code>.</p>
<pre class="brush: plain;">
{if logged_in}
	{if group_id == &quot;1&quot;}
    	{redirect='north/index'}
    {if:elseif group_id == &quot;2&quot;}
    	{redirect='south/index'}
    {if:elseif group_id == &quot;3&quot;}
    	{redirect='east/index'}
    {if:elseif group_id == &quot;4&quot;}
    	{redirect='west/index'}
    {if:else}
    	{redirect='login/restricted'}
    {/if}
{/if}
</pre>
<p>The loop determines to which member group the user belongs, and pairs template redirection with that specific <code>{group_id}</code>. Simply identify the id number for each member group (easily found through the CP), and that&#8217;s it! We conclude the <code>{if}</code> loop with an <code>{if:else}</code> statement that takes care of any users who sneak through the log in process.</p>
<p>The <code>{if:else}</code> statement redirects these folks (perhaps they are members, but aren&#8217;t in a member group privy to the information shielded by EE&#8217;s template access) to some other template that tells them, &#8220;you don&#8217;t belong here.&#8221; This is a nice system, because you won&#8217;t need to do any extra coding on the templates the members are redirected towards. EE can handle access to those on its own.</p>
<p>There are limitations, however, to setting up you member redirect in this way. First, it assumes that your member groups are rather static (they are not being created or deleted frequently). If you have a ton of member groups with a ton of corresponding template groups, this would make from a monstrous <code>{if}</code> statement. Another option you have is setting some PHP variables using the EE <code>{group_id}</code> global. To do this you would have to set the PHP parsing to &#8216;output&#8217; on the <code>{login/index}</code> template.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.keighl.com/2009/06/redirecting-members-with-expression-engine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
