Skip to main content

Redesign: CraftCMS Upgrade and Initial Design

I recently upgraded to CraftCMS v5.

I host on my own server and upgrading meant upgrading PHP to a supported version. Luckily, this didn't seem to pose a problem with the few other sites I host and maintain. But it was the most difficult part of the overall upgrade. CraftCMS's upgrade process could not have made it any easier.

The upgrade also meant a switch from the Redactor plugin I was using to write my posts to the CKEditor plugin which seems to have replaced it. This too was an easy switch. Overall, I've remained impressed by CraftCMS.

Site Design

I felt I was taking too long figuring out a site layout and design, so I just got to a point where I felt happy enough to continue on with other stuff, like adding pagination for my posts since I'll need that soon anyway.

Most pre-existing templates assume you want to have a lot of photos. I may upload a few at some point but it's primarily text-only. Doesn't give me a lot of options to choose from since I'm a programmer, not really a designer. I'll come back to it, but I don't want to get stuck on it for it.

The existing site leverages some css-grid and flex CSS to make the site responsive. The header/nav area are a bit clunky right now, but it'll do until I want to dive into it more.

Next up, I'll get into some CraftCMS coding to maybe show the most recent five posts on my home page and allow you to click a link to go back in time from there.

RailsConf and Site News

First off, RailsConf 2024 is in Detroit in a few weeks, and I'm attending. If you're reading this, it's likely that you know me somehow. My facial hair is likely more gray now, but I hope I'm still recognizable.

While I haven't posted about any site progress, I've been playing with colors/fonts a bit but haven't found anything I'm in love with.

And then CraftCMS v5 was announced so I'm looking into upgrading. I think I'm good except it requires me to upgrade the version of PHP on my server which I'm not looking forward to. If the site's broken, it's probably because I'm in the middle of that.

In the meantime, if you're at RailsConf, I hope we can catch up.

in News

Redesign: Page Layout

Now it's time to throw away my temporary CSS and start to work on my own. This post will focus on the overall page layout. Mainly having the entire page corresponding to a general width, and the aside area in a column to the right of the main content.

To do this, I did need to make one change to the HTML structure of the page to accommodate the index page, which lists multiple posts.

<!-- former layout -->
  <main>
    -- main content --
    <aside>
      -- sidebar content --
    </aside>
  </main>

<!-- updated layout -->
  <main>
    <section>
      -- main content --
    </section>
    <aside>
      -- sidebar content --
    </aside>
  </main>

While the former layout worked fine with a single article, the aside area it wouldn't play nicely. The updated layout makes a bit more sense as you can clearly see that the section area is one column, and the aside is another.

The skip to main content link

I'm blatantly stealing some code from Garett Dimon's site for this. Even copying his comments with a brief change because he included his within his HTML for reasons explained in the comments.

/*
 This is the position-related CSS for the "Skip to Content" links. It can be included directly in
 the HTML document to ensure that the link isn't rendered within the viewable area and then
 abruptly and obtrusively moved off-screen after the CSS loads.
*/
a[href="#main-content"] {
  display: inline-block;
  position: absolute;
  transform: translateY(-300%);
  transition: transform 0.3s;
}

/*
 This CSS brings the "Skip to Content" link into the viewable area when it's focused. That
 way, if someone tabs into the site to navigate via keyboard, they'll see the link and can
 interact with it like any other control on the page.
*/
a[href="#main-content"]:focus { transform: translateY(0%); }

Setting up initial variables

Modern CSS finally has the ability for you to setup root level variables that you can reference in other parts of your CSS. I'm just setting up for a light theme right now, but since I do plan to add a dark color scheme, I'm just putting stuff for that in place now so I don't have to go digging for it later.

:root {
  /* https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme */
  color-scheme: light dark;
  --background-color: #f8f8f8;
  --text-color: #333;
  --link-color: #005ec6;
}
/*
@media (prefers-color-scheme: dark) {
  :root {
      --background-color: #??;
      --text-color: #ccc;
      --link-color: #005ec6;
  }
}
*/

