How to Setup a Localhost WordPress (Sub-domain Multisite) Environment

By | Tutorial, WordPress | 21 Comments

Heads up that I work on a Mac so, therefore, this tutorial is for Mac OS. However, I’m sure the majority of this process can easily be applied to Windows.

So you want a localhost WordPress sub-domain multisite network for testing? Great! But, per WordPress Settings Requirements, “You cannot choose Sub-domain Install (for a domain-based network) if the WordPress address (URL) is localhost or” Eh. No worries. The requirements also point out that “you can create a domain-based network on your local machine by using your hosts file to map another hostname [to your local IP address], so that you never have to use the hostname localhost.”

In other words, unlike http://localhost, your localhost URL needs to have a domain name, e.g., so you’ll have to tell your local machine to use instead.

This is a pretty extensive tutorial that, in the end, will have walked you through the entire process of creating a localhost WordPress sub-domain multisite environment. However, if you don’t need multisite, or don’t need sub-domain multisite, just skip sections 3 and 5.

  1. Setup Your Local Server
  2. Place The WordPress Files
  3. Change Localhost To – required if you want a sub-domain multisite environment
  4. Install WordPress
  5. Create A WordPress Multisite Network – required if you want a multisite environment


Make sure you have the following setup, and downloaded, before moving forward.

  • The latest version of WordPress
    • It’s kind of important.
  • MAMP or WAMP
    • Allows you to install a local server environment on your Macintosh or Windows system.
    • Stands for Macintosh or Windows, Apache, MySQL, and PHP.
    • A server with Apache, MySQL, and PHP are all required in order to run WordPress. MAMP/WAMP allows you to run such a server on your computer!
    • At publication, I am running version 2.1.3, which is the most up-to-date version.
  • A code editor or text editor
    • I use Coda 2. It’s pretty nice. Anything from Panic is pretty nice.
    • There are a lot of free options. TextWrangler being one.
    • If you still don’t know, Google is your best friend.

1. Setup Your Local Server

Per WordPress requirements, in order to run WordPress you need a server running PHP and MySQL. MAMP, which stands for Macintosh, Apache, MySQL, and PHP, allows you to install such a server on your local system.

Configure MAMP

  1. Open MAMP.
  2. Click “Preferences” – I’ve included screenshots of my preferences below.
    • Start/Stop – These are really personal preferences. I like to check “Start Servers when Starting MAMP” and uncheck everything else.
      • I’m starting MAMP usually because I want to start the servers so why not automatically start the engines.
      • Not stopping the servers when you quit MAMP means you don’t have to keep MAMP open.
      • Not checking for MAMP PRO means I don’t get an annoying message every time I open MAMP.
      • My start page url is set to “/MAMP/”.
    • Ports – In order to have a sub-domain multisite environment, you must click “Set to default Apache and MySQL ports”. This will set the Apache port to 80 and the MySQL port to 3306.
    • PHP – I recommend selecting the most recent PHP version. My PHP extension is set to “XCache”.
    • Apache – Select a directory that will serve as your document root, i.e. the location where you will keep your WordPress files.
      • My preference? The “Sites” folder which, for Mac, is usually located in your Users folder. Mine is located at “/Users/rachelcarden/Sites”. But it really doesn’t matter. Just try to keep it simple and yet choose what you deem an important location. This could potentially hold a lot of important files.
  3. Click “OK” – to save and close your preferences.
  4. Click “Start Servers” – you might need to enter your administrator password.
  5. If you didn’t check “Stop Servers when quitting MAMP”, you can quit MAMP now. If not, you have to keep MAMP open for the servers to run.

Create Your Localhost WordPress Database

There’s just one more step to setting up your server. Your local machine is now running MySQL but you’ll need to create a a database for WordPress to use.

Create a database in phpMyAdmin

Create a database in phpMyAdmin

Create a database in Sequel Pro

Create a database in Sequel Pro

If you have a MySQL database management program, now’s the time to open that baby up. I use Sequel Pro. It’s pretty good and it’s free. If not, no worries. MAMP comes with phpMyAdmin, which is a web interface for MySQL management. All you have to do is open your MAMP start page, which should be http://localhost/MAMP/, and click on, you guessed it, “phpMyAdmin” in the top menu. Another way to open the start page? Open MAMP -> Click “Open start page”. Now just a few simple steps:

