Parenting tips and tricks

My 4th kid is now almost a month old, so it seems like as good a time as any to write up some random tips I’ve learned for dealing with young kids. Here they are, in no specific order.


A friend of mine with 3 kids, when asked for parenting advice, said “just think long and hard about how you are going to deal with the lack of sleep.” It has been the toughest aspect of parenting by far, for me.

Here are some things that helped us:

  • Never ever ever let the baby sleep on you, ever. Always put the baby down in bed when he or she is falling asleep, no matter what. Once they get used to sleeping on you, then it’s all over. After that, they will scream every time you put them in bed, no matter how sleepy you think they are. With our first 2, I spent many nights tossing and turning in a rocking chair with the baby on my chest, because of this mistake.
  • Seriously consider sleep training at about 6 months, if your baby is a crappy sleeper. The Ferber Method has saved our lives. Yes, there will be crying, but it won’t last long and it would save you months or years of sleep deprived insanity.
  • Take it with a grain of salt, but we’ve had more success by NOT swaddling our babies. That way they get used to being free and it’s not a big transition later, and they can learn to suck a thumb or whatever for soothing.
  • When your baby wakes up in the middle of the night and you can tell they’re not sleepy, make a cup of tea and put on some Netflix and try to make the best of it.
  • If you have $1000, then the Snoo smart bassinet is supposedly magic. We never tried it because it didn’t exist when we needed it, but people swear by it and I totally would have bought it if I could have. I would have sold my house for some decent sleep, for a while there.

By the way, some babies are good sleepers and some babies aren’t. If you are blessed with a good sleeper, and you haven’t experienced a bad sleeper, then just take my word for it: it’s absolute torture. I can’t properly describe what it feels like when it’s 4am, and you’ve slept about 18 minutes all night, and you lay the baby down in bed with the tiny bit of hope you have left, and as you sneak away you hear the screams starting. If you’re not sure if your baby is a good sleeper, then my rule of thumb is: if your baby sleeps for 2+ hours at a time, that’s a good sleeper.


Find exactly 1 well regarded book about babies, read it front to back, and then don’t read any others. That’ll give you the info you need, and you don’t risk confusing yourself or stressing yourself out with the stuff that other books disagree about (which is never that important anyway).


Spend the money on a real children’s Sonicare toothbrush, not a knockoff, and buy toothpaste with some dang flouride. Kids get cavities like dogs get fleas. It’s incredible. Take it seriously.

For the young kid that won’t let you brush their teeth without squirming and bouncing around, make them lay down and then sit right behind their head with your legs on top of their arms like this. It works fabulously to keep them still.


Hold the baby in one arm and vacuum a room with the other arm. The repetitive motion and loud white noise seems to work pretty well.

Also, just remember that babies cry. With our first kid, we flipped out every time our baby cried for a few minutes, thinking that something was wrong. With our 4th kid, not so much.


Buy one of the NoseFrida nose suckers and just go ahead and get over the “ew that’s icky” aspect of it because it works.

A fever below 101.4°F (or 100.4°F that lasts over 24 hours) isn’t worth worrying about (source). Same with random rashes and bumps.


Find a type/brand/size of sock that you like, buy a metric ton of that one type, and buy NO OTHER SOCKS! Oh, the endless frustration that I’ve dealt with over the years from trying to find tiny matching socks when we have 19 different types or designs or brands.

Keep a backup outfit in the car at all times.

Car seats

Make sure you buy a car seat with a push button to detach it from the car, like this. If you don’t, then trying to unhook the base from the car after it has been sitting in the heat for 6 months and probably has sticky crap all over it is more or less impossible.


When your kids are going insane and running around and screaming and you feel totally overwhelmed, put on some dance music and channel all that energy into a sweet dance party.


When they’re watching TV/movies, turn on captions because they will read them without meaning to and as they learn to read in school it’ll help them practice.


If you have multiple kids, then a rule of “everything belongs to everyone” can help. Just give the first turn to the kid that it actually does belong to, then start setting 10 minute timers to take turns until they get bored with it (which usually happens before the first cycle ends). That usually diffuses the fighting.


One of the things you don’t think about before you have kids is how impossible it is to have a non-stressful shopping or grocery trip with them, especially once they hit 2 or 3 years old. Get as much delivered as you can afford (including groceries), and save the rest for when you have a babysitter.

Don’t even attempt restaurants. It’s not worth it.


Don’t try to be the perfect parent because we all suck in our own personal ways that children are experts at identifying.

  • It’s fine if your kid doesn’t have a bath every single day
  • Bribing with candy is often totally worth it
  • If your kid wants to keep their pajamas on all day, who cares
  • If you need to lock yourself in a bathroom to keep from yelling, then do your thing

Just try to do what you need to do to give you and your kids a good time, because a happy family trumps everything else.


Book Riot’s 2018 Reading Challenge

I spent the first few months of 2018 working through the Book Riot 2018 Read Harder Challenge. I had gotten stuck in a rut of reading dumb suspense and murder mystery books and wanted to break out of that, so this seemed logical.

Overall thoughts

Two thumbs up! This challenge got me to read a ton of stuff that I never would have discovered otherwise, and some of it was really good. I used the Goodreads group a good bit for recommendations which helped a lot.

I liked the emphasis on minority and inclusion too. One category asked for a “female protagonist over the age of 60” and another asked for “a comic written or drawn by a person of color”, etc. That was pretty cool and I found some great stuff thanks to that.