Primary Block Layout

The three main areas of the page are the header, the main-content, and the footer. Here's the CSS that set's all this up.

body {
  background-color: var(--background-color);
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  max-width: 89em;
}
/*
 This and the max-width above keep the width of the
 main content areas from getting too wide. The margin
 here centers everything once the max-width is reached.
*/
@media screen and (min-width: 90em) {
  body {
    margin: 0 auto;
  }
}

body > header, #main-content, body > footer {
  padding: 0 5vw 0 5vw;
}

/*
 I'll pay more attention to the header in a future post.
 for now, this grid just spreads it out evenly at the top.
*/
header nav ul {
  align-items: center;
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}

footer {
  text-align: center;
}

The main content and aside areas

I found some magic that puts the aside area on the right of the page, but nicely flows it to the bottom on smaller screens.

The css keeps the main content section to a column taking 70% of the space. The aside taking 25% leaving a 5% space between the two.

The width calculation is the magic I was referring to. A negative width isn't understood, so it's defaulting to the min-width setting of 70% since it can't get lower than that. When the content is wider than 48em, width is set wide enough that the max-width setting of 100% kicks into gear.

#main-content {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  justify-content: space-between;
}

#main-content > section {
  max-width: 100%;
  min-width: 70%;
  width: calc((48em - 100%) * 1000);
}

#main-content > aside {
  max-width: 100%;
  min-width: 25%;
  width: calc((48em - 100%) * 1000);
}

Basic content styling

To round things out for now, I'm just using the color and styling I want for my links (at least for the light theme) and put a max-width for my article images so wide images don't break outside the area and throw off my layout!

a {
  color: var(--link-color);
  text-decoration: none;
}
a:hover {
  border-bottom: dotted 1px var(--link-color);
}

article img { 
  max-width: 100%;
}

That's it for this time. I'm not sure right now if I'll focus on the header area, or do something more with the colors or something for next time. Stay tuned.

Redesign: Article Content

I now have a main element to contain the primary content of the site. As I write this, here's the generalized code.

<main id="main-content">
  <section class="main">
    -- article content --
  </section>

  <aside>
    <div class="byline">--content--</div>
    <section class="lists">
      <h4>Categories</h4>
      <ul>
        <li><a href="">--category 1--</a></li>
        <li><a href="">--category 2--</a></li>
      </ul>
    </section>
  </aside>
</main>

I was keeping the main-content class on the main element as a hook for my Skip to main content link at the top of the page, but I'll strip all the other classes out for now.

I doubt I really need to wrap my article content with a section element, so I'll drop that, too. Articles are already wrapped within an article element.

The aside content was a sidebar area and that's what it will continue to be. The byline area is text so I'll make that plain p element right now. The Categories heading was an h4 purely for sizing. Semantically, I think that should maybe be a header instead to leave the h1/h2/h3/etc. tags more relevant to the main content area.

That leaves me with main content area looking more like this.

<main id="main-content">
  -- article content --

  <aside>
    <p>--content--</p>
    <section>
      <header>Categories</header>
      <ul>
        <li><a href="">--category 1--</a></li>
        <li><a href="">--category 2--</a></li>
      </ul>
    </section>
  </aside>
</main>

That feels better, but I may want some tweaking there once I start implementing a design.

Article Content

For the article content itself, the broad building blocks are in a template with CraftCMS but what you're reading comes mainly from me typing into a content editor.

<article>
  <header>
    <h1>-- title --</h1>
  </header>

  <p>Start of the actual post</p>
  <pre><code>A code block</code></pre>
  <h3>A subheading</h3>
  <p>More content</p>  

  <div class="metadata">
    <time class="text-sm block pb-4" datetime="2024-01-21">21 Jan 2024</time>
    in <a href="">--category 1--</a> <a href="">--category 2--</a>
  </div>
</article>

