Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: essay

  • Will You Help Me Sell My Plugin?

    Will You Help Me Sell My Plugin?

    I get asked this a lot. It comes with the territory, but people ask me to help them monetize their plugins all the time. And my answer is always the same.

    No

    As much as I am a strong advocate of people making money off of WordPress, and as much as I support plugin and theme devs in their work, I’m not out here to help you run your business. While I do spend time thinking of ways to get people to pay for services and software, I don’t prioritize it, and most of my ideas are just that. Ideas.

    Really what people are asking for is my ideas and my free work. And to that, I say no.

    Business Help Isn’t Free

    If you wanted to hire me to help, to look at your code and to assist you in coming up with business strategies, based on my experience in the WordPress world, that’s a different matter. That gets a ‘no’ because I don’t have the time to dedicate to that work. I have a full time job that I do like, and I have some volunteer work I enjoy, and I have a very addictive side project. Since I enjoy being married, I don’t take on extra work right now. I don’t need the money.

    But the point here, if you can’t tell, is that yes, I would expect you to pay me for my work.

    I’m No Good At Sales

    Of course, keep in mind the fact that I’m a terrible salesman. I don’t like exaggerating what a product can do, I don’t like even suggesting a lie. I downplay. And that’s because I don’t like it when people promise the moon and only deliver low Earth orbit. I want realistic goals and possibilities. Can you do anything with this plugin? Sure. But it comes at a cost and I feel people should know that cost.

    I’m Hard to be Bought

    Everyone may have a price, but my price is rarely money. I know this sounds weird, since I said I expect people to pay me for my work. You see, asking me to do you a favor for free doesn’t really happen. But also, asking me to do you a favor for pay won’t happen.

    And by this I mean reviews.

    I’ve been asked, many times, to review people’s themes and plugins and post about it here. And in general, I say no. I review the things I use and like because I use and like them. I’m driven by usability. If I like your ‘thing’ and I think people should hear about it, I’ll talk it up. If your thing is free or for sale, I don’t care. What I care is if your thing was what I needed and wanted, and I liked it.

    I Won’t Help You Sell

    That’s not my deal. It’s not my deal on this blog. I’ve never been bought off for a review, I’ve never been asked “Would you review this product of mine?” unless I’ve already been known to use it. And even then, I’ve told people “You don’t want me to review it. I like it, but you have some bad bugs.”

    I’m honest. I’m direct. I’m incurably truthful.

    You probably don’t want me to help you sell your stuff, but if I really like it, I may anyway.

  • Trust No One

    Trust No One

    A constant refrain for my security reviews of plugins and themes is to sanitize everything. And sometimes my pedantic nature of sanitizing everything leads people to ask me why I don’t trust users.

    The short answer is “Because I am one.”

    The longer answer is that I believe in three types of users, and I’m aware of their character flaws.

    Users

    Most people on the internet fall into this category. They know how to log in and check email and read a blog post. Maybe they leave comments, maybe not. These people are the most basic of them all, but that isn’t a bad thing at all. Users do what they want and don’t often think about the consequences, because for them there really are none except saying things they didn’t mean or wanting a comment deleted.

    These users are dangerous because they don’t think about what they’re doing. They trust, blindly sometimes, that the websites they visit won’t hurt them. That means that data they input has to be sanitized and validated because they may not realize what they’re doing. They may put a URL in the email field of your comment form, and they should be warned about those things.

    You can’t trust the users because they don’t know any better.

    Experienced Users

    This is actually not the most dangerous category. You might think they would be, because they know enough to be dangerous. Instead, I’ve found these users know enough to be cautious. They know what they don’t know, and they’re careful about what they’re doing. They check six or eight times before they paste in data, and they read error messages. Oh yes, these people. You know them, don’t you? They send screenshots of errors a test out theories before telling you “This is broken.”

    We like those people, though you may be wondering what about the experienced users who don’t do the legwork. To me, they’re users. There’s nothing wrong with being a user, but it changes my expectations on what they do and who they are. If someone is experienced, though, they’re going to play with things and that means they might break things when they try to recreate the problems.

    You can’t trust the experienced users because they mean well.

    Admin Users

    These are the users who terrify me the most, and sadly, this is where most WordPress users actually are. Because if you’ve installed your own version of WordPress, you are an admin user. God save your soul. And here’s why they scare me: they have more power the an the experience user but the skill of a user. They’re kind of like toddlers.

    This is not meant as an insult. The problem is that, unchecked, they can destroy their own sites. They copy and paste code or content into the post editor. In fact, that’s the biggest problem. Many years ago, my friend John and I spent five days debugging a crash, all because we didn’t know that no one who knew what they were doing would ever enter that data format into a field, and since we were admins, the check was overridden.

    You can’t trust the admin users because they have phenomenal cosmic powers.

    Trust No One

    Not to sound all Fox Mulder on you, trust no one’s data. Especially not your own. Don’t assume you know what you’re doing, that you never typo, that you’re always right. You’re not. No one is. And we don’t trust data because we could be wrong. It’s just that simple.

  • You Are Not Psychic

    You Are Not Psychic

    The other day I hear someone mention that they were securing software that they didn’t even have the words for 5 years ago. That reminded me of how fast technology moves. Things that didn’t exist last year are vulnerable today, and the discovery of those things only happens faster as we invent weirder and weirder ways of reinventing the wheel.

    The Myth of Perfection

    A well known saying is that the perfect is the enemy of the good. We take that to mean that if we wait until a thing is perfect, we will never feel it is done enough and ready enough for the world. In Open Source technology we’re fond of releasing and iterating, accepting the lack of perfection and aiming instead for the minimum. What is ‘good enough’ to let people use our work and improve on it?

    Perfection doesn’t exist. There is nothing on the planet that is perfect and there never will be. But accepting this doesn’t mean we allow imperfection and danger into our lives.

    The Balance of Reality

    Everyone screws up code, no matter how awesome a professional you are. Accept it 🙂

    I said that nearly three years ago, and I’ve argued before that it’s okay to screw up. I really do believe that making mistakes isn’t a bad thing. But at the same time, many people understood that to mean I was alright with shipping code that I knew was bad. This is not at all the case.

    If you know your code is bad or insecure, you fix it. Period. You don’t let things you know are bad out the door. But you do release things that work and perhaps lack all the features you want. There’s a difference between releasing bad code and releasing imperfect code.

    The Attack of Security

    To turn this on its ear a little, if someone comes up to you and says “This code is wrong, you should do this other thing.” then you have a choice. You can listen and believe them and study if they’re right and test it and fix it, or you can ignore it.

    When someone you respect tells you those things, you’re inclined to believe them. But at the same time, your heart takes a hit because “this code is wrong” sounds a lot like “this code is bad.” And that sounds like “you wrote bad code” and that feels like “you’re a bad coder.”

    That slope slipped right down, didn’t it? It’s a reality. It’s in our nature to take admonishments of our work as a personal attack, even if they are rarely meant that way. I can count on my hands the number of times I’ve actually told someone they were a bad coder. I can count on one hand the number of times I’ve told someone who wasn’t me that they’re a bad coder. I’ve certainly said it to myself a lot. I believe I’ve told one person directly that I thought they were a bad coder.

    I don’t think they actually understood what I meant… Which says something.

    The Shield of Arrogance

    We are not psychic. If you are, please let me know who to bet on for the World Series. Being humans, and therefore fallible, we cannot be so arrogant as to presume we know all the possible ways our code might be vulnerable. Technology moves so fast that what looks safe today may turn out to be terrible dangerous tomorrow.

    Knowing this, knowing we are imperfect, we know that our fellow humans are also imperfect. The greatest danger to our security is ourselves. And that means, as developer writing code to be used by others, it’s incumbent upon ourselves to protect our fellow humans from innocent mistakes.

    You are not psychic

    You don’t know what will be insecure next. You can’t. So secure your code as best you can and secure it better if people point out your shortcomings. Learn. Improve. Protect.

  • REST API – Democratizing Reading

    REST API – Democratizing Reading

    Democratize Publishing.

    We say that a lot in WordPress. We boldly state that the goal of WordPress is to democratize publishing through Open Source, GPL software.

    I’d like to turn that on it’s ear for a moment.

    The purpose of the REST API is to democratize reading.

    Democratize Discovery

    One of the myths of websites is that if you build it, people will come. If that was true, we’d never need plugins like Yoast SEO and we’d never need to self-promote. The reality is that we have to work hard and make our content good. WordPress helps us make it look good, and makes it easier to get it out there, and usually the rest is up to us.

    There’s another aspect to discovery, though, and that is the ease of findability. We already address this in WordPress to a degree with RSS, but as much as I’d love to say that was that, it’s not. It’s 2017. People don’t want RSS, they want email and they want the information on social media immediately.

    And? They want apps on their phones that alert them to new data.

    Democratize Consuming

    Reading data with WordPress is easy. We go to a webpage, we see the data, we consume, we move on. With emails and social media, people usually have to click to come to your site and read. While this is good for your traffic, anytime a person has to click you’re running a risk they might not click. That’s why Tweetstorms are more consumable than blog posts. While they are far more transient, they’re accessible in an immediate way.

    Making the consuming of data more direct, a more one-to-one relationship, improves the chances that someone will actually read the information. Much of this can be achieved with a good lede, but readers are well to aware of click-bait today. “She tried this blogging software. You won’t believe what happened next!”

    Right. You get the point. In order to get people to read, you have to make it easier for them to read. Converting WordPress posts to something an app can read needs to be easier for the blogger, or they won’t be able to have success.

    Democratize Reading

    The REST API does just that.

    It makes the discovery and consumption of your website easier by simplifying your output.

    When you look at a website you see the design and the layout and the wonderful beauty. When an app reads your data, however, it doesn’t want or need any of that. An app needs the raw data. And the REST API does that. It outputs the data in a super basic and simple way. Furthermore, it lets you add on to this and output specific data in special ways.

    Democratize Publishing

    You can publish your data in multiple ways. Today, we all know about the blogging aspect of WordPress. But here are some other ways you could share your data:

    • Allow users to download a CSV with all the products on your site and their costs
    • Create a plugin that calls custom data, allowing others to have a widget with the data
    • Power a mobile app without loading your theme

    Could you do all that without the REST API? Of course.

    Does the REST API make it easier and thus help you democratize faster? Yes. It does.

    The REST API can change your life, if you’d only let it.

  • On Uninstalling WordPress Plugins (and Data)

    On Uninstalling WordPress Plugins (and Data)

    Someone asked me why WordPress always says it’s going to delete files and data when it only removes the files and not the database options. There are two parts of the answer to this, one being a little historical and the other being a bit unhelpful.

    The Message: Delete Files and Data

    Once upon a time, when you uninstalled a WordPress plugin, it looked something like this:

    The Delete Plugin Screen

    That was a very simple screen. You were asked to delete the plugin files, you clicked that you were, done.

    Now you see this thanks to Shiny Updates:

    Shiny Updates - Delete Hello Dolly

    It’s a different message, telling you it’s deleting data!

    What Is The Data?

    The part you don’t see is that WordPress would also remove all the data as well as those files.

    Any time WordPress showed you that message to delete files and data, it was saying that it found a file called uninstall.php which would, presumably, delete the data set by the plugin. By this I mean the options and settings you chose for your plugin. Some plugins have data and others don’t. For example, Hello Dolly has no data, just files. It doesn’t need an uninstall file. On the other hand, a plugin like Jetpack has a lot of settings it should remove from the database on cleanup.

    Why Do We See ‘and Data’ If There’s None?

    Okay, so if Hello Dolly has no data to delete, why did we see that message? In part, this stems from the following idea:

    Delete plugin files AND data

    We wanted it to be more clear as to what was being deleted when you delete, and that was part of a proposed change to WordPress core to tell you if and when database settings are removed on uninstall, and let you leave it alone if needed. Wouldn’t that be nice? Letting you pick which way to go?

    Well. There’s a problem with that dream, and the name of the problem is “Plugin Frameworks.” No, not the CMB2 stuff, I mean the boilerplate plugin frameworks that are oh so popular.

    I hate them. Because they always have an uninstall, and most of the time people leave it alone. That’s right, your brilliant boilerplate will flag an alert that it’s deleting data when it’s not. This doesn’t impact the functionality of the base idea, but it does change the message.

    So Why Does It Say Data?

    Because when you uninstall a plugin, if it was well written, it removes the files and the data.

  • Mailbag: When Do I Use “If Exists”?

    Mailbag: When Do I Use “If Exists”?

    Someone pinged me on slack about this. Bear in mind, I tell people “If you got an email from plugins, please press reply and email back, don’t slack me.” because it allows me to keep track of the whole history of a conversation, but also because if I’m sick, someone else can reply to you and you’ll wait less. While, in this case, the answer should have been very short, it grew to be a lot longer than he’d expected because he didn’t quite understand what I meant.

    Unique Prefixes

    One of the requirements of the Plugin Directory is that all plugins have unique function names, defines, and classnames. This is for a pretty obvious reason: it will prevent your plugin from conflicting with other plugins or themes.

    • For plugins, use a function or classname that matches the plugin name: class ThisPluginName{} or function ThisPluginName_FUNCTION()
    • For specific specific sites, use a function class for the domain: class HalfElfOrg{} or class HELF{} or function helf_FUNCTION

    This extends to all things, including defines, namespaces, enqueue’d handles, and on and on. As I tell people, “A namespace or class of MyPlugin is not actually all that unique…” Defines are extra tricky since sometimes you want to define them and allow them to be replaced. But more on that in a minute. No matter what, this is bad: define( 'PLUGIN_PATH', plugins_url( __FILE__ ) );

    Since it’s 2016, I have to tell people that they shouldn’t use two letter slugs anymore as all the good ones are taken. I also tell them not to use wp_ or __ as a prefix.

    And then I say this:

    If those are intended to be in shared libraries, please detect IF the code is already included and not re-include it, as doing so will cause conflicts if two people call the same defines and functions.

    Yeah. It’s messy.

    If Define Exists…

    This is used a lot. Let’s say you know you need the plugin basename (the folder name) in multiple sub folders of you plugin, and it’s a pain in the ass to do plugins_urls( 'foo.css' , dirname( dirname( __FILE__ )) ); to go up two folders. That’s a case where a global define starts to make sense and it’s a case where rarely would you want to bother checking if it exists.

    The code is just this: define( 'MY_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );

    But what if you want to have a default value for an API Key and allow people to override it? Then you can one of these:

    // Option 1:
    if ( ! defined( 'MY_PLUGIN_APIKEY' ) )
        define( 'MY_PLUGIN_APIKEY', 'default key value' );
    
    // Option 2:
    defined('MY_PLUGIN_APIKEY') or define('MY_PLUGIN_APIKEY', 'default key value' );
    

    What those do is check “Does the define already exist?” for you.

    Now keep in mind, I wouldn’t do that. I’d do this:

    $apikey = ( defined('MY_PLUGIN_APIKEY') ) ? MY_PLUGIN_APIKEY : 'default key value' ;

    The best example of this in core WP is how WP_DEBUG is handled. If you delete that from your wp-config.php file, it doesn’t turn on debugging. The code checks for the existence and if it’s not there, it assumes no. For the most part, if you name your defines properly, there’s no need to allow them to be overwritten because you’re not defining them in advance. But in case you do, this code is a wise idea.

    If Function (or Class) Exists …

    Lately I’ve seen a lot of people do this:

    if ( ! function_exists( 'my_awesome_function' ) ) {
    	function my_awesome_function() {
    		//function stuff
    	}
    }
    

    Okay look. This sounds like a great idea until you realize the fatal flaw. What happens when (not if, when) someone else has a function with the same name and their plugin or theme loads first?

    As Lilu Dallas would say “Big badda boom.”

    This is a terrible idea unless we’re talking about shared libraries.

    Use if-checks With Shared Libraries

    That’s my answer here folks. The only time you should be checking if-exists is WHEN you are using a shared library. If your plugin includes a common PHP library, check for it before you include it.

    It’s a little different with Javascript and CSS though. Let’s say you’ve got Bootstrap. This is a commonly used library. A lot of plugins and themes have it, and you’re a good person. You want to make sure you only load it one time no matter how many people include it in their plugins and themes. In this moment, you have to do something paradoxically brilliant.

    Don’t use a unique name for your enqueues.

    function mypluginname_resources() {
        wp_enqueue_style( 'bootstrap', plugins_url( 'css/bootstrap.min.css', __FILE__ ), array(), VERSION );
        wp_enqueue_script( 'bootstrap', plugins_url( 'css/js', __FILE__ ), array(), VERSION );
    }
    add_action('wp_enqueue_scripts', 'mypluginname_resources');
    

    The magic here is specific to how WordPress handles enqueues. It knows “There’s already something enqueued as bootstrap! I don’t need this!” and you’ve sped up sites. Of course there’s a risk here when someone might have an older version loaded first. As far as I know, the enqueue system isn’t clever enough to detect what version is included, and use the newest one (I wish it was), so you may have to do some convoluted checks. Also making this worse is that people don’t name things properly. I’ve see people using bootstrap-js and bootstrap-css for the enqueue names, which is totally unnecessary. WordPress will handle that for you.

    Remember: When in doubt, if coding for WordPress do it the WordPress way.