Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: plugins

  • I Make Plugins CPT

    I Make Plugins CPT

    Mark Jaquith makes plugins. He also makes a plugin about making plugins, called I Make Plugins, which auto-formats your ‘local’ plugin pages, so you don’t have to write anything, and just pull in the WordPress repository readme for your plugin. It’s almost like the Victor/Victoria of plugins. Anyway, my issue was I don’t use pages for my plugin listing, I use CPTs. And in order to use Mark’s plugin, I had to hack it.

    How-to-install-Wordpress-Plugins

    So I did the smart thing, and emailed him with an “I love your plugin! Here’s what I had to change to make it work with a CPT, though.” A couple days later, Mark replied with “Use these filters instead. Untested!” He also bailed me out when I screwed it up, so he gets an Internet today.

    Even though I’ve never actually messed with filters in this way (actions yes, filters I’m still learning), I sat down with my coffee and started reading. Yes, I actually read things before I jump in, contrary to what my friends think.

    This turned out to be pretty simple, when you got around to it. Since Mark called apply_filters(NAME,PARAMS), all I had to do was add_filter(NAME,MYFUNCTION) and then make a function, passing the PARAMS and parsing as I needed. Mark fixed my original code (which was hellishly not optimized) and fixed my weird preview issue by returning an option I forgot.

    Post Type
    First I had to set the post type. In this case, Mark defaults to pages, I default to plugins. Yes, I named a post type ‘plugins.’ It works.

    add_filter( 'i-make-plugins__post_type', 'halfelf_imp_posttype' );
    function halfelf_imp_posttype() {
    	return 'plugins';
    }
    

    This takes in the arguments as $args, resets it to plugins, and returns the new value.

    Get Plugins
    Mark also has a ‘post parent’ so where I just use the CPT’s archive page for https://halfelf.org/plugins, he has an actual page with sub-pages. I don’t need post parent, so per Mark’s suggestion, I need to remove it from ‘get plugins.’

    add_filter( 'i-make-plugins__get_plugins', 'halfelf_imp_getplugins' );
    function halfelf_imp_getplugins( $options ) {
    	unset( $options['post_parent'] );
    	return $options;
    }
    
    

    Since the parameters I’m pulling in are an array, I have to use unset instead of making it a null value.

    Is Plugin
    The last check is to verify this is a plugin, and we can return the content. The normal string for this checks if the parent of the page is the ‘page parent’ (set earlier normally, unset by me). I just swapped it for a ‘is this a plugin?’ There are two parameters in this one, and the second is the post ID, which I need to check post type.

    add_filter ('i-make-plugins__is_plugin', 'halfelf_imp_isplugin', 10, 2);
    function halfelf_imp_isplugin( $is_plugin, $post ) {
    	$post = get_post( $post );
    	return $post->post_type === 'plugins';
    }
    

    Originally I had a call to is_preview() because, for some reason, it was overwriting all my post previews. While that only annoys me, it really annoys me! Thankfully once Mark fixed my ‘Get Plugins’ call, it all started working.

  • 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!

  • 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.

  • Yourls

    Yourls

    For a long time I’ve wanted short URLs for one of my sites. Finally I figured out a short URL, picked up the domain, and said “It would be great if I could redirect posts with this! But how?”

    As it turned out, I was making a mental mountain out of a miniature molehill. I do that sometimes, get all caught up in a non-meaningful detail. This was easy, it wasn’t super complicated, and it was fast. On the scale of things where WordPress is the easiest (1) and MediaWiki is the hardest (8), this landed next to Zenphoto (4) and was about the same (3 or 4, depending on your skills). It requires more RTFM than WordPress, and I had to do some things manually.

    Setting Up Your Domain

    First buy the domain. This part is obvious, I hope. Since I’m on cPanel, I added my new domain as an addon domain to the master. This let me have the short domain (do4.us let’s say) hosted off the main domain.com site, without making a separate account. If I’d wanted to map a domain, I would have parked instead of addon-ing.

    To add an addon domain in cPanel:

    1. Enter the domain for the new addon domain into the New Domain Name field.
    2. Enter the main FTP username for the addon domain in the Subdomain/Ftp Username field. You can use the one you use for the mani account if you want.
    3. In the Document Root field, enter the directory that will contain the addon domain’s files.
    4. Enter the password for the addon domain into the Password field.
      • Make sure you use a secure password.
      • You can have cPanel generate a secure pasword for you using the Generate Password feature.
    5. Confirm the password in the Password (Again) field.
    6. Click Add Domain
    7. To add files to the addon domain’s home directory, click the File Manager link, or use FTP/SSH like normal people.

    Once I did that, and DNS propagated, I was ready to go.

    Installing the App

    I decided to use Yourls for this, since my friends use it, and I know (in that internet way) the guys behind it. Hi, Ozh.

    That said, their install doc was screwed up. For 1.5, it says to edit a file that apparently isn’t included in the build. That’s okay, since I just used SVN anyway. The directions are very much geeky. This is not a simple WordPress install.

    What I did was first make a database domain_yourls and added my DB user account to it (I never use my domain FTP account). Then I ran an SVN checkout from googlecode to grab the files into the root of my add-on domain: svn checkout http://yourls.googlecode.com/svn/trunk/ .

    After that, it’s the manual editing of the config file (the sample of which is not included in the 1.5 zip) and then I went to myurls.com/admin/ to finish setup. I had to grab the .htaccess file sample, since mine didn’t copy down (my own fault there).

    Configuring the App

    Install the YOURLS: WordPress to Twitter plugin. Even if you don’t plan on using the auto-tweet function, this is the easiest way to get your URLs made. The “hard part” here is setting up a Twitter ‘app’ for the first time. If you’ve done it before, it’s not terribly hard, but with all new things, it’s scary. Ozh’s directions are painless, thankfully, and then … you’re done. And you have your own Short URLS!

    What’s Missing?

    Two things, and neither are YOURLS fault!

    1) Twitter doesn’t know that three different URLs (domain.com/postname, domain.com/?p=2 and do4.us/2 for example) are all the same URL. That means if you use those Twitter Rewteet buttons on posts, it doesn’t show up the same way, and the ‘count’ is off.

    2) There isn’t an easy way to tell Jetpack to use my short URLs instead of my site’s full one. Edited to add: By this I mean only in the ShareDaddy links. Like the ‘tweet/email/facebook’ ones. Actual shortlinks work perfectly.

    I suppose a third is ‘Damn it, Twitter, stop shortening a short URL!’ but that’s a different rant.

    Should you do this?

    I think so, but then again, I’m weird.

    Read Also…

    Otto – Using YOURLS with WordPress

    Rev. Voodoo – How I Set up Vudu.me URL Shortener With Yourls

  • “Without a plugin” considered dangerous | sabreuse

    There’s just one problem with this. Plugins exist for a very good reason: to add non-core functionality 1 to your site without hosing up the whole lot.

    Via “Without a plugin” considered dangerous | sabreuse