Jordan.Roher.me

Personal site, 2021

Jordan.Roher.me home page circa 2021

About

Jordan.Roher.me is my personal site, the one you’re looking at now. In November of 2021 I decided to completely redesign my site. It’s been on the same design since *checks git history* 2008.

I figured it’s due for an overhaul.

Build system

The first big change was the build system. I’ve used Grunt for as long as I’ve needed to build anything using JavaScript. I use it at Microsoft. But I wondered if I could build my simple blog without it. I’ve started getting into using npm scripts to do things. Could they replace Grunt’s functionality?

It took some doing, but yes, they could. I replaced this gruntfile.js with these scripts in my package.json. As a bonus, I added a watch mode. Theoretically removing gruntfile.js means one less file to manage. In practice I had to add two JavaScript files at the root of my project to handle the replace functions. It’s a fair trade.

gruntfile.js

const sass = require("node-sass");

module.exports = function (grunt) {
	grunt.initConfig({
		run: {
			hugo: {
				exec: "npm run hugo",
				cmd: "npm",
				args: ["run", "hugo"],
			},
		},

		sass: {
			dist: {
				options: {
					implementation: sass,
					sourceMap: false,
				},
				files: {
					"themes/jordan-roher/static/css/jordan-roher.css": ["themes/jordan-roher/static/css/main.scss"],
					"themes/jordan-roher/static/css/fonts.css": ["themes/jordan-roher/static/css/fonts.scss"],
				},
			},
		},

		clean: {
			public: ["public/**"],
			scss: ["public/**/*.scss", "public/css/core", "public/css/pages"],
			theme: ["themes/jordan-roher/static/css/*.css", "themes/jordan-roher/static/js/jordan-roher.js"],
			hugo: [
				"public/sitemap.xml",
				"public/index.xml",
				"public/tags/**/index.xml",
				"public/font",
				"public/lib",
				"public/js/*.ts",
				"public/.DS_Store",
				"public/**/.DS_Store",
			],
		},

		replace: {
			ids: {
				options: {
					patterns: [
						{
							match: /<h([1-6])\s*id="[A-Z0-9\-]+">/gi,
							replacement: "<h$1>",
						},
					],
				},
				files: [
					{
						src: ["public/*.html", "public/**/*.html"],
						expand: true,
					},
				],
			},
			alt: {
				options: {
					patterns: [
						{
							match: /<img[\s]*src="([^"]+)"[\s]*alt="([^"]+)"(?:[\s]*(?:\/)?)?>/gi,
							replacement: '<img src="$1" alt="$2" title="$2" />',
						},
					],
				},
				files: [
					{
						src: ["public/blog/index.html", "public/blog/**/*.html"],
						expand: true,
					},
				],
			},
		},

		prettify: {
			options: {
				indent: 1,
				indent_char: "	",
			},
			html: {
				expand: true,
				cwd: "public/",
				ext: ".html",
				src: ["*.html", "**/*.html"],
				dest: "public/",
			},
		},

		cssmin: {
			main: {
				options: {},
				files: {
					"themes/jordan-roher/static/css/jordan-roher.css": [
						"themes/jordan-roher/static/css/jordan-roher.css",
					],
					"themes/jordan-roher/static/css/fonts.css": ["themes/jordan-roher/static/css/fonts.css"],
				},
			},
		},

		ts: {
			main: {
				src: ["themes/jordan-roher/static/js/jordan-roher.ts"],
				options: {
					sourceMap: false,
					expand: true,
				},
			},
		},

		uglify: {
			main: {
				files: {
					"themes/jordan-roher/static/js/jordan-roher.js": [
						"themes/jordan-roher/static/lib/baguetteBox/baguetteBox.js",
						"themes/jordan-roher/static/js/jordan-roher.js",
					],
				},
			},
		},
	});

	grunt.loadNpmTasks("grunt-sass");
	grunt.loadNpmTasks("grunt-run");
	grunt.loadNpmTasks("grunt-ts");
	grunt.loadNpmTasks("grunt-contrib-clean");
	grunt.loadNpmTasks("grunt-replace");
	grunt.loadNpmTasks("grunt-prettify");
	grunt.loadNpmTasks("grunt-contrib-uglify");
	grunt.loadNpmTasks("grunt-contrib-cssmin");

	grunt.registerTask("default", [
		"clean:public",
		"sass",
		"cssmin:main",
		"ts:main",
		"uglify:main",
		"run:hugo",
		"prettify",
		"replace:ids",
		"replace:alt",
		"clean:scss",
		"clean:theme",
		"clean:hugo",
	]);
};

