Half-Elf on Tech

Thoughts From a Professional Lesbian

Author: Ipstenu (Mika Epstein)

  • One Direction: Sanely

    One Direction: Sanely

    In my ongoing saga of moving from MediaWiki to Jekyll, I decided to be smart and rename all my URLs.

    Stop.

    I know that’s the worst thing you can do. Please put down the pitchforks. I didn’t do this without redirections and I didn’t do it without deep thought. You see, the issue with MediaWiki is that it was a pretty flat file representation of the site. This doesn’t have to be the case. You can choose to put pages as sub-pages on MediaWiki very easily, but few people do. I didn’t. That means I had around 1000 pages that, in Jekyll land, would all be in one folder. And that sucked. Like I mentioned before, I made Collections.

    This meant I was moving from example.com/PAGE to example.com/folder/PAGE/ (and yes, the backslash matters, MediaWiki doesn’t do that). Now, from a structural standpoint, this makes a lot more sense. You want to have a collection of interviews, you have example.com/interviews/year/interviewname/ and that’s ridiculously easy to understand. But. When you’re moving from no structure to some structure, you have to accept a bit of a loss.

    So here’s how to redirect sanely:

    1. Make a list of what has a direct relation to a new page
    2. Look at your page visits to see what’s hit the most and make sure that’s redirected
    3. Have a catch-all at the end

    That’s it! Three simple steps to do it. But how did I do it?

    On the Wiki, I had a whole subsection called “Encyclopedia” which had all my internal documents like the about page, the policy pages, and so on and so forth. Those were all moved to the WordPress blog. Most had a new page, but the category itself did not so I added this the .htaccess in root:

    Redirect 301 /wiki/Category:Wiki /
    Redirect 301 /wiki/Encyclopedia:About /about/
    Redirect 301 /wiki/Encyclopedia:Policy /policy/
    RewriteRule ^wiki/Encyclopedia:Copy(.*)$  /copyrights/   [L,R=301]
    RewriteRule ^wiki/Encyclopedia:Terms(.*)$ /terms-of-use/ [L,R=301]
    RewriteRule ^wiki/Encyclopedia:(.*)isclaimer /disclaimer/ [L,R=301]
    

    That’s all incredibly straightforward for .htaccess rules. The first three are one-to-one direct links and the last three are with variables to handle URL strings like “Terms_Of_Use” and “Terms_of_use”, both of which were Wiki-forwarded to the correct “Terms of Use.” Similarly, I wanted to redirect “General_Disclaimer” and “Disclaimer” to one page, simplifying things.

    This pattern of one-to-ones continued on through my .htaccess. Pages that I could link like that I did. But then I hit on a couple big sections, the Interviews and News Articles. Those I had, for years, broken apart into pages by year. So I cleverly used tricks remembered from changing my WordPress date permalinks to do this:

    Redirect 301 /wiki/Interviews /library/transcript/
    RewriteRule ^wiki/Interviews_\((.*)\)$ /library/transcript/$1 [L,R=301]
    RedirectMatch 301 /wiki/(News|News_Articles) /library/news/
    RewriteRule ^wiki/News_Articles_\((.*)\)$ /library/news/$1 [L,R=301]
    

    The main URLs were directed to the new main locations, but the per-year ones were sent, logically, to their new year locations. But that was the easy part. When I moved things over, I got rid of ‘character’ pages (which I had only sporadically updated anyway) and I wanted to combine a lot of the redundant pages:

    RedirectMatch 301 /wiki/(The_West_Wing|West_Wing|west_wing|ww|Jed_Bartlett) /library/show/west-wing/
    RewriteRule ^wiki/The_West_Wing_\((.*)\)$ /library/show/west-wing-episodes/ [L,R=301]
    

    That’s starting to look a lot better. I did a lot of those. I tried to make them as dynamic as possible, but there were limits. In the end, I had about a dozen popular links I had to do manually. I don’t like that, but that’s the world I got myself into. I wanted to be able to redirect news and interviews to at the very least their year page, but as it turned out, I used the same naming conventions.

    Redirect 301 /wiki/Yahoo_News_(01_January_2000) /library/news/2000/yahoo-1/
    Redirect 301 /wiki/EOnline_(01_January_2011) /library/transcripts/2011/eonline-1/
    

    See the problem? There’s no way to really point those around. I played with a lot of options before I ran a search my recent traffic to see what pages were popular that people were going to in the /wiki/ folder and redirected them as best I could.

    Finally I had my fall back:

    RewriteRule ^wiki/(.*)$ /where-has-the-wiki-gone/ [L,R=301]
    

    This is the last rule. If anything gets through the others and down to this one, it sends them to a new page that explains where the wiki went and links to the popular pages.

    The most important thing to remember in all this is to put things in order. Your .htaccess is a top-down file. It starts at the top, it processes rules in order, until it’s done.

  • Quick Notes on Ruby and Jekyll

    Quick Notes on Ruby and Jekyll

    I feel like I should be writing about Once Upon A Time at this point…

    Let’s take a moment to talk about our stack here.

    • Ruby is a dynamic, reflective, object-oriented, general-purpose programming language.
    • Ruby libraries are bundled into gems.
    • Jekyll is a gem that can publish static websites.
    • Bundler lets you list all your dependencies required for the project you’re working on.
    • A Gemfile is a file in which we can list gems for the aforementioned dependencies.

    Still with me?

    This matters because you can use a Gemfile to define your standard libraries for a Jekyll site. The general idea is that you install Bundler:

    $ gem install bundler

    Then you make a Gemfile in your Jekyll folder:

    source 'https://rubygems.org'
    
    gem 'jekyll', '>= 3.0.0.pre.beta9'
    gem 'jekyll-oembed', :require => 'jekyll_oembed'
    gem 'jekyll-last-modified-at', :require => 'jekyll-last-modified-at'
    

    What this does is it defines what version of Jekyll I want to use and some of the gems I want to use. For example, if I wanted to add Jekyll Compose to all the users of my Git repository, I would add this:

    group :jekyll_plugins do
      gem 'jekyll_compose'
    end
    

    Now all they have to do is run bundle after their git pull, and they get the new requirement.

  • Mailbag: But You Can’t Post Mobile!

    Mailbag: But You Can’t Post Mobile!

    This has been marked as the biggest downside to using Jekyll. Once I started telling people I was moving the Wiki to Jekyll, a great many of them were cautionary about this issue.

    How do you post from your phone or iPad?

    The answer is that I don’t.

    I won’t lie. Mobile posting is a pain. Since I don’t have Jekyll running on my server, I can’t edit a file there and regenerate. If I had that it would all be a lot easy. In my case, since I’m using it as a non-blog it’s never the place I need to post mission critical things. Besides, if you’ve ever tried to keep your pretty formatted WordPress site updated when you want a custom crafted excerpt and a featured image, from your iPad, I gotta tell you … it sucks.

    And that’s WordPress, something that has a dedicated, usable, app for iOS. WordPress is also pretty okay in mobile. People like Ryan Boren spends a great deal of time caring about mobile usage. WordPress has gotten slower on the admin side in the last decade, but it’s gotten more responsive and agile at the same time.

    MediaWiki not so much. Editing should be a lot easier, seeing as there’s no ‘admin’ back end to mess with things, but for whatever reason MediaWiki was always terrible on my iPad. It was next to unusable on my iPhone. Even with their default themes (remember, with MediaWiki you see the front end theme on page edits) it was dodgy.

    Furthermore, what did I need to post? This is a wiki-type documentation site. It is rarely, if ever, updated on the fly. It houses long form news articles. There are recaps of TV episodes, explanations of humanitarian events, and reports of events. There is no live blogging. There is no quick off the cuff journaling. It’s storytelling.

    So here’s my ‘mobile’ workflow.

    1. Write the content in something, probably Byword
    2. Email it to myself
    3. Probably rewrite the whole thing in longer form, with design and fancy things
    4. Post

    I could probably streamline that better if I saved from Byword to Dropbox and had that automatically copy over (suggestions welcome), but I don’t really write from my iPad that much. I usually send myself an email with six or seven links and a note to ‘Import these things…’

  • Jekyll Table of Contents

    Jekyll Table of Contents

    One of the cool things about MediaWiki, about the only thing I missed, was the built in table of contents display. With Jekyll, since this was a static sort of site, you would have to tell it ‘When you build this page, include a table of contents.’

    And I found a brilliant Jekyll plugin, Jekyll ToC Generator, that added in a beautiful jquery based table of contents with a click back to top feature. But there was a problem. When I installed it and ran a build to test it, my Jekyll site took nine times as long to build.

    In order to generate a Jekyll site, you run the command jekyll build and, on Jekyll 3.0, that gives you the output “done in 8.493 seconds” or so on. Now, if I do a full build on a site I’ve cleaned (there’s a clean command you can run to scrub the site and ensure you get a clean rebuild), it generally takes about a minute. That’s to build a thousand files with a lot of weird trickery. If I’m just rebuilding the changed files, it takes about 10 seconds. Much more reasonable.

    With the ToC Plugin, it took 98 to 100 seconds, every single time. Right away, I knew why. I had included a plugin that had to check every single page on the site on that rebuild, see if it needed a table of contents, and then build the page. Of course that took a long time!

    I’m always talking about needs and wants when I work on websites. It’s a basic principle my high school drilled into me. Understand what you need and how it’s different from your wants. Don’t compromise on needs. Well, I knew that I didn’t need a table of contents, not on every page, so it clearly had to be a ‘mostly want.’

    By contrast, having my site build quickly was a need. A fast build ensured less overhead, less weight, and less time spent. Time is a massive factor in websites. The rendered site has to be fast for users, this much is obvious to everyone. But having your build be fast means you, the site maintainer, spends less time on the parts that don’t make the site better, freeing you to develop and write.

    Also speed is something Jekyll wants to work on. The build different between the 2.3 version of Jeykll and the 3.0-pre beta, is incredible. In 2013, a site with “362 articles with 660 words in average” took around 10 minutes for a full build. I have double the articles, about the same amount of words, and it’s a minute for a full build. It’s faster on my faster laptop (duh).

    The decision tree for Jekyll is more obvious on build than the same one is for WordPress (or MediaWiki) on render. The basic concept is simple. The more complex your site, the longer it takes to generate pages. For WordPress (or MediaWiki, or Drupal, or Joomla, etc etc), the render happens when someone visits your site. For Jekyll and other static site generators, the render occurs when you build the site. That means with Jekyll I can see right away, before I get close to deployment, which means I make the decisions well before the ‘stage’ step of my deployment process.

    What’s more important? The complexities that make your site personal or a fast build?

    Here’s an example from a Jekyll discussion on the matter. Someone had the following code in the templates, which made the date output rather pretty:

    <span>{% assign d = page.date | date: "%d" | plus:'0' %}
        {{ page.date | date: "%B" }} 
        {% case d %}
            {% when 1 or 21 or 31 %}{{ d }}st
            {% when 2 or 22 %}{{ d }}nd
            {% when 3 or 23 %}{{ d }}rd
            {% else %}{{ d }}th
        {% endcase %}, 
        {{ page.date | date: "%Y" }}
    </span>
    

    But that had to run on page builds, which naturally was going to make a site slower. One of the ways Jekyll has improve this was to introduce incremental updates. Only update the pages that need updating. That is a big “baboom!” moment and it let me run the plugin jekyll-last-modified-at (which spits out a last modified date on pages) without any performance hit except on the clean build. Since that only gets called when a page is built, and a page is only built when it changes, it’s a massive improvement for me.

    What does all this have to do with the table of contents?

    Once I pushed it into a ‘want’ and not a ‘need’ I opened my mind to other possibilities. I stopped looking for a Jekyll or Ruby or Liquid based table of contents, and I asked myself “Can Markdown make a table of contents?”

    Markdown is a ‘language’ like HTML that is actually faster to write in than raw HTML but can be read, rendered, and output as HTML. I’m a big fan of HTML and part of why I picked WordPress back in the beginning was that I stumbled on a post where Matt Mullenweg talked about how he didn’t like bbCode and didn’t want it in WordPress. HTML was something we knew. Why make people learn something new?

    It wasn’t until I started blogging more on my iPad and phone that Markdown made sense. Now I’m quite the fan. But I knew that I didn’t know a whole lot about Markdown. I did know that Jekyll used a flavor called ‘kramdown’ (all lowercase) so I read up on that and found that kramdown has a built in built in table of contents generator that was incredibly easy to implement.

    * TOC will be output here
    {:toc}
    

    It’s not something I want (or need) on every page, so I just put that on a few pages. No real overhead added and it’s easy enough to style with CSS. Suddenly I have my cake and I can eat it too.

  • Deploy Jekyll Without Ruby

    Deploy Jekyll Without Ruby

    This is a bit of a lie. I do have Ruby, it’s just on my laptop.

    I don’t have it on my server, though. I have my git repo there, though. I could, but there are a couple reasons I don’t, and because I don’t, I can’t just run a jekyll build on my server. I’m not the only one with this particular issue. A lot of people on shared hosts can’t do it, for example. And people on cloud based tools can’t really either.

    Option one, which is very common, is what I have been doing. I added _site (the Jekyll output folder) to Git and I copy that over on a post commit hook. For what it was, that worked just fine. It only ran when I did a git commit, and if I wanted to work on a version I could totally do that in a branch, edit it, and bring it back in without accidentally deploying things.

    But option two would be rsync and that appealed to me more.

    I found the gem I was looking for eventually. It’s called (simply) Jekyll deploy and you add it to your Gemfile with this:

    group :jekyll_plugins do
      gem 'jekyll_deploy'
    end
    

    Then run the bundle command:

    $ bundle

    Now you have a new command called deploy which runs first a build and then it deploys based on the configuration options you put in. In my case it’s an rsync deploy, but you can do Git too. There was just one problem with it. The build every time made it such that my site would rebuild every time, which meant the rysnc would always be 100% new and that was more traffic than I really wanted.

    So I did what you always do here and I made a fork of Jekyll Deploy and changed my Gemfile to this:

    group :jekyll_plugins do
    	gem 'jekyll_deploy', :git => 'https://github.com/ipstenu/jekyll_deploy.git', :branch => 'develop'
    end
    

    Now my deploy only runs a deploy.

    A better solution would have been to put in some options and create jekyll deploy --build to allow me to run a build first, but I actually kind of like having them separate.

    The only question left was if I should keep _site under version control. I decided that I should, since the git repository would keep the file dates under control, assuring me that only the files I changed would be pushed with a deploy.

    I will note that the only reason it’s so simple for me is that I have passwordless SSH set up, where I don’t have to put in my passwords when I connect from a trusted computer. And since I only have this installed on a trusted server, and if I didn’t, I’d have to have a password to get access to the git repo anyway, I felt it was safe.

  • App Review: iStat Menus

    App Review: iStat Menus

    It’s a simple question. If the meeting is held at noon Pacific time, what time is it UTC? The answer is 1900 hours.

    The reason for the question is complicated. I work with people around the world. My family lives in a multitude of timezones, some across the date line. I travel a lot. I need to know when ‘now’ is, and I need to know when ‘now’ is for someone else all the time.

    Enter iStat Menus for Mac.

    It’s not actually meant for what I use it for. iStat Menus is to help you make a menu item on your Mac that shows you some interesting stats. I can see, at a glance, how strong my wifi really is, or my computer’s temperature (I’m on a MacBook Air, so this is important). I can look at how much memory I’m using to quickly see why things are slow. It gives me quick links to deep dive into things. It’s wonderful when I’m testing new apps and I can see that, yes that one is slow slow slow.

    An example of iStat Menu showing me my CPU details

    But the side benefit for me is how it replaces the Time and Date Menu in my Apple menu bar. When I click on the time, I get this:

    Time and Date menu replacement in my toolbar

    I get my month at a glance, a list of everything for today (including birthdays which I blocked out for you) and then it lists what time it is now in various place. If I hover over each time, I get more details including a Mercator map showing where daylight is right now and relative other places people care about. For $18 I’m able to keep track and know “Oh, maybe I shouldn’t ping someone on social media when it’s 2am for them…” For that alone it would be worth it, but the rest have become invaluable to debugging why my laptop was rebooting randomly.

    If you just need the basic stats, iStat Mini is pretty brilliant. And it’s free.