Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: coding

  • Custom Excerpts Read More for Genesis

    Custom Excerpts Read More for Genesis

    I nearly always make a custom excerpt for every post I write. This has the benefit of letting my lede be extended into a great sub-headline. It has the downside of killing my ‘Read More’ links.

    The objective is simple. Have a custom excerpt and a read more link. The problem is that there are multiple excerpts and WordPress handles them all in different ways.

    1. The teaser – This is what you write in a post and end with a <!--more--> tag.
    2. The automatic excerpt – This is the first 55 words of a post.
    3. The custom excerpt – This is what you put in the ‘excerpt’ box on a post.

    Those are parsed in reverse order, so the custom excerpt is given the highest priority. That means in order to show my read-more links, I need to put this in my theme’s function.php file:

    function new_excerpt_more( $more ) {
    	return ' <a class="read-more" href="'. get_permalink( get_the_ID() ) . '">' . __('Read More', 'your-text-domain') . '</a>';
    }
    add_filter( 'excerpt_more', 'new_excerpt_more' );
    

    But. I’m using StudioPress’ Genesis theme. This means I’d like to take advantage of some of the awesome accessibility friendly features so that my read more link looks like this:

    <a href="http://example.com/cookies-and-cake" class="more-link">Read more<span class="more-link-title screen-reader-text"> about Cookies and Cake</span></a>
    

    Okay, cool. How do I do that? Back in the old days, this was how you’d edit the link for Genesis:

    //* Modify the WordPress read more link
    add_filter( 'the_content_more_link', 'sp_read_more_link' );
    function sp_read_more_link() {
    	return '<a class="more-link" href="' . get_permalink() . '">[Continue Reading]</a>';
    }
    

    As of Genesis 2.2, we’re into a world of properly accessibility friendly code, and the function get_the_content_limit() has a major change where it calls genesis_a11y_more_link and that is the function that added in the span for the screen-reader, which requires me to add in the genesis-accessibility theme support for my theme.

    // Customize the read-more links in all situations
    add_filter( 'the_content_more_link', 'sp_more_link_text' );
    add_filter( 'excerpt_more', 'sp_more_link_text' );
    
    function sp_more_link_text() {
    	return '&#x02026; <a class="more-link" href="'. get_permalink( get_the_ID() ) . '">[' . genesis_a11y_more_link( 'Continue Reading' ) . ']</a>';
    }
    

    And as far as it goes, that’s perfect. It makes sure everything matches nicely and is accessibility friendly. But it doesn’t take care of my custom excerpts. For that I need a force command:

    add_action( 'genesis_after_entry_content', 'sp_force_more', 15 );
    function sp_force_more() {
    	global $post;
    	if ( has_excerpt( $post->ID ) && !is_singular() ) {
    		echo '<p><a class="more-link" href="'. get_permalink( $post->ID ) . '">[' . genesis_a11y_more_link( 'Continue Reading' ) . ']</a></p>';
    	}
    }
    

    If there was an genesis_after_entry_excerpt sort of function to hook into, I’d be happier, but this works. It puts a [Continue Reading] paragraph at the end of each of my excerpts for my front page, my archives, and not my individual pages. This helps my readers who are, perhaps, not always as aware as they might be about where to click.

  • Don’t Publish Bad Code

    Don’t Publish Bad Code

    I thought it was self evident, but two of my more respected programer friends missed the point or, rather, took notice with one aspect.

    So let me rephrase what I meant when I said it was okay to write bad code.

    Write all the bad code you can. Learn from it. Make it better. But the code you publish should be the goddamned best damn code you’re capable of writing at that moment in time.

    The point I was trying to make was not to let the fear of ‘This code is shit’ stop you from learning and improving. That’s like saying if you can’t play a piece of music the first time out, you should quit. That’s stupid! Few people can do that! The rest of us have to practice and learn and keep going.

    And yes. That means sometimes when we give a public performance we screw up. That doesn’t mean we shouldn’t perform. That doesn’t mean we shouldn’t fail.

    You’re going to fail, okay? Just give up on that wish. Everyone fails. We fail more times than we succeed, and that failure hurts more than the success feels good.

    When you do a thing, do it to the best of your abilities and no less. If you’ve left a comment of “Come back and fix this.” then you damn well go fix it before you release the code. Writing bad code is no excuse to slack off, it’s an acceptance that not everyone gets it right from the start and you’re going to have to learn from it.

    So learn.

  • It’s Okay To Write Bad Code

    It’s Okay To Write Bad Code

    We all write Bad Code.

    We all write insecure code.

    We all can learn.

    When I posted about bad code, a reader remarked he’d done those things when he was new. So did I! So does everyone. We learn by copy/paste and seeing “Oh! Hello World actually worked!” Those are wonderful moments where we high-five ourselves and feel like we’re learning something cool.

    Everyone makes mistakes. Everyone writes bad code. Everyone misses something. These are all parts of the learning process. So

    Bad Code Educates Us

    When we write bad code, and someone calls us out on it, we learn something. Negative reinforcement is a terrible thing, but those lessons tend to stick with us better than the best positive ones. We remember the feeling and we do anything we can to avoid it again.

    Bad Code Humbles Us

    We’re not perfect. You’d think we don’t need a reminder, but our egos can get the better of us. We start to think we’re awesome and know everything and are always right. We’re not perfect. We’ll never be perfect. Don’t use this as an excuse to write sloppy code, but be aware of your inherent imperfections.

    Bad Code Inspires Us

    When I see bad code, it reminds me to be better and do better. It goes back to the education thing, but really it’s the desire not to be shitty that inspires us to do better. The positive feedback loop being what it is, we really want to be better and have that feeling.

    Bad Code Entertains Us

    I have a site where all that exists is code that ‘breaks’ your site. It’s funny in a way, to learn how to do things by doing it wrong. When I see how far off I was and how bad it was, I laugh. Because in being educated and humbled and inspired, I find the delight in the universe again and laugh.

    What Do You Learn?

    What do you learn from bad code?

  • Bad Code

    Bad Code

    You can pick your friends and you can pick your code, but you can’t pick your friends code.

    I said that to Michelle as we were walking from WordCamp Minneapolis, kind of as a joke, but then she looked at me and said how appropriate that was.

    Sometimes the people we like and rely on code things in ways we think are a little insane. Here are the things that make me sigh a lot when I look at the code. They’re not always bad, but they do make me wonder what people were thinking.

    Hidden

    Someone wrote a plugin where the options were called via a base64_decode() from a compressed storage:

    #default settings code
    $options = '1VtPj-smEP8qKz2pt0qJs5vs7ju29_bQS08WtolD1zYp4M3mPfW7F2yDwWAPPK0q9erMj_nDzDAzEPSaHbLX7_x1n73-9HdPxdeK8GuD7nlDazp--cpfd9OP5sPz9EFR5T1r1in3O5v0Ripx2SDe28QXTOqLiKWWUuSXaoP6caYmXR4huV7-jN5JSTuA-mn6wgUp3-4x6z-HEdtanAIgyKohRqBx9ZcO3_Irw2fyEcFBETeowE1O3zFjpMIRG6JAgrT4ihmhMTuIOtTcpS48L-kmB_2l7...';
    

    At the risk of sounding like the US government, there’s no reason to hide your public code. Knock it off. It’s public. Hide the service code if you must. Keep your serviceware code on your own data. But hiding code someone can download and decrypt? No, you’re shady.

    Nesting

    The plugin basically was one thing: add_filter('show_admin_bar', '__return_false');

    But the plugin setup was /hide-admin-bar/hide-admin-bar.php which included a file /lib/bar-settings.php which in turn included /lib/false.php

    Three files. One line of code. Why? Why!?

    Inconsistant

    I don’t mean tabs vs spaces. I mean with names. Like having add_menu_myplugin() and myplugin_settings() and then sanitize_myplugin_value() and finally double_check_myplugin() — Sure they all have ‘myplugin’ in there, but they don’t have any rhyme or reason to the names.

    Names should be consistent and descriptive. A good function name should tell you what the function does.

    Echo

    I see this one a lot. People using ‘echo’ on every line in a function call in order to output their results.

    $my_count = $whatever->my_count;
    
    echo '<h2>Hello World</h2>';
    echo '<p>This is a cool thing!</p>';
    echo '<p>This is even more cool. This is '.$my_count.' times cool</p>';
    echo '<p>Ain\'t this cool too? But I have to escape my apostrophes.</p>';
    

    Besides the fact that it looks ugly, it’s created more ‘data’ in your code. There are easier ways around this and ones that are more readable.

    What Do You Think Is Bad?

    And remember, we’re not talking about code that’s outright wrong, we’re talking about the things that work and are right, but make you cry “Why!?!” like Nancy Kerrigan.

  • Updating Bower with Grunt

    Updating Bower with Grunt

    The goal of automation is to make the annoying stuff I don’t want to have to remember to do easier to do. Bower is useful for updating things. Grunt is useful for running a series of commands. Using them together makes life easier.

    In my little world, everything lives in a folder called ‘assets’ and its very simple.

    Add a Package to Bower and call it in Grunt

    First I have a .bowerrc file which very simply says this:

    {
       "directory": "vendor"
    }
    

    That tells Bower where to install things. So when I run bower install jquery-backstretch --save in my asset folder, it saves backstretch to the vendor folder.

    In my gruntfile.js, I have this to pull in my backstretch arguments and the main file into one file, uncompressed, a folder level up:

    		concat: {
    			// Combine all the JS into one
    		    backstretch: {
    		    		src: ['js/backstretch.args.js', 'vendor/jquery-backstretch/jquery.backstretch.min.js'],
    				dest: '../js/backstretch.js',
    		    },
    		},
    

    Just like magic.

    Tell Grunt to Update Bower

    But while Bower pulled in the packages, I don’t want to have to tell Bower ‘Hey, make sure everything’s up to date!’ every few days. I want to make sure I’m on the latest version of a branch most of the time, for security reasons at the very least. That means I have this in my bower.json file:

      "dependencies": {
        "bourbon": "~4.2.3",
        "neat": "~1.7.2",
        "jquery-backstretch": "~2.0.4"
      }
    

    So if I run bower update I would get this:

    bower jquery-backstretch#~2.0.4 cached git://github.com/srobbin/jquery-backstretch.git#2.0.4
    bower jquery-backstretch#~2.0.4         validate 2.0.4 against git://github.com/srobbin/jquery-backstretch.git#~2.0.4
    bower bourbon#~4.2.3                      cached git://github.com/thoughtbot/bourbon.git#4.2.3
    bower bourbon#~4.2.3                    validate 4.2.3 against git://github.com/thoughtbot/bourbon.git#~4.2.3
    bower neat#~1.7.2                         cached git://github.com/thoughtbot/neat.git#1.7.2
    bower neat#~1.7.2                       validate 1.7.2 against git://github.com/thoughtbot/neat.git#~1.7.2
    bower jquery#~1.9.1                       cached git://github.com/jquery/jquery.git#1.9.1
    bower jquery#~1.9.1                     validate 1.9.1 against git://github.com/jquery/jquery.git#~1.9.1
    bower neat#~1.7.2                        install neat#1.7.2
    bower bourbon#~4.2.3                     install bourbon#4.2.3
    
    neat#1.7.2 vendor/neat
    └── bourbon#4.2.3
    

    Cool. But who wants to run that every day?

    Instead, I ran npm install grunt-bower-update --save-dev to install a new Grunt tool, Bower Update. With that code added to my gruntfile.js, every time I run my grunt update command, it first updates my libraries and then runs the processes.

    There is a downside to this. I use git to keep track of my work and either track the vendor packages in my repo (which can make it a little large) or I can remember to install the packages. There are other ways around this, like using grunt-bower-task to set up things to install if not found, update if they are found. I went with including them in my repos, which makes the git pull a bit large (it added about 6000 files), but since I properly delete my assets folder when I deploy from git, it won’t impact the size of my server’s package.

    Register a New Bower Package

    Randomly, when I initially tried to install backstretch, I forgot it was named ‘jquery-backstretch’ and did this:

    $ bower install backstretch --save
    bower                        ENOTFOUND Package backstretch not found
    

    Obviously the right fix is to use the right repo name (and bower has a great search tool to help me to that). But what if I did want to package it up as backstrech? Or if I wanted to add my own repo? Well I would have to register that package first. And that’s pretty easy:

    bower register backstretch git://github.com/srobbin/jquery-backstretch.git
    

    Your Tricks?

    Do you have Bower tricks?

  • Varnish Cache and Cache-Control

    Varnish Cache and Cache-Control

    In our quest for speed, making websites faster relies on telling browsers when content is new and when it’s not, allowing them to only download the new stuff. At their heart, Cache Headers are what tell the browser how long to cache content. There’s a special header called Cache-Control which allows each resource to decide it’s own policy, such as who can cache the response, when, where, and for how long. By default, they time we set for the cache to expire is how old a visitor’s copy can be before it needs a refresh.

    A lot of the time, I see people setting Cache-Control to none and wondering why their site is slow.

    Since I spend a lot of time working on DreamPress, which uses Varnish, I do a lot of diagnostics on people with slow sites. One of my internal scripts checks for Cache-Control so I can explain to people that setting it to none will tell Varnish (and browsers) literally not to cache the content.

    The way it works is that they actually set things to ‘no-cache’ or ‘no-store.’ The first one says that the content can actually be cached, but it’s going to check and make sure the resources haven’t changed. It’s not really ‘no-cache’ but ‘check-cache.’ If nothing’s changed, there’s no new download of content, which is good, but it’s still not caching.

    On the other hand, ‘no-store’ is really what we think about when we say not to cache. That tells the browser and all intermediate caches that every time someone wants this resource, download it from the server. Each. Time.

    What does this have to do with Varnish? Well here’s the Varnish doc on Cache-Control:

    no-store: The response body must not be stored by any cache mechanism;

    no-cache: Authorizes a cache mechanism to store the response in its cache but it must not reuse it without validating it with the origin server first. In order to avoid any confusion with this argument think of it as a “store-but-do-no-serve-from-cache-without-revalidation” instruction.

    Since Cache-Control always overrides Expires, setting things not to cache or store means you’re slowing down your site. Related to this, if you set your Max-Age to 0, then you’re telling visitors that the page’s cache is only valid for 0 seconds…

    And some of you just said “Oh.”

    Out of the box, WordPress actually doesn’t set these things poorly. That generally means if your site kicks out those horrible messages, it’s a plugin or a theme or, worst of all, a rogue Javascript that’s doing it. The last one is nigh-impossible to sort out. I’ve only been able to do it when I disable plugins and narrow down what does it. The problem is that just searching for ‘Cache-control’ can come up short when things are stashed in Javascript.

    But there’s some kind of cool news. You can tell Wordpress to override and not send those headers. I’ve not had great success with using this when it’s a script being an idiot, but it works well for most plugins and themes that seem to think not caching is the way to go.

    From StackExchange:

    function varnish_safe_http_headers() {
        header( 'X-UA-Compatible: IE=edge,chrome=1' );
        session_cache_limiter('');
        header("Cache-Control: public, s-maxage=120");
      if( !session_id() )
      {
        session_start();
      }
    }
    add_action( 'send_headers', 'varnish_safe_http_headers' );
    

    And yes, it works on DreamPress.