Half-Elf on Tech

Thoughts From a Professional Lesbian

Category: How To

  • Cloud Experiment

    Cloud Experiment

    While I’ve mentioned that I don’t ‘get’ CloudFlare, I took the time to buttonhole the guys at DreamCon and explain my issues. Many thanks to Maria Karaivanova for her presentation at DreamCon, too, which helped me a lot.

    Now, in so far as a ‘traditional’ CDN (where they host my images) goes, I don’t need it, but as a Cloud Proxy, I both understand and like it! The deal with a proxy is pretty simple: It’s an extra firewall between your server and users. Why is this faster? Because they have more servers than I do, which means they can handle a DDoS better than pretty much anything on Shared Servers will ever be able to do.

    Keep in mind, a VPS can handle a lot of this on it’s own. I could install Varnish and use that for caching, but it wouldn’t give me the ability to have multiple servers serving my content, and that’s what I’m looking for with my experiment here.

    It would be remiss if I didn’t note the more well known alternatives: Incapsula (starts at $19.99/month), Sucuri’s Cloud Proxy (starts at $9.99/month), MaxCDN (starts at $9.99/month), and Fastly (starts at $50/month). CloudFlare starts at ‘Free’ but its first paid offering is $20 a month for one website, $5 for each additional.

    On My Server

    I use ConfigFirewall (CSF) so I had to add in the CloudFlare IPs into csf.allow and csf.ignore. Yes, both, otherwise I got weird alert. This is pretty easy, though.

    Next I installed mod_cloudflare because I wanted to preserve the IP address without having to muck with plugins on everything. This particular site is my ‘Not all WordPress’ site after all. The catch is if I do it all manually, I have to redo it every time I upgrade via EasyApache(Don’t judge me). I already have to do that for PageSpeed. That said, cPanel suggested I read Installing mod_cloudflare on cPanel, so I did that and then ran EasyApache:

    Screen Shot of EasyApache

    So that was easy! By the way, TL Tech is one of my standard resources. They have a lot of tricks, and I’ve bookmarked ’em.

    Finally I checked out if there were issues with PageSpeed and CloudFlare. CloudFlare says no, but indicates the redundancy. That’s okay. I did an extra step of telling PageSpeed to not modify caching headers, as that’s something we did for DreamHost and Varnish (DreamPress!). Just add this to your .htaccess section for PageSpeed.

    ModPagespeedModifyCachingHeaders off
    

    On CloudFlare

    whohostsThis was straightforward. Follow their directions and it’s fine. I went for free, and fiddled with my Security Settings a lot. I hate captcha. And I know, I knooooow, the users for this site will cry if they get hit by one, so I turned my security to “Essentially Off” – This is the only way to get rid of Captcha. Sad panda. I also turned “Browser integrity check” on for now.

    In Performance Settings, I made Caching level “Simplified” and left the rest as default. Then I set up PageRules for WordPress and my other apps. You only get three rules with free (and 20 with the first level plan) so I made sure to free up the admin tools.

    On my webapps

    Last up, tackling purging caching. I’m far more familiar with this now, as I support a Varnish plugin that does much the same (and I did consider installing Varnish). The official CloudFlare plugin, for some reason, only serves the same purpose as mod_cloudflare, in that it restores IP addresses. But what I really want is a way to purge my cache with a new post. Pretend I’m saying this in that voice I used at WCSF… there’s a plugin for that: CloudFlare Cache Purge.

    Sadly there isn’t a similar plugin/extension for my other apps. And this is why I ended up at my current conclusion…

    Current Conclusion

    Sadly, even after letting it bake for a few days I determined it wasn’t quite right for me. Everything worked, and if my site was more static, it would be perfect. But this brought up the same problem I’ve had with all caches: my dynamic content gets hurt.

    cachingWhat is static that I can and should cache? JS, CSS, font files, images. What is not static? Blog posts, comments that are happening all the time, fast and furious. A gallery that needs to update. A wiki that has a deadline. Worst of all, it prevented two of my apps from being able to make their own ‘static’ cache in the background. Now really that means I shouldn’t have to make my static cache at all, but this brought up another issue. Coordinated pushes of content, where four separate apps update 1-3 pages each at the same time means I need to be able to purge those pages, right away. And right now, there aren’t extensions to do that.

    Of note: I noticed the exact same problem with Fastly and Varnish, so it’s not just CloudFlare, it’s a function of how these things are supposed to work.

    What would I need to make these desirable? Basically I need a way to purge my cache on the proxy efficiently, quickly, and selectively. Now that I work on the Varnish Cache at DreamHost, I’ve seen how deep the rabbit hole can go with this, however, and I know fully how hard this is. Proxy Caching is not for everyone. When you have dynamic content that changes for logged in users on the fly, it’s a pain. I mean, I use PageSpeed to compress and cache CSS and JS, and I have to flush it when I update my site design. Caching your caching is always going to be tricky, unless there’s a simple, one click, way to say “I’ve updated these pages, please purge them.”

    We’re not there yet.

    Recommendation

    CloudFlare is pretty awesome, actually. If you’re ‘just’ running a blog on shared hosting, I would seriously consider using it, especially in light of the various DDoS attacks out there. A cloud proxy will help you, if you don’t have server level access to tweak mod_security. The fact that CloudFlare gives you a ‘free’ option to test with, without having to give anyone your credit card info, makes it great for experimentation and puts it above the other proxies right now.

    But with all things, keep in mind your personal usage. It’s not just “Does this make my site run faster?” but it’s a lot of “Does this make my usage of my site better?” For me, they win on the first and fail on the second. Maybe one day I’ll change my workflow so cloud proxy, or Varnish, can be the answer, but that’s not today.

  • MySQL – my.cnf

    MySQL – my.cnf

    This is a fairly rare file, and one I never would have found had I not needed to run a standard SQL process via cron.

    Names have been changed to protect the innocent.

    As the story goes, no matter what I did, I could not get this one app to stop spewing out ‘smart’ quotes. You know the fancy apostrophes and quotes that curl? Well, that’s not normally a problem, like in WordPress I’d just filter it out, but in this locked down system, I didn’t have that option. I called the vendor, and they said “Make sure you don’t paste in smart quotes.”

    mysqlThat was all fine and dandy for me but I’m not the master of the universe like that. Well, not all the time. I had people to input data for me! They were going to have to manually take the forms (Word Docs), filled in by non-techs, and copy the data into the right places in the app. And you want me to tell them they have to fix this for the non-techs? I thought about how much time that would take, and decided the best fix was to change the forms! Right?

    If you’ve ever worked for a major company, you know why this was about as effective as aspirin for a root canal. No deal. So I decided to get inventive.

    The only time this was a problem, these ugly quotes, was when we ran our weekly reports. This was how I found out about it, a manager complained that there was garbage instead of quotes on the form titles. Ergo: All I need to do is script something to clean them out!

    Enter SQL!

    # REPLACE SMART QUOTES WITH STUPID ONES
    # FIRST, REPLACE UTF-8 characters.
    UPDATE `secretapp_table` SET `formtitle` = REPLACE(`formtitle`, 0xE2809C, '"');
    UPDATE `secretapp_table` SET `formtitle` = REPLACE(`formtitle`, 0xE2809D, '"');
    # NEXT, REPLACE their Windows-1252 equivalents.
    UPDATE `secretapp_table` SET `formtitle` = REPLACE(`formtitle`, CHAR(147), '"');
    UPDATE `secretapp_table` SET `formtitle` = REPLACE(`formtitle`, CHAR(148), '"');
    

    In my testing, if I ran that on formtitle, it cleaned it up for the report. This was a default report in the app, by the way, not something I had any control to change. And you wonder why I love open source? Anyhow, once I knew how this would work, I sent about scripting it. I couldn’t hook into any triggers on the app, though, because they don’t like to make it easy.

    Fine, I decided. A crontab time it is! I made this simple script to run at midnight, every night, and clean up the DB:

    #! /bin/bash
    
    mysql -h "dbname-secretapp" "secretapp_db" < "quotecleaner.sql"
    

    It worked when I ran it by hand, but it failed when cron’d. This took me some headbanging, but after reading up on how SQL works, I realized it worked when I ran it as me because I’m me! But cron is not me. I have permissions to run whatever I want in my database. Cron does not. Nor should it! So how do I script it? I don’t want the passwords sitting in that file, which would be accessible by anyone with the CMS to update it.

    I went around the corner to my buddy who was a DB expert, and after explaining my situation (and him agreeing that the cron/sql mashup was the best), he asked a simple question. “Who has access to log in as you?” The answer? Just me and the admins. The updating tool for our scripts was all stuff we ran on our PCs that pushed out to the servers, so no one but an admin (me) ever logged in directly.

    He grinned and wrote down this on a sticky “.my.cnf”

    Google and a Drupal site told me that it was a file that was used to give the mysql command line tools extra information. You shove it in the home directory of the account, and, well, here’s ours:

    # Secret App user and password
    user=secretapp_user
    password=secretapp_password
    

    The only reason I even remembered all this was because an ex-coworker said he ran into the documentation I left explaining all of this, and was thankful. He had to have it scan the body of the form now, because the managers wanted that in the report too!

  • Adding Per Site Multisite Options

    Adding Per Site Multisite Options

    johnc- said in IRC the other day, regarding the use of get_option API for WordPress “our standard practice is to use get_option to enable site specific features, if the feature needs to be unavailable for other sites then it gets broken into a separate plugin for clarity”

    diceSo to explain this for those who blinked a little we need some examples, and really this depends what you’re writing.

    We got to this point in the conversation while folks were watching my “Don’t Use WordPress Multisite” presentation from WordCamp SF. During the presentation, I mentioned that generally, when I want to write a function for a specific site on Multisite, I wrap it around a ‘If site 1, then …’ and put it in it’s own plugin file in mu-plugins. That leaves me with files like halfelf-functions.php so if I ever split the site out (see? I’m always thinking ahead) I know what file to copy.

    But that’s not the only way about it. Another way is to put all the functions in a file, and then wrap the actual filters and actions around a get_option call. Why would I want to do this instead of a separate function file? The question of portability comes up primarily. Exporting site options is not the easiest thing in the world on a Multisite, but there are cases, like my Capital H Dangit! function, where this would make sense. In general, I always want DreamHost to have a capital H, so since 99% of my sites have that on, I could, instead, use an option, since if I ever moved the one site that doesn’t use it, I just won’t bring the function over!

    Currently have wrapped that function around an ‘if site 2, then don’t run’ check, which works fine. But if I wanted to move that to options, it would go like this:

    
    // Add the default option of capital h to yes, and autoload
    add_option( 'helf_capital_H_dangit', 'yes', '', 'yes');
    
    if ( get_option( 'helf_capital_H_dangit' ) == 'yes' ) {
        foreach ( array( 'the_content', 'the_title', 'comment_text' ) as $filter )
            add_filter( $filter, 'capital_H_dangit', 11 );
    }
    
    function capital_H_dangit( $text ) { 
        [... code here ...]
    }
    

    This is pretty basic. It adds an option called helf_capital_H_dangit, auto-loads, and defaults to on for everyone. That was the easy part. The hard part is determining how to control it.

    One option is an interface where I can check a box on, say, General Settings > Writing > Formatting (right under the smilies check box would be perfect), but since I knew this was something I was going to want to control as the super-admin (that is, I don’t want the other people on my network to turn it off), I went in to the back end of my site at /wp-admin/network/site-info.php?id=2 (since this is site ) and searched for ‘Helf’

    Screen Shot 2013-08-21 at 2.21.41 PM

    I edited it to ‘no’ and saved. Boom. I can use DreamHost and Dreamhost here.

    Now this isn’t something I’d do for everything. In fact, my actual halfelf-functions.php file looks like this:

    global $blog_id;
    
    if ( $blog_id == 2 ) {
    
    	remove_filter( 'the_content', 'capital_P_dangit', 11 );
    	remove_filter( 'the_content', 'capital_H_dangit', 11 );
    
    	// I Make Plugins Filters
    }
    

    All the per-site filters are right there turned off as I want them. It’s not a lot of effort that way, and it’s still easy to pick up a site and drop it somewhere else.

    Businesswoman in Front of DoorsWhich is better? I don’t know. The real test would be to do some hardcore speed checks and see if checking for the blog ID is faster than checking for an option. I think the speed benefit gains would come from only calling this when needed, but for the limited world in which this is used, it should be fine. Also, keep in mind what both johnc- and I are saying, but in different ways: remember the 80/20 rule.

    In my opinion, if you’re making a feature that will be used by 80%+ of the sites on your Network, get_option is probably the easiest bet. If you’re making a feature that’s going to be used by 20%- of the sites, then a separate plugin (with a site_id check) is the way to go. Of course, you could do an option and default it to ‘no’ as well, but that brings up an interesting level of things to remember if you ever move a site.

    If you’ve got a more efficient way of doing the same thing, or even just a different way, speak up! More options are always better.

    Oh and no, we’re not going to sneakily install this on DreamPress, but if I did, it would also capitalize DreamPress, DreamCompute, and everything else out there. But I won’t.

  • Retina Favicons

    Retina Favicons

    Way back in 2009 I said that every site should have a favicon. It was not the first time I’d expressed such an opinion, and I still remember back when IE 5 rolled out and I saw them on my bookmarks for the first time. Actually, I remember when a coworker asked me to help her make them show again, and I had no idea what she was talking about. As soon as I saw them, I knew this tiny feature would be useful.

    Back in those days, of course, we didn’t have ‘tabbed’ browsers. So you knew what site you were on because that was your window. Now, with somewhere between 10 and 20 active tabs on a browser (depending on if you’re me or someone like Andrea or Nacin – I like the fewer) the favicon is a fantastic way to go “Aha! That’s where the tab for Google went…”

    Speaking of Google, the other day I was browsing on my iPad and realized that not only does Google show you different favicons depending on which page you’re on, but they also show you them in retina format.

    Hold the phone.

    Retina. Ready. Favicons.

    Well. Clearly I needed to upgrade mine! Of course there are problems with this. The old favicon standard was a 16×16 pixel square that you had to make memorable and identifiable. This is not simple. I picked a hat for ipstenu.org and on a retina display, this still looks okay, even though it’s pixelated. It gives off an 8-bit vibe to things, and that’s pretty me, in that retro-cool way, so I don’t mind. It’s not fuzzy, after all. The same cannot be said of my Spock-eye here, however. I didn’t want to lose the geekiness of the eyebrow, so I sat and pondered my options.

    favicon-old Since my original favicon (see right) was 16×16 and an ICO, I had no choice but to deal with being fuzzy, upgrade or make a whole new favicon. I wanted to keep Spock, so I grabbed a screen-shot of Spock from what is everyone’s favorite Spock episode, “Amok Time.”

    Amok Time

    I spent a lot of time cropping and tweaking, and finally I remembered that one of the things I am terrible at is images. Sorry, Spock. I still love you. But I resigned myself to my lack of ability in this, and figured that since I had recently redesigned Half-Elf, I may as well get a new icon. Something that wasn’t just geeky, but also more modern. Normally when I do this, I end up over at IconFactory, who were my go-to standards for desktop icons on my Mac. They used to have a pretty amazing Freeware section, but it hasn’t been updated since 2012, and that tells me they’re done with it.

    The real problem with icons is, of course, simplicity. The more complex you make one, the harder is it for anyone to know what it is. And it’s just plain hard to do this when you want higher resolutions. Conundrums. After messing around for more time, I remembered I had some old Nintendo retro icons saved from the last time I was doing this, and boiled it down to three:

    I’m not a huge Mario fan, so I kicked him out, and tried the Mushroom. Cute. Iconic. Identifiable to some. And it had a reminder to me of a childhood book. It was also ‘bright’ and stood out on my toolbar. So I did that.

    Now you can’t always get away with this. Sometimes you have to bite the bullet and make a new favicon, or convert the perfect PNG to a favicon. Remember, IE doesn’t accept PNGs for favicons. For that I actually use X-Icon Editor, which lets me tweak each size on it’s own. That means you have make a super complicated 64×64, for retinas, and a simple 16×16 for everyone else. But remember: KISS.

    Keep all this simple.

    Oh. And the mushroom is an extra joke. See, if you hit it in Super Mario Bros., it took you from Small Mario to Normal Mario. Now it takes me from small favicon to large favicon. And yes, it was on purpose.

  • MP6uccess – Tips and Tricks

    MP6uccess – Tips and Tricks

    Notice: Since WordPress 3.8 came out, you DO NOT need to install MP6 for anything to work. Promise. If you want the extra color schemes, use Admin Color Schemes, but everything else works in core WP.

    nyan-catI like MP6. It’s far, far, far easier for me to read the back end of WordPress with it. It has legible fonts, larger fonts, and best of all, it’s mobile friendly.

    The biggest complaint has been that it’s too dark. And I get that, I really do. I personally have trouble seeing white on black (computers only), and white on green (yes, road signs). So for me, the black sidebar was a little heavy, but something I could live with. Then version 2.0 came out and behold, color schemes!

    I immediately ran this update, zipped to my profile page (where I knew it had to be), and saw this:

    mp6-scheme

    The other options right now are Blue (looks like the old blue), Seaweed, Pixel, and Ectoplasm. Seaweed is my favorite, but I decided to make each site a little different and distinct, so I have Ectoplasm running right now on one site and Seaweed on the other. I can tell right away which is which. My only wish is the toolbar was colorized on both ends.

    Tips & Tricks

    Okay, okay, I’ll stop selling the plugin, and instead tell you what’s cool to do with it.

    Styling Menu Items

    The items on your menu sidebar default to some pretty boring icons. Bleah. For years we’ve always uploaded our own images to change things in our plugin and custom post types. Here’s an example for my own code for an old Custom Post Type, because I wanted a custom video icon to show up on my sidebar:

    function cptname_post_type_css() {
       echo "<style type='text/css' media='screen'>
               #menu-posts-CPTNAME .wp-menu-image {
                    background: url(/path/to/CPTNAME.png) no-repeat 6px -17px !important;
            }
               #menu-posts-CPTNAME:hover .wp-menu-image, #menu-posts-CPTNAME.wp-has-current-submenu .wp-menu-image {
                     background-position: 6px 7px!important;
            }
        </style>"
    }
    add_action( 'admin_head', 'cptname_post_type_css' );
    

    Now that I’m using MP6, I have access to Dashicons, which already has a video icon included, so I can use this:

    function cptname_post_type_css() {
       echo "<style type='text/css' media='screen'>
               .mp6 #adminmenu #menu-posts-CPTNAME .wp-menu-image:before {
                    content: '\\f126';
                }
             </style>";
    }
    add_action('admin_head', 'cptname_post_type_css');
    

    Menu with VideoNo need for a hover image, because this is a font and not an image, so the hover is automagically taken care of. The result is exactly what I wanted. It looked just like it was built into WordPress from day one, and my co-authors know right where they’re supposed to go to make a new video post.

    There are a lot of options to nab from, and there’s a double edged sword to having some ‘standards’ built in. While it’s super easy for me to make a plugin or CPT use what I want, the same goes for other people. I imagine a lot of shopping cart plugins will want to use '\f174' (the shopping cart) if they don’t have their own. Also it means that to ‘match’ you’ll have to use Font Icons yourself, and they’re not super easy to make. Not that everyone worries about matching.

    Force a Choice

    Okay, what if you want to force a choice for everyone?

    add_filter('get_user_option_admin_color', 'change_admin_color');
    function change_admin_color($result) {
        return 'ectoplasm';
    }
    

    This is the same as it’s always been, actually. But now everyone gets to use purple and green, yay! Keep in mind, this is a hard force. Everyone uses this. There’s no changing. I have this on one site, since the ecotplasm color actually matched the theme. I set it, went away for the weekend, and found the users laughing and loving the perfect match.

    Also check out…

    I’m sure I’m not the first person do dig out these tricks for MP6. At WordCamp Chicago I remarked that a cool plugin would be “MP6SS” – it would let you pick four colors (similar to the blocks the current MP6 plugin offers), and you could make your own colors on the fly. A little dangerous, but the next option up from that would be a fork of the CSS plugin in Jetpack, which lets you totally customize your MP6 CSS 100%.

    Here’s some links I’ve found to more MP6 fun:

    Do you have any tricks? Post links to your code!

  • Breaking Up Multisite

    Breaking Up Multisite

    This is by no means the be-all and end-all of how to break up a Multisite. These are, however, methods I’ve used to move Multisites around into brand new places. As always, if you have another method, feel free to explain in the comments, and link back to your own tutorials!

    brokeback-mountainYou see, Multisite is great at some things, but breaking up is crazy hard to do. If you want to just disable multisite, it’s not too bad, four steps, and the hardest is to delete the right tables. And if you want to move a whole multisite, it’s not terrible either.

    But. What happens when you want to move only one site on the network?

    Usually I see this happen when someone is developing a site for someone else, and thinks it’ll be ‘easier’ to do it on their Multisite. After all, the site will be ‘visible’ but clearly a development site, and remote clients can take a look all they want. The minority of people I see doing this for just themselves, knowing the site won’t ever need to be on a Multisite, but taking the ‘easy’ way out. And to them I suggest developing locally, as domain.dev, and then a blanket search/replace on ‘domain.dev’ for ‘domain.com’ when you’re ready to move. Then there is a small group of people who have a multisite installed on localhost for development, which … no. Don’t. It’s localhost. Spin up a new instance of WordPress.

    And still, while I lament the shortsighted nature of these things, there are clear-cut use-cases for this that people just can’t predict. Like the day you wake up and realize that Ennis and Jack can stay on brokebackblog.com, but maybe you should move the Hulk.(Ang Lee directed both movies.) Now you have a dilemma. Do you rebrand brokebackblog.com as angleefilms.com? Maybe you just domain map brokebackblog.com/hulk to hulksmashblog.com or maybe, maybe, you don’t want to run the Hulk blogs at all, but your friend Eric does. Certainly there are always options to splitting up a Multisite, yet for the sake of this post, you have decided that Eric (who has bought hulksmashblog.com) should have the whole site, all the posts and users, and you don’t want it on your server at all!

    Now what?

    Uber Easy: Export and Import

    This is straightforward. Install your new stand-alone WordPress instance, export the posts from brokebackblog.com/hulk, import them into hulksmashblog.com, customize the theme and plugins, done. If you don’t have a lot of users, this is the best bet. Yes, you’ll lose a lot of time resetting all the plugins and theme configs, but you probably had to do some of this anyway. All your comments come with, all your images too, so it’s going to be straightforward.

    A couple more things to keep in mind. User passwords will need to be reset, which is trivial in my experience, and a good idea anyway if you want to enforce good passwords. Many new themes are getting great at allowing you to export theme settings, so that may ease the pain as well. The plugin settings really are the biggest hassle to me, but in the long run, I’ve found that having to reset them isn’t horrible since the new home usually is a little different from the old one.

    Finally, you’ll probably need to search/replace your posts to compensate for the new image location. I prefer Velvet Blues Update URLs, but sometimes I use .htaccess to redirect instead. If you’re moving from an older Multisite, your images will all point to /files/, but newer ones are in /wp-content/uploads/sites/#/ instead. Of course, wp-cli make it even easier, and I use it all the time when moving people at work.

    $ wp search-replace brokebackblog.com/hulk hulksmashblog.com
    

    That’s right now my favorite command. It updated everything, with serialization handled safely, and I was done. If I can’t use that, I’ll grab the interconnectit search/replace tool (not just for WordPress) and run that instead, but for me, I install WP-CLI pretty much everywhere now. It’s just so easy!

    Ugly Complex: Database Dancing

    brokeback-mountain-20051213061537535When you’ve got a more complex situation, like a heavily customized and themed site, with lots of users and content, then you may have to do this the hard way. As before, make your new stand-alone instance of WordPress. Copy down all the plugins and the theme from your multisite, same as before. Instead of importing the content via an XML file, though, we’re going to import the following database tables as well as all the media images. Remember, no import, no media import, so you must SFTP them all over.

    Then the DB Tables you need are as follows:

    wp_x_*
    wp_user
    wp_usermeta
    

    This means you need to know your site number (not too hard, you know how to make them show up, right?), but don’t think it stops here! Now you have to rename tables. There are two directions to go. One is to rename all the wp_x_ tables to wp_, and the other is to rename the other two tables to wp_x_user and wp_x_usermeta instead.

    Either way you get to fuss even more. And don’t forget what I talked about in Recovering Your Cape: If your tables are named wp_x_ then you MUST have a field called wp_x_user_roles in wp_x_options, or no one will have any permissions at all. This almost makes it easier to think “Well I should just add in _x right?” You’d think, but then you’re stuck with this funny prefix you have to account for in your wp-config.php file, and you also have to consider what if hulksmashblog.com later wants to make itself a multisite. Be nice to the next guy. I would rename the tables, and then run a search/replace for wp_x_ and wp_ using wp-cli or that script.

    Now you’re still not done though. You actually moved over all of your users. That means you have a bunch that don’t have any posts. Go to the /users.php screen and sort by number of posts. Nuke everyone who doesn’t have any posts. Of course… what if they had comments and you want to keep that? Sadly that’s not listed. The comments table isn’t tied in to the users table in a easy to calculate way. But remember, deleting a user won’t delete the comment.

    Finally, remember you changed the domain name? Do that again, like you did with an import export.

    To The Pain: Moving Your Main Site

    brokeback_mountain_2005_6728_wallpaperOw. Ow. Okay, Jake, here’s where we get messy. There are just too many options to consider, so let’s look at them briefly.

    First, if you want to keep the main site at its current location (domain etc), then you want to actually move all the other sites and then disable multisite.

    However, if you want to keep the domain as a multisite and give the main site it’s own, new, home, you’ll want to switch out the main site for a subsite (detailed in WordPress Multisite 110 – around page 80), and then move it per one of the other ways… except remember the site number stays as ‘1’ which is to say ‘none’ so you’ll be moving wp_* and only the ones for the site, not the network (which you can’t delete unless you feel like breaking everything).

    Finally, and this one boggles my mind, you want to keep the multisite, and all the sites, but separately. You can see there’s no quick fix for this. Move ’em all manually, and have a beer when you’re done, cause it ain’t fast.

    Worse….

    There’s more? Just a little bit. Keep in mind that any network settings won’t copy over, so W3TC and WordPress SEO, just to name two popular plugins, have network wide settings. Those don’t magically come with, you’ll have to re-build all of that. With W3TC, you should be able to export the settings, but maybe not. Other plugins too may prove problematic. What about BuddyPress? That would pretty much have to be a table-copy over. At least bbPress should be easier, as it’s all CPTs.

    Obviously the more layers you get into with this, the messier it gets. Me? I try to do the age old export/import whenever possible.