comment 0

Links

A practical introduction to functional programming – The best article I’ve read about functional programming.

How-to make your iPhone Dimmer than Dim  – Even at its dimmest, the iPhone display is too bright for reading at night in bed. This makes it go even dimmer. (Let’s ignore the fact that I shouldn’t have my phone in bed in the first place.)

Hungarian paper money – A beautiful “redesign” of the fictional Hungarian euro.

keepachangelog.com – Well-considered rules and conventions for change logs. I’ll be keeping one for all of my projects from now on.

Under-promise and over-deliver is one of the most difficult and important principles in life. I’m still struggling to improve at this.

comment 0

Links

Parsley – Command-line tool to extract structured data from web pages as JSON. Its simple syntax is a superset of CSS3 and XPATH.

Downtown is for People –  “Rarely before has the citizen had such a chance to reshape the city, and to make it the kind of city that he likes and that others will too.” A classic article on urban planning. (Especially relevant now as my city, Utica, seems to in the early stages of a rebirth.)

The Possibility in Blank Spaces – Why it’s worth resisting the urge to fill everything.

Business Town! What Value-Creating Winners Do All Day – What if Richard Scarry grew up in Silicon Valley? The satire isn’t particularly original, but the illustrations are wonderful.

Aerial Wallpapers – iPhone wallpapers created from aerial satellite photos. Much more beautiful than they sound.

comment 0

Links

I subscribe to a handful of blogs that regularly publish interesting or useful links. Those tend to be my favorite kind of post, so I’m going to try sharing the wealth and publish some of my own. Enjoy!

Railsbox — An online GUI to build virtual machines for web development. Similar to PuPHPet and Protobox, but uses Ansible for provisioning and supports Unicorn/Passenger out of the box. (If I have some spare time, I’d like to create a pull request for deploying to Digital Ocean.)

Auto-Hide Sticky Header — This useful and subtle navigation UI pattern is everywhere lately. Here Osvaldas Valutis provides a canonical example and explanation, including a few variations.

Lorraine Loots on Instagram — Lorraine creates tiny, amazing drawing and paintings. Get lost in her Instagram feed!

Skyline — “A starting point for building custom CSS frameworks.” This is the type of groundwork that I wish Bootstrap and Foundation were built upon. Its modular organization is well-considered, and the use of SCSS and BEM notation appeal to me.

Artoo — Framework for programming robots in Ruby. There’s an Arduino library, which seems like a fun, native-feeling alternative to Processing.

comment 0

Failures, Successes, and Goals

It’s a few weeks into 2015 already, and I’m trying to redevelop a blogging habit as part of a larger effort to refocus my life. With that in mind, it seems appropriate to summarize the previous year, and then set some goals for the upcoming year.

Failures

My long-term side project, Boulder Problems, lost enough traction that it’s no longer worth developing in its current form. It failed for a variety of reasons: lack of marketing, lack of time, and lack of focus. Letting go of this project is emotionally challenging. I’ve poured huge amounts of time into it, and learned some difficult, important lessons. There’s unfortunately no way I can hope to compete with the upcoming logging tools that The Island has announced. I wish them success, as it seems they’re developing for exactly the niche that I believe needs to filled. (Despite all of the above, I am continuing to develop a new version of Boulder Problems, but focused toward personal, rather than social, logging. More on that another time.)

I got injured. A lot. As I mentioned on my other blog, 2014 was a bad year for my body. I ate poorly, drank too many beers, and didn’t exercise enough.

I stopped bouldering. Well, not entirely. But I barely climbed, and when I did, I lacked strength and motivation.

Successes

I got married! Weddings are surprisingly stressful and time-consuming affairs. Heather and I somehow managed to cobble together an unforgettably fun ceremony and reception with our closest family and friends. I wouldn’t trade the experience for anything, but also it’s a bit of a relief to put it behind us.

On the coding side of life, I fell in love with Ruby. I’ve been dabbling in it for a while, but this year I finally started to get comfortable with the language.

And I finally learned to write automated tests. It’s embarrassing to admit, but I only recently began writing tests for my code. Exercism.io introduced me to the practice, and Justin Weiss’s blog took me deeper.  I’ve barely scratched the surface, but having learned the basics, I’m excited to keep learning and improving.

I did less cowboy coding. As a self-taught developer who’s worked only on tiny coding teams, I’ve never been exposed to many industry best-practices. The more I experiment with tools and ideas like Ruby, Vagrant, Git, Capistrano, Semantic Versioning, and SASS, the more I appreciate the value of doing things correctly. I still have much to learn, but I think I’m on the right path.

And finally, I helped Heather launch her business, The Topping Tree!

Goals

Write more Ruby. I’m not sure how well this meshes with my current job as a PHP developer, but I’m going to try.

Blog more. At least once a week.

Strength train consistently. Every time I start a new strength training program, it goes well for a few months until I injure myself. This year I’m going to try a more consistent, less ambitious program.

Climb regularly. I’d like to set a regular schedule for the spring and summer, so that I’m in shape for the fall bouldering season. I’d love to send a V8 this year – a difficult, but attainable, goal.

Take an extended ski trip. Skiing powder is one of my favorite pleasures, and now that Heather has also gotten the bug, we’re thinking about moving West for a couple of months to ski. In future blog posts, I hope to lay out a plan for achieving this goal.

 

comment 0

What Problems to Solve

