WooCommerce Customize Checkout Fields

Note: This was updated for compatibility with WooCommerce 3.0+. This will cause fatal errors if used with older versions of WooCommerce.

I was digging around in WooCommerce while trying to come up with a quote for a client. Part of the scope had me wondering if you could remove some fields from the checkout process. If you aren’t selling physical products a billing address can be too much information and could even be off-putting to potential customers.

I eventually tracked the fields down from the checkout template, to the checkout class to the get_address_fields() method in the WC_Countries class.

Removing Billing Address

Like a lot of things in WooCommerce you can modify values via filter. To remove all the physical address fields from the billing address here is the code I used:

Yes this could go in functions.php but that kind of locks you into a specific theme. If this is a permanent change then you probably want to create a site-specific plugin and put it in the wp-content/mu-plugins/ folder.

Add a Custom Checkout Field

While I was fooling around I figured I would see if I could add a custom checkout field. Turns out this is a bit more complex, but ultimately do-able. The following code will add the field to the checkout page, save the data to order meta and display the order meta in the orders admin.

Update: After receiving multiple contacts about adding more than one field I have modified the sample code to add 2 fields.

Note: there is no foreach() in the rest of the function so we must save and display each field individually

Save the extra data on checkout

Display the extra data to users

Display extra data in admin

Alternatively, display extra data as editable data (and save)

This should function like the shipping and billing address data and reveal inputs when the little pencil icon is clicked. Make sure to delete the previous function as two functions with the same name will cause a PHP error.

Add the field to order emails

The easiest way to add data to the emails is to add our meta to the list of meta that WooCommerce will print out automatically. For WooCommerce 2.3 and after, you will do it the following way:

If you’d rather customize the output in the emails you can add some text to any of the hooks available in the email templates.

function kia_display_email_order_meta( $order, $sent_to_admin, $plain_text ) { $some_field = $order->get_meta( ‘_some_field’ ); $another_field = $order->get_meta( ‘_another_field’ ); if( $plain_text ){ echo ‘The value for some field is ‘ . $some_field . ‘ while the value of another field is ‘ . $another_field; } else { echo ‘

The value for some field is ‘ . $some_field. ‘ while the value of another field is ‘ . $another_field . ‘

‘; } } add_action(‘woocommerce_email_customer_details’, ‘kia_display_email_order_meta’, 30, 3 );

Hope that helps you. I think there are a few plugins out there now if this was too intimidating, so I would suggest using one of those.

Add a Repeating Text Field to Options Framework Plugin

Options framework repeating field

Options framework repeating field
This is what we’ll be building.
I don’t hardly even know why I was working on this today.  Well a friend wanted to be able to control the radio buttons in a metabox, from the backend (since the otherwise brilliant WP-Alchemy is all dev-level coding) and for some reason  my brain went to theme option.  He ultimately went a different route and used Advanced Custom Fields.  But some days I just feel like not working and doing something fun, and the question of repeating fields in the theme options piqued my interest.  I asked Devin Price if his awesome Options Framework plugin has such a thing and he replied that no it didn’t exist…. yet. He wasn’t sure it was possible, which is like the worst thing to say to me. Of course it is possible! And now instead of working on something responsible, I will now solve this riddle. So I started digging into Options Framework. At first I thought that I would fork OF, but it turns out that all the functions/filters needed are already in place!   Wherever you have your $options array in your theme’s options.php to get a repeating field you’d define your custom option like so:

Then to handle all the parts of displaying this, scripting the repeat, and validating the data you’ll need the following group of functions, added to your theme’s functions.php.

Creating the Output

First, we need to output something when Options Framework gets running and encounters the custom option of type ‘repeat_text’. Devin has a catch-all filter already built-in, so we just have to attach a function to the {$option_type}_option_type filter, in this case repeat_text_option_type. This callback will create the input box (as many as needed by the array of values) plus one hidden one. It also creates the “Add New” button and for good fun we’ll throw in delete buttons next to each input. The markup (and later the script to handle the repeat) draws a lot of inspiration for WP Alchemy’s repeating groups.

Sanitation and Saving

Options Framework won’t save anything unless the data gets run through a sanitization filter. The neat thing, is that if you set up the input names as name="somefield[1]" and so on, WordPress will automatically save all the “somefield” fields in an array. So we just need to rifle through the array and sanitize each text field. We can do this quickly with array_map. Next

Style and Scripting the Repeating Fields

Finally, all the bells and whistles. What good is a repeating field if it doesn’t, you know, repeat. Again, I have to credit Dimas Begunoff for his WP Alchemy class. I’ve simplified some of what he was doing in metaboxes, by merely adding a data-rel to the hidden input. Then a few quick on handlers for the button click events and that hidden input we created earlier gets cloned and given a proper name attribute. Clicking a delete button, removes it’s associated input from the DOM.


Because we’ve saved an array of data the if you try to echo out the results of of_get_option('example_repeat'); you will get Array. You have to loop through the array to print out each on individually with a foreach loop.

This is definitely beta-ish. For instance, I know it doesn’t take into account a way to set an array of defaults… like if you wanted to have two fields set up as the default. Maybe it is Google Chrome, but I’m also having a little issue with tab indexing. And finally… there was something else, but my mind just went blank. Get the full code from my Gist. As beta code, I am totally open to suggestions and improvements, but I won’t be able to help you set this up on your own sites. I’m just putting it out there for information purposes only. What would you use a repeating field for in theme options?

How to Use Multiple WYSIWYG (TinyMCE) Visual Editors in Your WordPress Metaboxes

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 “B” button.  So if we’re building a theme that requires multiple blocks of content it’s nice to reuse the visual editor.