I don’t think there were really any categories that were frustratingly hard to find something worth reading. If anything, I’d say a few were possibly too broad, but that’s fine – options are good.

The only thing I didn’t really like is that there were 3 separate categories that called for comics or graphic novels. That’s really not my genre, and that seemed like a lot for something so specific.

What’s next

I don’t know. I want to eventually try to get through the Pop Sugar 2018 Reading Challenge before the year is up, but I think I might need to take a break and read some brain candy for a few weeks first. It’s easy to burn out on trying to find books that fit a certain category over and over.

Full list

Here’s the full list of categories and some notes about the book that I chose for each one.

A book published posthumously

When Breath Becomes Air by Paul Kalanithi

My rating: ⭐⭐⭐⭐⭐

Poignant and sad. I’m really glad I picked this one. The epilogue written by his wife hit me especially hard.

A book of true crime

The Man With The Candy: The Story of The Houston Mass Murders by Jack Olsen

My rating: ⭐⭐

Bad choice. There are so many good true crime books out there and I chose this one for some unknown reason. I am ashamed of myself. It was boring and badly written.

A classic of genre fiction (i.e. mystery, sci fi/fantasy, romance)

And Then There Were None by Agatha Christie

My rating: ⭐⭐⭐⭐

I can see why Agatha Christie is such a big deal. This one had me on the edge of my seat until the very end and I did NOT see that coming.

A comic written and drawn by the same person

Nimona by Noelle Stevenson

My rating: ⭐⭐⭐⭐

This was my first ever graphic novel and I really enjoyed it. Super fun to read. It didn’t convert me enough to make me want to go read a ton of comics or anything, but I had a great time reading it.

A book set in or about one of the five BRICS countries (Brazil, Russia, India, China, or South Africa)

Little Fires Everywhere by Celeste Ng

My rating: ⭐⭐⭐⭐⭐

I loved this one so hard. More character and less plot focused than most of the books I tend to read, but I cared a lot about everyone in it.

A book about nature

A Walk in the Woods by Bill Bryson

My rating: ⭐⭐⭐

It started out great – hilarious and fun to read. As it went on, it got more and more into just long, boring (to me) descriptions and histories of the towns that he walked through. It had a few parts that had me laughing hard, which is how it got the 3 stars, but overall I was bummed.

A western

True Grit by Charles Portis

My rating: ⭐⭐⭐⭐

I had no idea what to do with the category. I basically grabbed the only Western novel that seemed obvious since that seemed like a safe bet. It drew me in, though. I especially loved the way the protagonist talked. I went around saying “said I” after everything I said for days afterwards. It drove my wife crazy.

“You want pasta for dinner?”

“Yes, said I.”

“Seriously, stop that.”

A comic written or drawn by a person of color

Black Panther: A Nation Under Our Feet, Book 1 by Ta-Nehisi Coates

My rating: ⭐⭐

I couldn’t get into it. The whole time, I just felt like I had no idea what was going on. Tons of names that I couldn’t remember or distinguish, and lots of plot lines that I couldn’t follow. It felt like I was supposed to have some background knowledge that I didn’t have. Maybe that’s the case – I’m a comic noob after all.

A book of colonial or postcolonial literature

The God of Small Things by Arundhati Roy

My rating: ⭐⭐⭐⭐

I feel pretty conflicted about this one. I could easily have given it 5 stars or 3 stars. It was really beautiful, and it had some of the most interesting phrasing and structure that I’ve ever read. It was also incredibly sad, and I love a good sad novel. But it also felt hard to get through the whole thing, and I couldn’t ever put my finger on why. Even though it was so interesting and different, I never was able to want to read it. I still feel like it deserves 4 stars though. It’s one of the ones that has stuck with me the most out of all of them.

A romance novel by or about a person of color