If Using phpMyAdmin

  1. Click the “Databases” tab.
  2. Enter the database name into the blank field. I’m gonna call mine WPDEV.
  3. Click “Create”.

If Using Sequel Pro

  1. Connect to your localhost server.
    • Name: Localhost
    • Host:
    • Username: root
    • Password: root
  2. Select “Database” from the top menu and click “Add Database…”.
  3. Enter the database name into the blank field. I’m gonna call mine WPDEV.
  4. Click “Add”.

2. Place The WordPress Files

Remember the document root you just selected in your MAMP preferences? Place the WordPress files in your document root directory. Mine is my “Sites” folder, located at “/Users/rachelcarden/Sites”.

3. Change Localhost To
required if you want a sub-domain multisite environment

Opening my hosts file in the terminal

Opening my hosts file in the terminal

What my hosts file looks like

What my hosts file looks like

As I pointed out at the beginning, per WordPress Settings Requirements, “You cannot choose Sub-domain Install (for a domain-based network) if the WordPress address (URL) is localhost or” You can, however, “create a domain-based network on your local machine by using your hosts file to map another hostname [to your local IP address], so that you never have to use the hostname localhost.”

In other words, unlike http://localhost, your localhost URL needs to have a domain name, e.g. It’s now time to map to our IP address so it can be used for our network domain.

Now, don’t freak out but the hosts file is locked so you’re going to have to use the Terminal. It’s really not that difficult. I promise. Just follow this nice, simple tutorial and, when you get to the part that says “simply append your new mappings”, append the following:  

Note: Unfortunately, you cannot cover ALL of your sub-domains with the above line which means you will have to repeat this process for each site on your sub-domain multisite network. If you already know of a sub-domain you wish to use, I recommend you go ahead and add it to the list. For example, I will use so I will also append the following:  

Once you’ve finished the tutorial, you should now be able to visit Do you see a WordPress Error screen that says “There doesn’t seem to be a wp-config.php file. I need this before we can get started.”? You do? Awesome! This means everything worked so click “Create A Configuration File” and let’s get configuring!

4. Install WordPress

A word to the wise going forward for sub-domain multisite setups: Make sure you’re on, and not just http://localhost, while you’re installing WordPress because WordPress will save your domain in its settings.

With the server set up, and the WordPress files in place, you are now ready to visit, which should initiate the WordPress installation script. WordPress provides a very helpful walkthrough to help you get everything setup properly.

Enter Your WordPress Database Connection Data

My WordPress database connection data

My WordPress database connection data

The first screen you’ll come across, that requires data, will be for the database connection. Enter the following information:

  • Database Name: the name of the database you just created – I used WPDEV
  • User Name: root
  • Password: root
  • Database Host: localhost
  • Table Prefix: wp_

Submit your information, finish the “famous five minute WordPress installation process”, and login to your WordPress admin/dashboard.

5. Create A WordPress Multisite Network
required if you want a multisite environment

Create a multisite network

Create a multisite network

The WordPress Create A Network codex page makes the process look pretty complicated so let me break it down for you:

  1. Allow for Multisite – follow step 2 on the Create A Network codex page.
  2. Go to your Admin. Click Tools -> Network Setup.
  3. Select “Sub-domains”. Enter network details. Click “Submit”.
  4. Don’t worry about the “Warning! Wildcard DNS may not be configured correctly!” warning.
  5. Follow the instructions on the page and click “Log In” at the bottom of the screen.
  6. Log back in to your admin.

Congratulations! You are now running a localhost WordPress Multisite! Now it’s time to add a second site.

Add a site to your WordPress network

Add a site to your WordPress network

Create A New Multisite Site

  1. Click “My Sites” at the top left (in your admin bar) and click “Network Admin”.
  2. Click “Sites”. You should now see that the only site listed is your primary site “”.
  3. Click the “Add New” link at the top, fill out the form, and click the “Add Site” button.

Now, remember how I mentioned back when we were editing the hosts file that the hosts file has to list ALL of your sub-domains? Well now’s the time to make sure your new sub-domain is listed in your hosts file because, otherwise, you will not be able to view your new site.

