Half-Elf on Tech

Thoughts From a Professional Lesbian

Category: How To

  • Uniqueness Matters

    Uniqueness Matters

    This email gets sent a lot to plugin devs lately:

    All plugins should have unique function names, defines, and classnames. This will prevent your plugin from conflicting with other plugins or themes.

    For example, if your plugin is called “Easy Custom Post Types”, then you might prefix your functions with ecpt_{your function name here}. Similarly a define of LICENSE would be better done as ECPT_LICENSE.

    Please update your plugin to use more unique names.

    And once in a while someone asks why we care so much.

    There are 38,308 active plugins in the WordPress.org repository. If every one of them uses a global define of IS_PLUGIN_SETUP then they will all conflict with each other. If half use a script handle of plugincss then all those plugins will stomp over each other when it comes to enqueuing the CSS.

    It’s literally a numbers game.

    Every day we get at least 30 new plugin submissions to WordPress.org. That means every day at least 30 new potential conflicts show up. And it’s not just plugins. In WordPress 4.2, a new function was added: get_avatar_url()

    This was a great idea that saved people countless hours of work. Unless they logged in to see the error Fatal error: Cannot redeclare get_avatar_url() prance across their screen.

    Now in this case, theme authors had previously been told to include/make themselves, but was later added to core. All theme devs hosting on WordPress.org were notified and it was posted on the change blogs. But not everyone remembers to check those. And not everyone updates their themes right away. In a way, this probably could have been communicated better, but had the themes called their function mythemename_get_avatar_url() then this wouldn’t have been a problem.

    Prefix everything. Make it unique to your plugin or theme. WordPress is ‘home free’ and shouldn’t have to, but you should.

  • Mailbag: Multisite Subdomains Live Where?

    Mailbag: Multisite Subdomains Live Where?

    Heather is confused, and I don’t blame her:

    I am want to use subdomains in my multisite. 1. Install WordPress in the subfolder and set it up to run from root before you create your subsites. 2. You should not use www in your URL ….. Where exactly do need to change this? Settings/ General ( that’s how i saw it in your book) or in my file manager, having to change it in many different files…. ( saw and read this from other internet sources).

    Let’s take this by the numbers.

    1. Install WordPress in the subfolder and set it up to run from root before you create your subsites.

    If (and that’s a big if) you want to install WordPress at example.com/wordpress but have the URL look like example.com then you must do this before you activate Multisite. Can it be done after? Yes. But you will go insane.

    1. You should not use www in your URL

    If you’re using subdomains, just don’t. The issue where WordPress breaks if you use the www here is not to do with WordPress so much as the variant hosts out there and how they handle the www/non-www redirects. Save yourself a headache. Don’t use www. You don’t use www. Yes, I know Google does. They don’t care so long as you’re consistent.

    In both cases, on your single site install of Wordpress, you go to the General panel. The value for Site Address (URL) is what you want people to see when they visit your site. The one for WordPress Address (URL) is where WordPress is installed.

    Make sure they both match in terms of schema and www. Then change the Site Address from http://example.com/folder to http://example.com and save it.

    The official directions are on the codex – Giving WordPress it’s own Directory. There’s a bit more when it comes to moving a couple files, but really that’s it. Once it’s done and working, go ahead and activate Multisite.

    By the way, I always get the WordPress Address and Site Address confused. It’s not just you.

  • CloudFlare Code Muncher

    CloudFlare Code Muncher

    CloudFlare’s email protection butchered my code examples.

    Just putting that out there.

    What Happened?

    I went, perhaps ironically, to a post about changing your git repo URLs after activating CloudFlare, and was confused. See, I knew the code was something like me@mydomain.com:/path/to/repo but when I visited the page, it was all gibberish like this:

    /* <![CDATA[ */!function(){try{var t="currentScript"in document?document.currentScript:function(){for(var t=document.getElementsByTagName("script"),e=t.length;e--;)if(t[e].getAttribute("cf-hash"))return t[e]}();if(t&&t.previousSibling){var e,r,n,i,c=t.previousSibling,a=c.getAttribute("data-cfemail");if(a){for(e="",r=parseInt(a.substr(0,2),16),n=2;a.length-n;n+=2)i=parseInt(a.substr(n,2),16)^r,e+=String.fromCharCode(i);e=document.createTextNode(e),c.parentNode.replaceChild(e,c)}}}catch(u){}}();/* ]]> */
    

    I quickly edited the post and saw the content there was just fine. The only content that was getting munged was code output. It was very confusing so I googled and found a surprising answer.

    What Was Wrong?

    Turns out it was “Email Address Obfuscation” — a feature in CloudFlare that munges your email address to protect it from being scraped. In and of itself, that is ultra cool.

    I could wrap everything like this:

    <!--email_off-->
    
    <!--/email_off-->
    

    Or I could filter all the shortcodes… Or I could turn off “Email Address Obfuscation”

    I went with turning off the setting because it was faster, and it’s not like people cant deduce my email address. But if I was going to set it up, the fastest would actually be to filter all shortcodes, and that proved problematic.

    Why All?

    One of the problems is that I use Syntax Highlighter Evolved to handle my code chunks, and one of the things that plugin does is let me use a shortcode based on the programing language. That means the most efficient way would be to say “If this is a shortcode, wrap it in the email-off tags to tell it to shut up.”

    Can You Code It?

    This is theoretical and not fully tested. Use at your own risk.

    With embeds, you can do things like this:

    add_filter('embed_oembed_html', 'halfelf_embed_oembed_html', 99, 4);
    function halfelf_embed_oembed_html($html, $url, $attr, $post_id) {
      return '<!--email_off-->' . $html . '<!--/email_off-->';
    }
    

    But sadly there isn’t a wrap around like that for shortcodes, which means we have to do some serious filtering. There’s a global array called $shortcode_tags that lists all shortcodes (as you register them, so shall they be added), so I’m going to take that and replace their callback functions with my own. Then in my callback, I’ll keep their callback but at the same time I’ll wrap around it:

    function cloudflare_email_off_for_shortcodes() {
        global $shortcode_tags;
    
        $shortcode_tags[ $tag ] = 'cloudflare_email_off_html';
    }
    add_action( 'init', 'cloudflare_email_off_for_shortcodes', 99 );
    
    function cloudflare_email_off_html( $attr, $content = null, $tag ) {
        global $shortcode_tags;
    
        return '<!--email_off-->' . call_user_func( $shortcode_tags[ $tag ], $attr, $content, $tag ) . '<!--/email_off-->';
    }
    

    But that struck me as a little expensive when I considered how rarely I put email addresses in things in the first place.

  • Bower To The Master

    Bower To The Master

    I recently mastered using Grunt to handle automation.

    And then I was handed some Bower code by Carrie Dils. I’m up for a challenge, I muttered under my breath. I already have Node and NPM and Git, so this shouldn’t be too terrible.

    Turns out I didn’t need to change a damn thing!

    First off, Carrie and I are on the same wavelength, having named our files nearly the same and separated them the same. Second, I had been incredibly brilliant and put all of my code in separate files (my.css, my-config.php, etc etc). Third, I had documented everything that I had changed in all of my files in a my-readme.txt file.

    But if I’m using Grunt, what am I going to get out of Bower?

    Bower is a ‘front end’ package manager.

    To install packages, I make a folder for my work and I go there in a command line, I type this:

    $ bower install jquery

    That would install bower into my folder. It’s dependency aware as well, so if I install Bourbon, it will include Neat. This is much the same as Grunt, which can install its plugins and dependencies, but where Grunt is for installing Node modules, Bower is for js and CSS and html as well.

    Grunt is for running tasks. Bower is for managing components. They’re friends.

    Bower lets me set up all the required components for my site (jquery for example). Grunt lets me compress, join, minify, and automate the deployment of those components.

    I tell Bower to get the files and what versions they could be. I tell Grunt to combine all my mini-js files into one, combine them, compress them, and put them in another location. That means I tell Bower to bring in jquery, but it puts it in a development folder. Grunt takes that and copies it to the js folder.

    Personally I take it a step further and, when I use Git to push my code, I tell it to delete the development folder off the server. I also do as Chase Adams does, and I don’t version control my dev packages. I may define jquery’s version, but I dont worry about capturing that in my repositories.

    You don’t have to use Grunt. You could use Gulp. I had a sticker for Grunt on my laptop from a friend, so I tried it first and found I liked it.

    Taking all this a step further, there are tools like Yeoman that will let you kickstart a project by saying ‘yo’ and telling it what kind of project you want to make. Yes, there’s a WordPress project called YeoPress.

    The point of all this is that automation is the queen of development. Don’t do manually what you can safely, reliably, and responsibly automate. Like the Queen on the chessboard, strike out in all directions and control the board. Use the tools to repeat the hard work, to keep dependencies up to date, and to automate the annoying work.

  • Mailbag: Static Bars and z-index

    Mailbag: Static Bars and z-index

    Lindsey asks:

    I found this post on your site (https://halfelf.org/2013/genesis-static-nav-bar/) and had a follow up question about it. My nav bar is now static and fixed to the top of my site, but for some reason a couple of things go over the top of it when I scroll, namely two AdSense ads and a related posts plugin’s images at the end of posts on single post pages. I would love any advice you may have on fixing this. I’m sure it must be something simple, but I can’t figure it out. Thanks!

    It’s the z-index. If you’ve used Photoshop, you know about layers. Well, z-index is similar for webpages. It defines the ‘stack’ order, or what’s ‘on top’ of everything else.

    Logically you want a video ‘on top’ of the CSS etc of the page, so most of the time this isn’t a problem. At the same time when we’re using CSS to position a menu, it gets … weird.

    The basic idea of z-index is that any element with greater stack order is always on top of an element with a lower stack order.

    Here’s the CSS I used for my floating menu:

    .nav-primary {
        position:fixed;
        z-index:99;
        top: 0;
        width: 100%
    }
    

    The z-index on the WP toolbar (that black bar on the top of your site) is z-index: 99999; so you can change your CSS from 99 to 99998 and that should take care of it. We do want that toolbar to always win, after all.

  • URL Validation

    URL Validation

    I was writing a script for a rather complex series of checks on a website. I wanted to do what I thought would be simple. I wanted to grab the website headers and parse them to check if a site was WordPress or not.

    That was a weird and wild trip.

    In theory, this is all the code you need:

    filter_var($url, FILTER_VALIDATE_URL)

    But as it turns out, that’s actually not the best thing! I started using it but found that I could break it pretty easily and, since I was writing a tool I knew would be used by end-users (who are exceptionally creative when it comes to breaking things), I googled around and found this blog post on Why URL validation with filter_var might not be a good idea.

    Yikes! All I was mad about was that FILTER_VALIDATE_URL thinks http://foo is okay, even when you tell it you want the damn host.

    In the end I used this Strict URL Validator code but even then I had to wrap it around this:

    	// Sanitize the URL
    	$gettheurl  = (string) rtrim( filter_var($_POST['url'], FILTER_SANITIZE_URL), '/' );
    	$gettheurl  = (string) $_POST['url'];
    
    	if (preg_match("~^https://~i", $gettheurl)) {
    		$gettheurl = "https://" . $gettheurl;
    	} elseif (!preg_match("~^(?:f|ht)tp?://~i", $gettheurl)) {
    	    $gettheurl = "http://" . $gettheurl;
    	}
    
    	// Is it a real URL? Call StrictURLValidator
    	require_once 'StrictUrlValidator.php';
    
    	if ( StrictUrlValidator::validate( $gettheurl, true, true ) === false ) { 
    
    		// Do the needful
    	}
    

    In many ways, this makes some sense. What is and isn’t a URL can be tetchy to check. http://foo is real. I can use it locally. That’s why http://localhost can exist. And we can’t just say “if not .com/org/net” anymore (if we ever really could). But boy is my code clunky.