Everything's wrapped in an article element which I'll keep as that's exactly what this content is wrapping.

The title is wrapped in both a header and h1 element. I'm not sure if I really need both, but I'm leaving them.

Running my existing content through an accessibility checker, I got some marks against me because I was using h3 tags for the subheadings when it expected h2 in order for the page hierarchy to not be confusing for screen readers. I'll start using h2's from now on and keep them in proper order. It's another instance of me using elements for styling. Other than that, the majority of the content would be img and p elements.

The metadata div is really an article footer. So if the article can have a header, it can have a footer. I'll update that. The time element has some classes on it that I probably copy/pasted from some example. I'll take those out.

That leaves us with this, which is much cleaner.

<article>
  <header>
    <h1>-- title --</h1>
  </header>

  <p>Start of the actual post</p>
  <pre><code>A code block</code></pre>
  <h2>A subheading</h2>
  <p>More content</p>  

  <footer>
    <time datetime="2024-01-21">21 Jan 2024</time>
    in <a href="">--category 1--</a> <a href="">--category 2--</a>
  </footer>
</article>

I think that wraps up what I feel is much better for the HTML layout and structure of the site. I'm skipping at least the search listing page, but it won't be too much different from the home page, just not displaying as much content.

Next up, I'll need to drop the temporary styling I've been using and go to work on the CSS. Initially it will be around layout before I get into fonts/colors.

Redesign: Header and Footer

After my last post, therealadam posted about some Low-key CSS libraries. These are small CSS libraries which don't do anything much more than style your baseline HTML elements.

Which was perfect for the current state of my site since I stripped my own styles away. I've gone with new.css as it's decently close to what I'm aiming for although I do plan to go with my own custom CSS long-term. This works until I actually start working on that to have something.

That said, let's start with the intent of this post which is the HTML structure of my header and footer sections.

Footer

The footer is really simple. I don't think it needs to change.

<footer>
  <p>
    Copyright © Updrift, all rights reserved.
    Powered by <a href="//www.craftcms.com">Craft CMS</a>.
  </p>
</footer>

A literal line of copy. If anything, I'm just not sure if the copyright should be me personally or Updrift, but I'll check that out later as that doesn't really pertain to the HTML structure.

Header

There's a bit more to the header section. I'll exclude the skip to content link, as that exists outside the header.

<header>
  <div class="logo">
   <a href="/"><img src="/assets/general/updrift-logo.svg" alt="Updrift logo" height="25" /></a>
  </div>
  <nav>
    <ul>
      <li class="selected"><a href="/">Home</a></li>
      <li><a href="/about">About</a></li>
      <li><a href="/contact">Contact</a></li>
      <li class="search">
        <form action="https://updrift.com/search/results">
          <input type="search" name="q" aria-label="search" placeholder="search">
          <button type="submit">Go</button>
        </form>
      </li>
    </ul>
  </nav>
</header>

There are three different things that are kind of related.

  1. Logo / nav link to the home page
  2. Actual nav links to the main areas of the site
  3. Search form

The logo is technically navigation, so It should be included in the nav block. I'll move that into the unordered list that's a child of that element. As it's a secondary link to the home page, I'll go by the W3C recommendations for functional images and set the alt value to an empty string since it performs the same function as the Home link. I'm leaving the Home link as it's text that can be read by a screen reader.

Speaking of the unordered list (ul), I feel it's appropriate because it literally is a list of nav items. The nav element itself gives me enough of a hook for styling that I shouldn't need any additional classes except for a selected class that goes on the li tag if you're on the About or Contact pages.

The search form is also navigation related in the sense that it will take you to a different page.

This leaves me with the following structure.

<header>
  <nav>
    <ul>
      <li><a href="/"><img src="/assets/general/updrift-logo.svg" alt="" height="25" /></a></li>
      <li class="selected"><a href="/">Home</a></li>
      <li><a href="/about">About</a></li>
      <li><a href="/contact">Contact</a></li>
      <li class="search">
        <form action="https://updrift.com/search/results">
          <input type="search" name="q" aria-label="search" placeholder="search">
          <button type="submit">Go</button>
        </form>
      </li>
    </ul>
  </nav>