Fit (Fit, #1) by Rebekah Weatherspoon

My rating: ⭐⭐

Erm, no comment.

A children’s classic published before 1980

From the Mixed-Up Files of Mrs. Basil E. Frankweiler by E.L. Konigsburg

My rating: ⭐⭐⭐

I love some children and young adult novels, but this one felt a little too kid-ish even for me. It was fairly fun and easy to get through.

A celebrity memoir

On Writing: A Memoir of the Craft by Stephen King

My rating: ⭐⭐⭐⭐⭐

I wouldn’t say I’m a huge Stephen King fan but I do typically like his work, especially his non-humongous novels. I really loved this though. Part interesting memoir, part style guide, it was interesting throughout and I picked up lots of good writing tips (for all the wiki pages and technical docs I write)

An Oprah Book Club selection

I Know This Much Is True by Wally Lamb

My rating: ⭐⭐⭐⭐⭐

This is the longest book I’ve ever read (not counting IT by King which I listened to on audiobook), at almost 1000 pages. It was also one of the hardest to put down out of any of them. All of it felt necessary to tell the whole story. I don’t know how to really describe how I felt about it, other than to say that it kind of broke my heart and blew my mind at different times.

A book of social science

The Culture Code: The Secrets of Highly Successful Groups by Daniel Coyle

My rating: ⭐⭐⭐⭐⭐

Great book, as these types of books go. Very actionable advice about leadership as it relates to business or parenting or whatever. Lots of bits and pieces have stuck with me and have changed how I approach some conversations since reading it.

A one-sitting book

The Stranger by Albert Camus

My rating: ⭐⭐⭐⭐

This one seems to be a classic and is in tons of “OMG you have to read these books before you die or else” type lists. I thought it was good as an interesting story, but I didn’t get any of the life-changing philosophical viewpoints from it that others seem to take away.

The first book in a new-to-you YA or middle grade series

Ghost (Track, #1) by Jason Reynolds

My rating: ⭐⭐⭐⭐

This made me feel things. I liked it a lot and I sent it to my 12 year old nephew to read it too. Pretty easy read with a big heart.

A sci fi novel with a female protagonist by a female author

Warcross (Warcross, #1) by Marie Lu

My rating: ⭐⭐⭐⭐

This struck me as more or less a ripoff of Ready Player One (which I loved) with a female protagonist and some other small tweaks, but I still really liked it. I don’t know if I liked it enough to read the rest of the series, but on its own it was definitely a fun one.

A comic that isn’t published by Marvel, DC, or Image

Lumberjanes (Lumberjanes, #01) by Noelle Stevenson

My rating: ⭐⭐⭐

Meh, didn’t really hook me.

A book of genre fiction in translation

In the Miso Soup by Ryū Murakami

My rating: ⭐⭐⭐⭐

This book is sheer insanity. I love books that dip into the minds of crazy people so this was right up my alley. Fairly creepy, fairly brutal, but mostly just super raw and very interesting.

A book with a cover you hate

Misery by Stephen King

My rating: ⭐⭐⭐⭐⭐

This has to be the most suspenseful book I’ve ever read. I really had trouble putting it down. This is the kind of King novel that I really love.

A mystery by a person of color or LGBTQ+ author

Trouble Is a Friend of Mine (Trouble, #1) by Stephanie Tromly

My rating: ⭐⭐⭐⭐

Yeah, the main character is much too clever and confident and cool to be anything like a real teenager, but who cares, it’s a book, it’s not real life. Very satisfying book with lots of “oh yeah, take THAT” parts. I’m looking forward to reading the rest in the series.

An essay anthology

Selfish, Shallow, and Self-Absorbed: Sixteen Writers on The Decision Not To Have Kids by Meghan Daum

My rating: ⭐⭐⭐⭐

I happened to read this book about people who chose not to have kids before, during (in the delivery room while my wife slept) and after having my 4th kid, so it was pretty bizarre timing and totally accidental. Some of the essays grabbed me more than others but on the whole I found them to be reasonable and thoughtful and very introspective, and not at all like the “because kids are the freaking worst!” type message that I expected.

I think this is especially worth reading to someone who can’t decide if they want kids, because there’s no shortage of “you should have kids!” opinions floating around in the world, so it’s important to get the other side as well. I will say that this re-affirmed why I have 4 kids myself, because none of the essays really made me regret any part of that.

A book with a female protagonist over the age of 60

Britt-Marie Was Here by Fredrik Backman

My rating: ⭐⭐⭐⭐⭐

This one really caught me off guard. The protagonist reminded me so much of my own grandmother, as a grumpy, older lady who has more going on in her history and her head than you might think. It made me feel so full after reading it in a way that none of the other books did.

An assigned book you hated (or never finished)

The Great Gatsby by F. Scott Fitzgerald

My rating: ⭐⭐⭐⭐

I still don’t really understand why this is such a classic, but I liked it. I thought it was a fairly interesting story with some themes and higher meaning that even a dumb reader like me was able to pick up.

I also finished reading it right when I started using GatsbyJS so that was pretty incredible timing.


Idiotic feelings per day (IFPD)

How often each day do you feel like an idiot? Hopefully, the answer is “just enough.” I believe that measuring idiotic feelings per day (IFPS) is a decent method of predicting or identifying burnout. Here are your options:

I feel like an idiot all the dang time!

This is likely a sign that one (or both) of two things is happening:

  • Your work is too difficult and stressful
  • Your self confidence is too low

Either of those things could lead you to burnout, and if you have both, then whoa nilly, watch yourself. Either one of those is a good thing to discuss with your manager.

I never feel like an idiot, idiot!

This probably means that you’re bored, and you’re not being challenged. Being bored at work is another easy way to lead yourself to burnout. You may need to speak up and say that your work isn’t engaging or challenging enough.

It could also just mean that your self confidence is way too high, but in practice I’ve found that to be very rare.

Sometimes I feel like an idiot.

If you feel like an idiot every now and then, particularly when you make a random mistake or encounter something you haven’t done before which is tough to understand, then you may just be in the sweet spot.

Your work is likely just challenging enough that it keeps you interested and engaged but not so hard that it’s driving you crazy. And hopefully your self confidence is keeping your failures under control so that they don’t swallow you up.

Embrace your inner idiot!

So it’s up to you to make sure that the work you’re doing is at the right level to make you feel like an idiot just enough. If you’re too far one way or the other, then reach out to your manager or someone else who can possibly help correct it.


A minimal .vimrc file

For those of you who work on a lot of unfamiliar servers, you probably use vim a good bit. It can be useful to have a simple, small .vimrc file that you can just copy to wherever to set some sane defaults.

Here’s the one I use for that. It fixes indenting, syntax highlighting, and a couple other small things, and that’s it.

set backspace=2         " backspace in insert mode works like normal editor
set shiftwidth=2        " indent by 2 spaces when auto-indenting
set softtabstop=2       " indent by 2 spaces when hitting tab
syntax on               " syntax highlighting
filetype indent on      " activates indenting for files
set autoindent          " auto indenting
set number              " line numbers
colorscheme desert      " colorscheme desert
set nobackup            " get rid of anoying ~file


JIRA ticket template in the 3 C’s format

If you’ve never heard of the 3 C’s, here’s some context.

Basically, it’s a strategy for writing issues/tickets that breaks them into the Card (user story), the Conversation (documentation and detailed requirements), and the Confirmation (testing steps and acceptance criteria).

Here’s a concise little template that you can copy and paste when creating JIRA tickets.

h2. Card

Also known as the User Story. Explain the requirement in a sentence or two. This should just enough text to identify the requirement, including any crucial information about site/environment.

As a [user role], I want [function], so that [value].

If this doesn’t fit as a user story (e.g., a bug ticket), that’s fine, just explain it as a concise sentence.

h2. Conversation

This should answer the question “What are all the things someone would need to know in order to build this?”

Attachments such as wireframes, screenshots, and other documentation may be referenced here. Implementation notes, if necessary, should go here as well.

h2. Confirmation

This should include both Acceptance Criteria for when a feature can be considered done and the Testing Steps on how to confirm that. Any other information required for testing should go here as well.

Note that there’s nothing really JIRA-specific about this besides the fact that the headings start with “h2.” which is JIRA’s formatting. Feel free to steal it and adapt it however you’d like if it’s useful to you.

Here it is as a Gist as well.


A collection of random useful Git snippets

This is the post that I’ll use as a living dumping ground for random useful git snippets that I come across. Enjoy!

git blame -w # ignores white space
git blame -M # ignores moving text
git blame -C # ignores moving text into other files

Use git blame to see when a change was REALLY made, as opposed to just a whitespace or copy/paste commit:

Fetch a file from another branch without switching branches:

git checkout <OTHER_BRANCH> -- path/to/file.txt

Delete already-merged git branches (except for specific ones you name):

git branch --merged | grep -v "\*" | grep -v master | grep -v develop | grep -v release | xargs -n 1 git branch -d

View the git log for a specific line or number of lines in a file:

git log -L 1,1:some-file.txt

Search all commit diffs for a specific string – both regex and non-regex versions

git rev-list --all | xargs git grep '<YOUR REGEX>' # regex
git rev-list --all | xargs git grep -F '<YOUR STRING>' # non-regex

View a diff on a specific file between the current branch and another branch

git diff some-other-branch some-filename.js

Move your last commit to a different branch, for when you accidentally commit to the wrong branch

# undo the last commit, but leave the changes available
git reset HEAD~ --soft
git add .
git stash

# move to the correct branch
git checkout name-of-the-correct-branch
git stash pop
git add .
git commit -m "your message here"

# now your changes are on the correct branch

Delete all untracked files, but do a dry run first:

git clean -fn

List the most recently updated branches:

git for-each-ref --sort=-committerdate refs/heads/ | head

Grav CMS for Drupal developers

If you’ve never heard of it, Grav is a pretty neat little flat-file CMS. If you’re a Drupal developer, words like “flat-file” and “neat” and “little” are probably foreign to you. This post is an attempt to explain what Grav is, why it’s neat, and how to use it, in terms that you’ll understand.

Wait, what’s wrong with just using Drupal?

Why would anyone EVER think of leaving our beloved Drupal in the ditch to use something else?!

“If you want to build a small web site, I’m not sure it makes sense to use Drupal today. It’s good for… ambitious sites.” #driesnote

— Actually, (@eaton) April 25, 2017

That’s a pretty good reason. Dries himself has said that Drupal may not be the best fit for small sites. There are simpler solutions that make the easy stuff easy and the hard stuff somewhat easier (as opposed to Drupal which makes the hard stuff easy and the easy stuff really frustratingly difficult sometimes).

First of all, where is the database?

As a Drupal developer, you live and die by the database. You’ve probably worked on sites that have had many hundreds of database tables. You might even remember the first time you realized that each field gets 2 database tables of its own.

The first thing you should understand about Grav is that there is no database. In place of it, there are 2 types of things:

– YAML files which hold configuration

– Markdown files which hold content

That’s it. If you want to make a change to config, you change it in the relevant YAML file. If you want to update a page, you change it in the relevant Markdown file.

Oh, so it’s a static site generator like Jekyll? No!

So far it may sound like a static site generator, but it’s not. It’s a CMS. This means that it can still do all the same types of things other CMS’es can do, that aren’t available to static site generators.

For example, there’s a really nice admin plugin that lets editors edit content via a UI, and upon saving, the content is instantly updated on the site (rather than the site needing to be re-built). Some static site generators have UI’s, but they still require the intermediary site-generation step after making an edit.

You can also still have dynamic content listings, send emails, redirect users, integrate with web services, display user-facing forms, etc., since Grav is built with PHP and is super duper alterable via custom plugins. You’d need to handle that stuff client-side with a static site generator.

Content types in Drupal = Page Types in Grav

Let’s start with the basics – the age old “content type.” In Drupal, creating a content type happens in the UI.

In Grav, to create a content type, you just create a “whatever.html.twig” file in the templates/ directory of your theme. Doing that automatically tells Grav that “Whatever” should be a new Page type.

This means that when creating a page in the UI, you can choose the “Whatever” page type. Or, if you’re creating content via adding a Markdown file directly, just name the file which tells Grav that it’s a “Whatever” type of page.

Read the docs on this.

Custom fields in Drupal = Blueprints in Grav

In Drupal, creating custom fields happens in the UI.

In Grav, to create custom fields for a given page type, you’ll do it in a YAML file. Grav calls this a “Blueprint”. Just create a file in /user/blueprints/pages/PAGETYPE.yaml and throw in something like this:

    type: default
    context: blueprints://pages
              type: text
              label: Heading
              type: text
              label: Subheading

Basically, that will add two new text fields (“Heading” and “Subheading”) to the “Content” tab of the form for that page type.

When you save that form, it’ll throw that data into a little YAML block at the top of the Markdown file that stores the content of that page. This is called Frontmatter or Headers and is actually really really cool because it means that the sky is basically the limit in terms of how to store structured data. You can store it in any way that YAML supports.

Then, in the Twig template (we’ll get to templates later), you can output the data for those custom fields using {{ header.heading }} or {{ header.subheading }}.

Read the docs on this.

Views in Drupal = Page Collections in Grav

In Drupal, creating a content listing happens (usually) in the Views UI.

In Grav, there’s the concept of a “Collection” which allows you to loop through and list arbitrary content. Here’s an example:

    items: @self.children
        by: date
        dir: desc
    limit: 10
    pagination: true

And then in the Twig template, you’d just loop through them like so:

{% for p in page.collection %}
    <h2>{{ p.title }}</h2>
    {{ p.summary }}
{% endfor %}

Collections support lots of the same filtering/sorting/pagination concepts that Views supports. Some of the more complex stuff (such as fields from relationships or exposed filters) would have to be custom built via a plugin, but this should handle most of the things you’d typically use Views for pretty well.

Another interesting note here is that there’s a 3rd party plugin called View that adds some more power to this system.

Read the docs on this.

Taxonomy in Drupal = Taxonomy in Grav

Yep, it’s even named the same thing for you.

In Drupal, creating a Taxonomy happens in the blah blah blah you get the idea. All of this stuff is done in the UI in Drupal.

In Grav, creating a Taxonomy just means adding it to your site.yaml config file, like so:

taxonomies: \[category,tag\]

Just add it to that array and you’ve created a new taxonomy. Then, you can reference it from any given page like this, in the YAML Frontmatter:

title: Post title
    tag: \[animal, dog\]
    category: pets

And that’s it. Taxonomies are MUCH simpler in Grav than in Drupal. They aren’t fieldable, for example (without some customization). They’re basically just a way to group content together, so that you can create listings (“Collections”) out of them.

Read the docs on this.

Configuration/CMI/Features in Drupal = YAML files in Grav

In Drupal, configuration is stored in the database. Drupal 8 provides core with the ability to sync this configuration with YAML in the filesystem, but the source of truth is the database.

This means that if you want to push some new configuration some site A to site B, you have to make the change in the UI, export it to YAML, move that YAML to the other site (via a git push or some other mechanism), and import it on the other site to make it live. People usually use Drush or Features to help with this process.

In Grav, the source of truth for configuration is the YAML itself, since there’s no database. To change configuration, just change the YAML file, and Grav will immediately recognize that. To move that change to another site, just git push/pull it and it’s live.

Read the docs on this.

Install profiles/distributions in Drupal = Skeletons in Grav

This is one area where Grav really shines.

In Drupal, shipping a distribution mostly involves doing work to make sure that a site has everything it need in code and exported configuration, and installs correctly using the installer. This is a result of Drupal relying on a database, but not wanting to ship an exported copy of that database with the distribution.

In Grav, since there’s no database, a “distribution” (or a “Skeleton” in Grav-speak) is basically just a copy of the codebase. Grav has no notion of “installation” like Drupal’s installer. Just copy the codebase to another web root somewhere and it’s ready to run. This means that it’s really easy to ship open source Skeletons, many of which are available here.

(It’s a tiny bit more nuanced than that since all you really need is the /user directory of the codebase which is where all the custom code is stored, but you get the idea).

Read the docs on this.

Paragraphs in Drupal = Modular Pages in Grav (kind of)

If you aren’t familiar, Paragraphs is a very popular Drupal module that lets you build content in arbitrary “slices”, each of which can contain arbitrary fields.

Grav has the concept of Modular Pages, which is pretty similar. Basically, a Modular Page is just a collection of other pages, but those “other pages” aren’t reachable on their own, and they’re special types that are made specifically for being placed into Modular Pages.

For example, a Modular Page being used as the homepage may be comprised of a Slideshow page, then a Feature List page, then an Image With Caption page, etc., and none of those sub-pages are actual pages that are reachable on their own. So even though they’re called “pages”, it’s basically the same idea as Paragraphs.

The UI for this is different since each of those sub-pages are editable on separate forms instead of all of them being in the same form like how Paragraphs does it, but you can accomplish most of the same things this way.

Read the docs on this.

Drush in Drupal = CLI tools in Grav

Drush has saved the butt of many a Drupal developer. These days, Drupal Console is doing pretty well for itself too, but it’s the same basic idea. Talking to your site via the CLI is useful.

Grav has a couple built in CLI tools for many of the same purposes:

  • bin/grav: performs basic site tasks such as clearing cache, making backups, installing dependencies, or creating new projects
  • bin/plugin: performans commands provided by plugins (instead of Grav core), such as creating new users via the admin plugin
  • bin/gpm: (“Grav Package Manager”) – performs tasks you would expect of a package manager, such as listing, downloading, and updating plugins

Other random stuff

Here’s some other stuff that didn’t really deserve its own section. Feel free to read up on the docs on these if you’re curious.

Shortcomings and Downsides

There are a few things to keep in mind if you’re looking at using Grav for a project instead of Drupal.

One is that Grav doesn’t scale nearly as well. Many Drupal sites have many millions of nodes, thanks to the usage of a database. In general, I probably wouldn’t suggest using Grav once you start getting into the thousands with page count. Performance will likely start to suffer.

Drupal also really shines in creating complex content models, where there are many types of nodes/entities which reference each other or embed each other or reuse each other’s fields, etc. Grav is perhaps more “page focused” than “data focused”, which makes it much easier to work with for many sites, but not a great fit for some sites that need those complex relationships.

Grav also doesn’t really have the notion of an editorial workflow or moderation system. It does support published vs. unpublished, and there are things like Git Syncto auto-deploy from a staging environment (or your local site) to a production environment if you set it up to do so, but there’s no approval process along the lines of what Drupal and some modules can provide.

Obviously, Grav also isn’t going to have anywhere near the amount of 3rd party plugins (modules) that Drupal has. Things like integration with web services or commonly used libraries will have to be hooked up yourself, more often than not. That said, the API is solid and the documentation for it is legit.

That’s by no means an exhaustive list, but it’s about all I’ve found so far. For your typical small to medium sized sites, Grav can be a really great solution that cuts out some of the overhead of a typical Drupal site. Recommended!


An insulting guide to budgeting

The cold harsh reality is that we have to balance the budget.

Michael Freaking Bloomberg

“But I don’t want to budget! Sticking to a budget is such a chore! Entering all my transactions is so hard!” Yeah, whew, that’s a tough one. But you know what is even harder? Being hopelessly, desperately poor.

Or, maybe try being hopelessly, desperately poor and then finding out your car transmission is shot. Or that your kid broke his arm and had an ER trip. Or that your roof is leaking. This is your future, and it’s really bumming me out.

Let’s try some honesty for a minute.

Step 1: Accept you’re a failure

Listen closely, because this part is important: You don’t earn enough money to be able to just say “screw it, I’ll buy whatever I want and it’ll be fine.” You’ve already lost. You absolute loser.

But here’s the thing: we’re all failures. Nobody earns enough to buy whatever they want all the time. Everybody has limits. I bet you Bill Gates has a budget that he’s using more effectively than you, and that’s Bill freaking Gates.

So given that you’re already a huge loser like the rest of us, your best chance is to do what you can with what you do have. That means taking whatever pitiful income you earn and not spending it like an idiot.

You need a budget. Yes you do.

Step 2: Track your spending for a month

I guarantee you have no idea how much money you spend on stuff each month, if you’re not tracking it. Take a guess at how much you spend on groceries or restaurants, then track that for a month. I bet the real amount will be at least double what you expected.

So given that you’re a failure when it comes to earning loads of money AND you have no idea where the money that you do earn is going, you’ll need to figure that part out.

Download any of the bajillions of mobile apps for tracking your spending, and use it consistently for a full month. That means entering an amount and category for everything you spend money on, from your mortgage all the way to a pack of gum.

Step 3: Sign up for YNAB (You Need A Budget)

Now that you have a rough idea of how much you’re spending on everything per month, you’re ready to make a budget.

Well aren’t you lucky, because it just so happens that there’s an app for that. First, watch this video. No seriously, it’s barely even a minute long.

Then head on over to sign up for YNAB. That’ll guide you through the process of entering your accounts and balances, then planning the budget for the coming month. And, OMG, there’s a free trial that lasts a month. It’s like Christmas!

Yes, it costs $5 per month after the trial ends. Do me a favor and just shut up about that. If you’re thinking there’s a free app out there that’s just as good, then trust me when I say there’s not. I’ve looked, really really hard. YNAB’s approach to budgeting and the YNAB method are pretty unique, and it’s about 5 steps above all the competitors.

No, Mint won’t cut it. Mint is good at looking back, but it’s terrible at looking forward. No, none of the free mobile apps are “good enough”. I’ve tried dozens. Just stop, trust me, pay the $5 and move on with your life safe in the knowledge that it’ll save you thousands.

Step 4: Set up your budget

Signed up for YNAB? Congratulations, you know how to fill out a registration form.

Take the result from step 2 (that’s the one where you tracked your spending, genius) and use that to fill in your budget. For example, if you spent $800 on groceries but you’re pretty sure you can keep it to 600, then go for it and enter 600 for your groceries budget. And on we go, for each budget category you set up. Isn’t this fun?

Note that YNAB lets you budget the money you actually HAVE in your account, with the goal of working up to the point of being able to budget your entire month with the money you already have when the month starts. This means you can get out of living paycheck to paycheck.

Given that you’re a money dummy, I’m going to assume you’re nowhere close to being able to do that yet, in which case you can start by budgeting until your next paycheck instead of the full month.

Step 5: Use the budget

Caution, big words coming: when you buy something, put it in YNAB. GASP

People always seem to have trouble with this. It takes 10 seconds. The mobile app even keeps track of where the stores you go to are and prepopulates the info the next time you’re there.

Just do it. If you can’t spare the extra 10 seconds whenever you buy something then you’re buying wayyyyy to much stuff and you care wayyyyy too little about not being a homeless person.

If you’re about to buy something but you notice that there’s no money left in that thing’s budget category, then you have 2 choices:

  1. Don’t buy it
  2. Take that money out of another category that doesn’t need it

There is no “Option 3: Buy it anyway” That’s not how this works. Your money is your money. You can’t buy stuff with money you don’t have unless your goal is devastating credit card debt in which case you’re taking great strides.

Step 6: Adjust and repeat

When that month ends, you budget the next month. Look at the places where you went over or under and adjust from there. Your goal is to become a little less obvlivious each month about where your money is going to go that month, while still putting money into “in case unexpected crap goes down” categories for when unexpected crap goes down.

After you’ve done this for a few months you should have a good handle on how much you HAVE to spend vs. how much you WANT to spend, and you can start moving some of that WANT to spend money into savings instead, but that’s a topic for another post.


An insulting guide to baby sleep training

The thing about babies is that they’re idiots. They can’t even sleep right, which is like the easiest thing ever. You have to teach them. You’re a parent, that’s what you do now.

Let’s get one thing straight though. Your baby sleeps plenty. It (yes, your baby is an “it” for the purpose of this post) just doesn’t sleep in a way/time/pattern/duration/position that’s convenient for you, you special snowflake.

Let’s work on changing that. Yes, we’re talking about sleep training. This is happening.

Step 0: Realize that you are not special

Everyone who has kids thinks that their kids are especially bad sleepers. (But seriously, mine really were especially bad.)

So don’t go acting like you’re the first person to be sleep deprived. Sleep deprivation is old news. People have been sleep deprived for like thousands and thousands of years. It’s pretty outdated now actually. Where have you been?

Your baby sucks at sleeping like babies in general suck at sleeping. Get past the snowflake syndrome, whiny-pants.

Step 1. Suck it up for the first few months

There’s not much you can do when they’re tiny. Most books/experts/people-who-know-this-stuff say that you can start sleep training at 4-6 months. So until then, you just kind of have to accept that your life is going to be crap. You will constantly be tired, you’ll be grumpy, and you’ll generally just have periods where you wonder why having that little ball of cry seemed like a good idea.

Your goal during this period is to avoid becoming an alcoholic, and keep both you and the baby alive.

If you’re just feeling too bad for yourself and you’re really wanting some tips for this period, then read these, but don’t expect any miracles:

  • Newborn babies have no trouble going to sleep on their own. Try your hardest to NOT break them of that amazing ability as they get older, and avoid resorting to rocking them or feeding them or walking them to sleep.
  • Then realize that that first tip is literally impossible to do when it’s 4am and you’ve only gotten 19 minutes of sleep, so forget that I ever said anything.
  • Try swaddling it with those velcro swaddle wrap things make escape tougher.
  • If its tiny arm muscles manage to break it free of the velcro swaddle wrap things, or if it starts flipping over, then try this weird space suit thing.
  • When your baby has a wide-awake period in the middle of the night, put on some Netflix and make a cup of tea and try to make the best of it instead of hopelessly walking the baby around for hours in a dark room, every step taking you closer to insanity.
  • Sleep when they’re sleeping. I know everyone says this but really commit to it, even if it’s 1pm and your house looks like a giant ate a normal house and spit it back out.
  • If you have other kids or a job and can’t take random naps during the day, then you’re screwed. Drink coffee or something.

Now is also probably a good time to note that there tends to be a big sleep regression at about 4 months, which can and will make you question who you are as a person.

Step 2: Prepare for the crying. Harden your heart.

You know that terrible feeling you get when your baby cries, especially when it’s that horrifying shrieking cry, where you want to just jump out of your skin and you’d do anything to make it stop? It’s a chemical thing involving Oxytocin and auditory cortexes and synaptic mechanisms and other words that I could copy/paste from the internet. Therefore, it’s hard to avoid feeling like that.

But you need to avoid feeling like that. If you’re going to teach your baby to sleep, it’s going to cry, and you’re going to have to just develop a cold, black heart and walk away you creampuff!

“I can’t take the crying” has to be the most common reason to not train babies to sleep. What do you think is worse, a few combined hours of crying (if that) spread out over a few days, or another YEAR OR TWO of feeling like you’d literally light your car on fire if it got you an extra nap?

And if you’re worried it’ll permanently damage your baby’s tiny brain, then cut that crap out now.

There are no long term data showing ill effects from these methods, and the practice parameters and guidelines for pediatric associations tend to support the [cry it out] method as an option. Wikipedia

Your baby is fine. Its arms won’t fall off from crying. In the morning it’ll still be the same baby. Get a grip.

Side note: this also means that all of those “no cry” sleep training methods are not to be trusted. They’re like the weight-loss plans where you can eat anything you want and only have to wiggle on a little wiggle-machine for 5 minutes a day. If you have tried and found success with these methods, then congratulations, but I think you’re lying.

Step 3: Show your baby how it’s done

There are a few methods of sleep training. But ignore those – they’ll just confuse your poor sleep deprived brain. The one I’m going to talk about is the Ferber Method, since it’s pretty common and seems to work well for lots of people.

Here’s what you do.

  1. Figure out some sort of nighttime ritual (bath, lullaby, whatever) and start doing it
  2. When your baby is sleepy-ish and it’s a good bedtime, put it in bed
  3. Walk the heck away and hold steady against the onslaught of horrid, screeching cries
  4. After 3 minutes, go in the room and pat your baby for a second and say something dumb and reassuring that your baby can’t understand, then leave again. Don’t take the baby out of bed!
  5. Repeat step 4 again after 5 minutes, then every 10 minutes until the baby falls asleep. Don’t take the baby out of bed!
  6. When your baby wakes up in the middle of the night, repeat steps 4 and 5 as needed until morning. Don’t take the freaking baby out of bed until morning! Stay strong!
  7. The next night, skip the 3 minute step and go straight to 5 minutes.
  8. From night 3 onward, just do every 10 minutes.

If your baby is like most babies and you are like most parents, then your baby will scream for long enough the first night that you’ll cave like a pansy and pick it up and apologize for everything you’ve ever done to it. But if you’re a strong parentthen you’ll last until your baby passes out, usually after like 20-30 minutes or so.

Each time you do it, it’ll take less time for the baby to go to sleep, and then eventually it’ll learn that crying is pointless and it’ll just lay there silently until it falls asleep. This is the part where your baby has learned to go to sleep on its own.

The next step from there is for it to stop waking up in the middle of the night, because it knows that it’s not going to get out of bed anyway, so there’s no point in freaking out.

Then you’ve made it.

Step 4: Sleep

If you are strong enough, brave enough, or just otherwise lack the compassion to care that your helpless baby is screaming, then you have a chance to change your life.

Do it.


Exporting and importing big Drupal databases

Once your site’s database dump file gets to be 1GB or more, phrases like “oh, just download and import a DB dump” can’t really be taken for granted anymore. So here are some tips for dealing with large databases, especially those of the Drupal variety.


Before we can import, we must export. With a big DB, you don’t want to just do a regular old mysqldump > outfile.sql and call it a day. Here are some tips.

Find the size before exporting

It can sometimes be useful to see how big the export is going to be before you actually export anything. That way, you can know ahead of time if you need to be doing this or that to reduce the size, or if it won’t matter since the whole thing won’t be that big anyway.

Here’s a query you can run to see the size per DB table:

  DATA_LENGTH / POWER(1024,1) Data_KB,
  DATA_LENGTH / POWER(1024,2) Data_MB,
  DATA_LENGTH / POWER(1024,3) Data_GB
FROM information_schema.tables
WHERE table_schema NOT IN

And here’s another query you can run to see what the total size for the entire DB is:

    Data_BB / POWER(1024,1) Data_KB,
    Data_BB / POWER(1024,2) Data_MB,
    Data_BB / POWER(1024,3) Data_GB
FROM (SELECT SUM(data_length)
  Data_BB FROM information_schema.tables
WHERE table_schema NOT IN

Dump without unnecessary data

For those cases where you need the database structure for all of the tables, but you don’t need the data for all of them, here’s a technique you can use. This will grab the entire DB structure, but lets you exclude data for any tables that you want. For example, searchindex, cache\*, or sessions tables will be good places to cut out some fat.

# First we export the table structure.
mysqldump --no-data database_name > /export.sql

Just replace “tablename1″ and “tablename2″ with the tables that you want to skip, and you’re golden. Also note that you can use the % character as a wildcard, so for example, you could ignore “cache%” for all cache tables.

After you do that, you’ll have a single export.sql file that contains the DB structure for all tables and the DB data for all tables except the ones you excluded. Then, you’ll probably want to compress it…

Compress all the things

This one may go without saying, but if you’re not compressing your database dumps then either they’re really tiny, or you’re dumber than a dummy.

drush sql-dump --gzip --result-file=db.sql

Compare that with the regular old:

drush sql-dump --result-file=db.sql

…and you’re going to see a huge difference.

Or if you already have the SQL dump that you need to compress, you can compress the file directly using:

gzip -v db.sql

That will output a db.sql.gz file for you.


Now you have a nice clean compressed DB dump with everything you need and nothing you don’t, and you’re ready to import. Here are a few ways to ease the pain.

Import a compressed dump directly

Instead of having to decompress the dump before importing, you can do it inline:

drush sqlq --file=db.sql.gz

Note that –file supports both compressed and uncompressed files.

Exclude data when importing

If you receive a DB dump that has a lot of data you don’t need (caches, sessions, search index, etc.), then you can just ignore that stuff when importing it as well. Here’s a little one-liner for this:

gunzip -c db.sql.gz
     | grep -Ev "^INSERT INTO \`(cache_|search_index|sessions)"
     | drush sqlc

What this is doing is using “grep” as a middleman and saying “skip any lines that are insertion lines for these specific tables we don’t care about”. You can edit what’s in the parenthesis to add/remove tables as needed.

Monitor import progress

There’s nothing worse than just sitting and waiting and having no idea how far along the import has made it. Monitoring progress makes a long import seem faster, because there’s no wondering.

If you have the ability to install it (from Homebrew or apt-get or whatever), the “pv” (Pipe Viewer) command is great here:

pv db.sql | drush sqlc

Or if your database is compressed:

pv db.sql.gz | gunzip | drush sqlc

Using “pv” will show you a progress bar and a completion percentage. It’s pretty awesome.

If you don’t have “pv” then you can settle for the poor man’s version:

watch "mysql database_name -Be 'SHOW TABLES' | tail -n2"

That slick little guy will show you the table that is currently importing, and auto-updates as it runs, so you can at least see how far through the table list it has gone.

Tools and Resource

In this post I tried to focus on commands that everyone already has. If this just isn’t cutting it for you, then look into these tools which could help even more:

  • SyncDB – a couple Drush commands that split DB dumps into separate files and import them in parallel, drastically speeding things up
  • Drush SQL Sync Pipe – an alternative to “drush sql-sync” that uses pipes where possible to speed things up