Half-Elf on Tech

Thoughts From a Professional Lesbian

Category: How It Works

  • Mailbag: How do plugins update?

    From Ken the Web Mechanic comes this:

    Hi! I wonder if you’d have any insight on this… I’ll mention Wordfence, though I imagine that it applies to any security plugin that compares plugin files with those in the WordPress repository… One of the most common things that Wordfence reports as a file “inconsistency” is the readme.txt of many plugins. Frequently, when using Wordfence’s compare feature, the readme of an installed and up-to-date plugin is shown as not the most current version and the repository shows the latest version – which is for the version that is installed!! If you delete the plugin and then download and install it anew from the repository, the readme is for the current, Wordfence has no complaint and all is right with the world… So I guess my question is… When a plugin is updated through WordPress, does the readme.txt file always get updated? It’s always been my understanding that during an update all of the old filed are deleted and then the new version is installed from the repository… It’s seeming like this may not be 100% of the case. It’s certainly only a minor irritation to me… but it makes me curious… Inquiring minds and all of that! 😉 Thanks!

    I put the whole question in because while the crux is “How are these buggers updating?” the whole picture is interesting. I’ve talked about this once before, but it was a very long time ago. How the WordPress Upgrade Works was posted in 2011, and Why does the WordPress background auto-upgrade work? was back in 2013. So it’s about time for a revisit.

    The short answer is “Actually, the readme.txt is deleted on plugin (and theme) upgrades.”

    The longer answer means first we should understand what’s going on with upgrades! How plugins (and themes) update is pretty basic and you can check out /wp-admin/includes/class-wp-upgrader.php to see all this code:

    1. Connect to the filesystem.
    2. Download a package.
    3. Unpack a compressed package file.
    4. Clears the directory where this item is going to be installed into.
    5. Install a package.

    These are all great failsafes, making sure multiple times that we’re not about to leave a user in a bad state. We check to make sure we can download and use the file before deleting and replacing. We check to make sure WordPress can find all the folders it needs, like plugins and wp-content and so on. If it can’t connect to any of the ones it needs, it will fail. We make sure we can download and unzip the file. Even when we look at the complex fourth step, we’re all checking over and over to make sure that when we really do delete these files, we have something to replace them with.

    The goal is that WordPress should never be able to leave you with a plugin deleted and not installed again, nor should it leave you with a half-deleted plugin. Obviously critical failures, like a server reboot mid-stream, will have some catastrophic effects. This is why WordPress tosses a .maintenance file down, mind you. Stops your site from looking like total poop while all this is going on.

    When we look at the class Plugin_Upgrader itself (line 766 or so), we get into some nitty gritty things. The public function upgrade does some interesting things:

    		add_filter('upgrader_pre_install', array($this, 'deactivate_plugin_before_upgrade'), 10, 2);
    		add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4);
    

    Here we are clearly deactivating and deleting safely before we upgrade. And at this point, I’m very confident that we’re deleting that readme.txt before we upgrade.

    Okay! So why is WordFence being a dillweed?

    I have a theory it’s related to the updates we do when WordPress core has a new version. You see, instead of updating the whole plugin, we update the readmes only to edit the “tested up to…” value. If there’s no code change, after all, why would we bother? No need to push an update! This means you no longer have a plugin that 100% matches what’s on Wordpress.org, you have a plugin where the code files match, but not the readme.txt files.

    And then poor WordFence notices that the readme you have and the readme on .org’s servers is out of whack, and tosses an error.

    I don’t know how WordFence would fix that, but I’m pretty sure this would hang ’em up.

    WordFence folks, got any ideas?

  • Mailbag: Hugo from iPads

    Mailbag: Hugo from iPads

    So I’ve done the whole Hugo thing and it’s great and it totally works for me. That 1% itch left from Jekyll is gone. So queue the inevitable…

    But what about mobile posting?!

    Why on earth the planet is obsessed with posting everything from their phone, I don’t know. Things like Instagram and Twitter make it easy for us to ‘communicate’ (and I use that loosely) and post photos of our lunch. And yes, the iOS app for the iPhone means I can ‘live blog’ but, to be honest, I hate it on my iPhone.

    My iPad though… I love posting from that.

    And yes, yes I can post to my Hugo run site from my iPhone or iPad. Remember, I can push my new content by running a git push command. The server will build, sync, and clean up on its own. All I need to do it is a Git app on my iPad that doesn’t suck

    Working Copy does not suck.

    It’s an iOS app that pulls my git repository to my iPad (the whole thing, so make sure you have room). Then I can edit files, commit them, and push. Hugo on the server does the rest, just like it would from my desktop.

    Working Copy is different from many other Git related apps because can hook into any git repository. I’m not using GitHub for this project. I want to do 100% self hosting, and that means no GitHub. Also no BitBucket. These tools are fine for what they are, and in fact I pay GitHub for some private repos. But I wanted my repo on my server, in part so I could do exactly what I’m doing.

    The tool is incredibly simple. It’s a familiar file navigator, tap through the folders. Tap edit to edit, make changes to the post, hit done. There’s even a preview feature that mostly works. Some of my Markdown files are very weird.

    If I wanted to edit in Byword, which is what I do most of my writing in for non-novel related things, I can share and go back and forth. I’d love it if the WordPress iOS app (or Calypso) did that. Write in Byword, send to other app. But even a copy/paste is simple enough. In this case, I can write in Byword and share to Working Copy. The interface takes the title of my document and let’s me pick the folder.

    Once I’m done with my edits, I commit my changes. Then I can push, or not. There’s an option to commit+push, but it crashed my app. A skim of reviews showed this happened to others. The iOS interface can be a bit tetchy so having this be two steps doesn’t bother me.

    I did find it odd that there was no button to push. I had to go back to the main folder, swipe-left, and press the orange push button. But that, and the weird crash, were it for annoyances.

    While free to download, it’s $9.99 for unlimited deployments. It was free for 3 weeks, which I tried out over WordCamp US and found simple and perfect for my workflow.

  • Hugo

    Hugo

    I’ve been playing with Jekyll a lot. After WordCamp US, I started toying with the idea of a JSON powered Jekyll site, where WordPress output its posts as JSON and Jekyll pulled in the posts and converted them. This ran into many snags. It wouldn’t be ‘dynamic’ for one, but the biggest issue is that Jekyll’s JSON reading ability was terrible. It didn’t like the complex JSON that WordPress put out.

    That sent me hunting down other things like Hugo. Unlike Jekyll and it’s use of Liquid, Hugo uses Go (hence the Go in the name you see).

    Installation (on a Mac) is easy.

    brew install hugo

    Done. It’s harder on my server, but still easier than Jekyll, which started to become a ‘thing’ as I worked through all this.

    Using Hugo is remarkably similar to Jekyll except that it works faster and a little more smoothly. The site builds incredibly fast and it dynamically refreshes. So if I edit a post, the page refreshes itself. This let me tweak my theme and posts and sort out the new language incredibly fast. Edit a file, boom, I see what’s wrong.

    It’s about as logical as Jekyll too, so it took me one DayQuil addled afternoon to sort out how to make things work.

    The Basics

    The basic are simple. You have a basic structure like this:

    ▸ archetypes/ 
    ▸ content/
    ▸ data/
    ▸ layouts/
    ▸ static/
    ▸ themes/
    config.toml

    The config file is what you think it is. Your posts go in content and the html-ized version shows up a public folder that gets created on the fly. The data folder is for your static data like a .json file or a .yaml.

    Independant to your theme, you can put css and js in the static folder, and layouts in the layout folder. Ditto archetypes, which are post-types. So if you know you’re always going to have a post type of ‘musician’ and you want it to have special headers, then you can have an archetype called musician.md with all that pre-filled in. Then when you want to make a new entry for Clifford:

    $ hugo new musician/clifford.md

    You can also have those in your theme if you wanted, but generally I use the same theme and separate projects. At this point, I was impressed enough to be swayed from Jekyll. I’m not going to explain how to write a post, since it’s just markdown and a header, just like Jekyll or GitHub Pages.

    Building Your Site

    The commands are basic. Running $ hugo server will build your demo server. Of course, you’ll want to post your drafts, so you need to add the param --buildDrafts … Oh and you want a theme …

    $ hugo server --theme=utility-pro --buildDrafts

    That’s silly, right? Why do I have to define all that? Thankfully I can edit my config.toml file:

    baseurl = "http://example.com/videos"
    languageCode = "en-us"
    title = "My Super cool Video Library"
    theme = "utility-pro"
    buildDrafts = "true"
    [params]
    Subtitle = "Videos about cats, collected from the internet."
    

    Now every time I run the command ‘hugo’ it will build my drafts with my theme!

    $ hugo
    45 of 45 drafts rendered
    0 future content
    45 pages created
    42 paginator pages created
    14 tags created
    3 categories created
    in 254 ms

    That’s incredible fast seeing as it built everything. Of course the other site I have is a great many more pages.

    Theming

    Since I’d already mastered Jekyll theming, this was trivial. Go and Liquid are weirdly similar and most of it was transposing. There’s not much to say here except that there’s a Twenty Fourteen Theme for Hugo and it’s pretty much what you expect. For WordPressers, it’s a good place to start.

    Shortcodes

    The neat thing is that Hugo has shortcodes! They’re not like WordPress ones, but you can see the similarity between WordPress and Hugo.

    [video mp4="video.mp4" flv="video.flv"]

    vs.

    {{< video mp4="video.mp4" flv="video.flv" >}}

    Sadly there’s no oEmbed. And I had to write the shortcode on my own, but again, if you know the basics of logic all this stuff is easy. Here’s the magic behind the shortcode:

    <video class="video-js" width="{{ if .Get "width" }}{{ .Get "width" }}{{ else }}640{{ end }}" height="{{ if .Get "height" }}{{ .Get "height" }}{{ else }}385{{ end }}" controls>
    
    	{{ if .Get "mp4"  }}<source src="{{ .Get "mp4" }}" type="video/mp4">{{ end }}
    	{{ if .Get "ogg"  }}<source src="{{ .Get "ogg" }}" type="video/ogg">{{ end }}
    	{{ if .Get "webm" }}<source src="{{ .Get "webm" }}" type="video/webm">{{ end }}
    
    Your browser does not support the video tag.
    </video>
    

    Once you look at it, it’s remarkably like WordPress. Only I don’t need a plugin. Everything in /layouts/shortcodes/ are like mu-plugins.

    And So?

    And so Hugo won enough of my attention that I’m going to keep playing with it and see what’s next.

  • Beginning to Understand JSON

    Beginning to Understand JSON

    Themes without php …

    Dynamic content without page requests …

    What about Multisite without Multisite?

    These are all things I’ve heard when people talk about the JSON REST API and how it’s the next greatest thing in WordPress. Well great, but what is it?

    REST stands for representational state transfer. It’s actually the juice that’s been powering the web since forever. RESTful systems generally run over HTTP (hypertext transfer protocol) and use the agreed upon language to get and put data. REST gives you a way to read and write data programmatically. You’ve been using it for years without even realizing it.

    This means our question isn’t what is it, but why do we want it or care about it?

    The WordPress REST API is a nice way to get at the data from WordPress without having to load all the heavy parts of WordPress. It’s useful for things like mobile apps, which don’t need to load everything, just the data, and it’s faster.

    Now, yes, WordPress has an API, called XML-RPC, and it sucks. You’ve used it already if you use the iOS app. We also have APIs like RSS, but that’s pretty much read only. The reasons that the current implementation of XML-RPC sucks are myriad, but basically it’s due to security, abuse, sanitization, and weight. It’s powerful but expensive and risky.

    The JSON API being added to WordPress aims to simplify and secure all that.

    Want to get your site’s posts? Simply send a GET request to url.com/wp-json/posts. Update user with ID 4? Send a POST request to url.com/wp-json/users/4. Get all posts with the search term “awesome”? GET url.com/wp-json/posts?filter[s]=awesome. It’s that easy.

    The WP API is very simply the interface to make it easier to get at your data. That’s it. How it does it is incredibly complicated. What it does is simple.

    Make it easier to get at my data without loading WordPress itself.

    What I dig the most about it is this idea.

    Take a website running backbone js that calls the JSON API from your WordPress site. Say frontend.com and backend.com are your URLs. You blog on backend.com and use WordPress normally. Your readers will visit a non WordPress site on frontend.com….

    Go on then. Hack the front end.

    It’s not WordPress, so unless you introduce an endpoint that puts you at risk, you have a way to protect your content. Plus now you can upgrade your blog all you want without having to worry really about taking your blog down.

    Obviously this isn’t perfect. By not using WordPress on the front end you won’t have access to a lot of features from plugins. Like related posts. And then again, maybe you can use related posts. Maybe you can even us Jetpack’s related posts.

    Mind? Blown.

    If everything WordPress can do the JSON API can do, then there’s nothing I can’t do. I can make any site where I run WordPress on the backend and anything I want on the front end. And now I can separate my site data, run by WordPress, and my theme and it’s options. I can dry run theme changes and layouts using my live data. I can tell the JSON API frontend.com site to ignore all posts with a special status, tell testend.com to use them, and draft posts.

    Migrations become easier. Who cares where the backend is, as long as the API frontend.com page can call what it calls.

    WordPress is becoming more and more of an application, and that is why we can all be excite about being at REST.

  • Mapping the Apple Watch

    Mapping the Apple Watch

    While in Japan, I had the chance to use my Apple Watch to get around and I figured out something.

    For walking or driving, the Apple Map app is the best to use with the Apple Watch. Not only do you get turn by turn directions with the haptic taps, but you can quickly see what’s next if you’re not sure what side of the street to be on. The haptics I love:

    A steady series of 12 taps means turn right at the intersection you’re approaching; three pairs of two taps means turn left…

    I use this feature constantly. It’s brilliant to be able to walk around and enjoy the area I’m in without worrying that I’ll get too terribly lost. As I walked through Kanda, my wrist tapped “tap-tap, tap-tap, tap-tap” and I turned left like a boss. The only time I used my phone was when I was at a five-way intersection. I can even use it to walk from my father’s apartment to his mother-in-law’s house a few blocks away. Or the 7-Eleven (which are awesome in Japan).

    For public transportation, the Google Maps app is brilliant. No. It’s phenomenal. Ueno station, in Tokyo, is one of the more complicated and confusing stations I’ve ever seen. It’s crowded, it has a damn shopping mall on top of it, and it’s where seventeen major train lines meet. The Google Map can, most of the time, tell me what track to be on and when for what train.

    Ueno makes Penn Station look tiny.

    But Google Maps can’t do ‘both.’ In fact, I’ve learned the Google Maps app is getting worse at things. You see, you go through Ueno to the Keisei Skyliner (the train to the airport) when you take the train from my dad’s apartment to Narita. It’s very simple. Takasaki line from Ageo to Ueno, exit Ueno via the South (not the Park) exit. Turn right. Pass the duck. Done.

    Instead of showing you a walking route, when I asked Google Maps to get me to Narita, it drew a straight-as-the-crow-flies line from Ueno Station to Keisei Skyliner. Yeah. Not so much there, Google-San.

    It only got worse when I wanted to take the train from Ageo to Kanda for WordCamp. You’d think that Google would be able to alert me, since they have an Apple Watch App, with taps “Hey, get off the train at the next stop.” But they don’t. In fact, the Apple Watch app just lists the directions, not very well, and doesn’t give me alerts. Even worse, you can’t easily track from the iPhone to the Watch. When I put in a direction on my Apple Maps, it automatically triggers the map on my Watch. Google Maps only shows ‘recent searches’ and Work and Home.

    It’s an absolute fail to use the technology properly.

    To make Google Maps ‘right’ for the Watch is pretty simple.

    1. Direction alerts. Tell me when to turn left or right. Steal it from Apple or make your own.
    2. Change train alerts. Tell me when I should get up. This will prevent people from sleeping through their stops.
    3. Give me easy directions to anywhere. Let me set up a path on my phone and immediately transfer it to my Watch.
    4. Use Siri. “Hey Siri, use Google Maps to get me home.”

    Four things. I’d settle for the first two, though I think the first three should be a priority for user experience.

    Until then, I’ll have to use my iPhone for transportation in a strange land, and my Watch for walking around the planet.

  • New Plugin: @Reply Two

    New Plugin: @Reply Two

    This blog has a cool trick in the comments section. The ‘reply’ link in comments will auto-generate your reply starting with “@person: ” and it does that with my plugin @Reply Two.

    The name is a pun because it’s a fork of the plugin @Reply (which has the slug reply-to), but it also has a ‘reply to’ feature (two … to … right?). I strip-mined the original and made sure it worked on the modern versions of WordPress. I made sure it looked good. And then I added in a feature I wanted, which was to allow for a way to see parent comments on the admin dashboard.

    That is, if you go look at a comment on the dashboard, you’ll see a little arrow that says “Show Parent Comment (15 words):” (or however many words). It strips out all HTML, so it’s a pretty accurate count. I wouldn’t want to use it on a site with a lot of really, really long comments where everyone was always replying to each other. It would make the comments page really slow to load.

    Stephen Cronin’s Show Parent Comment does the same thing there. His uses JS, and mine uses html5 with details-shim for fallback. Except for IE8. I hate IE8.

    I forked the plugin almost two years ago but I had it irregularly updated until Jeff posted about his experiences moderating comments on WP Tavern.

    The sad truth is that you can’t automate ‘enough’ of what makes moderating a pain in the ass. You can’t make it faster because it requires a human to read and pay attention to what they’ve read and process what it means. The part of the work that takes all the time is the part of the work that won’t be possible to teach a machine to do until we invent an AI.

    There’s a reason why spam-trapping isn’t perfect. While we have gotten pretty good about it, things will always get caught incorrectly, or let through when it should have been blocked. Why? Well we don’t yet have a way to scan someone for the intent in their heart. Metaphysics aside, we can’t find the answer in the soul of the person beside us.

    What we can do is make it easier for humans to look at a thing and go “Wait a second, that isn’t right!” Humans are generally good at that. We know what we’re ‘used’ to seeing and what we’re not. Hopefully that’s what @Reply Two does. Pun and all.