If you’re able to view your site then your multisite setup is complete!!! Hooray!!! Time for a happy dance! I hope this tutorial was helpful. If you have any questions or issues, and a quick Google search didn’t help you out, feel free to comment and I’ll try to help you out as soon as possible.

If you want to take your local testing environment a step further, then be on the lookout for my next tutorial: “How To Turn Your Localhost WordPress Environment Into A SVN Repository”.

How to Hide the WordPress Admin Bar

By | Tutorial, WordPress | No Comments

The WordPress admin bar, or toolbar, can be really helpful but sometimes it gets in my way, especially when I’m trying a new design and having difficulty imagining what it looks like without a dark gray bar running across the top.

For most people, with a single WordPress install, the solution is simply a matter of going into your profile and unchecking “Show Toolbar when viewing site”. But what if you’re running WordPress multisite? Unchecking that box removes the toolbar across your entire network when you only wanted to hide the toolbar on the new site you’re designing.

Sometimes I require a password for front-end content but there’s no need to grant access to the admin/dashboard, or frankly for them to even know it exists, so I’d rather not confuse them with a pointless toolbar.

Thankfully, as with most functionality in WordPress, there’s a pretty easy way to tell the admin bar to go away.

  1. Write a function which hooks into the “after_setup_theme” action.
    • Hooking into this action is important because it allows us to also remove the styles and scripts that WordPress enqueues for the admin bar. If they are not removed, then there will still be a space at the top of your page for the bar and that’s not very helpful.
  2. Inside your function, call the WordPress function, show_admin_bar() and pass just one parameter: false

There’s obviously a wide variety of scenarios for when and where to hide your admin bar, but hopefully the following examples will give you a good groundwork. This code will, most likely, go in your functions.php file.

Always Hide The Admin Bar

If you want to hide the admin bar for good, no matter who’s looking at the site, the code is pretty simple.

