Half-Elf on Tech

Thoughts From a Professional Lesbian

Author: Ipstenu (Mika Epstein)

  • WP JSON API Challenges

    WP JSON API Challenges

    In my frustration of my static process, I ripped everything out by it’s roots and decided to take things in a strict order.

    Decision: All-In-One or Separate?

    The first question was do I want to download everything as one big JSON file and split it out later, or do I want to, from the start, download each post as it’s own file? The time to download shouldn’t change, and if I do it right, I could script it to check if the date stamp on my downloaded file was older than the post date in WP. That means I could have this logic:

    if ( ! post file exists || post file date < post datestamp ) {
        download JSON for this post
    }
    

    That made it an easy win. Let’s split away from the original plan. Now my goal is to extract all the posts from my WP site in JSON format.

    Remember the goal here is to run a static website with WP. There are plugins that convert WP to static HTML, which you can then use to power a site, and this isn’t a bad idea.

    How To: Get all the posts from a WP site via the JSON API?

    This sounded easy. http://local.wordpress.dev//wp-json/wp/v2/posts listed posts, and the v1 comparison chart says that you can list all posts, it stands to reason that I can easily get all my posts.

    In a way, this is a WordPress problem. WP doesn’t want you to show all posts. It would make your site very slow if you had, say, 10,000 posts. Which means that the claim that the JSON API can lists all posts is true, it just doesn’t do them all at once.

    I happen to have 40 published posts on my test site, so when I GET with this URL, it loads all of them: http://local.wordpress.dev//wp-json/wp/v2/posts?per_page=100

    But that isn’t sustainable. And the old trick of making per_page equal to -1 didn’t work.

    I did determine that the JSON API actually knows what the amount of posts is!

    JSON reports X-WP-Total which, in my case is 40

    The header “X-WP-Total: 40” is what I needed. Of course, that is rather weird to get. It means to get all the files, I have to write ‘something’ that does this:

    1. Get http://local.wordpress.dev//wp-json/wp/v2/posts and parse it to get the value of X-WP-Total
    2. Get http://local.wordpress.dev//wp-json/wp/v2/posts?per_page=X-WP-Total

    Okay. So how?

    Well remember how I mentioned a plugin that made a static site already? I was talking about things like Really Static. Save a post, it saves the JSON file! Why not write this plugin?

    Why not use “Really Static”? Well I don’t want to have WP doing more than be my content generator. I want to separate content (the blog) from WP. And that means I will end up writing a plugin…

    Am I In Too Deep? Or Am I Over My Head?

    So far, this has been an incredible amount of work. It’s been a lot of two steps forward and three steps back, over and over and over. And yes, it’s been very frustrating. I’ve given up many times and, if my posts about multiple approaches are any indication, I’ve deleted and restarted many, many times.

    And I have to be honest here… I’m giving up on this overly ambitious plan right now.

    This marks two major failures (three if I could how insane the entire ‘use Jekyll/Hugo to run a gallery’ was). First, I’ve failed to sensibly convert JSON files to MD in a scriptable and reproducible way. Second, I’ve failed to export JSON from WordPress in a simple way. Both those failures can be worked around. I can build a plugin that exports the JSON. It’s not trivial, but having done similar things I’m sure I can do it. The issue is ‘is it worth it’? And right now I think the answer is no.

    I’m back to the drawing board right now, sketching up new plans and ideas. I want to eliminate as many steps as possible. I’d like to leave WordPress alone, let it be WordPress, and similarly let my static generator be static. These failures have taught me more about the interdependencies than I expected, and I’ve learned more from them than I may have if I’d had outright success from the start.

    While I’m starting over, again, I feel hopeful and less ‘I hate you, JSON’ than I thought I would. I now understand things more clearly and I see how I made things far, far more complicated for myself.

    The future of this project is, weirdly, bright.

  • Mailbag: Can I Track Issues with Github Like WP Support?

    Mailbag: Can I Track Issues with Github Like WP Support?

    How do I see all my Github issues for all my projects?

    I was asked this at a WordCamp by someone who had seen my ‘how to get into Github’ series with Carrie Dils.

    If you’re tracking the WordPress forums, https://wordpress.org/support/view/plugin-committer/YOURID will list all of the support requests and reviews for any plugin you have commit access.

    Not a comitter, just someone listed as an author? Use https://wordpress.org/support/view/plugin-contributor/YOURID

    But Github? Turns out it’s super easy!

    https://github.com/search?q=is%3Aissue+is%3Aopen+user%3AYOURNAME&type=Issues

    Basically you can go to the Github Search Page and put inis:issue is:open user:ott42 and you’ll see them all! There’s no RSS feed mind you but you do get emails for all those so you should be okay.

  • Representation of Code

    Representation of Code

    There’s a great many things to be learned from the drama of the recent Code of Conduct proposal. A great many people have demonstrated why one is needed, why ‘Just act professional’ is not a tenable long term solution, and why some people are exactly the sort of person who will fall afoul of the new guidelines.

    After all, who would really argue that these guidelines are ‘bad’:

    Examples of unacceptable behaviour by participants include:

    • The use of sexualized language or imagery
    • Personal attacks
    • Trolling or insulting/derogatory comments
    • Public or private harassment
    • Publishing other’s private information, such as physical or electronic addresses, without explicit permission
    • Other unethical or unprofessional conduct

    But that isn’t what it brought to my mind. The needs of a Code of Conduct are myriad, and the phrasing is complicated. It should be, at once, easy to understand and abide by, while being comprehensive and difficult to abuse. It should prevent rules-lawyers from gaming the system and min-maxing the hell out of their abhorrent behavior, while still permitting people to speak their mind. Anyone who’s played a table-top game with ‘that guy’ knows that pain.

    As I tweeted:

    Today PHP is learning that individuals bear the weight of representation of their groups.

    This is something everyone in a minority group has known for a long time. Not to throw politics into the mix, but compare the different reactions to the Baltimore protests of 2015 and the Malheur National Wildlife Refuge occupation of 2016. Consider the way some people are painted as ‘he should have known better’ and others are just ‘misunderstood.’

    One of the things I hate about WordPress is that I am now and forever representing it. Yes, forever. If WordPress is still around in 30 or 40 years, I will be representing it. If I leave it or say “Well I hate X” about it, I will reflect back on WordPress and my words will likely be taken and twisted around and contorted to mean something.

    Now and forever, I represent things that I am and things that I do. If I act like an ass online, it reflects on my company. A coworker of mine told a joke on Twitter and was subjected to attacks from someone who found it offensive. Whether or not the joke was tasteless, it reflected on him and our company. It doesn’t matter if the company endorsed it or not, nor does it really matter what our CEO may or may not have said regarding the situation. It matters that we represent myriad aspects of our life all the time.

    To give you a short list, I represent women, lesbians, LGBT as a whole, married people, childless families, Jews, Californians, Chicagoans, Canadians, Americans, caucasians, and please double the list and add ‘in tech’ to that. We haven’t even touched on things I work on and participate in the community like WordPress, Wikipedia, MediaWiki, Ada Camp, Hugo, Jekyll, PHP, ZenPhoto, etc etc and so on and so forth. Oh and DreamHost, the bank I used to work for, and possibly the guys I worked for before that. Then there are the games I play (D&D, Pern, WoD, etc).

    I don’t get to ‘stop’ being those things. Even though I’ve not played a MUSH in almost a decade, to some people I will forever be known as a MUSHer. And some people may change their opinions on me just hearing that. But also some people will say “Oh, she acts like that because she grew up on a MUSH.” And worse, “If she acts like that, then all MUSHers are assholes.”

    Look. We know it’s stupid. We all know that a person isn’t the sole representation of a thing, and yet we spend our lives looking over our shoulders because we will now and forever be what we are identified as being.

    It was hard for Leonard Nimoy to be Spock.

    Nimoy is so synonymous with his half-Vulcan alter ego that fans revolted upon seeing the title of his first memoir, “I Am Not Spock,” despite Nimoy’s insistence that behind the name was merely a nuanced explanation of the distinctions between himself and his character.

    When we think of him, we think of Spock, the role that made him famous. And it took him years to come to grips with understanding that he was now and always will be Spock to many of us. It’s a hard thing to accept, that you will forever represent yourself, a job you had for three years and a handful of movies, and that no matter what, whatever you say will reflect back on that.

    WordPress, PHP, those are our Star Treks and we are Spock.

    Live long and prosper.

  • GPL Isn’t Protecting You

    GPL Isn’t Protecting You

    Some days I know my plugin reviews are going to wreck me. January has had a lot of complaints from people about aspects of the GPL. Specifically they wanted to know how to protect themselves with the GPL.

    The truth is the GPL is not protecting anything except the right of the next guy to take your code and do stuff with it. And that terrifies people.

    I’m not entertaining a discourse on the merits or legality of the GPL here. Those comments will be deleted. Simply put, a requirement of the WordPress.org repositories is that to be hosted there you must be GPLv2 (or later). At that point, every other argument is moot. Your code has to be GPLv2 to be in the repositories. End of story.

    Okay. So what’s there left to discuss about protecting yourself and your code? Three things: Trademarks, copyright, and theft. Here we go.

    Trademarks

    GPLv2 doesn’t protect your trademark, but that doesn’t mean your trademark isn’t protected. While any image you put in your WordPress theme or plugin has to be given as GPLv2 compatible, that doesn’t void your trademark. A freely offered image that is trademarked (say, the WordPress logo) can be used in your plugin, but it comes with restrictions after all. The inclusion of the SVG of the logo in GPL code doesn’t change that.

    One of the things that changed in GPLv2 and GPLv3 was related to this. Remember, GPLv2 allows all code that does not include any restrictions that were not already in GPLv2. As long as license was as free (or freer) than GPLv2, it was deemed to be GPL-compatible (see the WTFPL). The issue with that is some licenses were very easy to comply with but had clauses like you couldn’t use certain trademarks. This caused confusion, as it was read as a restriction. The thing was that it wasn’t! Regardless of what the license said, you never had permission to use the trademark.

    This is good for companies. You can trademark your logo and, if someone takes it redistributes a fork with the logos still in it, they’ve violated trademark law. And you can protect yourself there. I suggest you read Joomla’s post on the matter of Trademark protection to get a better idea of how it all works.

    Copyright

    Copyrights are another thing that the GPL doesn’t protect. Except it does.

    GPLv2 and GPLv3 are both copyleft:

    To copyleft a program, we first state that it is copyrighted; then we add distribution terms, which are a legal instrument that gives everyone the rights to use, modify, and redistribute the program’s code or any program derived from it but only if the distribution terms are unchanged. Thus, the code and the freedoms become legally inseparable.

    What does that mean? Your copyright is yours. By the act of writing code, you own the copyright (with some exceptions, like if you’re hired to write the code). When you contribute code to an open source project like WordPress, you STILL retain the copyright unless you give it away, but the license is whatever the project’s license is. Most of the time this is fine, but as I recently saw with Hugo, this can be problematic when a project wants to change their license. Hugo had to get permission from every single person who had contributed.

    This is, by the way, why WordPress will probably always be GPLv2.

    One way around this is to require everyone to waive their copyrights in order to contribute. I believe DotNuke did this. Whomever owns the copyright, if the code is still licensed in a way that allows for free distribution then nothing’s really changed. The code is still open.

    Of course, then there’s the jQuery Foundation does with their Individual Contributor License Agreement – In order to contribute to jQuery’s code or website, you have to sign that and provide a valid email. This gives them a way to contact everyone and also makes sure you understand what you signed up for. WordPress just has a checkbox when you submit your code to remind you that you’ve given it up.

    If you’ve ever looked at the jQuery Foundation License, you may have noticed this line:

    You are free to use any jQuery Foundation project in any other project (even commercial projects) as long as the copyright header is left intact.

    This is not imposing a restriction more than GPLv2. See the bit in trademarks. Legally you had to do that anyway, they’re just reminding you not to be a tool and leave this simple line in:

    • Copyright jQuery Foundation and other contributors

    I bark at developers a lot for removing the license headers from javascript files. Don’t do it. You’re violating copyright and, if the original devs complain, you’ll lose your code until you fix it. Which is the point here. Copyright exists beyond GPL, so the fact that it doesn’t actively protect it doesn’t make it not enforceable.

    Theft

    I don’t mean legal here.

    A lot (a lot) of people argue that their plugin should be able to be encrypted or obfuscated to make it ‘harder to steal.’ I hear that about once a week, if not more. And my answer to all of them is “Not if you want to be hosted on WordPress.org.” WordPress.org has an ‘above and beyond’ understanding of the idea of distribution and allowing people to edit. It’s felt that the spirit of GPL means your code should be easy for someone to read and fork.

    I said a dirty thing there, I know. The ‘spirit’ of the GPL is probably causing some of my friends to roll their eyes so hard they’ve got migraines. Sorry about that. But it really is the one time I use it. When I say the ‘spirit’ I mean the intention of the license and it’s application to WordPress.org’s repositories only. Right or wrong, agree or disagree, it’s straightforward. If you want to have your code in the .org repos, it’s gotta be human readable.

    There’s a simple reason for this. The GPL Copyleft is all about freedom and keeping that freedom alive. The Copyleft says that anyone who redistributes the software, with or without changes, must pass along the same freedom to further copy and change it. In order to allow people to change the code, we want it to be human-readable. We want people to be able to look at your code and say “Oh I understand how this works. I will improve it!” When you take away, or overly complicate their ability to do that, we feel you’re intentionally impinging on that freedom. You’re trying to find a way around it, basically.

    About the only time I’ve heard someone not claim they were smushing the code up to protect it from being stolen is when someone has smashed their javascript into a p,a,c,k,e,d() type compression file. I actually hate those files. Javascript is hard enough as is! Stop making it harder. Plus I need to tell you something really important.

    While minifying your javascript will improve a website’s performing by decreasing the load time, it doesn’t make it run any faster for the majority of code out there. Of course there are situations (large libraries or limited devices) where this is not the case, but trust me here. Your 7 line javascript is not going to be significantly faster just because you compressed it. I advocate using the .min version of common libraries, but unless your code is huge, leave it alone and let other people see how to edit it.

    Bonus: Distribution

    GPL comes into play when your code is distributed. If I put my code on my server and never give it to anyone, it’s not been distributed so licenses don’t really matter. As the GPL FAQ explains:

    But if you release the modified version to the public in some way, the GPL requires you to make the modified source code available to the program’s users, under the GPL.

    It’s the big if there. What constitutes distribution? Is your browser downloading a javascript file in order to run my site distribution? Is handing you a zip file distribution?

    I always recommend people play it safe.

  • Mailbag: Why Do Cannonical URLs Mess Me Up?

    Mailbag: Why Do Cannonical URLs Mess Me Up?

    This came from a DreamHoster who said it was okay to blog it if I didn’t mention them by name. They were embarrassed about the mistake.

    Why was my site having a redirect loop, and why did changing the domain to force www in panel fix it?

    The ‘panel’ being mentioned here is DreamHost’s Panel. We don’t have cPanel, we have PANEL, and it’s our special, 100%, tool. In there, you can edit your domain settings. One of the settings has to do with your domain settings. Simply it asks “Do you want the www in your URL?”

    DreamHost Panel: Do you want www or not?

    In general I check “no” because I’m a no-www kind of person. I don’t like it.

    The issue this person was faceing was that you’d go to http://www.wordpress.dev and everything was fine, but his site went all over the place weird when you went to

    In order to fix that person’s website, I changed “Leave it alone” to “Add WWW” (their preference, not mine).

    Why did that work? Let’s understand the issue first. What was happening was that your server generally doesn’t care if you visit http://www.wordpress.dev or http://wordpress.dev because it knows that they both mean /home/user/wordpress/public_html/ (or whatever). But! Some servers (like DreamHost) let you prioritize and redirect. If they don’t, you can use nginx/htaccess to force www or not. As far as the server cares, none of this matters. If you force no-www and someone goes to www, they get redirected and everyone’s happy.

    Except WordPress. WordPress is picky. WordPress has special settings:

    Your home and site URLs in WP

    Recognize that? If you have WordPress set to use www and you go to the non-www URL, it won’t redirect you. It will, however, force all internal links and generated paths to have the www. The same thing happens if you don’t force https for your site. WordPress will still serve http://wordpress.dev but all the links on that page would be to https://wordpress.dev and so will your stylesheets and javascript.

    This may make you think that WordPress doesn’t care. You’d be wrong. WordPress cares deeply, and it shows up when you go a URL like http://wordpress.dev/i-am-fake/ – assuming you don’t have a page named that. If you’ve forced www, WordPress will look for that page and do a 404 redirect. Suddenly you’ll have www!

    Except in some cases, what happens is WordPress accepts the URL you gave it and shows without the www. Then it remembers it should have the www and redirects to that. Only it knows you told it non-www and redirects to that. And you get an endless 301 redirect loop. And you cry.

    If you force www in DreamHost’s Panel and you force it in htaccess and you set it your settings, this still may not be enough! You may have to do a search and replace to change all the non-www urls to www!

    Amusingly, when WordPress 4.4.1 dropped, we found a rare race condition with http and https and WooCommerce, born from a simple mistake.

    Woo lets you force http on post-checkout pages

    Everyone I know who looked at that went “Oh, right, if my site has https in the home and site URLs, maybe I shouldn’t try to force http here!” But Woo lets you shoot yourself in the foot. Or at least they did. There’s a ticket open where I suggested perhaps they prevent that.

    And for what it’s worth, I totally get how these things happen. You set up your domain and your WordPress site and your http/https settings at different times. It’s understandable that in 2013 you didn’t have SSL, but you added it in 2014. And at that time, you only put SSL on your checkout pages (right?) and since you wanted your cache to work better, you said “no https for checkout’ed!” That’s perfectly sane and logical. But since LetsEncrypt and HTTPS Everywhere became big in 2015, you changed the whole site over and simply forgot about that one, teensy, toggle…

    At least, until someone got that horrible 301 redirect on checkout.

    Like I told the people I fixed, don’t kick yourself over this. You have a lot of moving parts and the secret is understanding how each bit works. If you know that you set Panel properly, and .htaccess properly, and site/home URLs properly, and it only happens on checkout, you can zero in on what’s left and debug that.

  • Why CDN Media Needs a Plugin

    Why CDN Media Needs a Plugin

    I wanted to write a blog post for work (something I try to do once a month) so I thought “I should write about using a CDN for images. I wonder if you can do this without a plugin…”

    One hour later, and 1200 words, the answer is no. You cannot.

    My initial goal was to move media files (and only the media) from http://example.com/wp-content/uploads/ to http://static.example.com/wordpress/ on DreamObjects. I’ve written a plugin that does that, but to my frustration, I found you cannot do this without a plugin for one incredibly simple reason.

    But before the big reveal, let’s break down, in simple terms, what I would actually need to do in order to move the uploads. My two assumptions are that I already have a WordPress powered site (check) and I already have DreamObjects (check)

    1. Setup a bucket on DreamObjects (or AWS whatever) to house my images, and give it a CDN alias.
    2. Copy all the images to the bucket.
    3. Change the Upload URL to http://static.example.com/wordpress/ (my CDN alias for the bucket).
    4. Edit all posts and GUIDs to the new URL.

    The thing is, I can actually do all of that!

    Setup a Bucket on DreamObjects

    Log in to your Panel, click on Cloud, go to DreamObjects, and create a new bucket in DreamObjects. I called my domain-static because that’s easy for me to remember. Static content lives here. Once you have your bucket, click on the “Change Settings” link and add an alias of “static” to the domain you’re hosting all this on (example.com in this example).

    You can name your alias anything you want. I just picked static because I knew I wanted my URLs for images to be http://static.example.com/wordpress/2016/01/happynew.jpg and this makes it simple. I like to leave my CDN available for more than just WordPress, and doing this will let me have more folders like wiki or gallery.

    Next, scroll down to “DreamSpeed CDN” and turn on CDN Support. You’ll notice that tells you a special URL for CDN:

    Connect to the accelerated DreamSpeed CDN version of this bucket at: examplecom-uploads.objects-us-east-1.dream.io

    Don’t worry! You can use your custom URL too. You don’t have to, but most of us want to, to feel special. In order to use your custom alias that we just made, scroll up a little and check the box for ‘CDN’ on your alias. Press save and you’re good to go!

    Copy all the Images

    Set the bucket public first!

    Just trust me, here. Okay? Good. Set the bucket public and then upload all the images. I used Transmit. Cyberduck also works.

    Change the Upload URL

    This part was scary.

    We need a moment of history first. Up until WordPress 3.5 this was actually pretty easy to do. You went to your media page and you changed things. As of 3.5, WordPress decided that this was more trouble than it was worth. Too many people were accidentally doing silly things, breaking their sites, and it was too dangerous. So they removed the part of the screen that let you change this.

    I have issues with this, since for what I want to do, it makes it a hassle. But given the flaw in my great plan, I recognize the change as one that protects people who know less than I do.

    Using a plugin to restore this missing setting would be the easiest on many levels. And there are a few plugins that do this but I like Upload Url and Path Enabler. It’s simple and to the point.

    Of course, I love wp-cli and we have it on all our servers at DreamHost, so this command is similarly awesome:

    wp option set upload_url_path http://static.example.com/wordpress

    The last option for this is the secret WordPress page called “All Settings” — This is hands down the most powerful and dangerous page in all of WordPress. It lists all your options and settings that you have in the database. And yes, you can edit many of them in your browser at http://example.com/wp-admin/options.php

    Go ahead. Take a look. It lists a lot of things, most of which you should never, ever, ever, touch. If you were going to use this, search for upload_url_path, change the value from empty to http://static.example.com/wordpress, and press save.

    Edit All Your Posts

    This is a sucky part. You have to edit all your posts now to move the existing images. This is because those changes you made are only for images going forward. Which is really cool and means you didn’t break anything so far. But WordPress hardcodes the paths to images in your posts (for many reasons) so you need to change all of them.

    If you know how to use the command line, this is actually really easy:

    wp search-replace http://example.com/wp-content/uploads/ http://static.example.com/wordpress/

    Run that command and WP-CLI will magically fix all your posts.

    If you don’t want to use the command line, I recommend Velvet Blues Update URLs.

    Done!

    And to be clear on things, this worked perfectly. My media library showed properly, all my images showed, and everything looked perfect. So I decided to run some basic tests and upload new images…. and that’s where my house of cards fell apart.

    You cannot save files to another server.

    Actually You Can… if you sudo

    Now I have to tell you something. I lied. You totally can do this. The problem is that it’s hard and requires mounting your bucket as a local filesystem so that it would be available via the file-path of the server. You see, you could save files to /folder/location/wordpress/ anywhere on the server. I save mine to /home/user/public_html/static/ on one set up, and I have a static domain (domain-static.com) that runs from that folder.

    What that means if I had a location I could access, I could tell WordPress to save there, making it ‘local’ enough to trick it. You can do this with tools like s3fs-fuse, however they’re incredibly complicated and weird for the layman. And that right there was my problem.

    If you’re trying to present something as ‘Without a plugin’ then you don’t want to make the tradeoff be ‘..but with sudo access to a VPS.’ That’s unreasonable.

    And it’s why, right now, if you want to use a CDN for your media in WordPress, use a plugin.