You say you are a nameless man. You are not to your wife and to your child. You will not long remain so to your immediate colleagues if you can answer their simple questions when they come into your office. You are not nameless to me. Do not remain nameless to yourself – it is too sad a way to be. Know your place in the world and evaluate yourself fairly, not in terms of your naïve ideals of your own youth, nor in terms of what you erroneously imagine your teacher’s ideals are.

comment 0

Which .conf file(s) is Apache using?

I spent the majority of this week debugging some Apache ModRewrite rules. (Yes, today is Wednesday.) It shouldn’t have taken so long. The rules themselves weren’t complex, but the server environment is.

Our production web site consists of a load balancer, Memcached server, two synchronized app servers, and two synchronized static file servers. There are obsolete, broken, and duplicate Apache config files distributed in various directories across the app and static servers. Many of the config files recursively included directories full of other config files. By trial-and-error, I sifted through them all, adding debug statements and restarting httpd, over and over and over. Nothing worked; Apache ignored every file I touched.

As usual, it turns out there’s an easier way to discover exactly which .conf files Apache is using.

First, get some data about your running Apache process:

$ ps ax | grep httpd
21765 ?        Ss     0:00 /usr/sbin/httpd -f /var/www/conf/example.com.conf -E /var/www/logs/example.com-20140514-startup.log

This is valuable information, because now that we know the exact binary and config file Apache is running with, we can use the -S option to show VirtualHost settings:

$ /usr/sbin/httpd -f /var/www/conf/example.com.conf -S
VirtualHost configuration:
*:80                   is a NameVirtualHost
         default server www.example.com (/var/www/conf/virtual/example.com/www.example.com.conf:1)
         port 80 namevhost www.example.com (/var/www/conf/virtual/example.com/www.example.com.conf:1)
         port 80 namevhost www2.example.com (/var/www/conf/virtual/example.com/www2.example.com.conf:1)
...

From the output above, we see that www.example.com’s VirtualHost is defined in /var/www/conf/virtual/example.com/www.example.com.conf.

That’s all there is to it — no guesswork necessary.

WordPress multisite proxy configuration

I’ve been using WordPress multisite for a few projects at work lately, and it’s been great — mostly. Unfortunately, because of its reliance on ModRewrite, anything beyond the most basic configuration can be complicated.

In this case, I needed to install a multisite network in a subfolder, served from behind a load-balancing proxy. WordPress multisite is very particular about hostnames, so it detects that the proxy server hostnames (proxy1.mysite.com and proxy2.mysite.com) don’t match the site hostname (www.mysite.com), and degrades to an infinite redirect loop.

The solution below comes after days of research, testing, and tearing out my hair. Of course, all environments are different, so your mileage will probably vary.

The solution (well, maybe)

After enabling your multisite network, WordPress provides the following code snippets (which we’ll modify in just a moment):

# wp-config.php

define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', false);
define('DOMAIN_CURRENT_SITE', 'www.mysite.com');
define('PATH_CURRENT_SITE', '/subfolder/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);
# .htaccess

RewriteEngine On
RewriteBase /subfolder/
RewriteRule ^index.php$ - [L]

# uploaded files
RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*.php)$ $2 [L]
RewriteRule . index.php [L]

Now let’s make some additions. New lines are bold:

# wp-config.php

define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', false);
$base = '/subfolder/';
define('DOMAIN_CURRENT_SITE', 'www.mysite.com');
define('PATH_CURRENT_SITE', '/subfolder/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);

if ( isset( $_SERVER['HTTP_X_FORWARDED_HOST'] ) ) {
  $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}
# .htaccess

RewriteEngine On
RewriteBase /subfolder/
RewriteRule ^index.php$ - [L]

# uploaded files
RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{HTTP:X-Forwarded-Host} !^$
RewriteCond %{HTTP:X-Forwarded-Host} !^www. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.mysite.com%{REQUEST_URI} [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*.php)$ $2 [L]
RewriteRule . index.php [L]

And that’s it. This combination of rules delicately nudges your URLs into a format that WordPress and Apache won’t choke on.

comment 0

Melissa Godowski, a rock climber whose blog I’ve enjoyed following for years, just posted her Top 31 Things I Have Learned in 365 Days. It’s a great list, and applies equally to climbing and life. I have a few favorites, which seem especially applicable to my life at the moment:

  • Slow and steady wins the race. Go at your own pace, not someone else’s.
  • The present will dictate the future. Be in the moment and make smart decisions.
  • There is no such thing as normal. Even if there was, individuality is too special to give up.
  • It is important to have variety. Have a variety in activities and interests just like you would have a variety of vegetable colors.
  • Get to know yourself. Learn your patters, likes, and dislikes. Become aware of your emotions. Work together with you body. Having this knowledge about yourself will help you reach your goals faster.
comment 0

Relationships are everything. Getting what we want, having things our way, having control, being right … these things matter nothing compared to relationships. Imagine being in your death bed at the age of 80 … will your sense of being right and in control comfort you when you have no good relationships, no one who has loved you?

comment 0

I think as experienced game developers / engineers / artists / makers, we don’t realize how we’ve developed strong senses of “vision” — the ability to visualize and maintain this thing in our head, and gradually work to realize that thing into existence despite countless obstacles. Frequent failure is expected! But this kind of emotional intelligence, to be patient with yourself and your work, takes time to cultivate. People have trouble grasping this if they are new to making things, and maybe it’s our mission to help them own their constant failures.