BACK
|Technology

further Gatsby

Hi! I'm Ted Zlatanov and I'll write about remaking my small site http://lifelogs.com

This is part two. The first post talked about why I went with Gatsby / React as a platform. Now, let's see what I actually did to get a working website.

Shell stuff

Yarn is pretty nice and can be installed in Ubuntu as yarnpkg. There were just three or four basic commands I needed to learn:

yarnpkg add some-other-package
yarnpkg install
# run a local version of the site
yarnpkg develop
# test a full build
yarnpkg build

Beyond that, using Netlify and deploying from master means I can do a full deploy with a simple push. I'll use tags and more complex deploys if I have to, as soon as I hit 500K visitors per day. Real Soon.

git add ...
git commit -m ...
git push

Being an Emacs user, I prefer Magit, but also have some shell aliases to make the above even easier.

Editing the content

Well, that is boring. Just some Markdown. The schema used by the Netlify CMS is pretty weird but I'm sure someone somewhere really likes writing YAML schemas in YAML and linking that to WYSIWYG editors.

template: HomePage
meta:
  description: Gold Software Systems ∮ Lifelogs
  title: Gold Software Systems
slug: ''
title: 'Home'
featuredImage: ...
subtitle: ...
---
...page text goes here...

Editing that in Emacs is a joy, so I just didn't explore the CMS further. But I know it's there, waiting in the darkness... wait, wrong genre...

Custom pages

I quickly wanted some custom pages. The Services page for example needed some custom work.

Lost Grid

To generate a 3-column layout I installed Lost Grid, which I liked better than the million and one other CSS grid solutions. It was simple enough for what I needed, but no simpler.

I installed it by modifying gatsby-config.js and adding the lost Node package.

diff --git a/package.json b/package.json
...
+    "lost": "^8.3.1",
diff --git a/gatsby-config.js b/gatsby-config.js
...
+const lost = require('lost');
+const lost_options = {"gutter": "30px", "flexbox": "flex", "cycle": "auto"};
diff --git a/gatsby-config.js b/gatsby-config.js
...
         postCssPlugins: [
+          lost(lost_options),
           require(`postcss-preset-env`)({

The React component to show skills

I wrote a simple React component, SkillShowcase, with the following data hierarchy (sort of schema) in GraphQL:

         areas {
           heading
           blurbs {
             heading
             text
             skills {
               product
               url
             }
           }

With the corresponding YAML for each area looking like this:

- heading: Technical focus areas
  blurbs:
  - heading: Observability/Alerting
    text: Generating and managing actionable alerts
    skills:
      - product: custom alerting
      - { product: OpsGenie, url: https://www.atlassian.com/software/opsgenie }
      - { product: PagerDuty, url: https://www.pagerduty.com/ }
      - { product: 'Prometheus alertmanager', url: https://github.com/prometheus/alertmanager }

Now, remember, this was the first React component I ever wrote - everything else up to this point was tinkering. I was pretty impressed with the speed and ease of development. It felt a lot like Literate Programming or even Lisp, and not as heavy as org-mode.

import React from 'react'
import _kebabCase from 'lodash/kebabCase'
import { Link } from 'react-feather';
import './SkillShowcase.css'

export default class SkillShowcase extends React.Component {
  static defaultProps = {
    items: [],
    className: '',
  }

  handleClick = event => event.target.classList.toggle('active')

  renderSkill(skill) {
    if (skill.url == null)
    {
      return skill.product
    }
    else
    {
      return <a href={skill.url} className="button">{skill.product}<Link color="orange" size={12} /></a>
    }
  }

  render() {
    const { items, className } = this.props
    return (
      <div className={`SkillShowcase ${className}`}>
        {!!items &&
         items.map(item => (
           <div
             className={`SkillShowcase--area `}
             key={`skill-area-${_kebabCase(item.heading)}`}
           >
             {!!item.heading &&
              <h2 className={'heading'}>
                <span>{item.heading}</span>
              </h2>
             }
             {!!item.blurbs &&
              item.blurbs.map(blurb => (
                <div className={'blurb'}
                     key={`skill-area-${_kebabCase(item.heading)}-${_kebabCase(blurb.heading)}`}
                >
                  <h3 className="description">
                    {blurb.heading}
                  </h3>
                  {!!blurb.text &&
                   <span>
                     {blurb.text} <br />
                   </span>
                  }
                  <ul className={'skilllist'}>
                    {!!blurb.skills &&
                     blurb.skills.map(skill => (
                       <li className={'skill'}
                           key={`skill-area-${_kebabCase(item.heading)}-${_kebabCase(blurb.heading)}-${_kebabCase(skill.product)}`}
                       >
                         {this.renderSkill(skill)}
                       </li>
                     ))}
                  </ul>
                </div>
              ))}
           </div>
         ))}
      </div>
    )
  }
}

Then it was really simple to add the CSS to use Lost Grid and put the components in 3 columns.

--- a/src/components/SkillShowcase.css
+++ b/src/components/SkillShowcase.css
@@ -1,22 +1,13 @@
 .SkillShowcase {
 ...
+  lost-center: 980px;
 }
 
 .SkillShowcase--area {
...
+  lost-column: 1/3;
+  padding: 1rem;

Code highlighting

Installing and setting up PrismJS according to the plugin docs was really easy.

Next steps

In the next blog post I'll talk about tinkering with the metadata and setting up images to get the site usable.