add_action( 'after_setup_theme', 'my_website_remove_admin_bar' );
function my_website_remove_admin_bar() {
   show_admin_bar( false );

Hide the Admin Bar If The User Doesn’t Have Access To The Admin/Dashboard

If you want to hide the admin bar from users who don’t have access to the admin/dashboard, then check their user capabilities. The capability to “read” is what allows access to the administration panel.

add_action( 'after_setup_theme', 'my_website_remove_admin_bar' );
function my_website_remove_admin_bar() {
   // if the user cannot "read", then they cannot access the admin/dashboard
   if ( ! current_user_can( 'read' ) )
      show_admin_bar( false );


Hide The Admin Bar on Specific Multisite Sites

If you want to hide the admin bar on specific sites on your multisite network, use the global $blog_id variable in your logic. The global $blog_id variable contains the ID of which site is currently being viewed.

add_action( 'after_setup_theme', 'my_website_remove_admin_bar' );
function my_website_remove_admin_bar() {
   // access the global variable
   global $blog_id;

   // remove the admin bar for one site
   if ( 3 == $blog_id )
      show_admin_bar( false );

   // remove the admin bar from multiple sites
   if ( in_array( $blog_id, array( 3, 5, 8, 10 ) ) )
      show_admin_bar( false );


Hide The Admin Bar on Specific Pages

Using WordPress conditional tags allows you to easily hide the admin bar on specific sections, or pages, of your site.

add_action( 'after_setup_theme', 'my_website_remove_admin_bar' );
function my_website_remove_admin_bar() {

   // hide the admin bar on your main page
   if ( is_home() )
      show_admin_bar( false );

   // hide the admin bar on your page with the title of 'About Me'
   if ( is_page( 'About Me' )
      show_admin_bar( false );

   // hide the admin bar on any taxonomy archive page
   if ( is_tax() )
      show_admin_bar( false );


Things Are A (WordPress) Changing

By | WordPress | No Comments

Hey gang. I decided to mix things up a bit over at and migrate all my WordPress-ery to a new home,!

My plans are to now turn into a personal blog so I can begin to improve my writing skills and share a little more about myself with the world. I also hope to up my WordPress game by publishing increasingly regular WordPress tutorials and new resources for CPT-onomies, including a demo site and screencasts.

As for existing content, I moved everything over, and set up redirects from, so you should be able to find everything. If not, please let me know!

Why WP Dreamer?

Because I like to think outside the box. My strengths truly lie in logic and problem solving so pushing default functionality is what I do best! I love to push the boundaries of WordPress and believe anything is possible with a little know-how and ingenuity!

So, if you’re used to visiting, or was redirected from,, then be sure to bookmark my new site!


CPT-onomies Update: Version 1.3 (MULTISITE!)

By | CPT-onomies, Plugins, Uncategorized, WordPress | 3 Comments
Download CPT-onomiesCPT-onomies Documentation

I’m pretty excited about this update and multisite compatibility is the reason why! As someone who manages a pretty vast multisite network, I think WordPress multisite is awesome and hope others find this new functionality useful as well.

But version 1.3 didn’t present itself solely bearing the fruits of multisite. Here’s the full list of improvements:

  • Added multisite custom post type manager.
  • Added setting to assign meta box format, i.e. autocomplete, checklist or dropdown.
  • Added “Show Admin Column” to the CPT-onomy settings.
    • This is a new register_taxonomy() setting as of WordPress 3.5.
    • Before, CPT-onomies added the column itself but will now hook into this new core taxonomy functionality.
    • I will retain backwards compatability for a little while.
  • Deprecated the ability to make the CPT-onomy admin columns sortable in order to align with new, core WP taxonomy admin column functionality.
    • The new core WordPress taxonomy admin columns are not sortable so, therefore, I’ve removed the column sort functionality from the plugin.
  • Deprecated the ‘custom_post_type_onomies_add_cpt_onomy_admin_sortable_column’ filter.
    • Before, you could use this filter to turn off the column sortability. Now, with sorting gone, there’s no need to have the filter.
  • Added support for the “Gravity Forms + Custom Post Types” plugin.
    • This particular feature was commissioned by a user and will allow you to create CPT-onomy relationships when you use a Gravity Forms form to create a custom post type post.
  • Added the ability to only include/assign specific terms by passing term IDs to a filter.
    • Like the previously added “exclude” filter, this filter allows you to designate that you only want specific CPT-onomy term(s) to be allowed to be assigned.
  • Added wp_set_post_terms() to the CPT-onomy class.

Hope you the enjoy the update. I already have ideas for the next round! And, as always, please let me know if you have any questions or find any bugs! Thanks!

CPT-onomies Update: Version 1.2.1

By | CPT-onomies, WordPress | 2 Comments
Download CPT-onomiesCPT-onomies Documentation

A new version of CPT-onomies has joined the ranks but don’t get too excited. It’s just a few bug fixes that have been brought to my attention since I released 1.2 back in December.

I hope you’re enjoying CPT-onomies and, as always, please let me know if you find any bugs, or have any feature requests, by posting to the CPT-onomies support forum.

Thanks for being such awesome users!

CPT-onomies Update: Version 1.2

By | CPT-onomies, Uncategorized, WordPress | No Comments
Download CPT-onomiesCPT-onomies Documentation

To say my life has been crazy the past 6 months would be a very large understatement but CPT-onomies 1.2 is finally here! On top of a few minor bug fixes, here’s what 1.2 brings to the table:

  • Create custom CPT-onomy archive pages with just a few simple lines of code!
  • Added the ability to set a CPT-onomy term description using ‘term_description’ or ‘{$taxonomy}_description’ filter’.
  • Non-public custom post types can now be used as CPT-onomies.
  • Exclude CPT-onomy terms from being listed in the “Assigning CPT-onomy Terms” admin meta box and, therefore, from being assigned to a post.
  • Added numerous filters, allowing you to:
    • Remove “Assigning CPT-onomy Terms” meta boxes from admin
    • Remove CPT-onomy dropdown filters from admin
    • Remove the CPT-onomy column and/or it’s sortability
    • Customize settings by removing options and setting default property values
  • I changed the cpt_onomy.php filename to cpt-onomy.php to match cpt-onomies.php (I’m not really sure why I gave it an underscore to begin with).
  • I, like many others, fixed the $wpdb->prepare() issue.
  • If you use the following CPT-onomy settings, be sure to re-save your settings to fix potential bugs:
    • Capability Type
    • Capabilities -> Read Private Posts

I hope you enjoy the update! And, like always, please let me know if you find any bugs. If you need me anytime soon, I’ll be the one drinking some damn scotch. Until next time, keep up the awesomeness!

CPT-onomies Update: Version 1.1

By | CPT-onomies, WordPress | 4 Comments
Download CPT-onomiesCPT-onomies Documentation

It took me long enough but the next version of CPT-onomies has finally shipped out! And, with it, some pretty cool new features:

  • Programmatically register your CPT-onomies
    • Much kudos and thanks to Travis Smith for the assist with this one!
  • When assigning CPT-onomy terms on the “edit post” page, choose from three different formats:
    • a checklist (same ole, same ole),
    • an autocomplete box (a pretty cool one, I might add),
    • and a select dropdown (for when you only want to select one term)
  • Customize the CPT-onomy archive page slug
    • Before, you were pretty much stuck with “{post type}/tax/{term slug}” (which is still the default) but now, via the settings panel, you can use your own keywords with a little help from the variables $post_type, $term_slug and $term_id. Don’t forget to flush/reset your rewrite rules once you’re finished!
  • Tell the CPT-onomy tag cloud widget whether you want the terms to link to their archive page or to their custom post type post page
  • When you’re using wp_get_object_terms() to request term information, you can now specify term ids to exclude from your results
  • The CPT-onomy class has a new function! Introducing get_term_ancestors(). I think it’s a little self-explanatory =)
  • CPT-onomies now supports Internationalization (can’t believe it took me so long!)
  • I also tweaked the UI and fixed a few bugs

I hope everyone enjoys the update as much as I do. Sorry it took me so long. My life has been a little crazy but I’m glad to be on the other side of the hiatus!

Please let me know if you have any questions or find any bugs! Thanks for being such awesome users!!

How to Define Reserve Slugs for WordPress Posts and Pages

By | Tutorial, WordPress | No Comments

This post was inspired by an answer I posted in the WordPress Stack Exchange.

This is an interesting WordPress problem that could span several scenarios. But let’s say you have a custom post type named ‘songs’ and you defined its slug as ‘songs’ so its archive page URL is

This is fine and all but a slug used for a custom post type archive page, i.e. ‘songs’, is not saved in the database and is, therefore, not available when you’re creating/editing posts to tell WordPress “NO! The slug ‘songs’ is taken!”. With that said, a user could come along and create a post (or page) with the slug ‘songs’ which would therefore have the same URL as your custom post type archive page:

So how do you keep users on your site from creating posts with particular slugs, a.k.a. reserve slugs?

It’s pretty simple, actually. Use one, or both, of the following two filters. They hook into WordPress when it’s checking a post’s slug, allowing you to return “true” which tells WordPress that the post slug is bad. If you return “true”, WordPress adds on a suffix, just like it would do if you were trying to use a slug that is already taken.

The first filter, ‘wp_unique_post_slug_is_bad_hierarchical_slug’, is for hierarchical posts and the second filter, ‘wp_unique_post_slug_is_bad_flat_slug’, is for non-hierarchical posts. While both filters provide the post’s $slug and $post_type, the hierarchical filter also provides the ID for the post parent so if the $post_parent is 0, you know this is a “base” post.

add_filter( 'wp_unique_post_slug_is_bad_hierarchical_slug', 'rachel_carden_is_bad_hierarchical_slug', 10, 4 );
function rachel_carden_is_bad_hierarchical_slug( $is_bad_hierarchical_slug, $slug, $post_type, $post_parent ) {
   // This post has no parent and is a "base" post
   if ( !$post_parent && $slug == 'songs' )
      return true;
   return $is_bad_hierarchical_slug;

add_filter( 'wp_unique_post_slug_is_bad_flat_slug', 'rachel_carden_is_bad_flat_slug', 10, 3 );
function rachel_carden_is_bad_flat_slug( $is_bad_flat_slug, $slug, $post_type ) {
   if ( $slug == 'songs' )
      return true;
   return $is_bad_flat_slug;

These filters can be found in the WordPress function wp_unique_post_slug() in the wp-includes/post.php file.