I’ve been using the WP Alchemy Class by Dimas Begunoff to build my metaboxes for a while now.  It gives a *lot *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 How to Use Multiple WordPress WYSIWYG Visual Editors and it worked, up to a point.  Because TinyMCE is fickle (and despite their tagline being “Easy to Integrate”) this code didn’t work for repeating groups, which in my mind is the strength of Alchemy.

As of WordPress 3.3 you can finally use the built-in wp_editor() function for multiple editors in your metaboxes, but again these must be defined in advance.  You can’t use this function with WPA’s dynamically generated fields. So, repeatable, sortable WYSIWYG (TinyMCE) rich-text editors has been the elusive, ultimate dream of WP Alchemists. The <cough>Holy Grail</cough> of WP Alchemy. But after a lot of head-banging effort, I think I have it!

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. Upload and activate the theme, then 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. Download the sample theme from for an idea of how it works.

Fork me on github!  Perhaps we can figure out how to use the quicktags editor when the visual editor is disabled. Full tutorial to come…  maybe.

Create an Alphabetical Glossary of Posts in WordPress

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 don’t know if there is any performance benefit, but the code was a little more elegant and you get prettier permalinks: site.com/glossary/a instead of site.com/?glossary=a right off the bat without the need to do any complicated htaccess rewrite rules, since everyone knows that mod-rewrite is straight up voodoo.

Creating a Hidden Taxonomy

Pretty standard function for registering a taxonomy. Just going to accept a lot of the defaults, and not worry about labels since we’re going to hide it from the back-end by setting the ‘show_ui’ parameter to false. For this example we’re going to call the taxonomy “glossary” and we’re going to assign it to posts, but we could well have done it for any custom post type.

Automatically Setting Terms for each Post on Save/Update

It’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 “glossary” taxonomy. The following is the pretty standard function for saving information from a metabox, which works perfectly for our case even though we don’t have a visible metabox.

Auto-Assigning Terms to existing posts

If you’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’d run on the plugin’s activation hook.  Since it’s not you can just drop it into your functions.php and then reload your site. Thanks to the transient check you can leave it in there and it won’t run again. 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 “glossary” taxonomy.

Finally, Creating the Alphabet “Menu”

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…. 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… 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 kia_save_first_letter() function. 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: A B C D** E** …. and onwards, so I have re-created that effect.

Future Improvements

One thing I’d like to improve upon would be ensuring that the first letter I’m popping off with the substr PHP function is actually a letter… or maybe a number, but not a character.  I’d also like to get it to skip words like The, An, and other pointless words that don’t really reflect on the subject.  But then this isn’t a solution for everyone… if you want to make sure that “A Post about Bacon” and “The Bacon Post” show up in the same archive, well you should tag them in the Bacon tag and not hope that they show up alphabetically in the right place.  Still it has its uses.  Let me know of any improvements you make!

Customizing the WordPress Install Process with install.php

I came across a super interesting post at WPBits about [automating the wordpress installation][1] 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 “This is your First Post” post, changing the permalinks etc. then you can take advantage of this little trick.

Trolling the Source Code Like a Boss

If you are cruising through source (because there is plenty of stuff that isn’t well documented yet in the Codex) you will see

/wp-admin/includes/upgrade.php.  Now this is interesting because it means that when WordPress installs (or upgrades) it will look for a file called install.php in your /wp-content folder… or whatever you are using instead of the default /wp-content folder.  This file doesn’t exist by default but it gives you a chance to run some functions of your own during the installation process (since  /wp-admin/includes/upgrade.php is required by /wp-admin/install.php)

My First Custom Install.php

I followed WPBit’s example and decided to show off my new power over WordPress by putting the following into my custom /wp-content/install.php file:

is obviously isn’t helpful, but it is a good proof of concept and let’s you know that you have all the power.  Of course…

With great power comes great responsibility. – Uncle Ben

Functions We Can Hijack for Our Own Purposes

As WPBits explains in more detail, some of the ideal to tweak would be:

  • wp_install()
  • wp_install_defaults()
  • wp_new_blog_notification()
  • wp_upgrade()

All of these functions are now (currently version 3.3.1) in /wp-admin/includes/upgrade.php and they are pluggable, meaning they come with an if(function_exists()) wrapper that lets you define your own versions to override their behavior. Since wp_install_defaults() is the culprit for creating those useless “first post” posts and pages, we’re going to target it.  I copied the entire function to my own file: /wp-content/install.php and then hacked out all the parts that inserted the first post, first page, and changed the default category from Uncategorized to General.  I even cut down the number of widgets that are activated by default. 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 update_option() commands.  Just because I thought it’d be super clever, I updated the ping list, moderate and blacklist comment terms from text files by using file_get_contents().

Automagically Creating Myself as an Admin

I usually install WP for someone else, I decided that I wanted to create my client’s account on install and automatically create my own admin account.  I might reverse this process as I don’t like how the install’s welcome email doesn’t include a link to the login screen.  I 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… which I prefer for now.

Anyway, I initially overrode the default wp_install() file to do this, by repeating the process of copying the function from /wp-admin/includes/upgrade.php to my own install.php, 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. Here’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… currently they are left as USERNAME and YOU@YOUREMAIL.COM.  Right now it generates a random password, but that could easily be changed to always assign yourself the same password.

Edited: Sept 9, 2014 from WordPress 4.0

I don’t keep this file live on the server, but I suppose you could if you dropped an .htaccess file into the /wp-content folder and banned access to your custom install.php file

That about sums it all up.  Let me know what cool jedi tricks you are doing with your custom install.php file!


Download the whole thing from my Customizing the WordPress install gist.