Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: htaccess

  • Switching Network Types

    Switching Network Types

    This actually isn’t hard to do, but it can be tricky to complete if you don’t remember what you started with.

    To start with, let’s say I have a multisite with subdomains: ipstenu.loc. I’ve added in two subsites, foo.ipstenu.loc and bar.ipstenu.loc. But then I decide I really wanted to have ipstenu.loc/bar and ipstenu.loc/foo instead.

    The easy part is first. I know my wp-config.php has this:

    define('WP_ALLOW_MULTISITE', true);
    define('MULTISITE', true);
    define('SUBDOMAIN_INSTALL', true);
    $base = '/';
    define('DOMAIN_CURRENT_SITE', 'ipstenu.loc');
    define('PATH_CURRENT_SITE', '/');
    define('SITE_ID_CURRENT_SITE', 1);
    define('BLOG_ID_CURRENT_SITE',1);
    

    All I have to change is the one line define('SUBDOMAIN_INSTALL', true); to define('SUBDOMAIN_INSTALL', false); and now I’m using sub-folders!

    But that means that foo.ipstenu.loc isn’t really valid. Amusingly, it doesn’t break anything at first, so the still will work. But once I change the .htaccess, things will get hinky, so I’m going to do the ‘hard’ part.

    Go in to Network Admin -> Sites and Edit each site that uses a subdomain and you’ll see this:

    Looks familiar, right? I’m going to change foo.ipstenu.org to ipstenu.org and the line with / becomes /foo/:

    As soon as I hit save, the site is ‘moved.’ Great! Do this for all my sites and .. wait. Now they look all ugly!

    That’s because I have to edit the .htaccess. Go to Network Admin -> Settings -> Network Setup, and copy the .htaccess from there, replace, and now it works too.

    The one last step is re-saving the permalinks in your main site, and remembering your links are about to break. What’s that now? Oh, yes, you see ipstenu.loc now gets /blog/ shoved in for any posts, so ipstenu.org/2012/postname became ipstenu.loc/blog/2012/postname. The catch here is that if you don’t resave the permalinks, they will continue to work until you do. Once you hit ‘save’ on permalinks, blog jumps in, and WordPress cheerfully redirects people for you, so you lose nothing.

    And now you know!

  • DoS/DDoS and You

    DoS/DDoS and You

    Attack! Attack!To a lot of people, you say ‘DoS’ and they think MS DOS, that old command line tool we used to control Windows.

    DoS stands for denial-of-service attack and DDoS is distributed denial-of-service attack. It’s a fancy way of saying ‘Someone’s hitting my server with a hammer so hard, it can’t get up.’ Sometimes you can cause an accidental DoS, like by embedding an image from your server into a public Google Spreadsheet.(Which would have happened to poor Panos when he self-attacked.) And sometimes other people will do it to you by hotlinking your images.(Which is why we block that, children.) Even the scanning people have done for TimThumb can look like an attack.

    Some people like to say that this sort of attack is new, that the Internet used to be good and kind and safe. In the 90s, I remember clearly accidental DoS attacks happening when a site was so popular, having over 500 people log into it at once would crash it. And once it was learned that this happened on accident, it was used as a weapon. Even before then, you could demon dial a number over and over again, until it crashed. I probably just showed my age, but the point is we could always take down a site via overwhelming it, it’s just easier to do it now and not get caught. Picture a thousand people all coming and knocking at your door, or ringing your doorbell, over and over and over.

    So now that you have a general idea of what a denial of service attack is, what can you do about it? If you’re on shared hosting, not a whole lot. The vast majority of ‘good’ fixes for this sort of thing has to take place on a server level. It’s sort of like trying to prevent your house from flooding when a water main bursts. You can put up sand bags, but until the city turns off the water, or diverts the flow, you’re probably going to lose.

    A lot of people suggest blocking by IP address, or using a tool like Bad Behavior to stop the trouble making bots. The problem with this is the troublemakers are still ringing the doorbell. Not as many, perhaps, but quite a lot. I’ve said this many times. IP blocking is a bad idea. Yes, blocking by IP address can work, it’s amazingly powerful, and it’s easily circumvented. The TOR Project is consistently lowering the bar for people to get a new IP even faster than the old days, when I could just re-dial my modem. This is a great thing for groups like Anonymous, and annoying for anyone who has to fight the hidden masses. While I fully support your freedoms, I also retain the right to defend mine, and sometimes that means I have to dig in and sort out how to handle the crazy.

    The first thing you can do on Shared Hosting is protect yourself against hotlinking. I don’t know how many times I’ll have to say it for the world to pay attention, but linking directly to images on someone else’s website, unless they specifically say it’s okay, is bad. I firmly feel hotlinking is theft of services (bandwidth) as well. Please don’t do it. Every half-baked host in the world now supports mod_rewrite, so grab Perishable Press’ ultimate anti-hotlinking strategy and protect yourself.

    Mr. ProtectionAnother useful tool is applying the http:bl (HTTP Blacklist) to your server. That sounds like a lot of work, but the payoff is surprisingly awesome. You see, catching more flies with honey is easy when Project Honey Pot tracks all the naughty people. Naturally there are a few WP plugins for that. In addition, if you just need to punt people who are trying to hack you, I would use the 5G Blacklist 2012 by Perishable Press. Combine that with Bad Behavior and most script kiddies are turned away without you having to fuss.

    That may seem a little contradictory, since I don’t advocate blocking IPs. There’s a subtle difference between you running around blocking every IP for every jerk, and using a well supported tool to do so. When you get around to blocking IP ranges, you shouldn’t be trying to block individual people, but the robots.

    If you get hit anyway, the thing to do is contact your webhost and start a dialogue. They’ll be as helpful as they can, and if not, may I suggest Liquidweb as an alternative? I pay more because I get great service. A good host will take a look at what’s going on and tweak their servers to help carry the load. A good host will help you tweak what you can. Of course, their DOS service runs about $500 a month and I don’t know about you, but I can’t afford that. The little guy has to survive too. Thankfully the other reason I support Liquidweb is that I, as the little guy, get fantastic support. The point is you need to have a good rapport with your host. It’s like they’re your landlord. Respect them, and they come fix your dishwasher ASAP.

    Sadly, at the end of it all, the only thing to do about a DOS attack when you’re on shared hosting is to wait it out. Shared hosting is great for what it is, but if that kind of downtime is cutting into your bottom line, you need to consider moving up to the next level. Remember, if this is something that earns you your living, treat it well! It’s like your car. If you make your living driving, you put money into preventative maintenance, and a VPS (or dedicated server) is very much the same. You can only get out of it what you put into it, so put the effort in to make it secure, or hire someone to do if for you. There’s no shame in hiring a mechanic, after all.

  • The Anarchy of .htaccess and Multiple Domains

    The Anarchy of .htaccess and Multiple Domains

    Traffic sign of 301 htaccess redirectWhen you use domain mapping on a Multisite install (or anything similar, I know Drupal has this too), you run into the issue of sometimes wanting to redirect a URL just for one domain.

    Over the 15 years I’ve had this site, I’ve moved my blog posts around from https://ipstenu.org/ to http://blog.ipstenu.org back to https://ipstenu.org/ and then https://ipstenu.org/blog/yyyy/mm/dd/postname to https://ipstenu.org/blog/yyyy/postname and finally to https://ipstenu.org/yyyy/postname And in those years, I’ve managed to never slaughter my SEO. Why? Becuase I know the secret magic of .htaccess. I don’t (yet) use nginx, I’m sure that will change one day, so right now my genius is limited to knowing how to do a nice regex redirect in .htaccess.

    The majority of this magic comes in two lines:

    RewriteRule ^blog/([0-9]{4})/([0-9]{2})/(.*)$ https://ipstenu.org/$1/$3 [L,R=301]
    RewriteRule ^blog/(.*)$ https://ipstenu.org/$1 [L,R=301]
    

    I also have this to handle the blog.ipstenu.org:

    RewriteCond %{HTTP_HOST} ^blog\.ipstenu\.org  [NC]
    RewriteRule ^(.*) https://ipstenu.org/$1 [L,R=301]
    

    The RewriteCond is the neat bit that says ‘If you come here from blog.ipstenu.org, use the following rule.’ The [NC] is because domains aren’t case sensitive, and we want to CYA.

    For my old setup of a single install, this was great. Today I’m using Multisite, and if I used that redirect, then any site on my network would be redirected! If you’re using subfolder Multisite, you don’t need to worry about this at all, since a redirect for ^blog/ will only impact a URL that has the first folder of /blog/. And that’s precisely why it’s a problem for Subdomains and mapped domains (of which I use both). That redirect up there would affect both https://ipstenu.org/blog/monkeys and http://photos.ipstenu.org/blog/monkeys and https://halfelf.org/blog/monkeys — and I don’t want any of that. I only want to redirect for those URLs if you’re going to ipstenu.org.

    Thankfully, if you look at what I did for redirecting blog.ipstenu.org, you can easily see how to leverage that for this into two checks:

    RewriteCond %{HTTP_HOST} ^ipstenu\.org  [NC]
    RewriteRule ^blog/([0-9]{4})/([0-9]{2})/(.*)$ https://ipstenu.org/$1/$3 [L,R=301]
    RewriteCond %{HTTP_HOST} ^ipstenu\.org  [NC]
    RewriteRule ^blog/(.*)$ https://ipstenu.org/$1 [L,R=301]
    

    Why did I duplicate the RewriteCond? Typically, you cannot use multiple RewriteRule statements following a single RewriteCond. That means for ever call I make to a domain, I can use but one rewrite rule. There are ways around that, but none of them worked well for me.

    If you look at halfelf.org, however, the world gets even messier. Half-Elf is the combination of three domains. Ouch. Two can point to the same place, one needs to redirect totally differently, and then I have a category merge. Oddly that came out as only three sets.

    First we can look for http://code.ipstenu.org and http://tech.ipstenu.org and redirect everything to https://halfelf.org. The trick to this is using (code|tech) in my RewriteCond, which really is one of my favorite things. That’s a built in ‘or’ right there, and if I had a hundred subdomains, I could still do that.

    RewriteCond %{HTTP_HOST} ^(code|tech)\.ipstenu\.org [NC]
    RewriteRule ^(.*) https://halfelf.org/$1 [L,R=301]
    

    Next we want to redirect http://ebooks.ipstenu.org to https://halfelf.org/my-ebooks/ – notice how I don’t want to redirect it like I did for code and tech. Here, everything gets dumped back to the ebook page:

    RewriteCond %{HTTP_HOST} ^ebooks\.ipstenu\.org [NC]
    RewriteRule ^(.*) https://halfelf.org/my-ebooks/ [L,R=301]
    

    Finally I want to tackle the merge of my old categories, and again this is straightforward:

    RewriteCond %{HTTP_HOST} ^halfelf\.org [NC]
    RewriteRule ^category/code/(wordpress|bbpress|buddypress)(.*)?$ https://halfelf.org/tag/wp/ [L,R=301]
    

    My actual .htaccess is even crazier, since I have four domains pointing to multisite plus an add-on for my short URLs.

    This should get you started on customizing redirects in .htaccess for multiple domains. What are you favorite tricks?

  • Speed Up Your Site

    Speed Up Your Site

    FasterThe majority of what I do to speed up my website is on the server level. In 2009 I moved to a VPS, and just last year I switched to a Smart Server. I have access to install APC, to tune MaxClients, and to upgrade my PHP whenever I darn well want to. And I regularly use these tools to fine tune my server so it’s lean, fast, and efficient. 75% of why my domains run this fast under this much stress (I have two fan sites, they get hammered), is that I’ve done all this work, including some of the stuff I did on DDOS prevention.(My CT_LIMIT is set to 75 right now, and that seems to be the perfect balance. The only people hurt are some silly people in Brazil who like to open 100 pictures all at once. I’ve explained why this is bad.)

    However, not all of you have access to the server to make all those cool tweaks and changes to speed up your website. If you’re on shared hosting (and there’s nothing wrong with that), you can’t edit httpd.conf, you can’t always edit php.ini, and you sure can’t upgrade PHP on your own. Don’t worry, there are still things that you can do!

    The first thing you should do is understand that the more complicated your site is, the slower it’s going to be. So if you want a site with all those bells and whistles, you have a lot more work to do than a simple, plain, site. These are the tradeoffs we must accept in all things.(The exception being, perhaps, cookware. I have some awesome Lodge cast-iron pots and pans, and they’re pretty expensive for their simplicity. Then again, they’re made with such amazing skill and precision, they’re not ‘simple’ to make. So YMMV.) Reduce the complications and things run faster. You have to have a balance between ‘everything’ and usability. If your site is sexy as all get out, but slower than a truculent five year-old on a family walk, then you’re doing it wrong. That doesn’t mean you need to have the world’s most boring site, it just means you have to start learning what it is that makes your site slow. When you look at themes and plugins for a site, remember the more you have, the slower things may become, so use them wisely.

    My favorite tools to show why a site is slow are YSlow and PageSpeed. YSlow is a browser add-on you can use with Chrome, Firefox, and every other commonly used browser. Except for IE. Once installed, you simply go to the webpage and run the tool to get a scan of your site. You get ‘graded’ on an A through F scale, with F being the worst, and the grades are computed based on a fairly understandable methodology.(See FAQ: Grading) Page Speed is Google’s version, and I prefer it, but only because I don’t have to install anything to do it, and it gives really good explanations of what’s wrong. There’s also Web Page Test, which is great to find out if your site flails on different browsers, as well as giving you accurate speed breakdowns.

    Here are three of my sites, all installed on this server, scanned by YSlow:

    And here are the same three as SiteSpeed:

    I’m not going to go through every option, most of them are self explanatory (put the CSS at the top and JS at the bottom). Instead, I’ll explain the weirder ones that you can tweak yourself, and some that you can ignore. If you’re using a tool like W3 Total Cache, you actually can configure most of this directly in the tool instead. For what it’s worth, I did ‘fix’ my scores with both sites and I’m now in the 90s from Page Speed and .. Well not so much with YSlow. The two disagree on how much ‘weight’ to give various errors. Page Speed thinks minification is low priority, and doesn’t judge you about a CDN. It also understands that you can’t gzip what you don’t own. If you use YSlow, make note of what you score poorly in, and fix those as best you can.

    Things I Ignore

    When I get complaints of too many HTTP requests, that just means I’m calling ‘too many’ JS scripts and stylesheets. YSlow doesn’t say which ones those are, which isn’t actually helpful to the novice. If you click on ‘Read More’ it just explains why this is bad. The idea here is that you should have one CSS file, but realistically, any dynamically generated site is going to have more that one. Especially when you consider I’m calling some from Google, Facebook and Twitter for my sharing buttons. While this does slow your site down, unless you have 20 stylesheets on your own site (again, I’m not counting the ones on other domains), it’s not that big of an issue. If you minimize what you have, and combine as much as you can, you’re going to be okay.

    I also totally ignore any scores related to my CDN, or rather the fact that I’m not using one. Yes, a CDN will make your site much faster, but I don’t think this is applicable for everyone, and I generally ignore that value.

    Finally I ignore suggestions to use cookie-free domains, but that’s because I’m running WordPress, and it needs cookies.

    Things I Fix in .htaccess

    You can fix most expires headers errors, but only the ones that relate to your site. When I look at a scan for one of my domains, I see that the items my site loads that don’t have Expires headers are a flash module from PayPal, Google’s +1 javascript, a banner, and two gravatars. Those are all items that, yes, can slow my site down, but they’re outside my ability to fix! And in the case of gravatars, I don’t want them to Expire too soon, since they may change. I’m going to, again, ignore this.
    YSlow - Add Expires headers (F)

    Why wasn’t my server listed? It’s because I added Expires headers to my site. Obviously. The easiest way to do this for your site is to put the following in your .htaccess file(If you’re using WordPress, Drupal, or any web app that has it’s own .htaccess rules, remember to put these above the section for them! It’s important.):

    <ifmodule mod_expires.c>
      <filesmatch "\.(jpe?g|gif|png|css|js)$">
           ExpiresActive on
           ExpiresDefault "access plus 1 year"
       </filesmatch>
    </ifmodule>
    

    What this will do is turn on Expires and set to to today plus one year. Now this isn’t actually the best way to do it, as it leaves out a lot of variables, but for most people, it’s good. Keep in mind, the further you set out this expires, the harder it is to change any files! For example, if I upload a PNG with a 1 year expiration, and then upload a new version, no one will see it (unless they flush their browser cache). Don’t set this further than a year, and only set it for things you know aren’t changing often.(You’ll notice WordPress sourcecode has your JS and CSS files saved with ?ver=x.x at the end. This lets you work around the expires, as when you change your CSS, it changes the version, and thus, pushes the changes down to your users.)

    Cache-Control is the half-sibling of Expires, and lets you specify what files should be cached and for how long. The Ask Apache site has some great examples, as this is what I generally use:

    # 480 weeks
    <filesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
    Header set Cache-Control "max-age=290304000, public"
    </filesMatch>
     
    # 2 DAYS
    <filesMatch "\.(xml|txt)$">
    Header set Cache-Control "max-age=172800, public, must-revalidate"
    </filesMatch>
     
    # 2 HOURS
    <filesMatch "\.(html|htm)$">
    Header set Cache-Control "max-age=7200, must-revalidate"
    </filesMatch>
    

    The ‘must-revalidate’ tag is what makes sure your webpages changes actually get picked up quickly. Nothing’s worse than editing a typo, and not having it fixed for your readers!

    Related to that is ETags, which is a bit weird, but this too is something you can tweak. If you disable ETags, everyone has to trust your cache and that gives you a lot of control. It sounds easy, but there’s a reason we should be using ETags for some situations. My sites are using a pretty complex rule that was set by W3TC for me. It sets my Cache Control and ETag, generating the rules I need. If you just want the basics, though, AskApache’s Speed Tips: Turn Off ETags will get you there. For what it’s worth, a small site doesn’t need to worry about this too much.

    If you want to grab my default .htaccess starter, here you go!

    download TXT file

    Things I Fix via CPanel

    You can also speed up your site by enabling gzip. I’d say I left it off on purpose to show you the error, but the fact is I forgot to turn it on when I moved to a new server. If you have cPanel, this is stupid easy. Log in, go to ‘Optomize Website’ and turn it on.

    gzip

    Doing improved a lot of results on my site, though it didn’t want to consider three of my .js files gzipped for some reason, though it did on other domains on the same server when I changed it. I’m not terribly concerned at this point, since I used the HTTP Compression Test (from What’s My IP?) and it says I’m compressed.

    Things I Fix with Elbow Grease (or Plugins)

    Minification. If you view the source of this site, it’s ugly. Everything’s all crammed up without line breaks, and finding anything is a hassle. That’s because I minified my content. If you don’t have a plugin or add-on for your site that can do that for you, you’ll need to do this manually, via Minify CSS and Minify JS. It’s more of a hassle to do that manually, since it’s hard for you to edit later. After-the-fact compression can slow your site a little, but it’s easier to maintain and still faster than non-minified code. Now I use W3TC, which has a minification tool built in, but there are other WordPress plugins that do the same thing.

    The Rest

    There are a lot more tips and tricks to getting your site running faster. I mention W3 Total Cache (W3TC) multiple times because it works great. There’s also WP Super Cache, which I prefer for smaller hosts and shared servers. W3TC is very, very, very complicated, so be warned. WP Super Cache isn’t a ‘lesser’ tool, it’s just different, and I advocate using either one if your site is moderate to large.

    If your site is small, you really can get by with just minifying. There are a lot of minification plugins out there. Images can be reduced in size by compressing them more via Smush.it (there’s a plugin called WP Smushit for WordPress). Many people have also suggested using a Lazy Load plugin, like jQuery Image Lazy Loading, which loads images on demand. I like it, but it slows my site down, and doesn’t work well at all on ones with a lot of dynamic images. I may be using it wrong.

    Anyone can take advantage of a free CDN, Cloudflare has a free plan.(Caveat: I don’t use CDN, nor have I looked at Cloudflare in depth.) They claim to protect you as well as speed things up, and I’ve heard interesting (good) reports on it.

    Many people advocate using plugins to tune your database, but I really don’t like using a plugin for that. You can optimize your database with a cron job instead, or even just do it manually now and again, if you think your site is sluggish. For WordPress I limit my revisions and empty my trash more often with two lines in my wp-config.php:

    define('WP_POST_REVISIONS', 5);
    define('EMPTY_TRASH_DAYS', 5 );
    

    When all else fails and nothing you can do speeds up your site, take a look at your server. If the server itself is really slow, all the time, and I mean you can hardly get your email, ask your host if you can be put on another cluster. A lot of shared hosts are oversold, since not everyone needs all the space and power. It makes sense, but some hosts monitor the status of these servers and move people around if they become bad neighbors, while others wait for you to notice. Opening up a line of communication with your host is always a good thing. Remember, you’re paying these guys! They should be willing to help you out, or you should leave and get a new host.

    At a certain point, you’ll notice that the only ‘fixes’ are to throw more money at it, buying a better host, better themes, better tools, and so on. And that’s simply a fact of life. You can’t live forever on ramen and hot dogs.

  • Don’t Use WWW

    Don’t Use WWW

    It was asked why I don’t recommend using www in your URL for Multisite in WP Multisite 101.

    To quote me:

    You should not use www in your URL
    A lot of people complain about this. The simple fact is that any well built server will automatically redirect www.example.com to example.com seamlessly. By removing it from our install, we avoid any possible conflicts with subdomains. Your SEO will not be impacted.

    What I didn’t say, but I told the fellow with the question, is that some servers see www as a subdomain, and not an ‘alias’ (for lack of a better term) of example.com, which is my main reason for not using it. I’ve also seen a very rare, but infuriating, problem where, after upgrading, a site that happens to use www in their URL can no longer get to the network admin page, and instead gets a redirection loop. Since this only happens with www in the URL, and never when it’s not, it’s safer to drop the www.

    I’ve never yet heard a good technical reason to use it, though I do totally accept ‘But I like it!’ as a justification. Everyone has a preference. I don’t feel that the www makes your site more or less professional, mostly because I don’t think anyone really looks except, maybe, you. As long as the redirect is seamless, the user will never notice, and 99.999% of them won’t care. Yes, Google and Facebook both use the www, though newer sites like Tumblr and Twitter don’t. WordPress doesn’t, but I’ve been advocating no-www longer than I’ve used WordPress.

    My technical reasons for not using it stem from the No WWW guys.

    By default, all popular Web browsers assume the HTTP protocol. In doing so, the software prepends the ‘http://’ onto the requested URL and automatically connect to the HTTP server on port 80. Why then do many servers require their websites to communicate through the www subdomain? Mail servers do not require you to send emails to recipient@mail.domain.com. Likewise, web servers should allow access to their pages though the main domain unless a particular subdomain is required.

    Succinctly, use of the www subdomain is redundant and time consuming to communicate. The internet, media, and society are all better off without it.

    To explain what that means, www used to be the protocol to say ‘If data comes for www.example.com, it’s web traffic.’ Similarly, mail is the protocol for email, and mail.example.com sends traffic to your mail server. You could email me at mail.halfelf.org. And the point of all that all web browsers today know that http://example.com is a website. In fact, you can just type example.com into any browser, and it’ll know ‘Oh, this is a website.’ How does it know that? Because you’re in a web browser.

    It’s like when you dial a phone number, you don’t have to press a button to say ‘Phone number.’ Look at your cell phone. If you open up your text messaging app, enter a cell phone number, and send a message, the phone magically knows ‘This is a text!’ and sends it. But if you open the phone app and enter the exact same number, it knows ‘This is a phone call!’ You, the user, have to do nothing.

    That www in your URLs is telling the browser something it already knows. It’s redundant, it takes up space, and it’s unnecessary.

    Now people I respect, like Michael Hampton, maker of Bad Behavior (my out and out favorite add-on to any PHP web app), is the brain behind Yes WWW. His counter argument concludes with:

    The main reason I argue for leaving the www. in URLs is that it serves as a gentle reminder that there are other services than the Web on the Internet. Some of these, such as FTP and DNS, users typically use transparently without even realizing it. Others, such as e-mail, users access through separate applications. Even so, I know of many users who will claim with a straight face that e-mail is not part of the Internet.

    While I disagree (mostly since, if that holds true, we should use mail.example.com and so on), the question comes up that if we’re not using www, how do we differentiate between http://example.com and ftp://example.com in cases where they’re not on the same server? You can, easily, redirect ftp.example.com to a different IP, if needed, via DNS. Thankfully, there are some easy answers to this. First, you can route the requests via ports. If a request comes via FTP, that’s a different port, send it to the other server. What you can’t do, however, is serve HTTP and FTP over the same port, but … you shouldn’t do that anyway.

    There are many personal reasons to use www or non-www, and they are all perfectly valid. But there’s on big technical reason I would never consider it on a Multisite install of WordPress. Once in a blue moon, after an upgrade, someone finds out they can’t get to their network admin. This is, normally, due to a miss-match in URLs, where they’ve put http://example.com and http://www.example.com for their site and home URLs, back before they turned on Multisite. Fixing that is a monumental effort, and it doesn’t always take. (This is probably related to http://core.trac.wordpress.org/ticket/9873 now that I think about it.) Also, even more rare is the case where just having the www forces your subdomains to be subdomain.www.example.com.

    Both situations are frustrating. Both are avoidable by using just http://example.com

    As long as you redirect the www to non-www, your users will never notice. Except the geeks like me. And while we may disagree, it’s unlikely we’ll stop using your site over something that trivial. Go www free. It’s the way to be.

  • Moving Your Images For MultiSite (Updated)

    Moving Your Images For MultiSite (Updated)

    Updated after Andrew Nacin asked me “Why are you suggesting they replace ‘wp-content/blogs.dir/1/files/’ into their post content, instead of /files/?” (Answer: Because when I did this on my first site, about a year ago, I majorly goofed my SQL search/replace and shot myself in the foot For some reason, that made me think ‘files is bad! Blogs.dir is good!’ which … it’s not. Really, blogs.dir is fewer redirects, but that’s really about all I can say. So this has been edited. Thanks!)

    In generic WordPress single installs, your images are, by default, located in a folder called uploads off the wp-content folder, and tend to look like this: wp-content/uploads/YYYY/MM/image.jpg. When you use MultiSite WordPress, the files are now in wp-content/blogs.dir/#/files (where the # is the blog number). If you upgrade from Single to MultiSite, you can leave the files for Blog , i.e. your primary blog, where they are to no ill effects. Or you can move them.

    I’m not going to be using # as a placeholder, as for most people this blog will be 1. If for ANY REASON yours is not, change it.

    Also, I can’t stress this enough, you don’t have to do this! Your images will be just fine where they are, but if you want to move them, you can. Enough people have asked on the WordPress.org support forums that I bothered to consolidate my notes on this, however.

    Oh, and backup. Always backup before you start this sort of thing, otherwise you’re a reckless fool.

    Step 1 – Move the OLD files

    This is easy. Copy or move the files to wp-content/blogs.dir/1/files

    While you’re in there, remember to set the folder writable so you can update files later. Your images will now look like wp-content/blogs.dir/1/files/YYYY/MM/image.jpg – Make a note of this, you’ll need it in a second.

    Step 2 – Teach WordPress where the OLD files are

    There are two main ways to do this:

    Edit the Database
    If you have phpMyAdmin or are savvy at command line SQL, just go ahead and run the replace command:

     
    update wp_posts set post_content = replace(post_content, 'wp-content/uploads/', 'files/');
    

    Now someone here might go “Hang on, I put my files in blogs.dir/1/files and you’re saying to tell WordPress to look in files! What gives?” What gives is what Andrew reminded me! WordPress MultiSite parses files from ‘files.’ The shortest explanation is ‘It’s an .htaccess trick.’ The longer explanation is it’s own blog post.

    If you don’t like the idea of SQL, get a search and replace plugin like Search and Replace or Search RegEx and install it. Then search for wp-content/uploads/ and replace with wp-content/files/ to change the database.

    In both database cases, you’ll want to check changes all over the place. For wp_posts, check post_excerpt and post_content, and then go through wp_postmeta and edit the meta_value fields.

    .htaccess
    That’s a lot of work, and odds are you’re still going to miss something. You can also be really lazy and add this to your .htaccess file, before the WordPress stuff:

     
    # Moved Images
    RewriteRule ^wp-content/uploads/(.*)$ http://domain.com/files/$1 [L,R=301]
    

    That redirects things quietly. It’s probably not the best way, but like I said, I’m lazy. If I was doing this for a client, I’d probably do both the database fix and the .htaccess, to catch any stragglers.

    Step 3 – Tell WordPress where to put the NEW files

    Now the fun part! Go to your site’s wp-admin section, click on Super Admin and pick sites from the drop down. Hover your mouse just below the path to your main blog and click on Edit

    In that new screen, scroll down and look on the left for Upload Path – You want to change that to wp-content/blogs.dir/1/files

    You also want to change Fileupload Url to be http://domain.com/files (this will hold true even if you’re using subfolders or subdomains).

    If you see Upload Url Path, you can change if to http://domain.com/files as well, though it appears to be depreciated and no longer used.

    Step 4 – There is no Step 4

    That’s it! You’re done!