Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: wordpress

  • WordPress Site Description

    WordPress Site Description

    Someone asked me how I got the asterisks in my site description to be a link. It was actually really frustrating for about an hour. And then I remembered my filters.

    This site is using Hybrid Core, so there are some extra hooks:

    
    add_filter('option_blogdescription', 'halfelf_site_description');
    
    function halfelf_site_description($desc) {
            $desc .= '<a href="https://halfelf.org/#bitch" title="Brave, Intelligent, Tenacious, Creative and Honest">*</a>';
            return $desc;
    }
    

    If you’re doing it on a non-Hybrid theme, you have to filter bloginfo

    add_filter( 'bloginfo', 'halfelf_bloginfo', 10, 2 );
    function halfelf_bloginfo( $text, $show ) {
        if( 'description' == $show ) {
            $text .= '<a href="https://halfelf.org/#bitch" title="Brave, Intelligent, Tenacious, Creative and Honest">*</a>';
        }
        return $text;
    }
    

    Pretty simple.

  • Mailman Newsletter Widget

    Mailman Newsletter Widget

    I read How to Add a Newsletter Signup Box After Your Posts by Brian Gardner and thought to myself “Self,” I said, “I really would love to be able to add a signup widget for my mailman newsletter.”

    And so I did. The following code is plain HTML. Just drop it into a text widget wherever you want it to show up, and magically it will. If you’re using a Genesis theme, this is your replacement for Step 3.

    <div id="newsletter">
        <div class="white-border">
            <div class="newsletter-wrap">
                <h4>Newsletter</h4>
                <p>Get my awesome newsletter!</p>
                <form action="http://example.com/mailman/subscribe/newsletter_example.com" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank">
                <input type="email" value="" name="email" class="email" id="mce-EMAIL" placeholder="Email Address" required>
    			<input name="pw" type="password" class="password" id="mce-PASSWORD" placeholder="Enter Password" required>
    			<input name="pw-conf" type="password" class="password" id="mce-PASSWORD" placeholder="Confirm Password" required>
    			<input type="hidden" name="digest" value="No">
                <input type="submit" value="Sign Up" name="subscribe" id="mc-embedded-subscribe" class="button">
                </form>
            </div>
        </div>
    </div>
    

    One important thing to note here, I wanted everyone to get the emails as they happened, no digest, so I set this: . If you want to make it an option, the down and dirty way is to use this:

    Digest: <select name=digest>
    <option value=1>Yes</option>
    <option value=0>No</option>
    </select>
    

    The rest is pretty much Brian’s CSS, tweaked a little since my size requirements were different. Don’t change the ‘name’ values, as it makes Mailman cry. And how does it look?

    Looks nice, don’t it?

  • Jetpack Menu Stats

    Jetpack Menu Stats

    If you run a Multisite, you have a list of all your sites in the ‘My Sites’ menu. Adding your own custom menus to that isn’t all that complicated. Here’s a quick, practical, bit of code:

    <?php
    /*
    Plugin Name: Jetpack Menu Stats
    Plugin URI: https://halfelf.org/hacks/jetpack-menu-stats/
    Description: Show 'stats' in the per-site menu bar.
    Version: 2
    Author: Mika 'Ipstenu' Epstein
    Author URI: https://ipstenu.org/
    */
    
    function jetpack_stats_my_sites( $wp_admin_bar ) {
            global $wpdb;
    
            foreach ( (array) $wp_admin_bar->user->blogs as $blog ) {
    
                    $menu_id  = 'blog-' . $blog->userblog_id;
                    $args = array(
                       'parent' => $menu_id,
                       'id'     => $menu_id . '-stats',
                       'title'  => __( 'Site Stats', 'jetpack' ),
                       'href'   => get_admin_url( $blog->userblog_id ).'admin.php?page=stats',
                    );
                    $wp_admin_bar->add_node($args);
            }
    }
    
    add_action( 'admin_bar_menu', 'jetpack_stats_my_sites', 90 );
    
    ?>
    

    You can tweak this to anything you want, obvious. If you change the numerical value in the add_action() call, you can move it up or down the menu. A value of 10 will put it at the top. You could probably toss in a check if the plugin was activated per-site as well (I didn’t bother for Jetpack, since I know how to tell if Jetpack’s active via is_plugin_active(), but not a sub-plugin).

    As with all my code, is licensed GPL2. Use, abuse, tweak and customize. Don’t expect support, though.

    Edited to fix i8n and use add_node, thanks to Thomas and kessiemeijer!

  • WordPress Multisite 101

    WordPress Multisite 101

    So there’s this thing. I blog a lot, but sometimes the ‘lessons’ I want to teach would take up a few thousand words. I’ve sorted out that any blog post over 1200 words is ‘too long’ and I try to split it up. But then how do I organize it? Let’s face it, books are useful for a reason.

    After compiling and colating all the emails, IMs, forum posts, and blog posts Andrea and I have made over the last couple years, we realized we had a novel. The problem was organizing it so the scope wasn’t maddening and daunting for us to write, nor for the user to read. Finally inspiration struck. If you’re using Multisite, you really need to know WordPress first. You have to walk before you can run, as they say, and with Multisite, you have to already know how to do the basics.

    This book will not teach you how to pick a host, copy files up, create a database, or any of those things. It won’t even tell you if you should or should not use Multisite. What it will do is help you go from WordPress to WordPress Multisite, configure the options, understand what they mean, sort out the standard problems, and help you figure out what you need to know and where you need to be in your own head in order to do this thing.

    And it’s free. Well, no. It’s not. It’s pay what you want.

    That’s the other thing. I could go the traditional route with a book, find someone to publish it, etc etc. Or I could self-publish on the iBook store or eJunkie and take a hit for the overhead and the hassles of all that. Or… Or I could address the real problem about making ‘money’ with books. Obscurity. I have a whole philosophy about paying for ebooks and you can read it if you want. But the tl;dr for you is this.

    Pay me whatever you think the ebook is worth. If you aren’t going to pay, you weren’t anyway, and that’s nothing lost from my end. I’d appreciate a fiver if you find it useful. I totally support you downloading it first, reading it, then paying later. After all, how do you know it’s what you wanted without reading it?

    Grab a copy of WordPress Multisite 101, it’s in ePub and PDF. You know the drill. Right click and save as.

  • mu-plugins: What is it good for?

    mu-plugins: What is it good for?

    If you’ve been using WordPress seriously for a while, or Multisite for more than twenty minutes, you know about this weird thing called MU Plugins. That used to mean ‘Multi User’, as in WordPressMU, the predecessor to WordPress Multisite. The short version is that any plugin you put in there is ‘Automatically On’ for your site. On a Multisite Network, this means it’s on for all sites. On a single site, it means it’s on and you can’t turn it off.(Must use plugins and 3.0 – WPMU Tutorials)

    So why use it?

    In a theme, often people will add code snippets to a functions.php file to customize things, and that works great. It gets called via the theme and you’re happy. But what happens when you change a theme? Or if you want to apply the changes to multiple themes? Then you use mu-plugins! I use it for all my ‘non-interface’ code, that is stuff I want to set and forget.

    Here’s an example of a block of code I have:

    // Header Additions
    add_action('wp_head', 'fansite_head');
    
    function fansite_head() {
    
            echo '<link type="text/plain" rel="author" href="http://fansite.tld/humans.txt" />';
            echo '<script type="text/javascript" src="http://apis.google.com/js/plusone.js"></script>';
            echo "<script type='text/javascript'>function plusone_vote( obj ) {_gaq.push(['_trackEvent','plusone',obj.state]);}</script>";
            echo '<meta property="og:type" content="fansite"/>';
            echo '<link href="https://plus.google.com/xxxxx/" rel="publisher" />';
    }
    

    This adds in my humans.txt (yes, I have one), the Google +1 tracking, and a link for the publisher so G+ knows the site is really itself. Now this code is on every site in my network, without lifting a finger.

    Now there are some things that are very theme specific. Like I have a bit of code that adds similar data like my head example, but right below the HTML tag. Since that’s using a theme-specific call, I leave it in my theme functions.php instead. I even use this on my non-Multisite installs, since it just makes it easier to separate my perma-code from my theme code. In addition, when I’m making a site for someone else, and I’m not doing their theme (it happens), I can tuck things they want all the time, on every theme, in there, and they can’t ‘accidentally’ turn them off.

    I’ve gotten in the habit of naming the files things like sitename-cpts.php (which has all my Custom Post-Type data for one single-site) and sitename-functions.php (which has everything else) and even sitename-style.php (which turns on the visual editor styling to match my site, and changes the html editor font, as well as a small fix for a fixed position header that looks nasty with the admin bar when logged in).

    What do you love using mu-plugins for?

  • Risk vs Transparency

    Risk vs Transparency

    There's a 'fucking close to water' joke here. This was written without any special insider knowledge. I’ve simply watched, paid attention, and kept track for the last two years. Often when I report a plugin, Mark and Otto are nice enough to explain things to me, and I’ve listened.

    Occasionally a plugin vanishes from the WordPress repository. As a forum mod I tend to see people freak about this more often than not, and the question that inevitably comes up is ‘Why doesn’t WordPress publicize these things?’

    Let’s go down the list for why a plugin is removed first. This list is very short, and boils down to three:

    1. It breaks the rules
    2. It has a security exploit
    3. The author asks for it to be removed

    That’s pretty much it. The rules cover a lot, though Otto and I have been known to sum it up with ‘Don’t be a spamming dick.’ I actually had the chance to talk to folks about this before the ‘expanded guidelines’ went live, and I think I have a pretty good understanding of what the rules are. The majority of plugins, that I see removed, are done so for the most obvious reasons:

    • Phoning home (i.e. sending the author data about you without your permission)
    • Forward facing links (i.e. opt OUT links on the front of your site when you use the plugin)
    • Affiliate links (i.e. the author gets revenue from the plugin without disclosure)
    • Obfuscated code

    None of those are security reasons, and most of them are ‘fixed’ by us reporting the plugin, the plugin repo mods contacting the author, the author making the fix, and all is well. When the author doesn’t reply, or in the case of a ‘phone home’, often the plugin is yanked from the repo pending review. So where are these ‘security reasons’ to yank a plugin, and why should WordPress disclose them. Phoning home is, sometimes, a security reason, depending on what’s actually being transmitted.Usually it’s a vulnerability or an outright backdoor that would be a reason to pull a plugin.

    I see what you're thinkingThere’s an argument that ‘Trust requires transparency’ when it comes to security (see Verisign’s recent rigmarole) and that would mean WordPress needs to publish things like ‘This month, these plugins were removed for this reason.’ Except WordPress doesn’t, and in fact, if you look, rarely do companies do this until they have a fix. The ‘problem’ with WordPress is they don’t do the fix, the plugin devs do, and a surprisingly high amount of times, the plugin author fucks off like a monkey.

    On the other side of this argument is FUD(Fear, Uncertainty and Doubt) which is something you never want to feed. Look at the plugin “ToolsPack,” helpfully shown up on Sucuri. Now that was never hosted on WordPress.org, but if it had been, it would have been removed for exploitation. But once the offending plugin is removed, should WP go ahead

    In October of 2010, WordPress.org ‘introduced’ a kill switch for plugins. Not really, but kind of. BlogPress SEO was spam. Yoast, one of the few true ‘SEO experts’ I know of, caught it and decided to fix it the best way he knew how. See, this plugin was never on the WordPress repository and so WP could do little about it. Yoast registered a plugin with the same name, gave it a newer version of the plugin, and everyone saw that as an ‘update’ and thus were saved. Sort of. Now, even Yoast admits this is abuse of the system, and I’ll leave the coulda/woulda/shoulda to someone else.

    The reason I bring it up is this shows there is a way to handle bad plugins. But it’s not very efficient, it’s not very friendly, and it doesn’t promise that it will work. First off, not enough people run updates, and secondly it’s putting a lot of work on a very small group of people. While the theme reviewers have a lot of folks helping out, the plugins do not. Should they? Yes, but the number of people who understand all the code that could be in a plugin is far smaller than for a theme. I suppose it’s saying ‘plugins are harder than themes.’ I may be wrong, but it’s how I feel.

    Traffic Jam!To fix all this, you’d need to basically reboot the plugins directory, turn them all off, review each of the 18,000+ plugins, and turn them back on. Then you need an Otto or Nacin going through each one to make sure every check in is okay, every update and every change isn’t spamming. Oh yes, that’s what happens to theme devs, didn’t you know? All releases are approved before they go live. Can you see the plugin developers agreeing to that? That’s a nonsense complaint of mine, actually. If tomorrow the rules changed, maybe half the plugins in the repo would vanish and never come back, but most of the rest would be fine. Of course, we would need a dedicated team of people to do nothing but review and approve plugins to keep up with the traffic.

    So accepting what we have today, the wild west, why isn’t there a running list of all plugins yanked from the repo, and why? The list itself isn’t a bad idea. Having a list to say ‘This plugin was disabled on this date’ would be nice for a lot of us, and more so, having the plugin page show ‘This was disabled.’ would be nice. I can even think of a couple code ways to do it, but all of them need a full time person to go through the ‘removals’ and put up a splash page with ‘If you used this plugin, please consider alternatives: .’ and ‘If you wrote this plugin, please contact plugin support.’ Also, this would increase emails to the plugins support account, not from the authors, but from people who want to know why a plugin was removed. And what about a day when a plugin is removed because of a bad thing, but the authors fix it? Did we create a false feeling of doubt in a plugin that had a typo?

    On paper, it all sounds like we should be keeping a public list for this still, though. Put it all up there for the public, disclose everything.

    Every time I write that sentence, I wince.

    It sounds nice on paper, and all I can think is about the people who will cry foul, complain, and want to know more. “Why was this plugin removed and not that one?” Well, most of the time it’s because no one mentioned that plugin. Right now, the plugins that get yanked are ones people stumble across or report.

    But why worry about a simple list of removed plugins? Because the first thing I would do, if I was a nefarious hacker, would be to script a pull from that list and scan the web looking for sites that use the plugins, thus implementing a vector for attack. See, we already know people don’t update plugins as often as they should (which is why Yoast’s ‘fix’ isn’t as good an idea as we’d hope), but now not only are we leaving people at risk, we’re opening them to even more risk. If we email them to tell them the plugin’s risky, we have the same problem.

    There’s no safe way to inform people without putting anyone who’s not up to date at risk. Given that the most dangerous day to have an unpatched system is the day of disclosure, the only way WordPress, or anyone, could keep a list like that would be if, like Chrome, WP auto-pushed updates right away, forcing anyone who opened the site to upgrade. And that’s fraught with it’s own issues.

    Until then, I can’t advocate anyone keeping a list of removed plugins. It’s too risky.