Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: plugins

  • Art History of Plugins

    Art History of Plugins

    This post is dedicated to Lisa Sabin Wilson, who donated to help me get to WCSF. Lisa is to documentation what I am to the forums, and encourages me to write better (though she probably didn’t know that).

    A Sunday on La Grande Jatte, Georges Seurat, 1884Quite often people suggest that we ‘weigh’ the usefulness of plugins and themes in the WordPress repository differently. Some want to use star ratings, other popularity, and others compatibility of WordPress Versions.

    Invariably, if I get roped into these discussions, I say ‘None of it maters more than the rest.’ And people always argue that their chosen method is the best. No one has ever succeeded in convincing me they’re right and, I’m pretty sure, no one ever will.

    The reason I’m so sure about that is the same reason we don’t just buy cars based on the tire size, or a house based on a bathroom. It’s the reason we research and compare, study and inspect, and ask our friends. It’s because we know to look at the big picture.

    Let’s look at A Sunday Afternoon on the Island of La Grande Jatte. From afar, it’s simple. A painting of people on the island. But if you walk up to the painting (it lives in Chicago, I love visiting it) you’ll see Seurat painted entirely by dots! As you step in and out, the painting changes and your perspective and understanding of the work as a whole changes. You cannot simply say ‘There is blue paint.’ and make your final decision that this painting will look nice against a blue wall. You have to consider how it will look up close, far away, and will it be better to blend or contrast. Seurat liked the contrast, which is why it has a brown border and a white frame.

    The small moments, those dots, make up the whole of the piece and you have to consider everything that went into it, if you want to understand the painting. Anyone can look at if from afar and say ‘Yeah, nice.’ But when you start looking at the work, and the layers of meaning, you see things differently. With art, that’s the point. Sometimes a painting is just a painting, and sometimes a story is just a story, but more often than not, the ‘deeper meaning’ your teachers were after you to get from a story is simple: Look at the whole story. Look at how each character’s actions become a part of the whole.

    This relates, directly, to understanding plugins. At heart the question people are asking is simple: How do I know which plugin is the best to use for this situation?

    You can’t just take one and say ‘This is compatible with 3.4, therefore it is superior!’ I wish you could, my life would be easier. Instead, you must learn how to review plugins critically. Don’t throw your hands in the air, you don’t need to know code to do this. You do need to know what you want, and you need to read and pay attention, but at this point, if you’re still reading this blog post, you know how to do those.

    The secret magic, which I talk about in WordPress Multisite 110 (Chapter 6: Security, Plugins, pg 36), is to review all components of a plugin’s information. You have to look at how all the little dots make up the whole picture — that’s why we talked about Seurat — and use those to understand how likely a plugin is to be safe to use.

    Who wrote it? If I see a plugin written by someone I’m familiar with, I’m more inclined to trust their work. I already know how to get in touch with the developer if something goes wrong, and we have a rapport. Second to that is if they work on WordPress core. If they have commit access, I trust them (even Otto, who’s broken the site before). If they’re a regular contributor, it’s much the same. However this is not ‘common’ information. It’s easy to find, but it’s not something everyone knows off the top of their head. You can quickly search trac for their user name. I find it easier to limit the search by changesets, so here’s a search for wpmuguru’s credits in changesets. Yeah, looks like a trustworthy fellow!

    What does their website look like? In cases where the developer doesn’t have any core contribs, move on to look at their website. Is it the generic version of WordPress with barely any content? Is it a Geocities flashback? You know crappy websites when you see them, and a crappy website for a developer warns me that they don’t use WordPress the way I do. Little to no content implies they’re not writing posts, and if they aren’t writing posts, how do they keep up with the look and feel dynamic of WordPress?

    Is it well documented? Documentation is king. A plugin that is poorly documented, with poor spelling and grammar (regardless of language), and no screenshots makes me Spock the eyebrow. Not every plugin needs a screenshot, but a plugin should have the basic information included on that page. I’ve started copying my readme content into the contextual help in my plugins, for extra documentation levels. The point is, if the documentation is sparse, either the plugin is really simple, or you’re going to have a bad time of it when you have a problem. Developers, document. It will save you a lot of time.

    How often is it updated? This is where we start to get weird. The simpler a plugin, the less it needs to be updated. Impostercide has barely changed since WP 2.5. I do update it about once a year, to change the versions, or add internationalization/help screens, etc. The bones of the code have not changed since 2005, and the original version still works just fine. Not every plugin should be updated every month. Now a more complicated plugin, I’d actually like to see it updated more often, with smaller changes. Don’t change it all at once, after all. Review the Changelog (if they don’t have one, it’s not well documented). See what’s being changed.

    What problems have people had? Recently the Andy/Otto team made it easier to see the forum posts associated with a plugin, which means it’s easier for you to see how active a developer is with support, and how problematic the plugin is. Many of these issues are user-based (i.e. they’re not sure how to use a plugin), but sometimes they’re actually bugs. Check how many problems have people had, and if they are resolved. This example is a great sign:

    Support Example

    Compatibility MatrixWhat’s in the Compatibility Matrix? This is a very complicated thing, but it’s also very telling. Knowing how many people have reported a plugin works or doesn’t work, and getting an average, can help you. Sometimes you have to go back and forth, checking various plugin versions to WordPress releases, to get the whole picture, though, so it can time time to understand what’s going on.

    Requires, Compatible Up To, Last Updated, Downloads, RatingWhat Else? Only now do I take a look at things like downloads, what the author says it’s compatible to, when it was last updated, and what the stars are. Why? Because unless an author has written ‘This plugin will not work on WordPress 3.4!’ in the readme, there’s a darn good chance it’s just fine and they didn’t bother to update. And that pisses off a lot of people.

    Look. There’s no feasible way to force the developers to update their plugin documentation right now, and even if we did, there’s no way to assure they got it right! People make mistakes, which is why we have to learn to use our brains and think about what we want to do before we act. Yes, it’s work. As I’ve said many times, running a website is work. It’s always going to be, so at least try to work smarter.


    I didn’t touch on code reviews at all, but what tips and tricks do you use when you’re collecting all the dots and evaluating a plugin for use?

  • Plugin Licenses, Upsells, and Add-ons

    Plugin Licenses, Upsells, and Add-ons

    This post is dedicated to WPEngine, who donated to help me get to WCSF. While I don’t use them, I think that if you’ve outgrown WordPress.com and aren’t quite ready to host everything yourself, but you still want the plugins and themes, then you should check these guys out. They aren’t cheap, but then again, I firmly believe in paying for what’s important.

    Read the comments before you comment. Otto haz the smartz.

    Phone HomeOne of the many rules of WordPress.org hosted plugins is you can’t phone home. Actually you can, and the rule really is ‘Don’t phone home without a damn good reason.’ To use Akismet as an example, it phones home with information to help verify who posted on your site, and are they a damn dirty spammer. That’s a damn good reason. But phoning home to check “Did Bob pay for a license?” is not. That’s considered abuse of the “serviceware” guideline, and essentially making an API just to make sure a license is okay isn’t okay. Now making money on your plugins is an awesome thing. But when your code is open source and anyone can see it, how do you keep people honest?

    To get down to brass tacks, I’m going to take a little jounrey the wrong way, before I get to some suggestions on how you can provide ‘free’ and ‘pay’ versions of a plugin on the WordPress repository, and not cause any guideline issues.

    Let’s start out with the most common way people restrict you: A license key. If you put in a plain license key check like this, it’s easy to crack:

    if ( $license == "yes" ) { // Licensed! }

    Okay, you say, I want to encrypt things so that I tell someone ‘your license is ipstenuisreallyneatsheismadeofturtlemeat’ but when I look at my code, it shows ‘774ffc4efce8da294dff77f35f75df98‘ instead (that’s md5(ipstenuisreallyneatsheismadeofturtlemeat) as it happens). Wait. We can’t encrpyt code. Or rather, we can’t include encrypted code in a plugin, it’s against the no-obfuscation rule. We’d want to decrypt that instead. So I give you the code string instead and run it this way instead (Just pretend that $options['license'] is a site option.):

    if ( md5(ipstenuisreallyneatsheismadeofturtlemeat) == $options['license'] ) { // Licensed! }
    

    But then I have the problem of anyone can just look and see what’s going on again. You could go the extra step like putting ipstenuisreallyneatsheismadeofturtlemeat in a file and then pull off something like this:

    $md5file = file_get_contents("md5file.txt");
    if (md5_file("test.txt") == $options['license'] )
    

    No LicenseIs this easily decrypted? Yes. Is this easily circumvented by editing the code and removing the if? Again, yes. In fact the only way to really do this would be to use an API on your server to check the validity of the license (which you can’t do if you want to be hosted on WordPress.org anyway – no APIs just to check licenses), and even then I can strip mine your plugin and remove all checks like that. So why bother? Because you want to make a living on your code, and that’s certainly a fair-go! But as Otto rightly says, we can’t stop piracy, so why are we trying? DRM doesn’t work, and reverse engineering hasn’t proven sustainable. Maybe we’re building the wrong mousetrap.

    If we throw the code solutions out the window, because we know they won’t work, where are we left? The next most common thing I see is people offering two plugins. A free, totally open GPL one on the WordPress repository and then a version behind a pay-wall that you would ‘replace’ that free one with. For example, I have a Rickroll plugin, and let’s say I wanted to make a Rickroll Pro version that let you change the video to anything you want, just put in the YouTube URL. I would have a settings page on my free version that pretty much says “Hi, if you want to change the video, visit halfelf.org/plugins/rickroll-pro/ to download.” And now I have to code Rickroll Pro to check if Rickroll (free) is installed and active, and refuse to activate if so. Furthermore, my users have to be told to delete the free Rickroll.

    You know what? That’s a pain in the butt. What if instead I coded a Rickroll Pro add-on. No, I don’t mean ‘add this file to your plugin’ but ‘Install this second plugin, which will add functionality to Rickroll.’

    It’s a second plugin, yes, but now I can have Rickroll free look for Rickroll pro. Not active? The settings page (which I would keep in Rickroll free) would tell you ‘Hey, you don’t have Rickroll pro! Install it and get more things!’ or ‘Hi, you have Rickroll pro installed by not active. Don’t you know it’ll never give you up? Activate it and have fun!’

    Now the code muscle becomes a question of ‘How do I ensure my dependency checks work?’ First, Scribu wrote an awesome plugin dependency plugin, and the only flaw with it, is you’d have to install a third plugin. We don’t want that here, since yet another plugin is problematic. But looking back, that code grew out of a trac ticket about handling plugin dependencies. Now there’s a nice way to check: is_plugin_active()

    if (!is_plugin_active('rickroll/rickroll.php')) {
        // do not activate. Provide message why.
    }
    

    ProtectedYou could go to town with the checks in there. Like if the plugin isn’t active, deactivate the child and so on and so forth. I’m not going to write it all for you (though Otto wrote a lot about it for themes)

    Now going back in your parent plugin, you can run the same check:

    if (!is_plugin_active('rickroll-pro/rickroll.php')) {
        // Rickroll pro isn't active, prompt the user to buy it.
    } else {
       // Include rickroll-pro/adminsettings.php so they can use it
    }
    

    The one last thought I had on this was how to handle pro upgrades. Since I don’t like to upgrade a plugin a lot unless I have to, I’d make it an ‘upgrade both’. In Rickroll Pro I’d set a version constant, and then in that check to see if it’s active call, reference that version. So Rickroll, after verifying Rickroll Pro is active, would come back and say ‘My current supported version of Rickroll Pro is 1.5 and the constant is set to 1.0. You should upgrade!’ Then every time I write a new version of Rickroll Pro, I’d update Rickroll to point to the new version, and when they upgrade from WP, they would get notified about Rickroll Pro needing an update too.

    Probably not the most efficient or effective way about it, but the other option is a self hosted plugin update API.

    Bear in mind, because of GPL, all these hoops and ladders can be circumvented. Your plugin can and will be taken away for free. Don’t fight the pirates with registration circuses, and limit the weight of your code by selling the right thing. It’s a strange idea to think that giving your code away for free will help you earn money, but at the very least, not fighting against the pirates will give you time to write better, more secure, code. And that certainly will earn you more money. Then sell your support, because that time is money.

  • Highway To Plugin Danger Zone

    Highway To Plugin Danger Zone

    Danger ZoneThis post is dedicated to Mark Jaquith, who donated to help me get to WCSF. Thank you, Mark!

    There’s nothing wrong with using someone else’s code. All of us do it. That’s how we make something new: by building off the old. And we all build code that relies on someone else, even when we write operating systems. Everything is interdependent, and that’s okay. The problem with relying on someone else’s code, is that you’re open to their vulnerabilities.

    Recently there was a kerfluffle about TimThumb, where the community came together and made a script, used by many themes and plugins, better and safer. This was an awesome moment, where we saw disparate strangers overcome FUD and live up to the dreams of Open Source.

    In more recent days, there have been a lot of problems with the Uploadify script, to the point that Sucuri wonders if it’s the new TimThumb when it comes to overuse and vulnerability. Unlike TimThumb, Uploadify isn’t actually insecure due to a bug, but the design of how it works is insecure. Yes, it’s insecure by design. Uploadify allows easy multi-file uploads to your site, but it does it without integration with any user verification, so basically anyone who knows where the file is can upload anything they want to your site.

    Uploadify offers some security suggestions, which encourages you to use the right folder permissions, keep the file outside of your public_html, and use SSL. The problem there is you’re still not checking to make sure that the code is only accessed by the right people. This isn’t a flaw in Uploadify. It’s a flexible product that can be used with anything, so they don’t want to lock it down to just WordPress, Drupal, Joomla, or whatever. This is, alas, the reason it’s so dangerous. Anyone can hook into it, if you don’t make it secure enough.

    Now. A handful of WordPress plugins have been closed due to uploadify exploit potential (between 10 and 20). Not a lot, when you think about it. That’s because, perhaps surprisingly, not as many people are using it as you’d think. In part, this is from WordPress’s shift to plupload in WordPress 3.3, which allows you to hook into it in themes and plugins. By the way, I recommend you use plupload, because if you’re going to rely on third party code, it should be the one that comes with WordPress core.

    Beware! Insecurity AheadThe point is not to not use third party code, however, but to use it wisely and to use it safely. It’s your responsibility as a developer to make sure your plugin is secure, and to know what it does. If you don’t understand how someone else’s code works, don’t use it in your plugin, because by using it, you are now responsible for updating it, securing it and keeping it safe. How can you do it if you don’t get it? Furthermore its your responsibility to educate your users as to what a plugin does and how you’ve secured it. This is open source code, the bad guys can already peek in and see what’s up. If they know, then you owe it to the users to arm them with education.

    The weakest link in the security chain is the education of the end users. The servers, we hope, know what the heck they’re doing. Ditto the software writers. But the users, they’re often the new guy, the one who doesn’t know what’s what yet, and they trust you. They trust you do your best. Note, I am not saying they trust you to be perfect. Anyone who expects perfection is ridiculous. We all desire it, of course, but you cannot expect it unless you yourself can deliver it. Can you? I thought not.

    Alright then so what can you do to protect uploadify and similar scripts? First, lock it so it’s only accessible from the WordPress dashboard panels. If you can only get to it via WP, then you’ve locked yourself so no non-logged in users can access the tool. Then if you slap this code into the top of your file, no one can access it directly:

    if ( ! defined( 'ABSPATH' ) ){ die( 'Direct access not permitted.' ); }
    

    Next we should look into how we check for the user. Can any member of your site upload? Probably not. So let’s use capabilities and roles to lock it all down and make sure only the right users have access. We can use two simple lines to verify the user is logged in, and has the right capabilities to upload. The ‘manage_options’ cap is for Administrators, so loosen it up as you need:

    if ( ! current_user_can('manage_options') )
    die( 'Not allowed to upload.' );
    

    You can hook an upload handler up as an AJAX handler via WP’s admin-ajax.php, per AJAX in plugins. If you need a non-AJAX handler, you can handle form submissions on your plugin admin pages. Going through WP gets you authentication and capabilities checking, and easy usage of nonces (see wp_create_nonce() and related links at the bottom of that page for more info).

    There are of course more ways to secure things. There are nonces and AJAX, as well as using WordPress’s image tools to help double check if a file really is an image. After all, not everyone can use .htaccess, and some servers are silly enough to let you run a php file with a jpg extension.

    But all that really only works if you want to restrict your uploads to members of your site. What if you want to let anyone upload an image? Honestly, you should re-think that. You are not imagur or imageshack. They have layers of server protections which you don’t, and they have levels of checks and balances in software written specifically for image uploads and protections. You don’t. They are a tool specifically for the job of images. WordPress is not. Do you see where I’m going? Do you really need to allow images be uploaded to your site? I bet you don’t.

    One Insecure Link in the ChainShortly after TimThumb was exploited, it was yanked from the theme repository. Since WordPress 3.3 no theme can contain TimThumb. From what I can gather, part of the reason is that code like that should be a plugin, not a theme. But personally, I think that both TimThumb and Uploadify should have official plugins (supported by the original/current developers), and anyone who wants to use that code can hook into those plugins. Then, if there’s an exploit, it’s one plugin to fix and not a couple hundred.

    Of course there are as many flaws with that as with any other approach. If the original devs don’t want to support a plugin for WordPress or any other platform, the users would be SOL.

  • ZenPhoto and ColorBox

    ZenPhoto and ColorBox

    A color boxI use ZenPhoto for a gallery on a site that has a pretty hefty (gigs) gallery with many albums and subalbums. It’s too big for WordPress, in my experience, and so I picked up ZenPhoto as sort of the WP of the gallery world. Not knocking WP, it’s great for text, but sorting and organizing images are a hassle. The flip side to this is that getting straight directions on how to do anything in ZenPhoto makes me bang my head on the wall.

    See, WordPress has a lot of people involved, so the forums are filled with people who’ve been there before. And these people come from a varied array of talents, so some are designers, some programers, and some users. This means the documentation, while lacking in many respects, is actually a pretty awesome display of crowd-sourcing when you compare it to other web apps. The worst part is there’s no perfect way to replicate this dynamic. ZenPhoto is still relatively young, even though it’s only a year younger than nine year old WordPress! MediaWiki (at 11) is older than both, but ‘behaves’ more like the middle child, if you really want to break your head on things.

    It’s a lot to do with goals, and you can’t knock any one tool for the other. They have their places. I would never try to blog on MediaWiki, nor would I put a seriously hard-core gallery on WordPress. ZenPhoto has branched out into ZenPage, a simple CMS, but personally I’d rather see them optimize the hell out of their back end, which could use some UI love. Still, a lot of its simplicity is why I chose to use it instead of, say, Gallery or Coppermine.

    But the help is still lacking, so today was a bit of a wrangling and head bashing.

    What I want is, you’d think, straightforward: How do I edit the default theme of ZenPhoto to include ColorBox? If you ask this on the ZenPhoto forums, you get an understandably annoyed mod saying ‘This has been asked before.’ I feel for them, but as a mod and a user, I look at that and think ‘If people keep asking and you can’t give them a link to how to do it, something’s not right.’

    The directions I found in the forums never worked, but it wasn’t long before I realized why. There were simple typos. So here’s how you can turn on ColorBox for ZenPhoto.

    ZenPhoto

    1. Activate the Plugin

    This is a duh moment, but go Admin -> Plugins and check ColorBox. You do not need slideshow.

    2. Make sure ColorBox is on for your theme

    Go to Admin -> Options -> Plugins and click on ColorBox. Then find your theme and make sure that the pages you want to run ColorBox on are checked. I only wanted it to run on albums, so that’s all I checked.

    3. Edit your theme

    This is where everyone’s directions fell apart for me. Since I only want it on albums, I went to my default theme copy and set my image section to look like this:

            <div id="images">
            <?php while (next_image()): ?>
    		<div class="image"><div class="imagethumb">
    		<a href="<?php echo html_encode(getDefaultSizedImage());?>" rel="showcase" title="<?php echo getBareImageTitle();?>"><?php printImageThumb(getAnnotatedImageTitle()); ?></a>
    		</div></div>
    		<?php endwhile; ?>
    

    Make special note of your classes and rel here! In specific, notice how that I have two divs for image and then imagethumb? While either one will work, I made a note of imagethumb, since it was a little more specific. Also I made a note of the rel in my image itself, in this case rel=”showcase”

    Then back up before I close my head section, I added this:

    	<script type="text/javascript">
    	// <!-- <!&#91;CDATA&#91;
    	$(document).ready(function(){
    	$(".colorbox").colorbox({inline:true, href:"#imagethumb"});
    	$("a&#91;rel='showcase'&#93;").colorbox({transition:"none", height:700, width:"75%" });});
    	// &#93;&#93;&gt; -->
    	</script>
    

    See how I’m using the showcase and the imagethumb? That’s why I needed those.

    4. Customize

    Everyone says ‘Read the directions!‘ but when you look at them, they’re written for people who know jQuery. I don’t. So when I don’t know what I’m doing, I make a list of what I want. By the way, yes, it irritates me when directions are ‘too techy.’ You can’t know where people are in their understanding of things, and you can’t expect everyone to be amazing at everything. I was very close to appealing to anyone who owed me a favor for help before the end of this.

    No set height

    That’s as easy as removing height:700 from my js.

    Force colorbox to treat my cached image as an image

    Just add photo:true to the js. I had to do this because my server renders the images via a php file (to redirect to cache) and this was causing funny problems. It’s a known issue, though, so one I figured out how to search for ‘ColorBox is making my images show up as gibberish!’ I found the answer.

    Put a link to the full sized image

    And here began my headache. If I put in this (where I used to have the height code):

    title:function () { return "To view full size, " + "click here!".link(this.href);}

    … then my link goes to the getDefaultSizedImage() size (which is a max width of 540px for my theme) and that isn’t what I want. I could change it to getFullImageURL(), but then colorbox loads the fullsized image, and that’s just a little silly and bad for bandwidth. I spent the next hour reading up on jQuery to understand that I really wanted to pass data through. Finally I struck about the notion that I could make a new variable in my href.

    full=<?php echo html_encode(getFullImageURL()); ?>

    This makes a link to the full-sized image. And then I changed this.href to $(this).attr('full')

    In the end, it really wasn’t hard, but nowhere were all the pieces laid out in a way I understood. I’m happy with how it all turned out and the site now behaves like it’s 2012.

  • You Can’t Be Everything

    You Can’t Be Everything

    There’s no app out there that does everything.

    A lot of you just said ‘I know.’ but did you ever stop to think about why that’s the case? After all, some applications do everything you need them to do, and some you don’t, so who gets to decide what is and isn’t needed? When I talked about how WordPress was just fine on it’s own, without any plugins, people stepped up and said “But Ipstenu, I really need XYZ.” Heck, Lorelle said she needed Akismet.

    Learning how to separate your personal needs from the needs of the masses, when writing software, is a full-time job, and many of us come at it from a slant-wise point of view. In fact, writing core code for WordPress is in diametric opposition to why we write plugins! While I’m going to talk about it from a WordPress point of view, the concept holds true to any application that has ‘add ons.’

    Plugins are written, by in large, to solve a specific problem. They’re not ‘fixing’ WordPress, they’re expanding. Remember, your iPhone wasn’t broken until it had Angry Birds, nor was your iPad incomplete without Twitter. Those are things you wanted, and solved a problem for you. The base tools, in and of themselves, address a broader group of people, with a diverse set of needs, and have the option of being everything or nothing.

    The best tool, WordPress, your computer, etc, are built to be extendable. They’re built with the innate knowledge that the users may want things they can’t forsee. Five years ago, how many of you thought Google+ or Twitter would be a ‘thing’?  Let’s take that further. You know how when a new video game comes out, sometimes you can’t play it on your older computer? That’s because it wasn’t built with the new game in mind, so it’s just not capable. And that’s why computers generally let you upgrade memory, CPU, and hard drives. They are built to be extendable becuase they know they can’t know the future.

    Bringing it back to WordPress, it was built to meet a need. People wanted to blog, they wanted it to be easy and they wanted it to just bloody work! So the Matts said ‘This is what we want’ and built it. Thankfully, they understood that people wanted to extend WordPress. But not at first. Oh you didn’t know? Back in December 2003, a ‘new feature’ was introduced called my-hacks.php, which let you put a file by that name in the root of WP, and it would treat it like a functions file. In fact, that’s why I call my non-plugin code ‘hacks.’ Heck, we didn’t get pretty permalinks until January 2004 (then called ‘cruft free’ URLs).

    The point of this is not to expose the funny looking beginnings, but to demonstrate the nature of the software. As it grew, people had needs, and instead of writing everything into core, they cleverly changed WordPress so it was extendable and let people grow as they needed. So when we talk about things like needs and wants, we do it in the understanding that we write our software to fill a need, and we make add-ons to fill wants. Sounds like double speak, I know, but that’s why I said plugins and core development are in direct opposition.

    When I want to add things to core, I want them to be useful to everyone, so I’m forced to remove my ego from the equation. Looking at the (few) core submissions I’ve made, I carefully thought them out beforehand. I looked at places were the user experience was inconsistent or diminished. When I make suggestions or offer commentary to what I think could be better, I try to show my passion without acting like a teenager’s first big crush, or a screaming fangirl meeting her heroes.

    This isn’t to say I don’t think passion is a part of the driving force of any product, but that it must be tempered and controlled in things like WordPress core. We know that we can’t make WordPress core do everything, and we know we shouldn’t. When things are extendable, we utilize that and demonstrate our fire. When they’re difficult to extend, or kludgy to implement, we come back and say ‘You know, it would be nice if we could…’ But at the end of the day, when WordPress tags your trac ticket ‘wontfix,’ it’s because they know, being unable to be all things, that they must limit the things they are.

    If you haven’t yet, take the time to read WordPress’s Philosophy.

    Aaron Jorbin - Haters Gonna HateWhen I usually talk about divorcing my ego from a project, what I mean is that I don’t let my passion cloud my better judgement. One of the lessons I’ve learned in nearly 20 years of active fandom is that when you love something, you get fired up about it, and you tend to view peoples opinions and actions as a personal attack when, in fact, they often aren’t. Yes, there are idiots and trolls and people who hate-monger, but in general, people actually aren’t dicks. They’re selfish and self-centered, but that’s just human nature. Part of designing a project means you have to let go of your personal attachment to your baby, and understand that haters are just gonna hate, and there’s nothing you can do about it.

    This also applies to using a tool, though. People mock the evangelists, and we all hate the extremists, and certainly no one actually supports those who are outright malicious. But all those archtypes come part and parcel with a system, and are all aspects of the simple problem that no one product can do all the things. We want things to be a silver bullet, to fix everything we, personally, have a problem with, and we’re totally unrealistic in wanting that.

    Mark and I were talking recently, and he pointed out that WordPress was once 230kb. It’s now 3.8megs, even zipped up. Part of this is because it all grew and became more, but if you ask the old-timers, some will complain that around the 1.5 days, WordPress just became too big. It does too much! And those people say we should pull things like the importer out of WordPress. After all, you’re going to use it once, if at all. Core plugins would get pretty big too. Jetpack is 2.4megs on its own, zipped up. By trying to be everything, maybe we’re making things a little worse.

    So the next time someone gets their panties in a bunch at you for not doing everything, tell that it’s by design. Do what you want with your code, make it easily extendable for the next guy (or forkable), and carry on. They’re not getting that unicorn.

  • jQuery – Why U No Enqueued?

    jQuery – Why U No Enqueued?

    DevoThis is a followup to my how to get your plugin in the WordPress repository post.

    While code isn’t outright rejected for being ‘bad’ code (only security holes and guideline violations), a lot of plugins are doing the easy things wrong. These plugins will get approved, but they won’t work with all setups, they’re more likely to have issues with Multisite, and they’re just not thinking forward. They aim to solve a, singular, problem, without looking beyond. Primarily I see this when people are trying to bring in some js code into their plugin. Heavens knows I do it, and I’ve done it wrong too. But as I see more and more plugins, I’m starting to get better and better at knowing what’s wrong when I see it.(“I know it when I see it” thanks to United States Supreme Court Justice Potter Stewart)

    The easiest way to show you is to give you some really bad examples and go through some of the steps to fix it. The best part is that I’m actually going to use real plugins I’ve seen. Only the name has been changed to protect the innocent.

    Ready? Here’s what we’re doing wrong.

    Not using functions to define locations

    The very bad code:

    echo '<script src="/wp-content/plugins/myplugin/myscript.js"></script>';

    I wish this was something I made up. Worse, I’ve see it more than once. Recently.

    This install is assuming WordPress is installed in the root of your HTML folder (i.e. domain.com). This is not always the case, as many people install WordPress in subfolders. We’ll need to fix that first with home_url().

    echo '<script src="'.home_url('wp-content/plugins/myplugin/myscript.js').'"></script>';

    Now it’s a little better, as by using home_url() we’re letting WordPress define where ‘home’ is. Great! This has two pretty obvious problems, however. First, if I have WordPress installed in a folder, like /public_html/wordpress/, but I’m running it out of the main domain by giving it its own directory, this won’t work. Your code would point to http://example.com/wp-content… when mine is in http://example.com/wordpress/wp-content.. instead! The ‘easy’ fix is to change home_url() for site_url(), but what if I’m not using wp-content? You didn’t know we could Move wp-content? We can. So let’s address that.

    echo '<script src="'.content_url('plugins/myplugin/myscript.js').'"></script>';

    By using functions to determine plugin and content directories, we can make this much more flexible. That works, but it could be better. What if we didn’t have to define the plugins or myplugin folders? We could just do something simple like this.

    echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';

    Now we have a simple, flexible, functional script embed of js. Except there’s one, minor problem. We’re not including the script correctly.

    Not enqueuing files

    This isn’t ‘wrong’ really. I mean, if I put this in my plugin, it would echo out the script, and that’s what I want, right?

    echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';

    But let’s say I want to put it in my header:

    function my_scripts_method() {
        echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
    }
    add_action('wp_head', 'my_scripts_method');

    And now I want to include my CSS so it looks pretty:

    function my_scripts_method() {
        echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
        echo '<link rel="stylesheet" type="text/css" href="'.plugins_url('myscript.js',__FILE__).'" media="all" />';
    }
    add_action('wp_head', 'my_scripts_method');

    Oh, wait, no, I wanted my JS in the footer:

    function my_scripts_method_foot() {
        echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
    }
    function my_scripts_method_head() {
        echo '<link rel="stylesheet" type="text/css" href="'.plugins_url('myscript.js',__FILE__).'" media="all" />';
    }
    add_action('wp_head', 'my_scripts_method_head');
    add_action('wp_footer', 'my_scripts_method_foot');

    And really, this will work. But it’s not efficient, I’ve got extra actions, and I’m not considering any jquery dependencies anymore. By using wp_enqueue_script is better. Weblog Tools Collection did a series on how to properly add scripts (note that it’s a bit out of date with the use of WP-CONTENT constants). From that we can extrapolate to use just this to include our js and css:

    function my_scripts_method() {
        wp_enqueue_script('my_script', plugins_url('myscript.js',__FILE__) );
        wp_enqueue_style('my_script', plugins_url('myscript.css',__FILE__) );
    }
    add_action('wp_enqueue_scripts', 'my_scripts_method');
    

    What enqueue does is put your code in the best possible location and can be extended to load dependencies. wp_enque_scripts has a lot of power, and because it’s a WordPress function, it’s got options that make it more flexible. Like when I look at my above code, I remember, oops! I wanted to run my js out of the footer! Not a problem. Look at my options.

    wp_enqueue_script('handle', 'source', 'dependencies', 'version', 'in_footer');

    jQuery Logo looks like a Devo HatThe ‘handle’ is what I want to name my script, it should be unique. If I register my script, I can call the handle over and over again. We’re using my_script right now. The ‘source’ is where my file is located. We’re lifting that from our other code, the bad code, because it works. Your ‘dependencies’ are the other js files yours needs to function. If I put in array('jquery', 'scriptaculous') then both jQuery and Scriptaculous would get loaded before my script. Curiously, you don’t actually need the ‘version’ option, as you can leave it blank and WordPress will automatically add a version number equal to the current version of WordPress you are running. So every time you upgrade WP, it will get updated and force a re-download. This is good, since if you have dependencies to scripts included in WordPress, and they change with a new version (which is the only way they can change), then you get updated too. Finally we have the value I was looking for, ‘in_footer.’ Leave it blank and it’s in the header, put in true and it’s not.

    This makes my code:

    function my_scripts_method() {
        wp_enqueue_script('my_script', plugins_url('myscript.js',__FILE__), '','', true ););
        wp_enqueue_style('my_script', plugins_url('myscript.css',__FILE__) );
    }
    add_action('wp_enqueue_scripts', 'my_scripts_method');
    

    Yeah, isn’t that a lot easier?

    Using a different jQuery

    This last one I’m going to touch on today is the exact code I saw, in the wild, and it’s got two of my three buggaboos in it.

    wp_enqueue_script('jquery-1.4.3.min.js', '/wp-content/plugins/myplugin/js/jquery-1.4.3.min.js');

    Okay. You already know the right way to call the script, so we’ll edit that into something more flexible.

    wp_enqueue_script('jquery-1.4.3.min.js', plugins_url('js/jquery-1.4.3.min.js',__FILE__) );

    That should be okay, but it’s totally not.

    Most importantly here, we’re calling jquery, which is actually built in to WordPress. Now, we’re calling it by a different handle, but that’s no guarantee that it won’t cause conflicts. In fact, I’m pretty sure this will cause no end of problems with some plugins. The right thing to do would be this:

    function my_scripts_method() {
        wp_deregister_script( 'jquery' );
        wp_register_script( 'jquery', plugins_url('js/jquery-1.4.3.min.js',__FILE__) );
        wp_enqueue_script( 'jquery' );
    }
    add_action('wp_enqueue_scripts', 'my_scripts_method');

    Now we’re making sure we won’t have conflicts by re-registering jquery, replacing it, and moving on.

    A lot of people would actually recommend using Google instead, as it takes the responsibility off you for including a file you don’t ‘control.’ Also it makes your plugin smaller and load faster.

    function my_scripts_method() {
        wp_deregister_script( 'jquery' );
        wp_register_script( 'jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js' );
        wp_enqueue_script( 'jquery' );
    }
    add_action('wp_enqueue_scripts', 'my_scripts_method');
    

    Devo Hat looks like Devo HatGreat! Now we’re done, right? Wrong. As of this writing, WordPress is using jQuery 1.7.2. Now I couldn’t come up with a reason to include an old version of jQuery in WordPress (newer, yes, older, no), so I asked around and none of my friends could either. Using an older version is more likely to cause issues with newer code included in WordPress, as well as plugins which are upgraded to take advantage of the new features. You’re shooting yourself in the foot. The only thing you might be using this for is to include deprecated fictions, and really you need to update your code to fix that instead.

    If the whole point is to load the scripts from Google, though, there’s an awesome plugin for that.