</header>

That's not a drastic change from what I had. Ironically, having an empty alt tag on the logo is flagged by accessibility checkers, however, I'm doing exactly what W3C recommends so I'll go with W3C for now.

I know there's likely a bit of aria attributes I should add, but I'll defer that to a broader accessibility effort later on.

Next up, I'll look at the main content which, for this site, would be blog post content.

Redesign: HTML structure

With this post, I'm going to remove the styles from the site completely and focus on the HTML elements and structure alone.

For now, I'll focus on the HTML elements for the overall page alone then dive into the individual parts in future posts.

For posterity, here's what my current site's home page looks like with a bit cut out so we can see the top/bottom of the page.

Old design

Removing the styles, I fortunately have something that's still functional and not a complete mess. Things will just be a bit unstyled for a while as I work through things. If I actually have any followers anymore, they likely read my stuff through an RSS feed and the styling doesn't matter anyway.

Here's what that looks like.

Current Page Structure

Here's the general structure of the page itself.

<body>
  <header>
    -- header content--
  </header>
  <section class="page">
    -- page content --
    <section class="sidebar">
      -- sidebar content --
    </section>
  </section>
  <footer class="site">
    -- footer content --
  </footer>
</body>

This isn't really the best. Looking at current HTML documentation, I should probably replace the page section with a main element, and the sidebar section with an aside element that exists within the main element.

Additionally, as stated in the main element's HTML documentation, adding an id to it allows it to be a target for a skip navigation link. I want that, so I'll go ahead and add it along with the skip link at the top of the document.

I'm not sure if I'll need the class for the footer element. So I'll drop that for now and add it if needed later.

Resulting Page Structure

This leaves us with a much more modern html structure.

<body>
  <a href="#main-content">Skip to main content</a>
  <header>
    -- header content --
  </header>
  <main>
    -- main content --
    <aside>
      -- sidebar content --
    </aside>
  </main>
  <footer>
    -- footer content --
  </footer>
</body>

Next time, we'll address the header and footer sections.

Redesigning the website: What's in <head>

First, let's examine what's in the <head> area of my current site. Note that whatever's wrapped in {{ }} tags is Craft CMS code.

<!DOCTYPE html>
<html lang="{{ craft.app.language }}">
<head>

  <!-- Internet Explorer? Well, won't need this! -->
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />

  <!-- Next part is pretty standard. -->
  <meta charset="utf-8" />
  <title>{{ siteName }}</title>
  <meta http-equiv="Content-Type" content="text/html; charset={charset}" />
  <meta name="description" content="{{ craft.app.globals().getSetByHandle('siteInfo').siteDescription }}" />
  <meta name="keywords" content="Wade, Winningham, Wade Winningham, Updrift, Ruby on Rails, PHP, MySQL, Craft CMS, HTML" />
  <meta name="author" content="Wade Winningham" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />

  <meta name="referrer" content="origin-when-cross-origin" />

  <link rel="shortcut icon" href="/favicon.ico" />

  <link rel="manifest" href="/site.webmanifest">

  <!-- Links to rss/atom feeds for those who use RSS Readers -->
  <link rel="alternate" type="application/rss+xml" href="{{ url('feed.rss') }}">
  <link rel="alternate" type="application/atom+xml" href="{{ url('feed.atom') }}">

  <!-- Link to an Adobe webfont. I'll drop this in the redesign. -->
  <link rel="stylesheet" href="https://use.typekit.net/mbc8gkz.css">

  <!-- CraftCMS embedding the css file -->
  {% set stylesheet = rev('main.css') %}
  {% if stylesheet %}
    <link rel="stylesheet" href="/{{ rev('main.css') }}">
  {% endif %}

<!-- The rest of this is page view tracking for Matomo -->
<!-- which I host myself rather than use Google -->
<script>
  var _paq = window._paq = window._paq || [];
  /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  (function() {
    var u="//updrift.com/matomo/";
    _paq.push(['setTrackerUrl', u+'matomo.php']);
    _paq.push(['setSiteId', '1']);
    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
    g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
  })();
</script>
</head>

Referrer

Based on the info in this article on referrer best practices, one meaningful change I can make is to set my referrer policy to strict-origin-when-cross-origin for the reasons within that post.

While that seems to be the default for most browsers today, it's not guaranteed, so seems best to be explicit.

Viewport

The viewport value is stale. Been forever since I'd have set that. One item, the user-scalable=no can be bad as the documentation indicates it can cause accessibility issues. Which makes sense as it doesn't allow for scaling the screen for those with visibility issues.

So I'll reset that to a safer value of width=device-width, initial-scale=1 and can adjust it if necessary when I get more into the layout and design later.

Manifest

A site.webmanifest file isn't required, but nice for Android devices. So I'll keep it basic.

{
  "name": "Updrift",
  "short_name": "Updrift",
  "description": "A blog from Wade Winningham on tech, development, and building web sites and appliations.",
  "icons": [
    { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
    { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
  ]
}

Favicon

I'm going to stick to the recommendations in this evilmartians.com post and use these lines.

<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/site.webmanifest">

I already included the necessary bits in my site.webmanifest file above.

Summary

And there we have it. You can just view source on my site to check out the current status of it.

A bit of it is just the embed code for Matomo, but I may replace that with https://umami.is before I'm done. Hopefully it has less embedding code. 

Restarting my website from scratch

Last year, I had the intention to re-launch this website.

Here we are at the end of 2023 and that didn't happen. I'm a year late now. Another year won't pass me by with no action, so I'm cranking this side project up.

What kind of content will be on this site?

Updrift has always been intended to be my work-side. What do I do for work? I'm a developer, which would imply this site would have developer related posts.

The topics will be varied. Programming related mostly, but I'll probably write about my search for a new office desk, as well.

What's first?

First up, is a new logo. My original one feels a bit outdated to me and the orange-y color doesn't lend itself well to both light and dark backgrounds.

old-updrift-logo
Old Updrift Logo

The icon was reminiscent of a wave or swirl of wind.

Introducing the new Updrift logo, which makes use of Dan Cederholm's Cartridge Font available at simplebits.com. My wife, Pamela Winningham, came up with the new icon which is patterned after a parachute riding the air currents. She also hand-kerned a few of the letters.

new-updrift-logo
New Updrift Logo

What's next?

Soon, I'll strip away the styles on this website completely and start building a fresh site design step-by-step. Documenting everything here along the way.

My goals are:

  • Hand coded CSS. No frameworks like Bootstrap, Foundation, or Tailwind.
  • Limited Javascript. At first I was thinking absolutely none, but I would like to keep track of simple metrics like web views. That typically entails some javascript or possibly some hidden image. May use some to colorize code examples, as well.
  • Accessible. I'm amazed more business sites don't pay attention to making their sites and applications easier to use by everyone. Individual developers tend to pay more attention to it. Businesses mainly seem to care after a lawsuit is initiated.

That's mainly it. So expect a mess for a while. I'm sure once I start, it'll be slow going.

I plan to stick with using CraftCMS which I'm still happy with.

in News

Developing my CraftCMS site locally and deploying it

As mentioned in my previous post, I'm still in the middle of converting my old Expression Engine version of this site over to CraftCMS.

Local Development

I've kicked the tires on CraftCMS a few times before. Each time they had a different method of getting a local development environment set up. The fluctuation of varying methods seems like it would be irritating, but I've seen how much easier each one has made things. Therefore, I find it refreshing that they're always willing to move to something better rather than getting stuck with stale technology.

The current method entails using Docker with DDEV, which has made it really easy to set up a local environment.

I already use Docker for work, so it feels right to use it here. Starting up is as simple as moving into my local directory and typing this:

ddev start

This sets up a local URL where I can view and work with my site pretty much the same as it looks completely live, just how you'd expect and want it to work.

When I'm finished, whether that's updating templates, trying a new plugin, or setting up a new section, I type the following to shut things down.

ddev stop

Deploying

I set up a new cloud server at Vultr. I've hosted with them for a while and don't have any complaints.

Here's the general overview of the steps I went through.

  1. I used manual server setup instructions which I wrote for myself from past installations. This includes setting up the basics like the database, PHP, Apache (I'm just more used to it than Nginx).
  2. Created a server user for my site.
  3. I then followed the composer method from the Craft CMS do to install it.
  4. Created a backup of my local database that I then imported into the server's databases.
  5. Copied files from my local installation.

This got me almost completely functional except for one thing.

I only use a few plugins for this site, but I couldn't enable them. The admin area allowed me to and reported that they were enabled but they never actually flipped to being actually enabled.

The solution was to simply re-install the plugins using composer. That did the trick, and the entire site seemed functional afterward. I just finished up this post leaving the absolute last step, which is to point my domain over to the new server.

Manually copying files?

Wondering why I'm not setting this up with some fancy Github automated deployment? Well, I probably should, but it's just a small site I can easily back up. Any changes, I'll just work on the live site. I know.

What's Next?

  • Pagination. Since I'm just starting out, I don't really need it yet. I'll add it after I post some more.
  • Excerpts for the home page. Maybe. I don't plan to write monster posts. On the fence right now about this one.
in News

Relaunching the site with Craft CMS

After many years on ExpressionEngine (EE), I've finally converted over to Craft CMS.

I say finally because I've been eyeing Craft CMS for a long time.

Around 2012/2013, Pixel & Tonic, one of the primary developers of EE add-ons, created Craft CMS out of the frustration they and other third-party EE developers were experiencing at the time. Craft CMS's launch caused somewhat of a mass exodus from EE.

Eventually, EE was bought by Packet Tide, another big add-on developer, who I feel have done their best to bring EE closer to a modern CMS.

But maybe a bit too late. ExpressionEngine is still playing catch-up.

You can see the influence of Craft CMS in the last few versions of EE. EE is following now rather than leading. The two CMSs are still very similar since Craft CMS was born out of ExpressionEngine. But Craft has completely overshadowed it.

Why Craft CMS?

I really loved ExpressionEngine. It just made sense to me when WordPress, Drupal, and Textpattern (other CMSs I've had experience with) did not, or were simply difficult to work with.

Even the latest version of EE feels like more of a visual change than an architectural one. Living with Craft CMS for a bit now, it's simply more polished, and their developer support is outstanding. The process of setting up fields and templates, even editing content, is still familiar to my EE experience, just way much smoother.

The main thing that held me back is that I had a number of client sites that were built with ExpressionEngine, and they weren't going to be trivial or cost-effective to convert. Primarily due to relatively expensive add-ons for event scheduling and e-commerce.

Fortunately, those clients re-did their sites or were able to downsize sufficiently that moving them to Craft CMS has become more viable. Having those sites to convert over and continue to maintain was the deciding factor for choosing it for the site you're reading right now.

To be honest, I would definitely choose Ghost CMS if it wasn't for the other sites. I really love Ghost, but it is for blogs and not anywhere near as customizable as Craft CMS. Having this site in Craft CMS gives me a good playground for the others.

First Impressions

So far, my experience with EE has made it pretty smooth to get into Craft. A number of years ago, I had gone through some how-to videos on CraftQuest, which were a huge help. I plan to revisit some of their screencasts.

As I write this, I just have basic, non-styled HTML until I choose a template design I want to go with. By the time you read this, I'll have had that sorted out. I have no worries.

I'm excited to start this new journey with Craft CMS.

in News