package.json

"scripts": {
    "build": "npm run clean:before && npm run sass && npm run js && npm run hugo && npm run html && npm run clean:after && npm run replace",
    "start": "npm run build && open http://localhost:3000 && npm run serve:hugo",
    "watch": "npm-run-all --parallel sass:watch js:watch hugo:watch serve:open serve:hugo",
    "serve:hugo": "serve public",
    "serve:open": "open http://localhost:3000",
    "hugo": "hugo",
    "hugo:watch": "hugo --watch",
    "sass": "npm run sass:build && npm run sass:minify",
    "sass:watch": "npm run sass:build:watch",
    "sass:build": "sass --no-source-map themes/main/static/css/main.scss:themes/main/static/css/main.uncompiled.css",
    "sass:build:watch": "sass --no-source-map --watch themes/main/static/css/main.scss:themes/main/static/css/main.css",
    "sass:minify": "uglifycss themes/main/static/css/main.uncompiled.css > themes/main/static/css/main.css",
    "js": "webpack",
    "js:watch": "webpack --watch",
    "html": "html-minifier --remove-comments --collapse-whitespace --input-dir ./public --output-dir ./public --file-ext html",
    "clean": "npm run clean:before && npm run clean:after",
    "clean:before": "del-cli public",
    "clean:after": "del-cli themes/**/*.css themes/**/*.js themes/**/*.LICENSE.txt public/**/*.scss public/css/core public/css/pages public/css/*.uncompiled.css public/sitemap.xml public/index.xml public/tags/**/index.xml public/font public/css/shared public/contact public/categories public/portfolio/index* public/js/*.ts public/.DS_Store public/**/.DS_Store",
    "replace": "npm run replace:ids && npm run replace:img",
    "replace:ids": "replace-in-file --configFile replace-ids.js",
    "replace:img": "replace-in-file --configFile replace-img.js"
},
"devDependencies": {
    "del-cli": "^4.0.1",
    "html-minifier": "^4.0.0",
    "hugo-bin": "^0.77.1",
    "npm-run-all": "^4.1.5",
    "replace-in-file": "^6.3.2",
    "sass": "^1.43.4",
    "serve": "^13.0.2",
    "ts-loader": "^9.2.6",
    "typescript": "^4.4.4",
    "uglifycss": "^0.0.29",
    "uglifyjs": "^2.4.11",
    "webpack": "^5.62.1",
    "webpack-cli": "^4.9.1"
}

Front-end redesign

State of the art web design has come a long way since 2008. Clearfix hacks are out, CSS grids are in. I dismantled 95% of my site’s CSS and rewrote everything.

I wanted my personal site to feel breezy, approachable, and modest. I have a personal tagline I use on most other sites: “Seattle game and web developer.” But that didn’t feel right here. Other well-designed developer / designer sites go with a “I’m Vibram Toejam, surfer and heavy metal guitarist, and I move sweet pixels” vibe. I’m not that cool, but I have my own words.

White space replaced most the borders I used in the previous design. There’s still one in the footer where I embrace my “Apple packaging tagline” mantra. Big fonts are the other modern trend, but I had a hard time finding a good balance for the headlines.

I also worked on removing the number of pages in the site. The blog’s archive page is gone and so are the dedicated contact and portfolio pages. Now the home page is enormous. It’s partly to reduce clicks and redundancy, and partly to ensure the content doesn’t get too wide.

The font for this site is Larsseit.

New home page

New home page

Old home page

Old home page

New blog

New blog page

Old blog

Old blog archives pageOld blog archives page