<?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>Kathy is Awesome</title>
	<atom:link href="http://www.kathyisawesome.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kathyisawesome.com</link>
	<description>Let Me Solve Your WordPress and WooCommerce Problems</description>
	<lastBuildDate>Sun, 26 May 2013 09:40:54 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>WordPress Filters Fundamentals</title>
		<link>http://www.kathyisawesome.com/455/wordpress-filters-fundamentals/</link>
		<comments>http://www.kathyisawesome.com/455/wordpress-filters-fundamentals/#comments</comments>
		<pubDate>Sat, 20 Oct 2012 04:27:12 +0000</pubDate>
		<dc:creator>kathy</dc:creator>
				<category><![CDATA[Understanding the Basics]]></category>

		<guid isPermaLink="false">http://www.kathyisawesome.com/?p=455</guid>
		<description><![CDATA[Ok, so you’ve read my previous articles on PHP basics and how to use WordPress action hooks. Now you want to play with the big boys and girls and try your hand at filters. Just a reminder that you are still essentially learning a new language. Be patient with yourself. It took me close to [...]]]></description>
				<content:encoded><![CDATA[<p>Ok, so you’ve read my previous articles on PHP basics and how to use WordPress action hooks. Now you want to play with the big boys and girls and try your hand at filters. Just a reminder that you are still essentially learning a new language. Be patient with yourself. It took me close to a year to really understand filters, so if I can help you learn it quicker than that I’ll consider this a successful article.</p>
<p>In my discussion of hooks and functions I have described the system of hooks in WordPress as being similar to a parking lot. The hooks are like spaces, the cars are like functions that can be parked anywhere and can be moved around. To expound on this metaphor, (or to beat it to death) I think a filter is similar to changing something about the car while leaving it in the same place. A filter is like a magic function box that takes a value in ( remember I talked about parameters in by Basics tutorial ) do something with it and send it back. So you have a red Porsche on the lot, send it to a filter and it might become a blue Porsche. Or a black pickup truck. Whatever. But it will still be parked in the back, 2 spots from the end.</p>
<p>When browsing WordPress core, themes and plugins, you will be alerted to the availability of a filter by the appearance of the apply_filters() function. In generic terms it will look like so:</p>
<pre class="brush: php; title: ; notranslate">

apply_filters( 'name_of_target_filter', $variable_getting_filtered, #priority, $other_arg );

</pre>
<p>It might look like:</p>
<pre class="brush: php; title: ; notranslate">

return apply_filters( 'name_of_target_filter', $variable_getting_filtered, #priority, $other_arg );

</pre>
<p>or:</p>
<pre class="brush: php; title: ; notranslate">

echo apply_filters( 'name_of_target_filter', $variable_getting_filtered, #priority, $other_arg );

</pre>
<p>or even:</p>
<pre class="brush: php; title: ; notranslate">

$variable_getting_filtered = apply_filters( 'name_of_target_filter', $variable_getting_filtered, #priority, $other_arg );

</pre>
<h3>Parameters for the Filters</h3>
<p>But I repeat, the big tip off is the apply_filters() function. The apply_filters() function can take an unlimited number of parameters but only the first two are required.</p>
<p>1. The first is the name of the filter. I was very confused early on because the Thematic framework tended to name the filters the same thing as the functions that contained them. And then in the one instance where they were difference, I couldn’t get my filter to work for anything. I swore and through things, cried and shaved a few days off my life from the stress. Turns out their sharing names was a convenience factor that makes a lot more sense to me now. So, just remember that first parameter is the filter’s name.</p>
<p>2. This is an important one, because this parameter is the variable that your function will receive. This is the value we’re going to change. This is the red car that we will turn blue.</p>
<p>3. This it the priority. Just like with adding functions to hooks, this controls the order that filter functions will be applied should there be more than one. The default is 10, so if you need your filter to run before that you’d use a lower number. This is rare, and usually you need to run your filters after others, so you’d want to use a higher number. In fact, until you are sure that you are conflicting with another function you can pretty much just leave it at 10.</p>
<p>4+. These are other variables that might give you some useful information for manipulating the variable getting filtered. Remember we talked about scope in the PHP Basics. Instead of declaring these globally and hoping they arrive intact, WordPress will send your filtered variable along with some friends.</p>
<h3>A Filter with Training Wheels</h3>
<p>In super generic terms let’s take a look at the basic set up for filtering.</p>
<pre class="brush: php; title: ; notranslate">

function sample_filter_function( $in_from_function, $other_arg ) {

$out_to_function = $in_from_function . &quot; add some bacon here!&quot;;

return $out_to_function;

}

add_filter('name_of_target_filter','sample_filter_function', #priority, 2 );

</pre>
<p>The structure is almost exactly the same as that for add_action(). In reality, we are adding an action, just of a slightly different type: one that modifies a specific variable’s value. One thing to note here, is the number 2. This is the number of parameters that you are passing into the function. You’ll always pass 1 variable ( ie. the variable that you are filtering) and in this case you wouldn’t even need to declare it. That’s the default value, just as 10 is the default value for #priority. However, some filters provide access to other variables (like our fake $other_arg), and if you want to use them in your filter function then you have to name them inside the parentheses and then write the correct number at the end of the add_filter() statement.</p>
<p>If you have 2 parameters in the function, but don’t have the number 2 at the end of add_filter() you will get White Screen of Death. If you have the number 2, but don’t declare two parameters, guess what, you will also get WSOD. So make sure your parameters match up.</p>
<p>And you absolutely, must, sans doute, return a value. If you do not, that is essentially the same as returning a null string. If you echo something here, it will likely not appear where you expect it, so don’t. RETURN, RETURN, RETURN. Remember in my PHP basics I talked about two functions playing catch. The return statement, is you throwing your modified version of the variable back to the apply_filters() function so that WordPress can continue on its merry way, but using your value now.</p>
<h3>You’re a Real Boy Now, Pinnochio. A Real Filter</h3>
<p>If you’ve managed to read all this, then&#8230; well&#8230; Bless you. I want to end on a real filter that you can drop into your theme’s functions.php and actually see a working result.</p>
<pre class="brush: php; title: ; notranslate">

function kia_the_title( $title ) {

$title .= &quot; BACON!&quot;;

return $title;

}

add_filter('the_title','kia_the_title' );

</pre>
<p>Not too shockingly I am using Bacon in my testing code. If this bothers you&#8230;. well, its just code. WordPress has a filter called the_title() that lets you modify the title of every post! As written above it will literally add BACON everywhere the_title() is called. Bacon everywhere, all the time has its appeal, sure, but I will whet your appetite with some neato WordPress conditional logic that will only add Bacon to the titles in the main loop, and only on the front-end.</p>
<pre class="brush: php; title: ; notranslate">

function kia_the_title( $title ) {

if ( ! is_admin() &amp;&amp; is_main_loop() ) {

$title .= &quot; BACON!&quot;;

}

return $title;

}

add_filter('the_title','kia_the_title' );

</pre>
<h3>Conclusion</h3>
<p>I hope that helps things make more sense. Remember, THIS IS HARD!! Do not be discouraged if you don’t get it right away. I cannot provide specific support in the comments ( Hire Me, instead! ) but do let me know if there are places where I could be more clear.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kathyisawesome.com/455/wordpress-filters-fundamentals/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Nav Menu Roles Plugin</title>
		<link>http://www.kathyisawesome.com/449/nav-menu-roles/</link>
		<comments>http://www.kathyisawesome.com/449/nav-menu-roles/#comments</comments>
		<pubDate>Tue, 18 Sep 2012 15:15:08 +0000</pubDate>
		<dc:creator>kathy</dc:creator>
				<category><![CDATA[Plugins]]></category>
		<category><![CDATA[custom walker]]></category>
		<category><![CDATA[menu]]></category>

		<guid isPermaLink="false">http://www.kathyisawesome.com/?p=449</guid>
		<description><![CDATA[Over the weekend I was working on a project and my client needed to be able to hide certain menu links from non-logged in users.  In the past I have just created 2 menus, one for logged in users, and another for logged out users.  Not the most convenient thing ever, but simple enough.  However, [...]]]></description>
				<content:encoded><![CDATA[<p>Over the weekend I was working on a project and my client needed to be able to hide certain menu links from non-logged in users.  In the past I have just created 2 menus, one for logged in users, and another for logged out users.  Not the most convenient thing ever, but simple enough.  However, since this was at least the second, and possibly the third time this has come up in various projects I decided to dig further.</p>
<h3>Adding fields to the menu item back-end</h3>
<p>This was the trickiest part really, because there aren&#8217;t any action hooks in this part of the code.  I have requested one with the following <a title="Custom Fields for Menu Items Trac" href="http://core.trac.wordpress.org/ticket/21898" target="_blank">Trac Ticket</a>, but until that gets added to we have to do it in a slightly less efficient way.</p>
<p>Thanks to this <a title="Add custom fields answer" href="http://wordpress.stackexchange.com/questions/33342/how-to-add-a-custom-field-in-the-advanced-menu-properties#answer-33495" target="_blank">WordPress Answer</a> I found that the whole menu item form is created by the <code>Walker_Nav_Menu_Edit</code> Walker, but that tucked away in the code is the ability to filter this and send a new Walker via the <code>wp_edit_nav_menu_walker</code> filter.  Actually this answer got me about 80% of the way there so I can hardly claim to be clever or original.  I just packaged it up.  Couples with this <a title="custom front-end menu walkers" href="http://wordpress.stackexchange.com/questions/65192/hide-menu-items-base-on-capability#answer-65200" target="_blank">Answer about front-end menu Walkers</a>, the first beta draft of my plugin was born.  At this point it really only handled different roles.</p>
<div id="attachment_450" class="wp-caption alignleft" style="width: 432px"><img class="size-full wp-image-450" title="Nav Menu Roles screenshot" src="http://www.kathyisawesome.com/wp-content/uploads/screenshot3.png" alt="Nav Menu Roles screenshot" width="422" height="354" /><p class="wp-caption-text">New options for menu settings allow you to customize who can view particular menu items</p></div>
<p>Before it was even added to the WordPress repository, <a title="Pippinsplugin reviews Nav Menu Roles" href="http://pippinsplugins.com/nav-menu-roles-plugin/" target="_blank">Pippin Williamson did a quick video review</a>, so I guess I am not the only person who has needed this ability from WordPress.  Pippin also had the cool idea to add the ability to show an item to <em>all</em> logged-in users, or <em>all </em>logged-out users, so the video screenshots will look different from the end result of version 1.0.  I think this was a cool addition, so thanks Pippin for the idea and for helping me work on it.</p>
<h3>Basic Usage</h3>
<p>Install and activate the plugin like normal. Create a custom menu and add items to it just like you usually would. You will now see the extra fields shown in the screenshot. From here you select to show the item to all logged in users, all logged out users&#8230; or to customize by role. If you chose customize by role, then you can use the checkboxes to determine which roles should be allowed to see this particular menu item. If you choose customize by role and do not check any roles, then the item will show to everyone just like it used to. There isn&#8217;t any more to it than that. It should be pretty straight-forward.</p>
<h3>Download</h3>
<p>Now available in the <a title="Nav Menu Roles in the WordPress Plugin Repo" href="http://wordpress.org/extend/plugins/nav-menu-roles/">WordPress Repo</a>.</p>
<p>Also available via my <a title="Nav Menu Roles on Github" href="https://github.com/helgatheviking/Nav-Menu-Roles" target="_blank">Github repo</a>. Please report any issues at Github.  Download the <a title="Download Nav Menu Roles from github" href="https://github.com/helgatheviking/Nav-Menu-Roles/zipball/master" target="_blank">zipball</a>. It is translation ready, so if you want to send me some translations (there are only about 5 strings) I&#8217;d be happy to add them.</p>
<p>Enjoy! And let me know what you think in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kathyisawesome.com/449/nav-menu-roles/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Absolute PHP Basics for WordPress Newbs</title>
		<link>http://www.kathyisawesome.com/446/absolute-php-basics-for-wordpress-newbs/</link>
		<comments>http://www.kathyisawesome.com/446/absolute-php-basics-for-wordpress-newbs/#comments</comments>
		<pubDate>Fri, 03 Aug 2012 16:40:54 +0000</pubDate>
		<dc:creator>kathy</dc:creator>
				<category><![CDATA[Understanding the Basics]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[theme development]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.kathyisawesome.com/?p=446</guid>
		<description><![CDATA[“I&#8217;m just a designer. I&#8217;m comfortable with CSS but PHP scares me.” Yeah ok, well first off, if you are a designer&#8230;. instead of banging your head into a wall to learn a coding language, why not hire a developer? Some of my best clients have been designers. It is kind of a win, win. [...]]]></description>
				<content:encoded><![CDATA[<p>“I&#8217;m just a designer. I&#8217;m comfortable with CSS but PHP scares me.” Yeah ok, well first off, if you are a designer&#8230;. instead of banging your head into a wall to learn a coding language, why not hire a developer? Some of my best clients have been designers. It is kind of a win, win. I get to work on pretty sites and you get to do more designing and less stressing. <a title="Contact" href="http://www.kathyisawesome.com/contact/">Send me an email</a> and let&#8217;s see if I can help.</p>
<p>But if you insist on trying to defy your right-brained designery nature and become more left-brained here are a couple of points that I think will help you as you try to learn both PHP and its sub-dialect of WordPress.</p>
<h3>Function Function What&#8217;s Your Function</h3>
<p>Functions do things. Ever learn about functions in middle school math class? Magic black-boxes where numbers go and come out as something else? Well it is pretty much the same. Let&#8217;s start with the simplest function possible, a nice spin off on the classic “hello world”.</p>
<pre class="brush: php; title: ; notranslate">
function hello_bacon(){
  echo “hello bacon”;
}

hello_bacon(); // prints: hello bacon
</pre>
<p>But not all functions echo out a value because we don&#8217;t always want to echo (which is just another way to print something) a value out right away. Sometimes we need to process it more, etc. In that case you&#8217;d return a value. Returning a value is just the opposite of echoing a value. It says, don&#8217;t print it right now, save it for later.</p>
<pre class="brush: php; title: ; notranslate">
function hello_bacon(){
   return “hello bacon”;
}

hello_bacon(); // prints: NOTHING! oh hold up!
</pre>
<p>To print it later we&#8217;d have to actually echo out the function.</p>
<pre class="brush: php; title: ; notranslate">
echo hello_bacon();
</pre>
<p>or</p>
<pre class="brush: php; title: ; notranslate">
$hello = hello_bacon();
echo $hello; // prints: hello bacon
</pre>
<p>See what we did there in that second one? We defined a variable, which if you&#8217;ll remember from math class is a bit of an amorphous blob that can have any value. Then we set that variable equal to the value returned from the hello_bacon() function.</p>
<h3>Getting into Arguments</h3>
<p>The hello_bacon() function is obviously super simple. It always returns the same thing. Well that&#8217;s not so much fun and sort of defeats the purpose of a function. Remember those magic black boxes? Well now we want to take a variable in, manipulate it and spit it back as something new and shiny. We send variables into functions as arguments to that function.</p>
<pre class="brush: php; title: ; notranslate">
function favorite_food($food){
   echo 'My favorite food is ' . $food;
}

favorite_food(); //prints: My favorite food is &lt;--didn't pass an argument so $food is empty, and I'm hungry.
favorite_food('guacamole'); //prints: My favorite food is guacamole
</pre>
<p>As you can see above, the favorite_food() function accepts 1 argument. Inside of the favorite_food() function this argument will be referred to by the variable $food. This sort of touches on a concept that we&#8217;ll get into in a bit, called variable scope. But for now remember that $food does not exist outside the favorite_food() function.</p>
<pre class="brush: php; title: ; notranslate">
favorite_food('guacamole'); //still prints: My favorite food is guacamole
echo $food; //nothing doing
</pre>
<p>If you need to ensure that you never get an empty value for “My favorite food is ____” then you can give an argument a default. If you don&#8217;t pass an argument when calling a function it will simply use the default. Note below that &#8216;bacon&#8217; is the default value of the $food variable.</p>
<pre class="brush: php; title: ; notranslate">
function favorite_food($food = 'bacon'){
   echo 'My favorite food is ' . $food;
}

favorite_food(); //prints: My favorite food is bacon
favorite_food('guacamole'); //prints: My favorite food is guacamole
</pre>
<p>By now you might have noticed that we&#8217;ve only been dealing with what are called, &#8216;string&#8217; variable types&#8230;. words or letters essentially. You&#8217;ve been seeing me combine strings together with a period (.) in what is called string concatenation. But just like math class, PHP functions work on numbers.</p>
<pre class="brush: php; title: ; notranslate">
function double($x){
   return $x * 2;
}

$a = 10;
$a = double($a);
echo $a; //prints: 20
</pre>
<h3>Variable Scope</h3>
<p>Whoa hold up! You just said the argument was called $x, but there you go calling it $a. Yup. Remember when I said it was important to remember that variables (usually) only exist inside the function where they are defined. That is what is called variable scope. In PHP and WordPress you can declare variables as global in scope, meaning $x has the same value everywhere, but by default variables are local in scope, meaning again, they only exist within the functions using them.</p>
<p>I could rewrite the above to be:</p>
<pre class="brush: php; title: ; notranslate">
function double($guacamole){
   return $guacamole * 2;
}

$bacon = 10;
$bacon = double($bacon);
echo $bacon; //prints: 20
</pre>
<p>I can call the variables anything I want, because the $guacamole in the double() function is not the same as the $bacon outside of it. Remember variables are placeholders. Think of it like the two are playing catch. In the following line:</p>
<pre class="brush: php; title: ; notranslate">
$bacon = double($bacon);
</pre>
<p>We are passing a value to the double() function. The function then catches the value as its argument.</p>
<pre class="brush: php; title: ; notranslate">
function double($guacamole)
</pre>
<p>Now the variable has a new name, but the same value. In the example the value was 10, that part isn&#8217;t any different. Within the function the variable $guacamole now has a value of 10. Then it performs its multiplication and sends back the doubled value. The is the pass back.</p>
<pre class="brush: php; title: ; notranslate">
return $guacmole *2;
</pre>
<p>And that brings us back to:</p>
<pre class="brush: php; title: ; notranslate">
$bacon = double($bacon);
</pre>
<p>where the variable $bacon catches the return pass, and the variable $bacon is now equal to 20, which we see when we echo $bacon.</p>
<p>So it is like playing catch. If you are out in the yard playing catch with someone who doesn&#8217;t speak the same language as you and you toss the ball to your partner, when he catches it, he might call it a beisbol. When he throws it back to you, it is a baseball again, you both just had different words (variables) for it.</p>
<p>This is the official PHP manual that might help explain things if my metaphors made it clear as mud.</p>
<p>http://php.net/manual/en/language.variables.scope.php</p>
<h3>In Summary</h3>
<p>We covered functions, function arguments, string variables, numeric variables and variable scope.   There is quite a bit more, but I already feel like this is a lot actually and hopefully you are well on your way to programming hell&#8230; I mean bliss.  Please point out any errors or places where I could be more clear, but keep Thematic and WordPress specific questions for their respective forums.  Best of luck.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.kathyisawesome.com/446/absolute-php-basics-for-wordpress-newbs/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Radio Buttons for Taxonomies</title>
		<link>http://www.kathyisawesome.com/441/radio-buttons-for-taxonomies/</link>
		<comments>http://www.kathyisawesome.com/441/radio-buttons-for-taxonomies/#comments</comments>
		<pubDate>Thu, 12 Jul 2012 15:44:59 +0000</pubDate>
		<dc:creator>kathy</dc:creator>
				<category><![CDATA[Plugins]]></category>

		<guid isPermaLink="false">http://www.kathyisawesome.com/?p=441</guid>
		<description><![CDATA[Every now and then I run across a client who needs a taxonomy where the user is restricted to only allowing one term per post.  I&#8217;ve also seen people wanting this a few times for categories, and I, myself, have wished for it a few times.  Sometimes a post needs to be like a piece of paper [...]]]></description>
				<content:encoded><![CDATA[<div id="attachment_443" class="wp-caption alignright" style="width: 314px"><img class="size-full wp-image-443 " title="Radio Buttons for Taxonomies Screenshot 2" src="http://www.kathyisawesome.com/wp-content/uploads/screenshot2.png" alt="Radio Buttons for Taxonomies!" width="304" height="350" /><p class="wp-caption-text">Radio Buttons for Taxonomies! Unfortunately the subject can no longer be <em>both </em>guacamole <strong>and </strong>bacon. You&#8217;ll have to chose.</p></div>
<p>Every now and then I run across a client who needs a taxonomy where the user is restricted to only allowing <strong>one </strong>term per post.  I&#8217;ve also seen people wanting this a few times for categories, and I, myself, have wished for it a few times.  Sometimes a post needs to be like a piece of paper in a folder&#8230; and only be in 1 dang folder at a time.  Some might argue that categorization with a single, exclusive term is more-suited to post <em>meta</em>, and they might be right, but the ability to list all the existing terms is lacking from a post meta implementation.</p>
<p>So, the problem is checkboxes&#8230; checkboxes let users check <em>more</em> than one box.  So, the solution is then radio buttons!  Which enforce a single selection.  There are a few tutorials floating around on the interwebs on how to do this.</p>
<p>Hands-down, the <a title="How to Use Radio Buttons in Taxomies" href="http://wp.tutsplus.com/tutorials/creative-coding/how-to-use-radio-buttons-with-taxonomies/" target="_blank">best tutorial on radio buttons with taxonomies</a> was written by Stephen Harris, so I owe him a huge debt for providing most of the guts of my plugin.  His OOP class implementation allowed you to define some variables, such as taxonomy and post type&#8230; and the class would do the rest, but only for a single taxonomy.  Well the whole point of OOP-style programming is that you can re-use it!  I set about building a standard plugin container with a settings page where you can check which taxonomies you&#8217;d like to convert to radio buttons.  I would then create a new object based on each of these taxonomies.  So I had to tweak Stephen&#8217;s class so that I could use it to create new objects (basically just switched his load method to __contruct() and pass those objects a parameter, namely the taxonomy.  I scrapped the other parameters.   The div id will just be standardized based on the taxonomy and the metabox will be changed for every post type that uses a particular taxonomy.</p>
<div id="attachment_442" class="wp-caption alignright" style="width: 399px"><img class="size-full wp-image-442 " title="radio buttons for taxonomy screenshot 1" src="http://www.kathyisawesome.com/wp-content/uploads/screenshot11.png" alt="Radio Buttons for Taxonomies settings configuration" width="389" height="250" /><p class="wp-caption-text">Now it is super simple to convert any taxonomy to radio buttons</p></div>
<h3>Installation Instructions</h3>
<ol>
<li>Install Plugin</li>
<li>Activate Plugin</li>
<li>Go to Settings&gt;Radio Buttons for Taxonomies</li>
<li>Check which taxonomies you&#8217;d like to convert to taxonomies and click Save Changes</li>
</ol>
<p>Literally, that&#8217;s it.  And now when you return to your edit your post you will see the new metabox.  Hope you enjoy!  I have a few ideas for improvements, such as better error handling when you try to add new terms and getting radio buttons in the quick edit, but this should get you started.</p>
<h3>Download</h3>
<p><a href="http://wordpress.org/extend/plugins/radio-buttons-for-taxonomies/" title="Download Radio Buttons for Taxonomies Plugin" target="_blank">Download from the official WordPress Directory</a></p>
<p>or you can track, contribute to the development, or <a href="https://github.com/helgatheviking/Radio-Buttons-for-Taxonomies" title="Radio Buttons for Taxonomies on github" target="_blank">fork me at at Github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kathyisawesome.com/441/radio-buttons-for-taxonomies/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>A Newbie&#8217;s Guide to Thematic Hooks and Functions</title>
		<link>http://www.kathyisawesome.com/412/thematic-hooks-and-functions/</link>
		<comments>http://www.kathyisawesome.com/412/thematic-hooks-and-functions/#comments</comments>
		<pubDate>Tue, 10 Jul 2012 02:40:25 +0000</pubDate>
		<dc:creator>kathy</dc:creator>
				<category><![CDATA[Understanding the Basics]]></category>
		<category><![CDATA[basics]]></category>
		<category><![CDATA[Thematic]]></category>

		<guid isPermaLink="false">http://www.kathyisawesome.com/?p=412</guid>
		<description><![CDATA[When people start wanting to customize WordPress or specifically, Thematic, I always see questions like: How do I add &#8220;something&#8221;, &#8220;somewhere&#8221;? or How do I remove &#8220;something&#8221; from &#8220;somewhere&#8221;? or How do I change &#8220;something&#8221;? At first it is easy to think that adding a div to the #header is different from adding a menu [...]]]></description>
				<content:encoded><![CDATA[<p>When people start wanting to customize WordPress or specifically, Thematic, I always see questions like:</p>
<blockquote><p>How do I add &#8220;something&#8221;, &#8220;somewhere&#8221;?</p></blockquote>
<p>or</p>
<blockquote><p>How do I remove &#8220;something&#8221; from &#8220;somewhere&#8221;?</p></blockquote>
<p>or</p>
<blockquote><p>How do I change &#8220;something&#8221;?</p></blockquote>
<p>At first it is easy to think that adding a div to the #header is different from adding a menu to the #footer, but once you understand <em>how </em>filters and action hooks work, you&#8217;ll see these questions really all follow the same pattern. You just need to learn how to speak WordPress! Be patient with yourself, because you literally are learning a new language&#8230; especially if you aren&#8217;t already familiar with PHP.  I&#8217;ll be using examples for working with the <a class="theme-link" href="http://thematictheme.com" title="Thematic Theme Framework" rel="home">Thematic Theme Framework</a> but you don&#8217;t understanding hooks and functions and eventually filters will be handy in any WordPress project.  Let&#8217;s start&#8230;</p>
<h3>What the heck is an Action Hook</h3>
<p>Action hooks look like this:</p>
<pre class="brush: php; title: ; notranslate">

do_action('this_is_the_action_hook_name');

</pre>
<p>Now in Thematic most of these are buried in the library/extensions folder.  In fact, in the actual templates (like index.php, category.php etc) you will see hooks that look more like:</p>
<pre class="brush: php; title: ; notranslate">

// action hook for placing content above the index loop
 thematic_above_indexloop();

</pre>
<p>But if you go searching for the definition of that function you will find that it is in content-extensions.php</p>
<pre class="brush: php; title: ; notranslate">

/**
 * Register action hook: thematic_above_indexloop
 *
 * Located in index.php
 * Just before the loop
 */
function thematic_above_indexloop() {
 do_action('thematic_above_indexloop');
} // end thematic_above_indexloop

</pre>
<p>Now an action hook is sort of like a parking spot. Some are empty, some have cars on them. you can move the cars around, but the spots themselves stay put. When wordpress gets to an action hook, it will run all the functions that are attached to that particular hook. If it gets to a parking spot and finds a car, it will run that car. If not, then it will continue on to the next hook/space.</p>
<h3>How To Add Any Function to any Hook</h3>
<p>A completely fictitious example:</p>
<pre class="brush: php; title: ; notranslate">
function function_you_want_to_add(){
echo &quot;I heart bacon!&quot;;
}
add_action('destination_hook','function_you_want_to_add', $priority, $args );
</pre>
<p>The add_action line is doing the heavy lifting here, and always takes this same &#8220;form&#8221;&#8230;. it sort of reads like this in english:</p>
<blockquote><p>Add the function called &#8216;function_you_want_to_add&#8217; to the hook called &#8216;destination_hook&#8217; in the order of $priority with some optional extra arguments called $args.</p></blockquote>
<p>You can read all about <a title="add_action in the Codex" href="http://codex.wordpress.org/Function_Reference/add_action" target="_blank">add_action in the WordPress Codex</a> (hint: there is a TON of info there, but I understand it can be overwhelming at first).</p>
<p>The $priority is always a number. It is like a traffic cop in the parking lot, or maybe just an orange cone. if more than 1 function wants to be on a particular hook the priority decides which goes first. If 2 cars wanted to be in the same spot, the one with the lower number priority would get ground level parking and the one with the higher priority would be stacked on top. Yay 3-d parking! Sorry, prepare yourself we are going to beat this metaphor to death. The default priority is 10, so if you don&#8217;t need to change that you don&#8217;t even need to define it in your add_action line.</p>
<p>Some hooks pass additional variables to the functions that operate on them, but this is pretty advanced so for an introductory primer we will ignore it.</p>
<p>Now, a practical example:</p>
<pre class="brush: php; title: ; notranslate">
function function_you_want_to_add(){
echo &quot;I heart bacon!&quot;;
}
add_action('thematic_above_indexloop','function_you_want_to_add');
</pre>
<p>If you add the practice example to your child theme&#8217;s functions.php you will see &#8220;I heart bacon!&#8221; appear on your blog page. Now leave that there and add the following just underneath it in your functions.php.</p>
<pre class="brush: php; title: ; notranslate">
function kia_another_function(){
echo &quot;Guacamole makes me happy!
&quot;;
}
add_action('thematic_above_indexloop','kia_another_function', 5);
</pre>
<p>Notice the priority number is 5. This means it has a lower priority number than the first function, which is 10 by default since we didn&#8217;t specify anything. When you reload your theme you should now see Guacamole makes me happy! on the blog index above the line about loving bacon. Bacon and guacamole together. It must be code heaven.</p>
<h3>How to Remove Something From a Hook</h3>
<p>removing stuff works a bit differently:</p>
<pre class="brush: php; title: ; notranslate">
function remove_stuff(){
remove_action('hook_location','function_you_want_to_remove',$priority );
}
add_action('init','remove_stuff');
</pre>
<p>In english this sort of translates to:</p>
<blockquote><p>When WordPress runs the init hook, please remove the function called &#8220;function_you_want_to_remove&#8221; that is located on the hook called &#8220;hook_location&#8221; with a priority of $priority.</p></blockquote>
<p>init is just a WordPress hook. in fact, it is the one of the earliest hooks that run when WP starts whirring&#8230; it is like priority parking. You can see most all of the hooks that run in the WordPress process again at the Codex: <a title="WordPress Codex Hook Reference" href="http://codex.wordpress.org/Plugin_API/Action_Reference" target="_blank">Action Hooks</a>  To remove something that had a specific priority originally, you must remove_action it with the same priority.  A good practical example would be removing the Thematic blog title.</p>
<pre class="brush: php; title: ; notranslate">
function remove_thematic_header(){
remove_action('thematic_header','thematic_blogtitle', 3);
}
add_action('init','remove_thematic_header');
</pre>
<p>Paste the above into your functions.php, reload your child theme and poof the blog title is gonzo!</p>
<p>Moving the #access menu is another practical example, that combines adding and removing functions.  I&#8217;ll include it here because I see this question asked all the time.</p>
<pre class="brush: php; title: ; notranslate">
function remove_thematic_header(){
remove_action('thematic_header','thematic_access', 9);
}
add_action('init','remove_thematic_header');
add_action('thematic_aboveheader','thematic_access');
</pre>
<p>Note that we don&#8217;t have to define thematic_access, because it already is defined by thematic. We can simply add_action it to a new parking spot.</p>
<h3>Overrides R&#8217; Us</h3>
<p>Thematic has a bunch of functions built in that if you define them, they auto<em>magically</em> replace the function thematic was going to add to a specific hook, with your custom function.  In WordPress parlance, this is called a pluggable function.  Many thematic functions can be overridden by copying a thematic function to your functions.php and altering the function&#8217;s prefix from thematic_ to childtheme_override_.  The overrides completely change the car that is parked on a particular parking spot but they don&#8217;t change its location.</p>
<p>For instance to override the thematic_blog_description you could put the following in your functions.php</p>
<pre class="brush: php; title: ; notranslate">
function childtheme_override_blogdescription(){
echo &quot;Evil laugh! Now your blog is only about bacon!&quot;;
}
</pre>
<p>Refresh your theme and you will see the blog description has been taken over by bacon. , which I think is neat.  Note that with pluggable functions you do <em>not</em> need to also call add_action.  Doing so will add the function twice.  Most functions in thematic have this override capability, but not all.  You can browse through the extensions folder (look but don&#8217;t touch the parent theme!)</p>
<p>If you see something like:</p>
<pre class="brush: php; title: ; notranslate">
if ( function_exists('childtheme_override_blogdescription') )
</pre>
<p>That&#8217;s a sign that you can use the override feature.  The full IF statement reads something like:</p>
<blockquote><p>If you define a child_theme_override function then Thematic will add your custom function to the appropriate hook instead of its own function.</p></blockquote>
<p>Overrides are significantly more intuitive than filters, but filters can be more elegant: the scalpel instead of a broadsword if you don&#8217;t need to change the entire function.  However, this post is crazy long, so I will leave filters for the next part of series.</p>
<h3>Additional Resources</h3>
<p>To help you know what hooks are available in Thematic, here are 2 visual aids:</p>
<p><a href="http://www.bluemandala.com/thematic/thematic-structure.html" rel="nofollow">http://www.bluemandala.com/thematic/thematic-structure.html</a></p>
<p><a href="http://visualizing.thematic4you.com/" rel="nofollow">http://visualizing.thematic4you.com</a></p>
<h3>Additional Help</h3>
<p>I&#8217;ve tried to make this as beginner-friendly as possible, but I&#8217;ve been doing this for a few years now and so it makes total sense to me. Please let me know in the comments if something about this tutorial is not clear so that I can make it better.</p>
<p>Also, I don&#8217;t have time to respond to specific support requests in the comments. If you have Thematic questions post them at the Thematic Forums or <a title="Contact" href="http://www.kathyisawesome.com/contact/" target="_blank">contact me for some premium support</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kathyisawesome.com/412/thematic-hooks-and-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>KIA Subtitle</title>
		<link>http://www.kathyisawesome.com/436/kia-subtitle/</link>
		<comments>http://www.kathyisawesome.com/436/kia-subtitle/#comments</comments>
		<pubDate>Mon, 02 Jul 2012 21:50:06 +0000</pubDate>
		<dc:creator>kathy</dc:creator>
				<category><![CDATA[Plugins]]></category>
		<category><![CDATA[subtitle]]></category>

		<guid isPermaLink="false">http://www.kathyisawesome.com/?p=436</guid>
		<description><![CDATA[Recently I was working on a project and needed a subtitle. There are probably two subtitle plugins already in existence. I happened to pick The Subtitle by Luc Princen, which worked pretty much as intended except the actually input box wasn&#8217;t always where it was supposed to be and I found that admin notices seemed [...]]]></description>
				<content:encoded><![CDATA[<div id="attachment_438" class="wp-caption alignnone" style="width: 592px"><a href="http://www.kathyisawesome.com/wp-content/uploads/screenshot1.png"><img class="size-full wp-image-438" title="KIA Subtitle Screenshot" alt="" src="http://www.kathyisawesome.com/wp-content/uploads/screenshot1.png" width="582" height="229" /></a><p class="wp-caption-text">now our subtitle input is always in the right place</p></div>
<p>Recently I was working on a project and needed a subtitle. There are probably two subtitle plugins already in existence. I happened to pick <a title="Luc Princen The Subtitle" href="http://www.to-wonder.com/the-subtitle" target="_blank">The Subtitle by Luc Princen</a>, which worked pretty much as intended except the actually input box wasn&#8217;t always where it was supposed to be and I found that admin notices seemed to make it pretty unreadable and not totally obvious to my clients.</p>
<p>Well instead of seeing if this problem was solved in the other, already-available plugin, I did what I always do when I have more important things I could be working on: I fixed it. I went ahead and tweaked a bunch of other things too: like moving the plugin into a class (I have no idea if this is beneficial, but I feel smart doing it so I do), not <em>saving</em> &#8220;Subtitle&#8221; as the meta on posts with no subtitle instead of relying on the callbacks to not display it.  Making it translation-ready&#8230; with a whopping 1 translatable string.  Oh and just because I am all multi-lingual like that (meaning I can use translate.google.com) I translated it into french and spanish.</p>
<h3>USAGE</h3>
<p>Usage is covered in the readme.txt but I&#8217;ll cover it again here.  Wherever you want to <strong>echo<em> </em></strong>the subtitle, you&#8217;d use the <strong>the_subtitle()</strong> template tag.  We&#8217;re wrapping it in the function_exists wrapper in case you decide to uninstall the plugin (why?), this way your theme won&#8217;t break.</p>
<pre class="brush: php; title: ; notranslate">

if(function_exists('the_subtitle')) the_subtitle();

</pre>
<p>As of version 1.2, <strong>the_subtitle()</strong> accepts three parameters: a string to come before the subtitle, a string to come after the subtitle, and whether or not to echo the subtitle: true by default.  Basically we are mimicking the capabilities of WordPress&#8217;s default <strong>the_title()</strong> function.</p>
<p>So for example, you can wrap the subtitle in some HTML tags using the first two parameters:</p>
<pre class="brush: php; title: ; notranslate">

if(function_exists('the_subtitle')) the_subtitle( '&lt;h2 class=&quot;subtitle&quot;&gt;', '&lt;/h2&gt;');

</pre>
<p>If you need to <strong>return</strong> the value, much like the default WordPress functions, you can use <strong>get_the_subtitle()</strong> which accepts a $post_id parameter if you need to use it outside the loop.  If you do not supply a $post_id, it will automatically grab the ID from the current post.  But if you supplied a number there, you could ostensibly use it to grab the subtitle of another post.</p>
<pre class="brush: php; title: ; notranslate">

if(function_exists('the_subtitle')) $subtitle = get_the_subtitle($post_id);

</pre>
<p>Oh, and I left the shortcode in tact, though I can&#8217;t figure out why you&#8217;d use the shortcode instead of just straight typing into the post editor.  But if you want it, it is still:</p>
<pre>[ the-subtitle ]</pre>
<p>with no spaces.</p>
<h3>To DO:</h3>
<p>I&#8217;m wondering if it is worthwhile to add a subtitle column to the edit screen and if I should then add it to the &#8220;quick edit&#8221;. Let me know your opinion in the comments!</p>
<h3>Download</h3>
<p>Now available at WordPress: <a title="KIA Subtitle in WordPress Plugin Directory" href="http://wordpress.org/extend/plugins/kia-subtitle/" target="_blank">KIA Subtitle at WordPress</a></p>
<p>or check it out at the <a title="KIA Subtitle Github" href="https://github.com/helgatheviking/KIA-Subtitle" target="_blank">KIA Subtitle github repo</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kathyisawesome.com/436/kia-subtitle/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Thematic 1.0.1 Upgrade Breaks Your Menu</title>
		<link>http://www.kathyisawesome.com/433/thematic-upgrade-breaks-menu/</link>
		<comments>http://www.kathyisawesome.com/433/thematic-upgrade-breaks-menu/#comments</comments>
		<pubDate>Thu, 31 May 2012 19:56:39 +0000</pubDate>
		<dc:creator>kathy</dc:creator>
				<category><![CDATA[Thematic]]></category>

		<guid isPermaLink="false">http://www.kathyisawesome.com/?p=433</guid>
		<description><![CDATA[After a long wait, Thematic 1.0.1 has been live in the WordPress repositories now for a couple of days now! And some issues are starting to crop up in the forum. So far the most recurring issues have to do with the menus. Oh menus, you never cease to cause trouble. The problem is that [...]]]></description>
				<content:encoded><![CDATA[<p>After a long wait, <a href="http://wordpress.org/extend/themes/thematic" target="_blank">Thematic</a> 1.0.1 has been live in the WordPress repositories now for a couple of days now! And some issues are starting to crop up in the forum. So far the most recurring issues have to do with the menus. Oh menus, you never cease to cause trouble.</p>
<p>The problem is that thematic 1.0 underwent some major changes to be compliant with WordPress Theme Review Guidelines and the change with the most impact on menus in particular is our switch to properly enqueing stylesheets and scripts using wp_enqueue_stylesheet and wp_enqueue_script. This has led to some changes to existing functions and the removal of a few old filters that didn&#8217;t make sense anymore given the new approach. You can see the massive changelog in the readme.txt file that comes with Thematic, but really, its huge, so it would be easy to miss the ones that are effecting you.</p>
<h3>I Upgraded and Now My Menu is Broken</h3>
<p>We&#8217;re going to need to diagnose what went wrong based on what you used to be doing and what has changed.</p>
<h4>* Changed: Filter <code>thematic_dropdown_options</code>.</h4>
<p>Were you serving your own modified version of the thematic-dropdowns.js script to tweak the widths of the dropdowns, add arrows, or change the delay on the hover? If so, then you might have been filtering thematic_dropdown_options. This filter used to work like so:</p>
<pre class="brush: php; title: ; notranslate">
function childtheme_dropdown_options() {
$newscript_uri = &quot;\n&quot; . '&lt;script type=&quot;text/javascript&quot; src=&quot;' . get_stylesheet_directory_uri() . ' /scripts/thematic-dropdowns.js&quot;&gt;&lt;/script&gt;' . &quot;\n&quot;;
 return $newscript_uri;
}
add_filter('thematic_dropdown_options','childtheme_dropdown_options');
</pre>
<p>in that you needed to return the whole script tag. That is no longer the case and now you need only to return the URL of the script like so:</p>
<pre class="brush: php; title: ; notranslate">
function childtheme_dropdown_options() {
 $newscript_uri = get_stylesheet_directory_uri() . '/scripts/thematic-dropdowns.js';
 return $newscript_uri;
}
add_filter('thematic_dropdown_options','childtheme_dropdown_options');
</pre>
<p>&nbsp;</p>
<h4>* Removed: Variable <code>thematic_use_superfish</code>. * Added: <code>add_theme_support('thematic_superfish')</code></h4>
<p>We&#8217;ve switched to using the WordPress function add_theme_support to determine whether to load the superfish scripts. Previously there was a filter called themtatic_use_superfish, that you could target to remove the dropdown scripts if you didn&#8217;t need them.</p>
<pre class="brush: php; title: ; notranslate">
function childtheme_no_superfish(){
 return FALSE; // we don't want any of your vegetables!
}
add_filter('thematic_use_superfish','childtheme_no_superfish');
</pre>
<p>or if you were being super elegant, perhaps you killed the dropdowns with this:</p>
<pre class="brush: php; title: ; notranslate">
add_filter('thematic_use_superfish','__return_FALSE');
</pre>
<p>But, we&#8217;ve ditched this filter in favor of using WordPress&#8217; theme support feature. It is an easy switch. If you don&#8217;t want to load any of the superfish, dropdown scripts then you should now do it this way: <a name="kill-dropdowns"></a></p>
<pre class="brush: php; title: ; notranslate">
function childtheme_no_superfish(){
 remove_theme_support('thematic_superfish');
}
add_action('thematic_child_init','childtheme_no_superfish');
</pre>
<p>Note that thematic_child_init is a new action hook, that is specifically placed to remove any theme supports added by thematic. </p>
<h4>* Removed: Filter <code>thematic_head_scripts</code>.</h4>
<p>To be fair this one isn&#8217;t in the readme as far as I can see, but the problem is similar to the issue with thematic-dropdowns.js. Maybe you were using this filter to you maybe wanted to remove all the superfish and supersubs scripts because you don&#8217;t use dropdowns. Or perhaps you were adding your own scripts here.</p>
<pre class="brush: php; title: ; notranslate">
function childtheme_scripts($scripts){
 return FALSE; //we don't want any of your vegetable scripts!
}
add_filter('thematic_head_scripts','childtheme_scripts');
</pre>
<p>or if you were adding a scripts of your own, maybe you did something like this:</p>
<pre class="brush: php; title: ; notranslate">
function childtheme_scripts($scripts){
 $scripts . = &quot;\n&quot; . '&lt;script type=&quot;text/javascript&quot; src=&quot;' . get_stylesheet_directory_uri() . ' /scripts/thematic-dropdowns.js&quot;&gt;&lt;/script&gt;' . &quot;\n&quot;;
 return $scripts;
}
add_filter('thematic_head_scripts','childtheme_scripts');
</pre>
<p>As before, we are now using using wp_enqueue_script, so thematic_head_scripts() is now only a function that is added to the wp_enqueue_scripts hook. You can remove it entirely the same way you remove any action:</p>
<pre class="brush: php; title: ; notranslate">
function childtheme_remove_scripts(){
 remove_action('wp_enqueue_scripts','thematic_head_scripts');
}
add_action('init','childtheme_remove_scripts');
</pre>
<p>or possibly you were using the override:</p>
<pre class="brush: php; title: ; notranslate">
function childtheme_override_head_scripts(){
 // absolutely no bacon here
}
</pre>
<p>However, that is a bit of a nuclear bomb approach and will also wipe out an important script for handling comment replies, which you may or may not need. But thematic is super granular and you can use a scalpel to kill the drop downs scripts quite easily instead of using a viking war hammer with the <a href="#kill-dropdowns">remove_theme_support</a>scrap of code from earlier.</p>
<p>If instead, you need to load more scripts, then you should make like Thematic and use wp_enqueue_script.</p>
<pre class="brush: php; title: ; notranslate">
function childtheme_scripts(){
 wp_enqueue_script('bacon-script', get_stylesheet_directory_uri . '/scripts/bacon.js', array('jquery'), '1.0', true);
 wp_enqueue_script('guacmole-script', get_stylesheet_directory_uri . '/scripts/guac.js', array('jquery'));
}
add_action('wp_enqueue_scripts','childtheme_scripts');
</pre>
<p>If you are wondering about why the two lines are different, you can read more about how to use wp_enqueue_script in the WordPress Codex:</p>
<h4>* Changed: Function <code>thematic_create_stylesheet</code> to <code>wp_enqueue_style</code>.<br />
* Removed: filter <code>thematic_create_stylesheet</code>.</h4>
<p>I saw this come up in the forum already. Someone was using the thematic_create_stylesheet filter to add extra stylesheets to the header. Something along the lines of :</p>
<pre class="brush: php; title: ; notranslate">
function childtheme_create_stylesheet($style) {
 $style .= '';
 return $style;
}
add_filter('thematic_create_stylesheet', 'childtheme_create_stylesheet');
</pre>
<p>Well that filter is gone like a bowl of my famous guacamole, so if you need to add more stylesheets, then we&#8217;ll have to add them the updated way&#8230; which by the by, will work better with any caching plugins you might be using and prevents the same style from being loaded twice (like if you were loading the supersized script&#8217;s css and then you had a plugin that was also trying to load the same stylesheet).<br />
Thematic is now loading the main stylesheet like so:</p>
<pre class="brush: php; title: ; notranslate">
function thematic_create_stylesheet() {
 wp_enqueue_style( 'thematic_style', get_stylesheet_uri() );
}
add_action('wp_enqueue_scripts','thematic_create_stylesheet');
</pre>
<p>I can&#8217;t think of too many reasons why you&#8217;d ever need to change that. Your theme will always need a style.css in order to be a valid theme. But if you need to add more stylesheets, it is going to work just like enqueueing scripts except we use a slightly different function, <a href="http://codex.wordpress.org/Function_Reference/wp_enqueue_style" target="_blank">wp_enqueue_style</a>.</p>
<pre class="brush: php; title: ; notranslate">
function childtheme_create_stylesheet() {
 wp_enqueue_style( 'blue_style', get_stylesheet_directory_uri() . '/styles/blue.css' );
}
add_action('wp_enqueue_scripts','childtheme_create_stylesheet');
</pre>
<h3>Oh Noes! My menu is still broken!</h3>
<p>Well, head to the support forums and start a new thread. Here is a tip for getting better support: do NOT just say &#8220;my menu won&#8217;t work&#8221;. This tells me and the other volunteers absolutely nothing and makes it impossible to help you. Be precise when describing exactly what you are trying to accomplish, what you are seeing/experiencing now, compare that to what you were experiencing before hand, and tell us anything that you might have already tried. Screenshots can be helpful as can links to your live site.</p>
<p><a title="Thematic Support Forums" href="http://thematictheme.com/forums/" target="_blank">Thematic Support Forums</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kathyisawesome.com/433/thematic-upgrade-breaks-menu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Use Multiple WYSIWYG (TinyMCE) Visual Editors in Your WordPress Metaboxes</title>
		<link>http://www.kathyisawesome.com/426/multiple-wordpress-wysiwyg-visual-editors/</link>
		<comments>http://www.kathyisawesome.com/426/multiple-wordpress-wysiwyg-visual-editors/#comments</comments>
		<pubDate>Thu, 08 Mar 2012 04:55:23 +0000</pubDate>
		<dc:creator>kathy</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[metaboxes]]></category>
		<category><![CDATA[scripts]]></category>
		<category><![CDATA[tinymce]]></category>
		<category><![CDATA[WP Alchemy]]></category>

		<guid isPermaLink="false">http://www.kathyisawesome.com/?p=426</guid>
		<description><![CDATA[Ever since WordPress invented the metabox, people have been trying to put the rich text editor (in WP this is provided by TinyMCE) into their metaboxes.  And it makes sense.  Sure us uber-geeks know the HTML tags required to make some text bold, but most of the world does not., but they do know how [...]]]></description>
				<content:encoded><![CDATA[<p>Ever since WordPress invented the metabox, people have been trying to put the rich text editor (in WP this is provided by TinyMCE) into their metaboxes.  And it makes sense.  Sure us uber-geeks know the HTML tags required to make some text bold, but most of the world does not., but they do know how to click on the &#8220;B&#8221; button.  So if we&#8217;re building a theme that requires multiple blocks of content it&#8217;s nice to reuse the visual editor.</p>
<p>I&#8217;ve been using the <a href="http://www.farinspace.com/wpalchemy-metabox/" target="_blank">WP Alchemy Class</a> by Dimas Begunoff to build my metaboxes for a while now.  It gives a <em>lot </em>of power to build really complicated field sets, especially repeating ones.  For a long time using the visual editor in the metaboxes was elusive.  Dimas wrote an article on <a title="How to Use Multiple WordPress WYSIWYG Visual Editors" href="http://www.farinspace.com/multiple-wordpress-wysiwyg-visual-editors/" rel="bookmark" target="_blank">How to Use Multiple WordPress WYSIWYG Visual Editors</a> and it worked, up to a point.  Because TinyMCE is fickle (and despite their tagline being &#8220;Easy to Integrate&#8221;) this code didn&#8217;t work for repeating groups, which in my mind is the strength of Alchemy.</p>
<p>As of WordPress 3.3 you can finally use the built-in <strong>wp_editor()</strong> function for multiple editors in your metaboxes, but again these must be defined in advance.  You can&#8217;t use this function with WPA&#8217;s dynamically generated fields.</p>
<p>So, repeatable, sortable WYSIWYG (TinyMCE) rich-text editors has been the elusive, ultimate dream of WP Alchemists.  The &lt;cough&gt;&#8221;Holy Grail&#8221;&lt;/cough&gt; of WP Alchemy.  But after a lot of head-banging effort, I think I have it!</p>
<p>I have create a Twenty Eleven child theme that shows WP Alchemy-powered metaboxes with repeatable, sortable, WYSIWYG (tinyMCE-enabled) text editors complete with media buttons.  And as a bonus, it shows a single field using wp_editor() because that also needed a little twist to work with WPA.</p>
<p>Dimas seems to recommend putting the WP Alchemy core files in /wp-content so they are not included in my theme.  You&#8217;ll need to do that (or change my theme to include the WPA class elsewhere), and then simply activate the theme and add a new post to see the boxes in action.  For the curious, and come on you know you are, the real magic is in the kia-metabox.js script.</p>
<p>Download the sample theme from for an idea of how it works:</p>
<div id='wpdm_file_16' class='wpdm_file wpdm-only-button'><div class='cont'><div class='btn_outer'><div class='btn_outer_c' style=''><a class='btn_left  has-counter' rel='16' title='WP Alchemy Holy Grail' href='http://www.kathyisawesome.com/?wpdmact=process&did=MTYuaG90bGluaw=='  >Download</a><span class='btn_right counter'>876 downloads</span></div></div><div class='clear'></div></div></div>
<p><a href="https://github.com/helgatheviking/WP-Alchemy-Holy-Grail-Theme">Fork me on github!</a>  Perhaps we can figure out how to use the quicktags editor when the visual editor is disabled.</p>
<p>Full tutorial to come&#8230;  maybe.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kathyisawesome.com/426/multiple-wordpress-wysiwyg-visual-editors/feed/</wfw:commentRss>
		<slash:comments>53</slash:comments>
		</item>
		<item>
		<title>Create an Alphabetical Glossary of Posts in WordPress</title>
		<link>http://www.kathyisawesome.com/424/alphabetical-posts-glossary/</link>
		<comments>http://www.kathyisawesome.com/424/alphabetical-posts-glossary/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 21:04:02 +0000</pubDate>
		<dc:creator>kathy</dc:creator>
				<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.kathyisawesome.com/?p=424</guid>
		<description><![CDATA[Once up a time i did a client project where i had to have archives organized alphabetically.   I ended up accomplishing by adding a query variable and targeting the posts_where filter.  However, in answering a recent question at WordPress Stack Exchange I decided that it might be neater to create a hidden taxonomy instead.  I [...]]]></description>
				<content:encoded><![CDATA[<p>Once up a time i did a client project where i had to have archives organized alphabetically.   I ended up accomplishing by adding a query variable and targeting the <strong>posts_where</strong> filter.  However, in answering a recent question at <a title="How to Build an Alphabetical WordPress Directory" href="http://wordpress.stackexchange.com/questions/41660/how-to-build-a-directory-with-indexes-in-wordpress/" target="_blank">WordPress Stack Exchange</a> I decided that it might be neater to create a hidden taxonomy instead.  I don&#8217;t know if there is any performance benefit, but the code was a little more elegant and you get prettier permalinks:</p>
<p>site.com/glossary/a</p>
<p>instead of</p>
<p>site.com/?glossary=a</p>
<p>right off the bat without the need to do any complicated htaccess rewrite rules, since everyone knows that mod-rewrite is straight up <em>voodoo</em>.</p>
<h3>Creating a Hidden Taxonomy</h3>
<p>Pretty standard function for registering a taxonomy. Just going to accept a lot of the defaults, and not worry about labels since we&#8217;re going to hide it from the back-end by setting the &#8216;show_ui&#8217; parameter to false. For this example we&#8217;re going to call the taxonomy &#8220;glossary&#8221; and we&#8217;re going to assign it to posts, but we could well have done it for any custom post type.</p>
<pre class="brush: php; title: ; notranslate">
// Add new taxonomy, NOT hierarchical (like tags)
function kia_create_glossary_taxonomy(){
    if(!taxonomy_exists('glossary')){
        register_taxonomy('glossary',array('post'),array(
        'show_ui' =&gt; false
      ));
     }
}
add_action('init','kia_create_glossary_taxonomy');
</pre>
<h3>Automatically Setting Terms for each Post on Save/Update</h3>
<p>It&#8217;d be a pain if we had to actively remember to sort each post by its letter each time we wrote a post. I have enough difficulty just writing a post in the first place. But with some code we can automatically pop off the first letter of the post title and assign that letter as the term in our &#8220;glossary&#8221; taxonomy. The following is the pretty standard function for saving information from a metabox, which works perfectly for our case even though we don&#8217;t have a visible metabox.</p>
<pre class="brush: php; title: ; notranslate">
/* When the post is saved, saves our custom data */
function kia_save_first_letter( $post_id ) {
// verify if this is an auto save routine.
// If it is our form has not been submitted, so we dont want to do anything
if ( defined( 'DOING_AUTOSAVE' ) &amp;&amp; DOING_AUTOSAVE )
return;

//check location (only run for posts)
$limitPostTypes = array('post');
if (!in_array($_POST['post_type'], $limitPostTypes)) return;

// Check permissions
if ( !current_user_can( 'edit_post', $post_id ) )
return;

// OK, we're authenticated: we need to find and save the data
$taxonomy = 'glossary';

//set term as first letter of post title, lower case
wp_set_post_terms( $post_id, strtolower(substr($_POST['post_title'], 0, 1)), $taxonomy );

//delete the transient that is storing the alphabet letters
delete_transient( 'kia_archive_alphabet');
}
add_action( 'save_post', 'kia_save_first_letter' );
</pre>
<h3>Auto-Assigning Terms to existing posts</h3>
<p>If you&#8217;ve had a blog for a while and have a lot of posts the idea of going back and manually saving the posts again sounds worse than pulling our your toenails.  So you can run a little function to do it automatically.  Ideally, if this were a plugin, it&#8217;d run on the plugin&#8217;s activation hook.  Since it&#8217;s not you can just drop it into your functions.php, reload your site (probably 2x for good measure) and then delete the function.  Basically what it will do it grab all your posts, loop through them all, pop off the first letter of the title and assign it to the &#8220;glossary&#8221; taxonomy.</p>
<pre class="brush: php; title: ; notranslate">
//create array from existing posts
function kia_run_once(){
$taxonomy = 'glossary';

$alphabet = array();
$posts = get_posts(array('numberposts' =&gt; -1) );

foreach($posts as $p) :
//set term as first letter of post title, lower case
wp_set_post_terms( $p-&gt;ID, strtolower(substr($p-&gt;post_title, 0, 1)), $taxonomy );
endforeach;
}
add_action('init','kia_run_once');
</pre>
<h3>Finally, Creating the Alphabet &#8220;Menu&#8221;</h3>
<p>Now that we have assigned a term for each existing post and for every post to come in our custom taxonomy, we should display an alphabet menu&#8230;. or some way to access the different Letter archives.  This was the one place were the code was not 10x more elegant than in my first iteration because there was no easy way to test whether a term had a post in it.  Usually, yes, it would&#8230; but if you changed a post name and there were no other posts under a certain letter you could come up with an empty section.  So what I did was get all the terms in the taxonomy with get_terms which hides empty terms by default, loop through that data and store it in an array, then check each letter of the alphabet against that array.  To avoid running through that every single page load, I used the transient API to store the resulting array of alphabet terms.  This array refreshes whenever a post is updated (this actually happens in an earlier code block for the <strong>kia_save_first_letter() function.</strong></p>
<p>For my original project I wanted to have the letters with posts have an active link and the letters without posts in that section just have the letter.  Something like:</p>
<p>A <strong>B</strong> C D<strong> E</strong> &#8230;. and onwards, so I have re-created that effect.</p>
<pre class="brush: php; title: ; notranslate">
$taxonomy = 'glossary';

// save the terms that have posts in an array as a transient
if ( false === ( $alphabet = get_transient( 'kia_archive_alphabet' ) ) ) {
    // It wasn't there, so regenerate the data and save the transient
    $terms = get_terms($taxonomy);

    $alphabet = array();
    if($terms){
        foreach ($terms as $term){
            $alphabet[] = $term-&gt;slug;
        }
    }
     set_transient( 'kia_archive_alphabet', $alphabet );
}

?&gt;

&lt;div id=&quot;archive-menu&quot; class=&quot;menu&quot;&gt;

	&lt;ul id=&quot;alphabet-menu&quot;&gt;

	&lt;?php 
	
	foreach(range('a', 'z') as $i) :              

		$current = ($i == get_query_var($taxonomy)) ? &quot;current-menu-item&quot; : &quot;menu-item&quot;;              

		if (in_array( $i, $alphabet )){ 
			printf( '&lt;li class=&quot;az-char %s&quot;&gt;&lt;a href=&quot;%s&quot;&gt;%s&lt;/a&gt;&lt;/li&gt;', $current, get_term_link( $i, $taxonomy ), strtoupper($i) );
		} else { 
			printf( '&lt;li class=&quot;az-char %s&quot;&gt;%s&lt;/li&gt;', $current, strtoupper($i) );
		} 

	endforeach; 
	
	?&gt;
	&lt;/ul&gt;

&lt;/div&gt;
</pre>
<h3>Future Improvements</h3>
<p>One thing I&#8217;d like to improve upon would be ensuring that the first letter I&#8217;m popping off with the substr PHP function is actually a letter&#8230; or maybe a number, but not a character.  I&#8217;d also like to get it to skip words like The, An, and other pointless words that don&#8217;t really reflect on the subject.  But then this isn&#8217;t a solution for everyone&#8230; if you want to make sure that &#8220;A Post about Bacon&#8221; and &#8220;The Bacon Post&#8221; show up in the same archive, well you should tag them in the <em>Bacon</em> tag and not hope that they show up alphabetically in the right place.  Still it has its uses.  Let me know of any improvememts you make!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kathyisawesome.com/424/alphabetical-posts-glossary/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Customizing the WordPress Install Process with install.php</title>
		<link>http://www.kathyisawesome.com/421/customizing-wordpress-install/</link>
		<comments>http://www.kathyisawesome.com/421/customizing-wordpress-install/#comments</comments>
		<pubDate>Sat, 28 Jan 2012 02:53:06 +0000</pubDate>
		<dc:creator>kathy</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[custom install]]></category>
		<category><![CDATA[jedi]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.kathyisawesome.com/?p=421</guid>
		<description><![CDATA[I came across a super interesting post at WPBits about automating the wordpress installation process.  Some of the parts about where some of the functions are located in WP that allow you to change certain things on the installation are outdated since the post is from 2007, but the concept remains perfectly intact.  If you find [...]]]></description>
				<content:encoded><![CDATA[<p>I came across a super interesting post at WPBits about <a title="Automating the WordPress Install" href="http://wpbits.wordpress.com/2007/08/10/automating-wordpress-customizations-the-installphp-way/" target="_blank">automating the wordpress installation</a> process.  Some of the parts about where some of the functions are located in WP that allow you to change certain things on the installation are outdated since the post is from 2007, but the concept remains perfectly intact.  If you find yourself installing a lot of WordPress blogs and are tired of always having to delete the &#8220;This is your First Post&#8221; post, changing the permalinks etc. then you can take advantage of this little trick.</p>
<h3>Trolling the Source Code Like a Boss</h3>
<p>If you are cruising through source (because there <strong>is</strong> plenty of stuff that isn&#8217;t well documented yet in the Codex) you will see</p>
<pre class="brush: php; title: ; notranslate">

/** Include user install customize script. */
if ( file_exists(WP_CONTENT_DIR . '/install.php') )
 require (WP_CONTENT_DIR . '/install.php');

</pre>
<p>in <em>/wp-admin/includes/upgrade.php</em>.  Now this is interesting because it means that when WordPress installs (or upgrades) it will look for a file called <em>install.php</em> in your <em>/wp-content</em> folder&#8230; or whatever you are using instead of the default <em>/wp-content</em> folder.  This file doesn&#8217;t exist by default but it gives you a chance to run some functions of your own during the installation process (since  <em>/wp-admin/includes/upgrade.php</em> is required by <em>/wp-admin/install.php</em>)</p>
<h3>My First CuSTOM INSTALL.PHP</h3>
<p>I followed WPBit&#8217;s example and decided to show off my new power over WordPress by putting the following into my custom <em>/wp-content/install.php</em> file.</p>
<pre class="brush: php; title: ; notranslate">

No Bacon for You

&lt;br/&gt;Evil Superpowers

&lt;?php exit();?&gt;

</pre>
<p>This obviously isn&#8217;t helpful, but it is a good proof of concept and let&#8217;s you know that you have all the power.  Of course&#8230;</p>
<blockquote><p>With great power comes great responsibility. &#8211; <cite>Uncle Ben</cite></p></blockquote>
<h3>Functions We Can Hijack for Our Own Purposes</h3>
<p>As WPBits explains in more detail, some of the ideal functions to tweak would be:</p>
<ul>
<li><em>wp_install()</em></li>
<li><em>wp_install_defaults()</em></li>
<li><em>wp_new_blog_notification()</em></li>
<li><em>wp_upgrade()</em></li>
</ul>
<p>All of these functions are now (currently version 3.3.1) in <em>/wp-admin/includes/upgrade.php</em> and they are pluggable, meaning they come with an <em>if(function_exists())</em> wrapper that lets you define your own versions to override their behavior.</p>
<p>Since <strong>wp_install_defaults()</strong> is the culprit for creating those useless &#8220;first post&#8221; posts and pages, we&#8217;re going to target it.  I copied the entire function to my own file: <em>/wp-content/install.php</em> and then hacked out all the parts that inserted the first post, first page, the default links in the blogroll (sorry WordPress), and changed the default category from <em>Uncategorized</em> to <em>General</em>.  You can also adjust the widgets that are activated by default, but I thought that was going too far.</p>
<p>I also wanted to change some options, like permalinks, time zone, size of the post editor, banning emoticons, etc.  So I added a bunch of <strong>update_option()</strong> commands.  Just because I thought it&#8217;d be super clever, I updated the ping list, moderate and blacklist comment terms from <strong>text files</strong> by using<strong> file_get_contents()</strong>.</p>
<h3>Automagically Creating Myself as an Admin</h3>
<p>I usually install WP for someone else, I decided that I wanted to create my client&#8217;s account on install and automatically create my own admin account.  I <em>might</em> reverse this process as I don&#8217;t like how the install&#8217;s welcome email doesn&#8217;t include a link to the login screen.  <em>I </em>know that you just tack on wp-login.php but a newbie client might not.  At the same time, the way I have it means I never have to change my credentials in the file&#8230; which I prefer for now.</p>
<p>Anyway, I initially overrode the default <strong>wp_install()</strong> file to do this, by repeating the process of copying the function from <em>/wp-admin/includes/upgrade.php</em> to my own<em> install.php</em>, but it turns out that I can just create a new user from the function I already have.  In that case, I decided to only override one core function.</p>
<p>Here&#8217;s the code I used.  Remember to use it at your own risk.  This is really targeted at people who know what they are doing with WordPress and are installing it on a regular basis.  Take note to change the username and email address for the account you are creating for yourself&#8230; currently they are left as <strong>USERNAME</strong> and <strong>YOU@YOUREMAIL.COM</strong>.  Right now it generates a random password, but that could easily be changed to always assign yourself the same password.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

/**
 * Override Default Installation Content
 * do not create empty page, first test post, default links, default comment, etc
 */
function wp_install_defaults($user_id) {
 global $wpdb, $wp_rewrite, $current_site, $table_prefix;

 /*
 * BEGIN KIA TWEAKS
 * Customize Some Options
 */

 // Set Timezone

 //$timezone = &quot;America/New_York&quot;;
 $timezone = &quot;America/Chicago&quot;;
 //$timezone = &quot;America/Denver&quot;;
 //$timezone = &quot;America/Los_Angeles&quot;;

 update_option('timezone_string',$timezone);

 // Start of the Week
 update_option('start_of_week',0); //0 is Sunday, 1 is Monday and so on

 // Disable Smilies
 update_option('use_smilies', 0);

 // Increase the Size of the Post Editor
 update_option('default_post_edit_rows',40);

 // Update Ping Services
 // http://mrjimhudson.com/wordpress-update-services-use-a-larger-ping-list/
 if ( file_exists(WP_CONTENT_DIR . '/KIA-ping-list.txt') ) {
 $services = file_get_contents('KIA-ping-list.txt', true);
 update_option('ping_sites',$services);
 }

 // Update Comment Moderation List
 // http://perishablepress.com/wordpress-blacklist-characters/
 if ( file_exists(WP_CONTENT_DIR . '/KIA-comment-moderation-list.txt') ) {
 $modlist = file_get_contents('KIA-comment-moderation-list.txt', true);
 update_option('moderation_keys',$modlist);
 }

 // Update Comment Blacklist
 // http://www.pureblogging.com/2008/04/29/create-a-comment-blacklist-in-wordpress-download-my-list-of-spam-words/
 if ( file_exists(WP_CONTENT_DIR . '/KIA-comment-blacklist.txt') ) {
 $blacklist = file_get_contents('KIA-comment-blacklist.txt', true);
 update_option('blacklist_keys',$blacklist);
 }

 // Don't Organize Uploads by Date
 update_option('uploads_use_yearmonth_folders',0);

 // Update Permalinks
 update_option('selection','custom');
 update_option('permalink_structure','/%post_id%/%postname%/');
 $wp_rewrite-&gt;flush_rules();

 // Default category
 $cat_name = __('General');
 /* translators: Default category slug */
 $cat_slug = sanitize_title(_x('General', 'Default category slug'));

 /*
 * Create Self as Admin User. If the user already exists, the user tables are
 * being shared among blogs. Just set the role in that case.
 */
 $self_id = username_exists('USERNAME');
 if ( !$self_id ) {
 $self_password = wp_generate_password( 12, false );
 $self_id = wp_create_user('USERNAME', $user_password, 'YOU@YOUREMAIL.COM');
 update_user_option($self_id, 'default_password_nag', true, true);
 wp_new_user_notification( $self_id, $self_password );
 }

$self = new WP_User($self_id);
 $self-&gt;set_role('administrator');

 /*
 * END KIA TWEAKS
 */

 /*
 * END KIA TWEAKS
 */

if ( global_terms_enabled() ) {
 $cat_id = $wpdb-&gt;get_var( $wpdb-&gt;prepare( &quot;SELECT cat_ID FROM {$wpdb-&gt;sitecategories} WHERE category_nicename = %s&quot;, $cat_slug ) );
 if ( $cat_id == null ) {
 $wpdb-&gt;insert( $wpdb-&gt;sitecategories, array('cat_ID' =&gt; 0, 'cat_name' =&gt; $cat_name, 'category_nicename' =&gt; $cat_slug, 'last_updated' =&gt; current_time('mysql', true)) );
 $cat_id = $wpdb-&gt;insert_id;
 }
 update_option('default_category', $cat_id);
 } else {
 $cat_id = 1;
 }

$wpdb-&gt;insert( $wpdb-&gt;terms, array('term_id' =&gt; $cat_id, 'name' =&gt; $cat_name, 'slug' =&gt; $cat_slug, 'term_group' =&gt; 0) );
 $wpdb-&gt;insert( $wpdb-&gt;term_taxonomy, array('term_id' =&gt; $cat_id, 'taxonomy' =&gt; 'category', 'description' =&gt; '', 'parent' =&gt; 0, 'count' =&gt; 1));
 $cat_tt_id = $wpdb-&gt;insert_id;

// Default link category
 $cat_name = __('Blogroll');
 /* translators: Default link category slug */
 $cat_slug = sanitize_title(_x('Blogroll', 'Default link category slug'));

if ( global_terms_enabled() ) {
 $blogroll_id = $wpdb-&gt;get_var( $wpdb-&gt;prepare( &quot;SELECT cat_ID FROM {$wpdb-&gt;sitecategories} WHERE category_nicename = %s&quot;, $cat_slug ) );
 if ( $blogroll_id == null ) {
 $wpdb-&gt;insert( $wpdb-&gt;sitecategories, array('cat_ID' =&gt; 0, 'cat_name' =&gt; $cat_name, 'category_nicename' =&gt; $cat_slug, 'last_updated' =&gt; current_time('mysql', true)) );
 $blogroll_id = $wpdb-&gt;insert_id;
 }
 update_option('default_link_category', $blogroll_id);
 } else {
 $blogroll_id = 2;
 }

$wpdb-&gt;insert( $wpdb-&gt;terms, array('term_id' =&gt; $blogroll_id, 'name' =&gt; $cat_name, 'slug' =&gt; $cat_slug, 'term_group' =&gt; 0) );
 $wpdb-&gt;insert( $wpdb-&gt;term_taxonomy, array('term_id' =&gt; $blogroll_id, 'taxonomy' =&gt; 'link_category', 'description' =&gt; '', 'parent' =&gt; 0, 'count' =&gt; 7));
 $blogroll_tt_id = $wpdb-&gt;insert_id;

// Set up default widgets for default theme.
 update_option( 'widget_search', array ( 2 =&gt; array ( 'title' =&gt; '' ), '_multiwidget' =&gt; 1 ) );
 update_option( 'widget_recent-posts', array ( 2 =&gt; array ( 'title' =&gt; '', 'number' =&gt; 5 ), '_multiwidget' =&gt; 1 ) );
 update_option( 'widget_recent-comments', array ( 2 =&gt; array ( 'title' =&gt; '', 'number' =&gt; 5 ), '_multiwidget' =&gt; 1 ) );
 update_option( 'widget_archives', array ( 2 =&gt; array ( 'title' =&gt; '', 'count' =&gt; 0, 'dropdown' =&gt; 0 ), '_multiwidget' =&gt; 1 ) );
 update_option( 'widget_categories', array ( 2 =&gt; array ( 'title' =&gt; '', 'count' =&gt; 0, 'hierarchical' =&gt; 0, 'dropdown' =&gt; 0 ), '_multiwidget' =&gt; 1 ) );
 update_option( 'widget_meta', array ( 2 =&gt; array ( 'title' =&gt; '' ), '_multiwidget' =&gt; 1 ) );

 update_option( 'sidebars_widgets', array ( 'wp_inactive_widgets' =&gt; array ( ), 'sidebar-1' =&gt; array ( 0 =&gt; 'search-2', 1 =&gt; 'recent-posts-2', 2 =&gt; 'recent-comments-2', 3 =&gt; 'archives-2', 4 =&gt; 'categories-2', 5 =&gt; 'meta-2',), 'sidebar-2' =&gt; array ( ), 'sidebar-3' =&gt; array ( ), 'sidebar-4' =&gt; array ( ), 'sidebar-5' =&gt; array ( ), 'array_version' =&gt; 3 ) );

if ( ! is_multisite() )
 update_user_meta( $user_id, 'show_welcome_panel', 1 );
 elseif ( ! is_super_admin( $user_id ) &amp;&amp; ! metadata_exists( 'user', $user_id, 'show_welcome_panel' ) )
 update_user_meta( $user_id, 'show_welcome_panel', 2 );

if ( is_multisite() ) {
 // Flush rules to pick up the new page.
 $wp_rewrite-&gt;init();
 $wp_rewrite-&gt;flush_rules();

$user = new WP_User($user_id);
 $wpdb-&gt;update( $wpdb-&gt;options, array('option_value' =&gt; $user-&gt;user_email), array('option_name' =&gt; 'admin_email') );

// Remove all perms except for the login user.
 $wpdb-&gt;query( $wpdb-&gt;prepare(&quot;DELETE FROM $wpdb-&gt;usermeta WHERE user_id != %d AND meta_key = %s&quot;, $user_id, $table_prefix.'user_level') );
 $wpdb-&gt;query( $wpdb-&gt;prepare(&quot;DELETE FROM $wpdb-&gt;usermeta WHERE user_id != %d AND meta_key = %s&quot;, $user_id, $table_prefix.'capabilities') );

// Delete any caps that snuck into the previously active blog. (Hardcoded to blog 1 for now.) TODO: Get previous_blog_id.
 if ( !is_super_admin( $user_id ) &amp;&amp; $user_id != 1 )
 $wpdb-&gt;query( $wpdb-&gt;prepare(&quot;DELETE FROM $wpdb-&gt;usermeta WHERE user_id = %d AND meta_key = %s&quot;, $user_id, $wpdb-&gt;base_prefix.'1_capabilities') );
 }
}

</pre>
<p>I don&#8217;t keep this file live on the server, but I suppose you could if you dropped an <em>.htaccess</em> file into the <em>/wp-content</em> folder and banned access to your custom <em>install.php</em> file</p>
<pre class="brush: php; title: ; notranslate">

&lt;Files install.php&gt;
 Order Allow,Deny
 Deny from all
&lt;/Files&gt;

</pre>
<p>That about sums it all up.  Let me know what cool jedi tricks you are doing with your custom <em>install.php</em> file!</p>
<h3>Downloads</h3>
<p><div id='wpdm_file_12' class='wpdm_file wpdm-only-button'><div class='cont'><div class='btn_outer'><div class='btn_outer_c' style=''><a class='btn_left  has-counter' rel='12' title='Install.php' href='http://www.kathyisawesome.com/?wpdmact=process&did=MTIuaG90bGluaw=='  >Download</a><span class='btn_right counter'>479 downloads</span></div></div><div class='clear'></div></div></div> //rename from install.php2 to install.php<br />
<div id='wpdm_file_9' class='wpdm_file wpdm-only-button'><div class='cont'><div class='btn_outer'><div class='btn_outer_c' style=''><a class='btn_left  has-counter' rel='9' title='KIA-ping-list' href='http://www.kathyisawesome.com/?wpdmact=process&did=OS5ob3RsaW5r'  >Download</a><span class='btn_right counter'>790 downloads</span></div></div><div class='clear'></div></div></div> (source: <a title="Mr. Jim Hudson.Com" href="http://mrjimhudson.com/wordpress-update-services-use-a-larger-ping-list/">mrjimhudson.com</a> )<br />
<div id='wpdm_file_13' class='wpdm_file wpdm-only-button'><div class='cont'><div class='btn_outer'><div class='btn_outer_c' style=''><a class='btn_left  has-counter' rel='13' title='KIA-comment-blacklist' href='http://www.kathyisawesome.com/?wpdmact=process&did=MTMuaG90bGluaw=='  >Download</a><span class='btn_right counter'>321 downloads</span></div></div><div class='clear'></div></div></div> (source: <a title="Comment Spam Blacklist Chacaters" href="http://perishablepress.com/wordpress-blacklist-characters/" target="_blank">perishablepress.com</a> )<br />
<div id='wpdm_file_8' class='wpdm_file wpdm-only-button'><div class='cont'><div class='btn_outer'><div class='btn_outer_c' style=''><a class='btn_left  has-counter' rel='8' title='KIA-comment-moderation-list' href='http://www.kathyisawesome.com/?wpdmact=process&did=OC5ob3RsaW5r'  >Download</a><span class='btn_right counter'>387 downloads</span></div></div><div class='clear'></div></div></div> (source: <a title="Comment Spam Blacklist Words" href="http://www.pureblogging.com/2008/04/29/create-a-comment-blacklist-in-wordpress-download-my-list-of-spam-words/" target="_blank">pureblogging.com</a> )</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kathyisawesome.com/421/customizing-wordpress-install/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
