Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: development

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

  • Say Thank You Publicly and Be a Better Coder

    Say Thank You Publicly and Be a Better Coder

    Takayuki Miyoshi is one of the best developers for WordPress you probably don’t know about. Miyoshi-san is quiet, thoughtful, and had written a handful of plugins you probably do know. Like Contact Form 7. He’s also written a wonderful multilanguage plugin called Bogo.

    He gave his very first presentation in English about why he uses free plugins. Miyoshi-san’s reasoning is plain and simple. By giving back to WordPress and open-sourcing the code, you have a greater chance of people helping you make your code better. More people will find bugs, more people will help you fix, more people will use it, and things will be made better for everyone.

    This is much the same idea as Pippin Williamson has about his open source philosophy. Now Pippin is pretty upfront that he thinks you should open source your plugins. And he’s got some strong views on supporting your site projects (and the responsibility there in). But he also mentioned once that he supports putting premium (i.e. paywall’d) products on Github.

    For free.

    That’s right. He said you can totally put your code up on Github for anyone to download or edit or fork.

    I thought about it for a moment, and how open and honest Pippin has always been with his code, and how some of his early WordPress code was not the greatest. Yes, I have been around WordPress long enough that some of the people I think of as being ‘The Real Shit’ about coding for WP were pretty bad. Maybe not as bad as I was when I started, maybe they were. My point is that Pippin, like everyone else, started out as a beginner. And some of his beginner code was bad, like everyone else’s.

    Would Pippin be as good a programmer as he is today without open source and without people giving him code corrections and suggestions?

    I think not.

    Furthermore, I don’t think that you’re going to lose any money here. The intersection of people who would both buy your plugin and are technically capable of using Github to install plugins is pretty small. I say this as someone who understands well the desire of people to get things ‘free’ from the internet and the seriousness of customers. If you make it easy for someone to buy your products (and in the case of WordPress, get updates for it), people will pay you. Because they like convenience. Remember the tale of Oatmeal vs HBO. If you stop people from being able to get your product easily, they just won’t.

    Most people are afraid of monetary loss, which I get. But you have to rethink things. First of all, most people won’t use Github. They won’t like not getting security updates, for one. And if you present Github as a technical place, they won’t use it. Done. Secondly, I happily bought the Person of Interest DVDs once Netflix got punched by (I presume) WGN on re-broadcast rights and couldn’t show me Season 4 before Season 5 airs. I get the added bonus of watching it on my Blu-Ray player, in super ultra HD. This behavior is NORMAL. Amazon made it easy for me to get what I wanted, and now I own it and if the Internet is out, well I’ll watch Root and Shaw and the Machine all day.

    And there’s something else to consider. The people who would use Github to get something for free are the folks who wouldn’t have paid in the first place. You’re losing money that you’d never have. To help explain this, I’ve made a little Venn Diagram for you, to show you how small this intersection is:

    percentage of people who would both buy your plugin and are technically capable of using Github to install plugins is pretty small

    I’m serious here. This is non-mathematical but based on my allegorical experiences of years in support be it free or paid. This is coming from someone who lives and breathes WordPress plugins. If you make it easy for them to pay, you will not lose money by putting the code up in a way for other developers to submit pull requests. That small sliver of green, the people who can use Git and would still pay you, those are your contributors. Those are the people you want. Because Open Source Code means more eyes, and more eyes means more reviews, and more reviews means better code.

    Everyone wins.

    And like Pippin and Miyoshi-san, I think that having your code available for others means I may learn new things and become a better developer. When I say ‘pull requests welcome’ what I mean is ‘teach me what you know, I love to learn!’ Even if I say “No, I don’t want to add that feature” trust me that your lesson was welcome and absorbed.

    When I went to WordCamp Tokyo, I had the intention of seeking Miyoshi-san out to tell him how much I like Bogo. That it solved a problem for me. That it just worked. That the code was good. Miyoshi-san also wanted to tell me thank you for the things I’ve done for him.

    It’s possible we both got a little teary eyed.

    And he and I agree on the big things. Make your code available for others to review and comment on and get pull requests. It will make you better.

  • Arbitrary Component Upgrades Are Not Helpful

    Arbitrary Component Upgrades Are Not Helpful

    Often WordPress gets shit for still supporting PHP 5.2. In fact, while they recommend 5.6 or up, WordPress still works on 5.2 and probably will for years to come, even though everyone knows PHP 5.2 is buggy, insecure, and not supported. No sensible webhost still uses it if there’s an alternative, but sadly there are reasons why some hosts are stuck on it.

    Why does WordPress still work on 5.2? Because there’s little benefit to be had in upgrading, and only harm. As I’ve said before, in the name of progress we run the risk of running ourselves right off the cliff. There’s nothing in 5.4 that WordPress needs. Please remember that I am a stickler about needs vs wants, there’s a lot we want, but nothing that is critical and that cannot be accomplished in a PHP 5.2 world. One day that will change, and when it does, we’ll rethink this whole argument. But right now, there is no need.

    My fear with a PHP 5.2 upgrade is that the people we would hurt with it are the ones least capable of resolving the problem. If we showed users an alert on their admin dashboard saying “You’re using PHP 5.2, please contact your hosting administrator and ask them to upgrade to a modern, secure, version of PHP” then we’re telling the wrong people something. It’s not the users who need to hear this, it’s the webhosts. And speaking as one? We know. Not only do we know, we actually care more than you do, and we’re working on it for everything not because of WordPress and it’s 25% market share, but because we know it’s the right thing to do.

    But this is not a PHP version debate. This is actually a reflection on something happening today. You see, WordPress still uses the 1.x branch of jQuery. Why? Again, it works. There’s no reason to upgrade to jQuery 2.x and doing so would break things. Among other reasons, WordPress still supports IE 8 which is used by 11% of computers out there. That’s not a small number. In fact, 11% of WordPress sites still use PHP 5.2! You see the situation? 11% is not insignificant.

    This comes up because Bootstrap 4 has decided to drop support for the jQuery 1.x branch. As far as I understand, they don’t want to support IE 8 and it’s 12% smaller. There isn’t a single code benefit that is included in jQuery 2.x that Bootstrap is using and, since jQuery 2.x is compatible with 1.x, you can switch back to it right now without any loss. But they don’t want to support IE 8. In fact, they don’t support it, and from that perspective it sounds wise, doesn’t it?

    It’s not.

    WordPress includes its own version of jQuery (still on the 1.x branch) and many other similar JS files, which have all been rigorously tested with both WordPress and many of the most common plugins. In order to provide the best compatibility and experience for users, WordPress asks that you not package your own (especially not an older version) and instead use wp_enqueue_script() to pull in WordPress’s version. There are many reasons for this but the simplest are as follows

    1. WordPress has jQuery. Save diskspace and leave your own out.
    2. If every plugin and theme removes WordPress’ jQuery and uses their own, there’s a potential for conflicts. Who’s jQuery wins?
    3. Using your own jQuery changes the way WordPress plugins and themes may work in unexpected ways.

    Can you remove jQuery and use your own? Of course! You just can’t host your code on WordPress.org if you do that.

    Now, there’s a missing metric here. What the percentage of sites using Bootstrap are on WordPress? For that I’m going to have to extrapolate. Looking at builtwith trends, it looks like 1.8% of the entire Internet uses a site with Bootstrap. Joomla 3.x uses v1.11.3, Drupal 7.x uses jQuery 1.4.4, and Drupal 8 will use 2.1.4. Remember this is a total rewrite of Drupal, though. They do not concern themselves with backwards compatibility when they jump to new versions, and that means you cannot measure the percentage of sites on the internet that will use Drupal 8. We can reasonably assume, since WordPress is fully backwards compatible, that the 80% of WordPress users who are on the 4.x branch will upgrade to 4.4 in December, and continue to do so for the future.

    Even if we cannot claim that 25% of Bootstrap sites are on WordPress, we can argue that with all major CMSs currently using jQuery 1.x, Bootstrap is about to kick a significant portion of their audience to the curb. Of course, not even 2% of the Internet is using Bootstrap. Will that be a great loss for the Internet? Not really. But it will incur a massive lost to Bootstrap.

    This real life example is precisely what I mean when I say that I worry about the user experience with our bold assumptions in our projects. Bootstrap’s logical assumption, that since they don’t support IE 8 there will be no loss by moving to components that don’t support IE 8 either, is a fallacy. They are thinking only on one level. They’re only seeing the ‘benefit’ (and I use this term loosely) of formally ending support for a user-base they never supported in the first place. This won’t impact their users, so it doesn’t matter.

    What they’ve neglected to consider is that their userbase actually encompasses other people who support IE 8. So while we know that no one using Bootstrap and WordPress supports IE 8, simply by dint of using Bootstrap, this new jQuery version actually forces them to exclude them, instead of passively. And by doing this, they will shortly find plugins and themes that use Bootstrap 4 rejected from the repository, which will only harm adoption of Bootstrap as a framework.

    This isn’t a threat. This is reality. This is the difference between “We don’t support IE 8” and “We would rather not support IE 8 than be compatible with 25% of the Internet.”

    Looking at it that way, it’s a simple call.

    Put jQuery 1.x back in. Make 2.x a recommended option. And move on.

  • Jekyll Layouts vs Wiki Templates

    Jekyll Layouts vs Wiki Templates

    One of the things I was doing in Mediawiki was using a lot of templates. A lot. The way a template works in Mediawiki, you have a special page called Template:NAME and you can embed it with {{NAME}} in any post. You can even embed a template in a template. They’re basically static ‘blurbs.’ You can make them dynamic, but I have found that even after ten years of using Mediawiki, it’s still a bit of a mystery.

    With Jekyll, that gets thrown out the window.

    Let’s take, for example, my list of interviews. I have 14 or so years of interviews, broken up into a separate page by year and internally sorted by date. Manually. I also have a template {{Interviews}} which outputs a pretty formatted link to each year. Also made manually. For every new interview, I edited at least two pages (the interview itself and the year). And for every year I had to update the main interviews page and the template.

    My end goal was to do the following:

    1. Each year index would dynamically list the posts for that year
    2. The interview main page would list links to all the available years
    3. The interview ‘template’ would be output on every page
    4. The interview year page would list everything from that year
    5. All those things would dynamically update when I added a new item

    Oh and I also wanted a layout to be intelligent enough to show a special header with specific information on the individual interview pages.

    Love Collections

    To convert this, I first made use of collections, making one for _interviews and within that I have a folder for each year with the interview as a flat file and an index.md to make the main index. I don’t have to do this. I could have the index anywhere I wanted, but this was easier for me.

    There is a big gotcha here, though. Subfolders and collections and sorting by date doesn’t work the way you’d think it would. I could make it easily sort by title, and I could reverse it, but sorting by date proved to be a killer. Eventually I figured this out:

    1. All the pages have to have a date, even if you’re not going to sort that page (see my index)
    2. You can’t sort in a for loop

    The final code looks like this:

    {% assign posts = site.interviews | sort: 'date' %}
    <ul>
    	{% for post in posts %}
    		{% if post.topic != 'index' and post.tags contains page.year %}
    			<li><a href="{{ site.baseurl }}{{ post.url }}">{{ post.title }} ({{ post.date | date: "%d %B" }})</a></li>
    		{% endif %}
    	{% endfor %}
    </ul>
    

    Front Matters

    This is funnier if you know that the ‘header’ of a Jekyll file is called the Font matter. Here’s an example of mine:

    ---
    title: Interviews
    author: Mika E.
    layout: interview
    permalink: /interviews/
    date: 2001-01-01
    topic: index
    tags:
      - 2001
    ---
    

    Everything except topic: index is a default variable. I made the topic, and what that does is tell me “This page is an index page” and what year things are. There are reasons for this down the line. Now I also want to sort by year, but I can parse the date for that.

    Design the Layout

    I designated my layout as ‘interview’ in the first example, so I made a file called interview.html in layouts and made it a child of my default layout. In there, I have this code:

    <ul>
    {% for post in site.interviews %}
    	{% if post.topic == 'index' %}
    		<li><a href="{{ site.baseurl }}{{ post.url }}">{{ post.date | date: "%Y" }}</a></li>
    	{% endif %}
    {% endfor %}
    </ul>
    

    That says “if a page is an index, list it.” Now when I want a new year, I just add in a new folder with an index file.

    I’ve gone even further, taking the logic from some WordPress themes I’ve see, and the layout file has all the code for both the index view and the per-item view, allowing me to format my interviews with custom headers and footers around the content.

    Does it Work?

    Yes it does! Mostly.

    The problem with this, and yes there’s a problem, is that the interview layout page doesn’t regenerate itself. I have to go and re-save the layout for interviews in order to regenerate any lists I have on that page.

    I can get away with typing this in shell: touch _content/_jekyll/layouts/interview.html && jekyll build but it is a little annoying. Even running a manual jekyll build won’t do it because the layout doesn’t realize it has a change yet. I do understand why, though. It may be worth moving that somewhere else, though I have a feeling even if I make it a template it would have the same problem, since that template file wouldn’t know to update until it was edited.

    It took me a while to find the magic sauce is a bit of code called regenerate: true – This is not something you should use everywhere! I use it on my interviews index pages because those pages get updated when a new item is added to their folder. It actually lets my index pages be totally blank except the yaml headers which is nice and simple.

  • Jekyll Collections

    Jekyll Collections

    Early on, Jekyll’s developers said that if someone was using posts for non-blog content, they were doing something wrong. That left one other avenue open, the first time I looked at Jekyll, which was pages. They’re nice, but they’re not what I wanted.

    Enter Jekyll collections. These are ‘arbitrary’ groups of related content which you put in their own folder. I had 15 years of interviews collected, so for me this seemed like a perfect idea. I read up on Ben Balter’s – Explain Jekyll Collections like I’m 5 and it helped me sort out what I wanted.

    Configure

    This is easy. You just add the collection code to _config.yaml

    # Collections
    collections:
      interviews:
        output: true
    

    Having the output set to true means that when I run jekyll build the pages are generated. That’s pretty simple. They don’t get auto-generated when you run a jekyll serve and you’re testing locally, however. Which sucks. I upgraded to Jekyll 3.0 beta and it started working, though, and I’m okay with running a beta.

    Create A Folder

    Also easy. Make a folder called _interviews in the main Jekyll folder. I will note, this gave me a fit. I wish I could put all my collections in a subfolder, because now I have this:

    _data
    _includes
    _interviews
    _layouts
    _pages
    _posts
    _sass
    _site
    

    It’s messy, and if I didn’t know that some of those folders are special (like _includes) I could easily be confused. The _site folder makes some sense, that’s where my site is output. But even if I use the source setting to move all my source pages into a folder (called _source in my case), I still can’t separate the code from the content. What I would like is this:

    _assets – Store all of my ‘code’ like layouts, plugins, css, etc here.
    _content – Store all my post content, collections, pages, etc here.

    Still this is a little better for me. Less insane. I will note, I was able to move my folders by defining the directories in my configuration file like this:

    # Moving Folders
    source:       _content
    plugins_dir:  _jekyll/plugins
    layouts_dir:  _jekyll/layouts
    includes_dir: _jekyll/includes
    

    So now my main folder has two folders _site and _content which is a lot easier for me to work with. I feel less muddled. Inside the content folder is a _jekyll folder which is my ‘wp-content’ folder, and a _data folder, which has some data files. More on that later.

    NB: This only works on Jekyll 3.0 and up!

    Create Files

    All I had to do was make my files in my _interviews folder and I was done. Well. Not really. I needed a way for Jekyll to link through everything, and I really didn’t think making manual pages was smart. I tossed in this code to my interviews post file and it cleverly looped through everything it found, generating the page on the fly:

    <ul>
    {% for topic in site.interviews %}
    	<li><a href="{{ site.baseurl }}{{ topic.url }}">{{ topic.title }}</a></li>
    {% endfor %}
    </ul>
    

    If you’re familiar with WordPress loops, this is the same thing as saying “For all posts in a category…”

    Customize the Hell Out of It

    Of course you know that’s what I did next. I went and made it super-complex by putting my interviews in year subfolders and then making the main interview page a list of all the years, with links to those pages, and loops back and … well. That’s another post.

  • Changing Git History

    Changing Git History

    Working on a group project in Git, I did the smart thing with my code. I made a branch and proceeded to edit my files. I also did a dumb thing. I made four commits.

    The first was for the first, ugly, functional version of the code. The second was a less ugly, kind of broken version. The third was the rewrite and the fourth was the working version. When I wanted to submit my changes for a review, it was going to be ugly. I did not need or want people looking at four commits They only wanted the one.

    Now I’m a weird person for how I do commits. I add a new feature like a new function to parse things, and I commit that. Then I change my CSS and commit that. And so on and so on. This means I can look through my commit history and see exactly when I made a change. When I’m ready to do my release, I document all the changes based on that commit log and have it as my message.

    But when you’re working with a team, and all they want is one clean commit? Well I’m their worst nightmare. There is a cure for this, though! You can squash your commits, merging them all into one.

    Squash

    Actually it’s rebase. It can be squash too, though. I ran the following command which says to rebase my last 4 commits:

    git rebase -i HEAD~4
    

    That opens up another editor

    pick b17617p Crap I need to do this thing!
    pick 122hdla Added feature HUMAN to autogenerate a humans.txt file
    pick nw9v88a Changed comment avatar size to 96px
    pick 8jsdy1m Updated CSS for comment avatars to make them a circle
    
    # Rebase b17617p..8jsdy1m onto b17617p
    #
    # Commands:
    #  p, pick = use commit
    #  r, reword = use commit, but edit the commit message
    #  e, edit = use commit, but stop for amending
    #  s, squash = use commit, but meld into previous commit
    #  f, fixup = like "squash", but discard this commit's log message
    #  x, exec = run command (the rest of the line) using shell
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #
    

    Now here’s where it’s weird. The first one, b17617p is the one I have to merge everything into. And it has the worst commit message, doesn’t it? Oh and I was totally not using the right formatting for how the company wants me to format my commits. They want the comment to be “Feature: Change” so I would have “Humans: Added new feature to autogenerate humans.txt”

    Since I knew I wanted to merge it all and totally rewrite the commit, I just did this:

    pick b17617p Crap I need to do this thing!
    squash 122hdla Added feature HUMAN to autogenerate a humans.txt file
    squash nw9v88a Changed comment avatar size to 96px
    squash 8jsdy1m Updated CSS for comment avatars to make them a circle
    

    Which, once saved and exited, gave me this:

    # This is a combination of 4 commits.
    # The first commit's message is:
    
    Crap I need to do this thing!
    
    # This is the 2nd commit message:
    
    Added feature HUMAN to autogenerate a humans.txt file
    
    # This is the 3rd commit message:
    
    Changed comment avatar size to 96px
    
    # This is the 4th commit message:
    
    Updated CSS for comment avatars to make them a circle
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    # Explicit paths specified without -i nor -o; assuming --only paths...
    # Not currently on any branch.
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #	new file:   LICENSE
    #	modified:   README.textile
    #	modified:   Rakefile
    #	modified:   bin/jekyll
    #
    

    Since everything with a # is ignored, I deleted it and made it this:

    Humans: New Feature -- Humans.txt is now autogenerated
    Comments: Changed avatar size to 96px and edited CSS to make it a circle
    

    Yeah, that’s it. Admittedly, these should be two separate changes, but they’re all a part of the same project in this case so it’s okay.

    Of course, at the end of this, I looked at my code on our web tool and swore, because I’d left a debug line in. My hero Mike said “Don’t worry! ammend!”

    I made my change, instead of a normal git commit -a -m "These are my changes" I ran a git add FILENAME and git commit --ammend to fix up your most recent commit.

    It lets you combine staged changes with the previous commit instead of committing it as an entirely new snapshot. It can also be used to simply edit the previous commit message without changing its snapshot.

    And yes, it’s pretty awesome. Use it wisely.