Half-Elf on Tech

Thoughts From a Professional Lesbian

Author: Ipstenu (Mika Epstein)

  • SEO Slides Is A Pie

    SEO Slides Is A Pie

    This review is of the FREE version during the beta release!

    I wanted to love you. All my friends rave about you and tease me for using PowerPoint. “Don’t you want to own your data!” they harangue me. And it’s true, I do! So the idea of having my slides on my server, embedable into posts? Hey that sounds great!

    The cake, is, alas, a pie.

    It’s not really a ‘lie’, but there are points that I just don’t love like they do. This is not to say I don’t like it, in fact I am happily using it, and I’m going to keep using it, and for a lot of people, this will be perfect to make slides. It’s not (quite) perfect for me, but that’s because of my current usage. I can see the future of slides and WordPress, and it really is going to be SEO Slides for many (if not all) of us.

    seoslidesBefore I get deep into this, you have to register to import PDFs. This is perfectly fair and understandable. They’re converting a PDF into images on their server and importing. Okay, I’m jiggy with that. I could conceivably make the images myself, but this is fine. The problem, or rather the part I don’t like, is that they really all just images. And they’re named things like c6ddd0b82e5a45c70fb2718869cad3e1-7. So once I import, I have to go back and change all the titles and (if I want) copy in my notes.

    So why not just write it in SEO Slides? Because of Presenter View.

    Say what you want about PowerPoint, but the fact that I get a presenter view, filled with my notes, is actually very important to me. I make notes, as you may have noticed reading my post from WordCamp Portland, 2013. Sometimes they’re exactly what I’m going to say, sometimes they’re slightly different bullet points than my slide has. Sometimes I have NO bullet points on the slide, so they’re all in the text. I really try to use that aspect of Power Point. I don’t really script my talks to 100% detail, but I treat those notes as flashcards to keep me on topic and on pace. They even will have time notations.

    As a presenter, keeping to my time limit and topic is important to me. Since I do give similar talks a lot (example: I used ‘A Tale of Two Servers’ to talk about Managed WP hosting in Boston, but I also have a Degrassi themed one called ‘Whatever it Takes’), the notes are often the same, but the pacing will be different. I try to cater to my audience. For now, this is the absolute number one reason I’m sad-panda about the plugin. But if that’s not your thing? You have no worries!

    The important factor to me is embed-ability. I have to be able to embed my content on a page. I use that page with a custom shortlink and put it in my slidedeck. Now with SEO Slides, I can just use the page, but it doesn’t let me put text or notes around it, so I’ll still want this to be embedded. Problem? Embedding with SEO Slides is not as obvious as you’d think. I read the Embedding FAQ and this just did not happen for me:

    When you “Publish” your presentation, you will be provided a link to “Use presentation in a new post.” This option will embed your presentation directly into a new blog post.

    I thought I was doing something wrong, but finally I realized the ONLY way to get this “Use in presentation” link was to save the post once published. Gah. Why not a nice button? Still, this was not insurmountable, and in the end, I really did like the look of the embed way better than the Slideshare one.

    Except … I’m not really thrilled with having to upload all my media. It makes me want to make a dedicated SEO Slides site on my network so I can isolate content. Part of the issue is with how I like to write my slides. I know for a WordCamp where I speak for 45 minutes, in order to leave room for questions, I should have no more than 30 slides, and that’s only if I’m doing roughly a slide a minute! I try to keep it closer to 20-25 honestly. A 45 minute talk should have at least 5 minutes for questions. I like to keep the text on my slides minimal, so I have a lot more to actually talk about.

    I hate slides that are pretty much what the person reads off… thanks. And that’s really a totally personal thing, but it means my slides are really image heavy. So that adds a lot of weight to a site. It’s not a plus or minus, just something I have to consider.

    The other problem with embeds is the embed CODE. You get a lot of parameters but the ones that jump out at me is this:

    site_src="http://slides.ipstenu.org/site_title="Slideshows"
    

    It looks cool, and I can change the site_src and site_title…. What I can’t do is change the output. I mean, I can’t remove that ‘source and title’ at all. I can’t change the default so it’s always ‘halfelf.org’ instead of my placeholder site. And worse? I can’t turn it OFF so other people can’t embed my stuff. I mean, what if I don’t want them to embed my warez? This means if someone looks at my slides, clicks the slick plus-sign, they get the code for embedding and they get my slides.ipstenu.org link. Now if you go there, you get redirected, but that’s not the point! Why have this customizable if I can’t… customize it? There are no settings options save entering my API key and allowing for tracking (which I turned off). Why not have an option for customizing output!

    A final minor note with SEO Slides, the title is also wonky. This may be because I’m running Trunk but I get this weird title thing in my … well … title:

    titlewonk

    Not really super happy about that. I did report it though. Also I reported that I ‘ran out’ of uploads of PDFs. In the free version, you get three free PDF conversions. I did it once. I tried a second time and it said “Upload Error: Your subscription has exhausted the use of this service.” So I filed tickets for both of those on November 14th.

    On the good side? These guys are WAY responsive to my enquiry about something (which they changed promptly), and helpful when I said “DaFUQ?” about embedding.

    I’m not sure if I want to use it going on. I may end up using it for embedding, though, but it won’t be a replacement for PowerPoint for me any time soon. Now I just have to decide if I want to pony up the $200 a year just to convert my PDFs. There are enough ‘little’ things missing that frustrate me, like no quick-edit if you just want to change titles, no categories, no tags, no main ‘slides’ page (that is – the custom post type has no archive page).

    Of note! Since this initial review was written, but before it was posted, SEO Slides upgraded me, so I’ll have to come back and re-review once I bang on the Premium Version: Is it worth it? Since, clearly, the brunt of why I’m ‘meh’ about this is the presenter mode, I may fall in love with Premium! The software’s only been out for two months at the time I wrote this, there’s a LOT of room for growth and I’m probably just being really really impatient.

    As this moves from Beta to Live, I expect a lot of great things from SEO Slides. Do I love them? Not yet. But I like them a hell of a lot more than I like PowerPoint, with that sole exception. The presenter view. God help ’em, no idea how you’d tackle that! Can’t wait to see how they do it.

  • Email PopUp

    Email PopUp

    Edited to note: The popup is NOT on this site. You’re not missing anything.

    Blame Chris Lema. Not for “making” me do anything, but for making a good article that was insightful and inspiring. But then again, he’s good at that.

    When I read the article he wrote about Growing your Email List, I was interested. While I don’t have the same needs he does, I do want to pull in more subscribers to one site. Look, in general, I don’t worry about who’s following me on my personal sites. However I do have a site, one site, where I do care about the followers, especially since I broke my old mailing list a while back.

    Revisiting My Options

    The old mailing list worked, but no one could sign up any more, and it was becoming a hassle. It was finally time to move off the old and embrace some new. But what new? I’m a huge proponent of self hosting, but to be frank, I hated managing email server stuff and Mailman is both long in the tooth and not exactly user friendly for the non-technical people. It was time to accept that this was not my forte, and you know what? I didn’t want to learn it. Since 100% of the news on that site was pushed via WordPress, it was logical to use something I already had: Jetpack. It had subscriptions, done.

    “I broke it.”

    That was in the body of the email I sent.

    I emailed everyone on that old list and explained the situation. I apologized for my screwup, and explained how they could re-subscribe if they wanted. Within 12 hours, 50% of them did. That was good enough for me, and while I’m watching more people trickle in, I think it’s going to top out around a 70% retention rate. That’s not bad at all. A handful of people emailed me back laughing (literally ‘LOL’ was the entirety of more than five replies) and saying it was okay, thank you for letting them know. I was heartfelt, I was honest, and I was deprecating.

    I’ve always had a link to my email list in my sidebar as an alias, domain.com/updates linked to domain.com/mailman/list/updates, so changing that to an actual page all it’s own with a subscription form was crazy simple. New page, delete redirect, done.

    Back to Chris though. See, the most enlightening thing I gleaned from his email was the horrifying fact that pop-ups work. He didn’t give me stats or anything, but I believe him. When I read that, I believed him enough that I went and read other articles about those ‘non-annoying’ pop-ups. Chris and I are vastly different people, passionate about different things, and obsessive about others. But we share a talent for writing, telling stories, and engaging. We also share a hate of pop-ups. His is certainly not annoying.

    Actually I’ve barely noticed his, except to go “Oh, there was a pop-up to get him in my email.” No, I didn’t sign up, I like getting Chris in my RSS box.

    jquery

    This was the hardest part so let’s tackle it first. All I have to do is show it in a pop-up. Except it’s not really a pop-up, it’s a sliding tab. Sure, I could use anything I wanted, but like Chris, I hate pop ups.

    This part stumped me hard. Chris got it easy by having a third-party hand him the code. I, like many people, have an email list and want to use that. But I’m still very much a rookie when it comes to jquery, so when I ran into this information about how to code a wordpress.com follow button and Follow me button on WordPress with MailChimp, I did a little dance.

    The jquery actually comes straight from WordPress.com (I viewed a lot of source to reverse this one):

    jQuery.extend(jQuery.easing,
    {
     easeOutCubic: function (x, t, b, c, d) {
      return c*((t=t/d-1)*t*t + 1) + b;
     }
    });
    jQuery(document).ready(function($) {
    	var isopen = false,
    	    bitHeight = $('#bitsubscribe').height(),
    		$bit = $('#bit');
    	setTimeout(function () {
    		$bit.animate({
    				bottom: '-' + bitHeight - 10 + 'px'
    			}, 200);
    		if ( document.location.href.indexOf('subscribe=') > -1 ) {
    			open();
    		}
    	}, 300);
    	var open = function() {
    		if (isopen) return;
    		isopen = true;
    		$('a.bsub', $bit).addClass('open');
    		$('#bitsubscribe', $bit).addClass('open')
    		$bit.stop();
    		$bit.animate({
    			bottom: '0px'
    		   },{duration:400, easing:"easeOutCubic"});
    	}
    	var close = function() {
    		if (!isopen) return;
    		isopen = false;
    		$bit.stop();
    		$bit.animate({
    			bottom: '-' + bitHeight - 10 + 'px'
    		}, 200, function() { 
    			$('a.bsub', $bit).removeClass('open');
    			$('#bitsubscribe', $bit).removeClass('open');
    		});
    	}
    	$('a.bsub', $bit).click(function () {
    		if ( !isopen )
    			open();
    		else
    			close();
    	});
    	var target = $bit.has('form').length? $bit : $(document);
    	target.keyup(function(e) {
    		if (27 == e.keyCode) close();
    	});
    	
    	$( '#loggedout-follow' ).submit( function() {
    		email = $( '#loggedout-follow-field' ).val();
    		if ( '' === email || !email.match( /^.*@.*\..*$/ ) ) {
    			var error = LoggedOutFollow.invalid_email;
    			$( '#loggedout-follow-error' ).text( error ).css( 'opacity', 1 ).fadeIn( 'slow' );
    			$( '#loggedout-follow-field' ).focus( function() { $('#loggedout-follow-error').fadeOut(); } );
    			return false;
    		}
    		return true;
    	});
    });;
    

    If I enqueued that in my theme, then all I’d have to do is call this somehow in my theme:

    <div id="bit" class=""><a class="bsub" href="javascript:void(0)"><span id="bsub-text">TITLE</span></a><div id="bitsubscribe">CONTENT</div></div>
    

    The jquery would automatically handle placement and everything, so I struck upon the dead-simple solution.

    Widget

    Since I only need to use this on a WordPress site, I put it in a widget, and slapped some CSS around it to make it sexier. The very simple (Genesis skewed) widget is as follows:

    //* Register side-up-bit area
    genesis_register_sidebar( array(
    	'id'            => 'slide-up-bit',
    	'name'          => __( 'Slide Up Bit', 'mygenesis' ),
    	'description'   => __( 'This is a widget area that slides up.', 'mygenesis' ),
    ) );
    
    //* Hook after post widget area after post content
    add_action( 'genesis_after_footer', 'my_slide_up_bit' );
    
    function my_slide_up_bit() {
        genesis_widget_area( 'slide-up-bit', array(
            'before' => '<div id="bit"><a class="bsub" href="javascript:void(0)"><span id="bsub-text">Follow SITE</span></a><div id="bitsubscribe">',
            'after' => '</div></div>',
    	) );
    }
    

    Yes, I hard coded in the “Follow Site” title bit. Couldn’t figure out how not to, since I needed the link in the title. If this was a normal widget, I’d use the ‘before_title’ and ‘after_title’ trick, and while that’s supposed to work with Genesis too, I hit a wall and was in a time-crunch. That said, afterwards, all I had to do was drop Jetpack subscribe widget into the widget area, and the jquery code went into a function to show in my footer. Done. Time for the elf to study up on jquery, though, as I still don’t understand it all.

    Bonus note:

    if (document.location.href.indexOf('subscribe=') !== -1) 
    

    That little bit of code says “If someone has subscribed, make sure the popup is up when they visit.” It shows them that they have subscribed successfully, which is great, but I quickly realized I could tweak that to pop up when someone visited my site from, say, Facebook or RSS links:

    if ( (document.location.href.indexOf('subscribe=') > -1) || (document.location.href.indexOf('fb_source=') > -1) || (document.location.href.indexOf('utm_source=rss') > -1) ) 
    

    The RSS folks are pretty small, and I doubt they care, but the FaceBook people were absolutely delighted. I want to stress that I was doing this specifically because I have very non-technical people, and even having a link for email updates was beyond them. But having this slide-up is non-offensive and apparently much needed. My email subscribers tripled within a week.

  • Who’s Following Me Anyway

    Who’s Following Me Anyway

    There are two basic ways to deal with tracking people who follow you on the internet: don’t do it or overdo it.

    In a recent post, Brian Gardner talked about embracing his unsubscribers, as he noticed a number of people un-subbing after he posted a personal post on his personal site. Since then, my friends and followers have asked me about how I feel, and I’ve had to explain that my basic philosophy of ‘tracking’ followers is this: I don’t.

    Now this doesn’t mean I don’t keep tabs on metrics and browsers and the like, to know how to appeal to my readers, but it means the raw numbers, like how many people read a post, are by in large ignored. Except sometimes they’re not. At that point, I agreed that my methodology was complicated, and needed a blog post. So here’s when I do and when I don’t and why I do or don’t as needed.

    It’s Personal

    messing with your statisticsFor the most part, I don’t track visitors on personal sites. I don’t track metrics. I couldn’t tell you who follows my blog on ipstenu.org, and I don’t really care. It’s my personal blog where I’ve decided to write for me, so if I track anything at all, it’s what browsers. A lot of people read the site on an iPhone? Okay, better have a good theme for that! One person is still using Netscape? Forget about ’em.(Sorry Mr. Netscape. It’s 2013, the Internet called and wants you to upgrade.) I never pay attention to the number of my followers on my personal social media accounts. Facebook, Twitter, whatever. I know who I’m following. When you stop being entertaining/interesting/enjoyable, I unfollow. It’s all just me being me for me. You’re welcome to read along, but it’s a personal site for personal people.

    It’s Technical

    Okay, so what about my professional sites? Well, I do and I don’t follow along, depending on how professional the site is. Take this site, for example. While this is certainly my more professional site (I initially split it out because my family reads the main blog and didn’t care about tech babble), I don’t have a dedicated Twitter account for it, or a Facebook fan page. It’s just another aspect of me. I do track metrics here, though. It matters a little more when I’m presenting content for education. I want to make sure everyone can read the site, get the data they need, and move on. And I do keep tabs on my subscription numbers a little, but I don’t actively watch who signs up and who leaves. The way I figure it, if you find the information valuable, you read.

    The only times I’ve ever actually noticed traffic here was when Matt Mullenweg linked here and I got a massive uptick of rabid folks pissed off that I’d used the naming of Constantinople as a metaphor (you’re welcome for the earworm), and when Ars Technica linked to my posts about stopping the botnets with mod_security or with .htaccess.

    This does not mean I haven’t noticed the increase in visitors from tens a day to a hundred and beyond. It just means that since I’m not trying to making a living from this site, it’s not something I dwell on very much. Every time I have to write an article about stats, that means I have to sit and study them here, because I’m just not tracking.

    It’s Professional

    But that really wasn’t me being ‘professional.’ What about my site where I have a custom Facebook page, a Tumblr, a dedicated Twitter account, and the whole nine yards? Oh yes, I track. I check analytics to see entry and exit pages, and I even have conversion goals. I notice my bounce rate, traffic flow, and all of those things. For work, yes, I monitor all these things, talk to marketing and sales about how to improve those things, write code to make things serve up faster and better. How did our campaigns go? What should be targeting?

    Lies, Damn Lies and StatisticsMost importantly here, I try to understand the data I’m getting. We’re really good at collecting data these days, but we’re pretty crap at understanding it and using it to our benefit. How often have you seen A/B testing result in flawed assumptions? It’s not easy understanding what to do with the data. It’s not something you can do quickly, and most of us can use metrics and analysis to prove the point we want to make.

    This is hard. It’s really hard and worst of all, how much weight you put in everything depends on who your audience is. How hard? Well there is a science in the testing but not many people use it right.

    It all depends

    And that’s really my point here. It all depends on what your goal is. Who are your readers and who are you writing for (they may not be the same)? Also who do you want to write for?

    Everything comes down to having a goal, knowing what you want to do, and doing it. And there is absolutely nothing wrong with just writing for yourself.

  • Torrenting

    Torrenting

    I torrent.

    Look. There are hundreds of legit reasons to do this. I’m not going to argue if it’s right or wrong, because we all know that taking something that people charge for, without paying, is called stealing. Let’s put that aside. I’ve got a torrent I want to download, because downloading this way will be faster than a normal FTP of a 1G file.

    The first thing you need is a Torrent client. I like uTorrent personally, as it’s small and easy for me to use.

    The next thing you need is a torrent file. Let’s say I want to get the DRM free music from SXSW. I could download them all one at a time, or I could use a torrent from http://www.sxswtorrent.com/

    2005-sxsw

    That’s 2.6 gigs of music. And you’d think this would take a long time to download. You’d be wrong. What you download is “SXSW_2005_Showcasing_Artists-Release_1.torrent” and open that tiny file in your client.

    uTorrent lets me select what files I want to download (all of them today):

    uTorrent

    I click okay, and it starts to download. This is where it gets fun. The more people who are sharing this file, the faster my download goes.

    utorrent-dowloading

    Here it is, trucking along at 1M a second and it’ll download in about 45 minutes. Just enough time for me to take a shower.

    The magic in the torrent sauce is that instead of FTP where it’s one person asking one server for one file, this is a million people asking a million people for a file, as bits, not a file. So I can get one snippet of a file from Bob in Minnesota, and another from Arman in Atlanta. The more of us who download, the more of us who are sharing what we just downloaded!

    But torrenting is really my favorite way to share large files to the masses. And yes, when I’m done downloading, I leave it up to ‘seed.’

    I am aware, by the way, that as of 2010, SXSW was a little iffy about distribution via torrent, but it’s been three years and no one’s shut the site down. They’re all well aware of it so if no one’s been slapped with a C&D by now, they’re all okay. Anyway, all these songs are available to download off SXSW’s official site. The issue was with the distribution, which I can understand. I try really hard to only download legal files from legit sources, because I appreciate the value of the work that went into what I’m enjoying.

    Now if you’ll excuse me, I have some new music to listen to!

  • No More PHP Code (In Widgets)

    No More PHP Code (In Widgets)

    I consider Otto one of my friends. He’s a guy I don’t mind hanging out with in a bar for hours. His code advice (and debugging advice) has furthered my career. He’s also one of the more realistic folks out there when it comes to work/life balance. Enjoy your beers, bro. So you can guess my surprise when, a couple years ago, he lamented to me about his plugin, PHP Code Widget, and how he wished everyone would quit using it. “I use it.” I replied, and earned an Otto-Grumpy Cat glare. “Don’t.”

    25508154Further conversations illuminated the situation. The code works, but it’s not great since people can use it to insert anything PHPish. Sure, in the wrong hands that is hella dangerous. I was about to broadly declare “I’m not the wrong hands!” when I thought back on everything I do, and where I do it, and I sheepishly replied, “I guess I’m just lazy.”

    And that’s the crux. I am lazy, and I looked for the easier way to include a PHP file in my widget areas. I was using it to show ads (the ones you see all over this site) via include("/home/foo/public_html/blah.php");. Why? Because I use the same ads on multiple places. But that’s it for my PHP usage. Which means for me, replacing it with anything else is super easy!

    Shortcodes

    They work in widgets, so hey! I knew I just needed to include a specific PHP file from a specific location, so for me, this was pretty simple. Also it meant I could call a do_shortcode in other places in my theme functions to add it in.

    // My Ads [myads name="name"]
    function myads_func( $atts ) {
            extract( shortcode_atts( array(
                    'name' => 'placeholder',
            ), $atts ) );
    
            $filename = '/home/foo/public_html/ads/'.$name.'.php';
    
            if ( !file_exists($filename) ) { return '<!-- Ad would go here, but you messed up! '.$filename.' not found -->'; }
    
            ob_start();
            include($filename);
            $content = ob_get_clean();
            return '<div id="'.$name.'">'.$content.'</div>';
            }
    
    add_shortcode( 'myads', 'myads_func' );
    

    I put in the little fail check to be hidden, so I would know where to look. This obviously works well for me since I’m pretty limited in how I was using Otto’s code. Before this, though, I was also using it for some BuddyPress sidebar trickery which could not be done (easily) with shortcodes, and really nor should it be, so that brings us to number two…

    Make Your Own Widget

    phpcode-287392Widget code is … weird. It’s not as easy as a function, and it’s way the heck larger than shortcode code, for many things. But you should remember that better or worse is subjective, I know, but for me it wasn’t worth the time to do it. It takes me way longer to master widget code, which I can’t use everywhere (in post content, in footers etc). But Otto’s general advice has been to make a widget.

    It’s also probably way safer than doing an include like I am, but when I started needing the shortcode all over the place, that’s what it was.

  • My Super Secret .htaccess File

    My Super Secret .htaccess File

    This came up back in April in the comments of WordPress Login Protection With .htaccess, where I remarked my .htaccess was pretty long and weird. It came up again when I was doing a MeetWP presentation about hacked sites and some security.

    So what is it? Actually less long and weird these days. I’ve been trimming stuff out. But since people ask, here it is, broken out into ‘chunks.’

    Security

    Everything in this section is for security purposes. That is, I feel it helps my site be safer.

    # Tinfoil Hat Stuff
    Options +Includes
    Options +FollowSymLinks -Indexes
    

    This is basic .htaccess stuff, says to allow includes and symlinks, but stop indexes. This means if you go to halfelf.org/wp-content/uploads/ you don’t see anything, even if I don’t have an index file.

    ### Blocking Spammers Section ###
    <files wp-config.php>
    order allow,deny
    deny from all
    </files>
    

    Now we’re into a little odder bits. This stops anyone from surfing to my wp-config.php file. It shouldn’t matter, PHP won’t let it load the content, but if my PHP is off, it protects me just in case!

    # Stop protected folders from being narked. Also helps with spammers
    ErrorDocument 401 /401.html
    

    This is because of the next section. It gives a nice error for 401s, which WP normally gets gitty over. And not the fun way.

    <IfModule mod_rewrite.c>
    # Stop spam attack logins and comments
    	RewriteEngine On
    	RewriteCond %{REQUEST_METHOD} POST
    	RewriteCond %{REQUEST_URI} .(wp-comments-post|wp-login)\.php*
    	RewriteCond %{HTTP_REFERER} !.*(ipstenu.org|halfelf.org|ipstenu.org|otherplace.net).* [OR]
    	RewriteCond %{HTTP_USER_AGENT} ^$
    	RewriteRule (.*) http://%{REMOTE_ADDR}/$ [R=301,L]
     # SVN & Git protection
    	RewriteRule ^(.*/)?(\.svn|\.git)/ - [F,L]
    	ErrorDocument 403 "Access Forbidden"
    </ifModule>
    

    Ahhh, yes. Here I say “If you’re coming to wp-comments-post OR wp-login and you are NOT refereed by one of my domains, sod off.” And then it says “Oh and if you’re looking for .svn or .git files? Go away.” This isn’t perfect, but it works for some of the botnets. The fun part is that the rewrite sends them back to themselves, which should cause annoying things to happen. Don’t want that? Redirect them to fbi.gov. Actually, if some tool had a page “Redirect botnets here…” I would use that, but generally I send them to http://lmgtfy.com/?q=wordpress+botnet because I’m that sort of kid.

    Speed and Bandwidth

    Now that I’m safer, lets speed this stuff up!

    <IfModule mod_rewrite.c>
     RewriteEngine on
    # ultimate hotlink protection
     RewriteCond %{HTTP_REFERER}     !^$
     RewriteCond %{REQUEST_FILENAME} -f
     RewriteCond %{REQUEST_FILENAME} \.(gif|jpe?g?|png)$               [NC]
     RewriteCond %{HTTP_REFERER}     !^https?://([^.]+\.)?(ipstenu.org|taffys.org|halfelf.org|poohnau.us|ipstenu.org) [NC]
     RewriteRule \.(gif|jpe?g?|png)$                                 - [F,NC,L]
    </ifModule>
    

    First up, stop the hotlinks! I got the idea from Perishable Press, and it stops you from embedding my images. This means my site is faster, as you’re not sucking up my bandwidth. I get 5G so it’s not too much of a concern right now, but it’s the principle of the thing. Don’t hotlink images!

    ### Caching Section ###
    # mod_pagespeed
    <IfModule pagespeed_module>
    	ModPagespeed on
    	ModPagespeedEnableFilters defer_javascript,combine_javascript,move_css_to_head,insert_dns_prefetch,insert_image_dimensions,inline_preview_images,resize_mobile_images
    	ModPagespeedDisallow */FOLDERNAME/*
    	ModPagespeedEnableFilters insert_ga
    	ModPagespeedAnalyticsID UA-MYCODE-4
    </IfModule>
    

    I use Pagespeed on my server, so here I’ve added in my extra rules. Not everything is active for all sites. This is my default WP rule-set though, and it works well. I have it skipping a couple non WP folders, who have their own rules inside on their own .htaccess files anyway. If you don’t have pagespeed? Skip this section.

    # Expired
    <IfModule mod_expires.c>
    <Filesmatch "\.(jp?eg|png|gif|ico|woff)$">
        ExpiresActive on
        ExpiresDefault "access 1 year"
    </Filesmatch>
    
    <Filesmatch "\.(css|js|swf|mov|mp3|mpeg|mp4|ogg|ogv|ttf|xml|svg|html)$">
        ExpiresActive on
        ExpiresDefault "access 1 month"
    </Filesmatch>
    
        ExpiresDefault "access 2 days"
    </IfModule>
    ## END EXPIRES ##
    

    Oy. There are a couple ways you can control all these things. One is the way I did (filesmatch) and the other is ExpiresByType image/jpg "access plus 1 year". Is one better than they other? I don’t know. Not that I’ve managed to see, but I find the filesmatch to be easier to read and add things too. It’s shorter. Does that make it better? Only in so far as my management goes.

    #Gzip
    <IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml text/css application/x-javascript application/javascript text/javascript font/opentype font/truetype font/eot application/x-font-ttf
    </IfModule>
    #End Gzip
    

    Finally we have gzip, which compresses and makes things smaller and thus faster. Using gzip saves me about 80% in filesize, so it makes things faster to download and, thus, display. If you’re using this in your .htaccess, do not also try to use it in plugins/extensions for other web apps, that way likes double compression and garbage on your pages.

    Add support!

    This is a really short bit to add in support for filetypes I use that aren’t always standard:

    # Add filetypes
    AddType application/x-mobipocket-ebook mobi
    AddType application/epub+zip epub .epub
    AddType video/ogg .ogv
    AddType video/mp4 .mp4
    AddType video/webm .webm
    

    Rewrites

    In general, this is useless to everyone else, save as an example.

    ### Massive Redirect Section! ###
    <IfModule mod_rewrite.c>
    RewriteEngine On
    
    # Apple Touch Icons
    RewriteRule ^(.*)-precomposed.png /code/images/apple/$1.png [L,R=301]
    RewriteRule ^apple-touch-icon(.*) /code/images/apple/apple-touch-icon$1 [L,R=301]
    
    # Ipstenu Moves
    RewriteCond %{HTTP_HOST} ^blog\.ipstenu\.org
    RewriteRule ^(.*) https://ipstenu.org/$1 [L,R=301]
    RewriteCond %{HTTP_HOST} ^ipstenu\.org
    RewriteRule ^blog/([0-9]{4})/([0-9]{2})/(.*)$ https://ipstenu.org/$1/$3 [L,R=301]
    RewriteCond %{HTTP_HOST} ^ipstenu\.org
    RewriteRule ^blog/(.*)$ https://ipstenu.org/$1 [L,R=301]
    RewriteCond %{HTTP_HOST} ^ipstenu\.org
    RewriteRule ^wp-content/blogs.dir/1/files/(.*)$ https://ipstenu.org/wp-content/uploads/sites/1/$1 [L,R=301]
    RewriteCond %{HTTP_HOST} ^ipstenu\.org
    RewriteRule ^(.*)favicon.(ico|png)$ /code/images/favicons/ipstenu.ico [L,R=301]
    
    [NB: This sort of thing is duplicated for other domains which also had things moved around]
    </IfModule>
    

    I cut out a couple of sections, where what I did with the ‘Only redirect ipstenu.org’ stuff is repeated for each site. I built much of that after reading my 404 logs and determining what needed to be redirected. Everything is commented and in logical sections, so I can easily find and remember what the heck I was doing.

    This is the longest section, the stuff under # Ipstenu Moves and such, because they’re accounting for files that moved a million years ago. But the moves section is pretty straightforward too, as you can see where things went. I try to keep it as compact as I can. Sometimes I go through and make them more and more efficient, as I learn new tricks.

    What used to be here?

    I used to include the 5G Blacklist 2013 and/or the 2013 User Agent Blacklist (or whatever the current versions are), but now I don’t have it on all my sites because of the work I’ve been putting in on my firewall and ModSecurity instead. Every once in a while, someone tells me I’m putting too much work on Apache to handle the hackers and spammers, and I generally reply “Better Apache than WordPress.”

    Regularly, I go through my .htaccess and see what I can push over to ModSec. I also trim down my PageSpeed rules into things that work on most sites, things that only work on this site, and things that work for everything. This is why there’s no blacklisting here, it’s all handled by my firewall and mod_security and that’s that. I like to take the load off of apache and .htaccess and PHP and make the server do the work.

    Why not nginx?

    Per site configuration is still a pill. No, really that’s it. It’s a hassle to re-do everything I have in htaccess, I can’t just toss a .nginx file in there on the fly without restarting nginx, which means for shared hosts it’s just not gonna happen. Sucks. For managed hosting, where you don’t allow users to make those changes, sure, it’s great. But that’s not my use case. I may use it for a Varnish in front server one day, after I rebuild everything from scratch.