DEV Community

TJ Fogarty
TJ Fogarty

Posted on • Originally published at tj.ie

2 2

A Signal in the Static (moving to a static site)

About a year ago I set out to rebuild my site, and being reared on PHP I opted to go for Craft CMS while it was in beta. I figured it'd be interesting to learn it while it was still in development, and maybe create my own plugins.

Haha. Jokes. I did not. I tried, though, but never really needed anything extra.

I was also using Laravel Forge to automatically deploy whenever I pushed any changes to the master branch. To this day it's still a nice approach, but there's a lot of moving parts. I have a repo, a server that needs to be looked after (like when I updated PHP and broke everything), a database that needs to be backed up, and a CMS with some plugins that need to be kept up to date. Granted, I could not have touched it after day 1 and it would still work just the same, but that's not me. If it ain't broke, go fix it.

That's where the allure of a static site generator comes in. As far as the site goes, everything is in one place. Content lives in Markdown files which makes things pretty portable. I landed on using Hugo after seeing some recommendations for it, and in about a day I had my entire site copied over, including CSS and JS. To copy the content I took advantage of the Element API plugin for Craft to get a JSON object of all my posts. The config file for the plugin looked like this:

<?php

use craft\elements\Entry;
use craft\helpers\UrlHelper;

return [
  'endpoints' => [
    'posts.json' => [
      'elementType' => Entry::class,
      'criteria' => ['section' => 'posts'],
      'transformer' => function(Entry $entry) {
        return [
          'title' => $entry->title,
          'url' => $entry->url,
          'date_published' => $entry->postDate->format(\DateTime::ATOM),
          'slug' => $entry->slug,
          'body' => $entry->postContent,
          'categories' => $entry->categories->all()
        ];
      },
    ]
  ]
];
Enter fullscreen mode Exit fullscreen mode

So when it hit https://my-site.com/posts.json it returned everything I needed. I saved this to a file to quickly generate markdown versions like so:

const posts = require('./data.json')
const fs = require('fs')

function buildCategory({ title }) {
  return `- ${title}`
}

function buildFrontMatter(post) {
  return `---
title: "${post.title.replace(/"/g, '\'')}"
date: ${post.date_published}
draft: false
categories: \n${post.categories.map(buildCategory).join(`\n`)}
---`
}

posts.data.forEach(post => {
  let content = `${buildFrontMatter(post)}\n${post.body}`

  fs.writeFile(`../path/to/final/content/posts/${post.slug}.md`, content, err => {
    if(err) {
      return console.log(err);
    }

    console.log("The file was saved!");
  }); 
})
Enter fullscreen mode Exit fullscreen mode

I needed to run sudo node index.js on that as it needed to create files, but I didn't have to touch the generated markdown files once they were in the right folder.

Once that was done, I skipped on over to Netlify and hooked it up. I needed to do some configuration before everything would work. Mainly this was down to my assets living in a theme which was in a subfolder. To let Netlify know about it, I had to create a new package.json in the root with a build command that did the following:

[build]
publish = "public"
command = "hugo --minify && npm run build"
Enter fullscreen mode Exit fullscreen mode

Then the build command in my root package.json dug into the folder it needed and ran some more commands:

"scripts": {
  "build": "cd ./themes/nua && npm install && npm run production"
}
Enter fullscreen mode Exit fullscreen mode

After that, it was smooth sailing. Limerick just won the All-Ireland senior hurling final so I'm gonna grab a beer. That makes two victories today. Cheers, agus Luimneach Abú!!!

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs