2018 year end review

Highlight of my 2018 summer was visiting Zion, Bryce Canyon, and the Grand Canyon.

As 2018 comes to a close, I’m doing what I do every year and reflecting on the year gone by and looking ahead to 2019. This was a year where I believe I struck more of a work/life balance than previous years when I may have been a bit too ambitious. I learned a few things about technology and had many “first” experiences.

Dove into front-end frameworks (finally)

I’ve dipped my toes in the water during years past, but this is the first year I really got going. I have a working prototype of several apps, all connected to Firebase or FireStore. Vue is definitely my framework of choice right now, I find it very approachable. It might help that I got a subscription to VuevMastery which has taught me a TON. So I feel like I understand this framework better than React for that reason.

Dog log – Prototype built with React to demo an idea. The idea was to have an application that my wife and I can both login to that would allow us to see the last time the dog has been outside.Ego education – Prototype application built with React to allow me to keep track of ACIM Workbook lessons. The lessons help me with mindfulness and keep me focused on what is truly important throughout the day.

Yoga app – Prototype built with VueJS. This application allows you to do Routines comprised of different Asanas. You can name and save your Routines. The app uses Firebase to store the information.

Dining menu – This prototype is from work and was built with VueJS. Data is coming from a vendor’s service and being “massaged” with a piece of middleware, then stored in FireStore before Vue grabs it. Prototype has the ability to login, and add “Favorites”.

New marketing pages at work – With the help of the Digital Services and Marketing teams, we were able to get some awesome work done, including a new “Academics” section of the site, Program Finder, and a revised program page template. This process also gave us a rough blueprint for how to tackle the rest of the higher-level pages on the site. Links and pictures are in tweets below.

Beyond technology, I had some good life experiences that were significant. Visiting the Grand Canyon, Bryce Canyon, and Zion National Park were among the experiences. As was hosting our first Thanksgiving (successfully).

Got a new desk setup (I have still yet to get a dimmer)

That about wraps up the highlights of 2018 (that I can think of currently). Here’s to a great 2019. 🥂🍾

Switching my WordPress sites to https on GreenGeeks

I’ve used GreenGeeks hosting for years now and I really enjoy their services. I’m going to briefly talk about my experience moving two of my WordPress sites to SSL on GreenGeeks shared hosting. Moving to https used to be a little more of a pain in the butt, however thanks to Let’s Encrypt and forward-thinking web hosting providers, it’s now a breeze

First, I simply submitted a ticket to GreenGeeks to have them set up a Let’s Encrypt SSL cert for the sites that I wanted https on. In my situation, I had one site whose domain name was run through their nameservers and in that case they immediately were able to enable https. On my second site, however, I am using Google domains for DNS management. In this case, I just had to get a couple of DNS records from GreenGeeks support and viola, I was up and running. Their support team did a great job explaining what I needed to do.

There was one small problem remaining. I could still access the sites on http as well as https. So the last piece of this was to redirect http traffic to https. I did this in 2 steps.

  1. Change the site and home URL in your WordPress site to reflect the new https URL.
  2. Using .htaccess add a few lines to your WordPress htaccess file (shown below)
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://josephfitzsimmons.com/$1 [R,L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

I am a professional

I’ve been a professional programmer for about 6 years now and I thought I’d share a story about something stupid I did. I think a lot of new programmers or people just trying to get into the field of web development feel dumb or get frustrated easily when things don’t work.

When I was just starting out, I considered someone who had 6 years of experience something of a “guru” who knew everything about the terminal and could code their way out of any situation.

I decided to sit down and continue learning Vue. Before starting, I was trying to make it so VS Code would launch from the terminal, so I did what I normally do and Googled it. Now I could’ve done it right from VS Code, but instead I tried to do it manually by editing my .bash_profile to add VS Code to the $PATH.

Turns out I didn’t actually append it to the path, I replaced it. So that means the only thing in my PATH was `code`. Needless to say, this completely screwed up my environment and my Mac terminal became essentially useless.

  • `ls` wouldn’t work
  • `git` wouldn’t work
  • every basic command wouldn’t work

I couldn’t launch code editors, drush didn’t work, composer didn’t work, node didn’t work, npm didn’t work. I thought the only way to get out of this mess was to factory reset. Before I did that, I Googled the issue “screwed up my $path mac” and luckily found an answer that made sense. I found a working solution for how to “reset” my $PATH variable so things would be usable again. Once my basic utilities were back, I was able to reconnect my dotfiles and I was back up in running.

The situation was a good reminder that even people who seem to know what they’re doing really don’t. 🤪 The only difference is that I have 6 years experience of Googling my way out of problems with computers.

Design is never done

“People are time bound entities transiting from cradle to grave. Any “solved problem” that involves human beings solves a problem whose parameters must change through time.
– Bruce Sterline, 2005

The bold emphasis is mine. This quote is from a Luke Wroblewski tweet that resonates strongly with me as a web designer/developer. If the point of design is to solve a problem, it must be accepted that the parameters of that problem must change through time as our environment and people change.

On top of the tweet which mentioned the above quote, Luke Wroblewski has a “Design is never done” series of tweets that further exemplify this idea.

For more examples of the “design is never done” concept, check out this advanced Twitter search.

This concept is an important one to hear, especially within higher education where change is often perceived as scary, unneeded, threatening, and has a number of other negative connotations. There is no “ideal state” that we will reach that will mark a website as “done.”

Investing in personnel who can execute ideas and ensure that digital assets can continue to evolve is extremely important in IT, communication, and marketing efforts within higher education.

Without this investment, organizations are reliant on 3rd party vendors, who may do a fantastic job, but it certainly isn’t the same as having a team on staff who can respond to the evolving needs of stakeholders and visitors.

My Terminus Drupal 7 cheat sheet

The Terminus documentation is amazing. However, I tend to only use a couple commands over and over so I created this post so I can continually reference it and have some “copy/paste” ready commands to use on my projects.

Get a URL to the latest snapshot of my production database

terminus backup:create <site>.live --element db
terminus backup:get <site>.live --element db

Adding a new module and committing it to dev

terminus connection:set <site>.dev sftp
terminus drush <site>.dev -- en paragraphs
terminus env:commit --message "message" <site>.dev

Using different template (tpl.php) files for a specific content type in Drupal 7

Use case

In one of our sites, we post email communications that were sent out as all-campus announcements on our website.

The problem is, our basic web template does not look like an email template.

So I thought, “I wonder if I could just load a separate set of tpl.php files based on the content type.” Spoiler alert: I could.

I wanted a solution that didn’t require hacking my original theme. I wanted to leave the current theme untouched and simply provide new html.tpl.php and page.tpl.php for this specific content type (presidential_email).

Start with Features

This step is technically optional. If you don’t have a local or dev environment then you don’t need to package your content type in a feature. But for those of us who have to push code through dev -> stg -> prod, features is the best route so you don’t have to rebuild the content type on each environment.

Create your content type in your local environment. Add fields to your liking. Now export that content type using Features.

I typically use the “Generate Feature” functionality under Advanced Options, but you can do whatever you want. Generate Feature allows me to write the code directly where I want to. In this case, it was sites/all/modules/custom.

Fire up your code editor and add your hooks

Go to your sites/all/modules/custom directory and you should see a folder in the path you specified with your content type exported into a Features module.

Add your hooks to your modulename.module file to really get cookin’!


In your hook_theme implementation, you want to specify the new tpl files you want to use. In my case, I want this module to override html.tpl.php and page.tpl.php for the presidential_email content type.

 * Implements hook_theme().
function presidential_email_theme($existing, $type, $theme, $path) {
    $theme = array();
    $theme['html__presidential_email'] = array(
        'render element' => 'content',
        'base hook' => 'node',
        'template' => 'html--presidential-email',
        'path' => drupal_get_path('module', 'presidential_email') . '/templates',
    $theme['page__presidential_email'] = array(
        'render element' => 'content',
        'base hook' => 'node',
        'template' => 'page--presidential-email',
        'path' => drupal_get_path('module', 'presidential_email') . '/templates',
    return $theme;

Create your templates folder and files
In your created module folder, add a templates folder. The above functions are telling Drupal to look in yourmodule/templates for html–presidential-email.tpl.php and page–presidential-email.tpl.php.


Depending on your use case, this could be optional. In my case, I didn’t want ANY of the typical CSS to be loaded because I wanted to use inline styles created by the MailChimp template. To achieve this, my hook_css_alter looked something like this:

 * Implements hook_css_alter().
function presidential_email_css_alter(&$css) {
    $node = menu_get_object();
    if ($node && $node->type == 'presidential_email' ) {
        foreach ($css as $k => $v) {
            if (!strpos($k, "navbar")) {

Essentially, this code checks to see if the current node is a ‘presidential_email’ and then loops through all the CSS files, unsetting them all unless it’s necessary for the navbar (I still want it to look presentable while logged in).

hook_preprocess_html and hook_preprocess_page

Last but certainly not least, this method only works if you have auto-generated template suggestions based on node type. For instance, consider my template_preprocess_html and template_preprocess_page functions (replace template with your theme name).

You could also put these in your .module file changing ‘template’ in the function name to your module name.

 * Implements template_preprocess_html().
function template_preprocess_html(&$vars) {
    $node = menu_get_object();
    if ($node && $node->nid) {
        $vars['theme_hook_suggestions'][] = 'html__' . $node->type;

 * Implements template_preprocess_page().
function template_preprocess_page(&$variables) {
    if (isset($variables['node']->type)) {
        $nodetype = $variables['node']->type;
        $variables['theme_hook_suggestions'][] = 'page__' . $nodetype;

I wrote these at different times in my Drupal career but they do the trick. A content type of “presidential_email” will now produce template suggestions for html–presidential-email.tpl.php and page–presidential-email.tpl.php.

With this in place, the module will now load templates in the module’s template folder when the presidential_email content type is being displayed. Worked well for my simple use case!

How to do a basic accessibility audit on your site

Here are some tools and methods for running an accessibility audit on your site. This can be a little bit easier if you already have a design system or component library in place, but it isn’t necessary to gain some insights into how your site can be more accessible.

The way I usually do it is I first run some automated accessibility checkers, then I do some manual testing. I’ll unpack what this means below.

Note: most of this information is a summary of the W3C’s WCAG site, which is the authority on recommendations regarding web content accessibility. The content on that site can be a little dense so hopefully this provides a good summary and jumping off points.

Free automated accessibility checkers

One thing that is important to remember when using automated tools is that they are not perfect. Just because your site “passes” an automated check doesn’t mean that it is accessible. Also if your site has errors, that doesn’t necessarily mean that it is inaccessible.

Web accessibility evaluation tools can not determine the accessibility of Web sites; they can only assist in doing so.

That being said, it is still quite valuable to run automated checkers on your sites because they can assist in catching errors before manual testing takes place.

One of the more popular automated checkers is WAVE by WebAim. This site allows you to enter a URL and then get a live preview of your site with highlighted accessibility issues in there. It certainly isn’t perfect because it can report some false positives, but it’s a great way to catch obvious issues and contrast errors.

Image of accessibility audit on my site through WAVE.
WAVE’s accessibility audit

Further reading

Manual testing

Here is where the “real” accessibility testing comes in. I say “real” because these methods are actually emulating how users with disabilities actually use your site. Manual testing also can help find gaps in your automated testing.

Keyboard navigation

A basic principle of WCAG 2.0 recommendations is that your site should be operable using nothing more than a keyboard. Give it a shot. Run through your site using your keyboard by pressing tab. Many users with limited motor control rely on keyboard navigation to navigate web sites.

  • Can you access all the links in a logical order?
  • Does advanced functionality like carousels work with keyboard controls?

Reading up on the tabindex attribute can provide enough know-how to make your site way more accessible.

Using voiceover or screen readers

I’m on a Mac so it was quite eye-opening for me to browse sites using the built in Voiceover functionality that comes with all Macs. Using Voiceover shed some light on accessibility principles that I never really understood properly.

For example, we all know the basic rule-of-thumb that alt text is good to use on images. But when using Voiceover, alt text can actually hinder understanding of certain elements such as images with text over them.

Consider this simple image block:

Image block example with text overlay

This image block has alt text of “Student at computer,” which most accessibility novices would assume is a good thing. However, Voiceover reads this element as “Link, Online MBA ranks highest in state student at computer.” This is less than ideal because it is actually less meaningful than if it had alt=””. In situations like this, screen readers tack on alt text to the text that is in the element. By using alt=”” in these situations you can be sure that screen readers will obtain the true meaning of the element.

This is a great example of something that can only be caught using manual testing.

In closing

This was a very brief overview of some tools, resources, and techniques to test your site against WCAG 2.0 accessibility recommendations.

To take it to the next level, there is no substitute for reading the WCAG 2.0 site and browsing through the quick reference provided by the W3C on how to meet the recommendations.

Happy auditing!

Launching a college news site with Drupal

SUNY Oswego recently switched from a legacy install of Expression Engine to integrating with the rest of our web platform and using Drupal hosted by Acquia to “re-design” our new News site. Hopefully this post will help others thinking of migrating to Drupal and provide some helpful tips if you’re already in the process of doing so.

Our old site

Even though our old news site was in Expression Engine, the power of it being a PHP/MySQL app wasn’t fully utilized.

Now, this is through no fault of our office, it just hasn’t been looked at in a very long time. The old site worked well enough for what we needed so we left it alone until an opportunity presented itself to give it a little update.

As a result, the homepage was consistently static. Photos and images were dumped into one WYSIWYG text blob which meant it was difficult to display teaser photos or do anything that is possible with structured content.

Photo captions were placed at the bottom of the articles, separated from their photos. Tagging had no specific function other than creating a word cloud that kinda looked cool. Categories weren’t maintained and difficult to browse by. Finding a list of just all news ordered by date was a hard task to complete.


Moving forward

In order to move forward and utilize Drupal to the fullest extent, we planned out content types, audited our workflow, and looked for areas that could be improved as we moved into Drupal.

Auditing our content types

First we sat down and looked at what kind of content was being created. We had a few different content types that were regularly published. News story, People in action, and Spotlight. All of this content was published using one content type and tags to differentiate them in the system.

For the new news site, we now have the same three as before, plus a new Media mention content type. I separated each piece of content into different content types. This allows us to style the content differently and add different fields depending on what the content type needs. The content types are:

  • News story
    • This is the bread and butter of the news site. Most of the content being entered is a news story about something awesome happening on campus.
  • People in action
    • This content type is for faculty, staff, and students who are doing cool things but it’s not necessarily enough to make an entire story or Spotlight out of it.
  • Spotlight
    • This is for highlighting faculty, staff, and students in an in-depth in a Q&A format.
  • Media mention
    • When a news outlet picks up one of our stories, we log it in this content type and display it on the news site to show how our word of our college is spreading.

Social media sharing

When we looked at our analytics of the old site, it wasn’t surprising to find that a large portion of our traffic was when something was shared to Facebook or Twitter. This made the decision easy to invest some resources into:

  • Making sure that the site is easily sharable
  • Making sure the teasers look good on accounts

Metatag module to the rescue

The Drupal metatag module was a YUGE help in making sure that our teasers looked good when shared on social media. If you’re using Drupal, this module is a no brainer.

Beautiful social media teasers, made possible by content strategy and the metatag module.

Google news sitemap module

Another must-have module is the Google news sitemap module. This ensures your articles and content are in a format that is easily consumable by Google. This allows our news stories to be indexed by Google news.

How our news stories appear in Google news search results
How our news stories appear in Google news search results

Human-centered workflow

Last but certainly not least, massive improvements were made to the editorial experience. Drupal gives a site maintainer/developer a tremendous amount of control over the editorial experience, which I tried to leverage as much as possible to make the site easy to update and maintain.

Tabs for each type of content

I’ve referenced this technique in another post and I can’t recommend it enough for improving the editorial experience. By cloning some administration views, we gave editors a super easy way to look at all content of a certain type. This helps reduce cognitive load, making editors more efficient.

Our news admin content interface
Our news admin content interface

I can’t tell you how many times I’ve logged into Drupal with a task in mind, and by the time I figure out which admin area I need to go to, I’ve forgotten what I was doing. Small shortcuts like this technique can reduce these errors and make people’s lives a little better.

Make common tasks as easy as possible

One of the tasks that our news team needs to do is to switch out our featured story once or twice a week, depending on what is happening on campus. I tried to make this as painless as possible, understanding that our writers are not web people. They’re writers. They shouldn’t need to be a web genius to change the featured news story.

Using a combination of views and nodequeue, I added a column to the “News Stories” content tab that allows our senior editor to simply click a link to make that story the featured story on the home page.

Using Views and Nodequeue, a link was added to our news stories admin list to make switching the featured story as easy as clicking a link

Make content guidelines visible

For each of the different types of content, guidelines were developed to ensure that the content would look great once no matter where it is syndicated or in what context it is used.

To help editors know what character count they are at for the summary, I wrote a small module that counts characters for the summary field. As you can see from the screen shot, even the greatest technical solution is at the whim of people and process.


A major feature of this news site is now the ability to syndicate news stories from the news site to academic department and college sites through the use of tags and AJAX.

We worked on a list of tags for editors to use that would allow them to syndicate a piece of content to a particular site based on what it was tagged. When implementing, I ensured the field had auto-complete in the add/edit form so we could reduce the number of slightly duplicate tags (for example, Physics department / Physics Department).

Example of news syndication to the Chemistry department website from our News site.
Example of news syndication to the Chemistry department website from our News site.

In closing: a note on people, process, and technology

As with any technology-related project, there are three components that lead to a successful product. People, process, and technology. People and process are vital, and also the most variable.

Sitting down with people to talk about their process is incredibly helpful when building the technical solutions. Often times when the technical team sits down to discuss process, the people who are closest to the process can’t really nail down what it is. That’s where it’s our job to ask questions and try to figure out how things work. This is absolutely necessary if we’re going to turn around a specific, concrete system that the process fits in.

It’s certainly a challenge and it’s never going to be perfect. People change and processes change. Good communication and trust between teams is the only way to get as close to the ideal as we can.

For this iteration, I think we did a really good job. The site is leaps and bounds better in regards to surfacing the latest goings-on at SUNY Oswego. Also, the editor experience is much better as pointed out by our writers who actually use the system (win!).