25
Apr 13

Time

Recently I built a scheduling application for my work web site. It’s pretty awesome.

Anywho, I had to learn about time, and how it’s handled. Going into this, I always thought that if I were a systems administrator all over again I would have my machines all run in GMT to eliminate timezone problems. Now that I’ve learned, I know it’s now called “UTC” and it’s still a really really really really really good idea to do as much as you can in UTC and only present localized times only when the user sees them.

I learned about how time works in four tools: Postgres, Python, Django, and Javascript.

Postgres

Totally sweet support for time. You can say

generate_series(date(X at time zone 'UTC' - interval '120 minutes'),
                date(Y at time zone 'UTC - interval '120 minutes'),
                '1 day'::interval)

and get all the dates between X and Y. Everything about datetimes is super duper good.

Python

datetime library is pretty good. It is a little unfortunate (although understandable) that you need a non-Python library (usually pytz) to localize times. (This is because Python does not want to handle the political problems (literally) of keeping timezone definitions up to date.)

Notably, I built a small library called “time_shortcuts” to help with common time stuff:

  • utc_dt(str)–convert the string into a UTC-localized datetime object.
  • utc_now()–right now in UTC
  • xtimerange(start, end, step)–walk from start to end by step.
  • minute_diff(start, end)–returns a diff between start and end in minutes, not days. makes a bad assumption about how many minutes are in a day.

This way I could write utc_dt(“2013-04-25 18:00:00”) and know I was getting back a datetime timezone-aware object. This is much more helpful than it should be.

Django

Django gets a little angry if you feed it DateTimeFields that aren’t timezone-aware. Hence the above helper library. Other than that, it makes the Python <-> Postgres interface transparent, which is all you can ask for. You deal in Datetime objects, and it handles Postgres.

I have one notable instance where I call straight SQL (using a cursor) so that I can do some of the Postgres goodness described above.

Javascript

Good stuff: Javascript’s Date() object.

Bad stuff: Javascript’s Date() object.

It is nice to call

new Date().getTimezoneOffset()

and get the timezone diff in minutes. It is also nice to be able to call .getUTCHours().

It is unfortunate that I don’t know of a way to change the timezone that Javascript uses for a given session. This resulted in me creating a clunky <select id=”timezone”> object that has all the timezones and their minute offset and this becomes a weird interactive variable that redraws the time-related parts of the page when it’s changed.


25
Apr 13

Chrome setup

In the spirit of “basic things I do to make my life easier,” here’s how I have Chrome set up:

Extensions

  • AdBlock Plus: Blocks many ads.
  • Ghostery: Lets you control what JavaScript is executed as you browse, e.g. you can turn off some DoubleClick tracking.
  • OneTab: You click the button and all your open tabs go into OneTab. (They stop taking CPU cycles/RAM.) You can then re-open them as you see fit. I open tabs constantly, and OneTab is an easy way to “save” those sets of tabs if I’m not ready to look at them.
  • 1Password (installed via the 1Password application): super good application/extension to keep track of passwords and generate passwords. Note: once the extension’s installed, ⌘-\ will fill in passwords for you.

Bookmarks

The only bookmarks I have in Chrome are on the bookmarks bar, right below the location bar. I use Pinboard for all my other bookmarks.

  • “fxns” folder:
    • pinboard bookmarklet to bookmark a page
    • “read later” bookmarklet to bookmark in pinboard with “read later”
    • “pinboard random” to read a random pinboard unread bookmark
  • “tabs” folder: each of the tabs I want open whenever I’m in Chrome. (I have one window that’s my “work” window with my email, to-do list, etc as tabs.) Then you can right-click this folder and say “open all”. For my work account:
    • Gmail
    • Google Drive
    • Toodledo
    • Google Calendar
    • Google Voice (Note: this links directly to my “alt”/personal account, so I don’t have to click to change Google accounts. Each Google product handles this differently, but for Google Voice it’s https://www.google.com/voice/b/1#inbox where the number is a 0-based count of which account you want to open.)
    • Google Intranet for my business
    • HootSuite
  • “temp” folder: folder for stuff I’m going to reference a lot, but just for a little while. For example, when I’m doing a creative commons image search for a presentation then I might bookmark that page in this folder.
  • other web sites, bookmarked straight on the bookmarks bar, with NO TEXT. If you edit a bookmark and delete its text, Chrome will still show the icon. I do this for the Django documentation, for example–I just see the icon for Django (~¼” wide) rather than the icon + description (1+” wide). This way your bookmarks bar stays less cluttered.

Settings

I personally turn off form auto-fill and saved passwords, because I use 1Password for that. (1Password can store your “identities,” credit card info, etc, so you can have 1Password fill out these forms.)

Fancy things

  • Hush: separate program that detects when you are seeing a Hulu commercial and mutes your volume until the commercial is over

24
Apr 13

bash helper stuff

I get fixated a little on how to be more “efficient.” Part of that includes setting up my environment so it works well. When I’m using bash (a UNIX shell), here are a couple of things that’ve helped save time:

  • bash-completion: Totally Awesome. Use this or else. (Note that ssh ser<TAB> will complete the server name, for example.)
  • Bash Emacs Editing Mode cheat sheet. (Note I grew up in vi but have been dedicating a LOT of time to learning Emacs, so I use set -o emacs.)
  • bashmarks: gives you simple aliases you can use to move directories, e.g. “g alias” goes to the directory associated with “alias”.
  • git-flow-bash-completion
  • venv_cd: If you use virtualenvs, this will auto-“workon” them for you. Make sure you source this *before* bashmarks. I don’t know why, but my experience is that this needs to get sourced first so that “g alias” will also check for virtualenvs.
  • Learn your basic bash shortcuts, e.g. the power of squiggles “mv x{,-old}”, variable manipulation (e.g. “${x%.html}” removes “.html” from the end) and re-use of previous arguments e.g. “ls -l !$”

24
Apr 13

Stuff You Should Do when building a wordpress site

Update 4/25: added a section about menus.

I am not a WordPress expert. That said, I have learned a little bit about WordPress, and Lauren encouraged me to write it down.

Users

I use two users: “admin” and “john”. If you’re going to mess with your blog and it’s brand new, consider creating an account for yourself and giving it WordPress administrator access. Then everything will at least be recorded as you. Then “admin” user becomes your “user of last resort.”

General Settings

Reading

  1. Create two “pages”–“Home” and “Blog”. Home will be your home page. The content of “Blog” will be totally ignored; just create the page.
  2. Go to Settings > Reading.
  3. Change “Front page displays” to “A static page” and set Front page to “Home” and Posts page to “Blog” (the two pages you created in step #1).

Permalinks

  1. Go to Settings > Permalinks
  2. Select “Custom Structure”
  3. Type in “/blog/%year%/%monthnum%/%postname%/”. This will make your blog posts start with “/blog/” and your URLs look like “/blog/2013/04/stuff-you-should-do-when-building-a-wordpress-site/”

Plugins

Install and set up these plugins:

  • Akismet: pay for it if you need to (I did). Very important.
  • Disqus comment system: set up an account and do this. Move the comments infrastructure (including managing identities) from being your problem to being their problem. If you already have a blog and switch to Disqus, you can have WordPress import your comments. I did this last week but it took like 5 days before the import completed.
  • Google Analytics for WordPress: get an ID and do this.
    • Once installed, go to the settings. Click the “show advanced settings” checkbox. Set “Ignore Users” to “Subscriber (ignore all logged in users)”. Now when you’re logged in you won’t be added to the analytics.
  • Google XML Sitemaps: install.
  • If needed, Open in New Window Plugin. This adds JavaScript that will convert all off-site links to open in a new window. I used to think this was horrible practice, but many people seem to be doing this nowadays and now I kind of expect it.
  • Redirection, so you can manage your HTTP redirects within WordPress.
  • Slick Social Share Buttons. This can put a bunch of different services’ share buttons on your page. You can configure the heck out of how they’re displayed
  • W3 Total Cache, if you are concerned about potential spikes in traffic. This plug-in can be super complicated but it can also help you use really advanced capacity management services like CloudFlare.
  • Widget Context. This allows you to say widgets only show on certain pages–for example, the blog categories list should only show up on blog pages.

Themes

If you are the kind of person who will make ANY changes to your theme, you need to create a “child theme” for it. Basically you create a new theme directory and create a file called “style.css” in it that has a special comment header in it. Part of that header (“Template”) tells WordPress it’s a child theme. After you’ve set this up, you can select your child theme from the Themes list and it will inherit everything from the parent theme.

You put your mods into the child theme (e.g. additions to functions.php, other PHP files, styles). When you update the parent theme, these mods “stick” and you don’t have to re-do them.

Stuff you could potentially do with your theme:

  • Make an “author-<<username>>.php” page to have a fancier blog author page.
  • Change how blog lists show up and are summarized
  • editor-style.css: Change the stylesheets use in the editor to better mirror what visitors see.
  • Change your footer.php
  • Add JavaScript on top of your pages e.g. I made a “hide”/”show” thing for my work email sign-up widget.

Widgets

If you installed Widget Context, you can change where your widgets show up. I find this helpful especially to limit the blog-specific stuff from showing up on posts (i.e. non blog pages).

Menus

By default, WordPress will build a top-level menu for your site that includes all your pages that don’t have a parent. To change this,

  1. Go to Appearance > Menus
  2. Create a Menu (maybe called “Home menu”? The name is not important)
  3. Add whatever you want to it
  4. Save it
  5. Under “Theme Locations” (upper left), hopefully you have an option for “Primary Menu”. Set this to the menu you created (“Home menu”).
  6. Now only what you add manually to this Home menu will show up as your top-level menu.

24
Apr 13

Biannual blog update

Every couple of years I seem to update my blog. So, here goes.

I just moved my web hosting to webfaction. The shortest version of the story is, I started a company and have been doing some Django programming and webfaction is really good for Python-based hosting and I realized some of what I’ve been missing out on. In fact, I’d used them many years ago to host a Plone site for the UU Fellowship of Winston-Salem. (Anyone who advertises that they host Plone sites is pretty hardcore.)

Looking under the hood, I feel better about webfaction because…

  • They let you run multiple “applications,” which you can tie to one or more “domains.” For example, ‘johnborwick.com’ (no ‘www’) is running a bare bones application that just forwards people to ‘www.johnborwick.com’.
  • They have their own WordPress installer, which makes me feel better than the Fantastico/whatever the replacement for Fantastico is called. For my old host, if you wanted to keep your site up-to-date with the package manager you’d wait for a few weeks before they got the upgrade script. (I have also started to feel more comfortable giving WordPress the permissions needed to update itself.)
  • If I want to start building simple services for people, I can easily set them up as new applications on my account. (Before, I’d used Google App Engine to build a few test apps, but you have to subtly change your apps to run in that environment and I’d read some FUD about the ability to scale/lack of control you have with GAE.)
  • I feel like I have a lot of control, but the framework makes good sense.
  • They are highly regarded.