Convert website to Hugo

This commit is contained in:
Noah 2023-09-13 17:35:55 -07:00
parent fb8bb53ab8
commit 47689c1634
2153 changed files with 701 additions and 263 deletions

0
.hugo_build.lock Normal file
View File

View File

@ -2,11 +2,11 @@ all: build
@PHONY: build
build:
./build.py
hugo
@PHONY: watch
watch:
./watch.sh
hugo server
@PHONY: clean
clean:

View File

@ -1,19 +1,9 @@
# noah.is
* Everything in `templates/` is assumed to be a Jinja2 template.
* Everything in `static/` is assumed to be a file to be taken literally.
* Run `make build` to compile all the templates from `templates/` and copy
all of the files from `static/` into a shared public root directory called
`public/`
* Upload `public/*` to your web server.
Just a simple Hugo website.
## Features
* Pretty path names (`templates/about.html` -> `public/about/index.html`)
## Setup Instructions
For Fedora: `sudo dnf install python3-jinja2 inotify-tools`
* `make build` to build it
* `make watch` to run it locally
## License

6
archetypes/default.md Normal file
View File

@ -0,0 +1,6 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---

145
build.py
View File

@ -1,145 +0,0 @@
#!/usr/bin/env python3
import codecs
import logging
import os
from shutil import copyfile
import jinja2
logging.basicConfig()
log = logging.getLogger("build")
log.setLevel(logging.INFO)
class App(object):
# Global template variables.
def vars(self):
return {
"site": {
"name": "noah.is",
},
}
def __init__(self):
# Jinja environment.
self.env = jinja2.Environment(
loader=jinja2.FileSystemLoader("./templates"),
)
# Collect all the templates and all the static files.
self.templates = self.crawl("./templates") # TODO: remove list() wrapper
self.static = self.crawl("./static")
# Copy all of the static files into the public root.
if not os.path.isdir("./public"):
self.mkdir("./public")
for static in self.static:
public = static.replace("./static/", "./public/")
self.mkdir(public.rsplit("/", 1)[0]) # ensure the path will exist
if self.should_copy_static(static, public):
log.info("COPY STATIC FILE %s -> %s", static, public)
copyfile(static, public)
# And render all of the templates.
for template in self.templates:
if template.startswith("./templates/layout"): # don't create these
continue
public = self.template_to_public(template)
self.mkdir(public.rsplit("/", 1)[0]) # ensure the path will exist
log.info("RENDER TEMPLATE: %s -> %s", template, public)
self.render_template(template, public)
def render_template(self, template, public):
"""
Render a template to the public path.
Parameters:
template (str): path in ./templates
public (str): path in ./public
"""
tpl = self.env.get_template(template.replace("./templates/", ""))
vars = self.vars()
vars["template"] = template
vars["filename"] = template.split("/")[-1]
html = tpl.render(vars)
with codecs.open(public, "w", "utf-8") as fh:
fh.write(html)
def crawl(self, path):
"""
Crawl a directory recursively and return a list of file paths.
Parameters:
path (str)
Returns:
filepaths (list[str])
"""
for root, dirs, files in os.walk(path):
for file in files:
yield os.path.join(root, file)
def should_copy_static(self, static_file, public_file):
"""
Determine if a static file should be copied over to the public folder.
This means the public file either does not exist yet, or is older
than the static file and so the new static file should be copied over it.
Parameters:
static_file (str)
public_file (str)
Returns:
bool: True if public_file doesn't exist or is older than static_file.
"""
if not os.path.exists(public_file):
return True
return os.stat(static_file).st_mtime > os.stat(public_file).st_mtime
def template_to_public(self, template_filename):
"""
Convert a template filename into a public name, preferring clean URL
paths without file extension suffixes.
Examples:
* /index.html -> /index.html
* /about.html -> /about/index.html
* /photos/index.html -> /photos/index.html
* /photos/2018.html -> /photos/2018/index.html
The `.html` and `.md` file types will suppress suffixes in this way.
Parameters:
template_filename: like ``./templates/about.html``
Returns:
public_filename: like ``./public/about/index.html``
"""
public = template_filename.replace("./templates/", "./public/")
path, filename = public.rsplit("/", 1)
basename, ext = filename.rsplit(".", 1)
if ext not in ["html", "md"]:
# Not a web page so just keep the path literal.
return public
print("template_to_public:", template_filename, public)
# See if it's already an index page or if we need to create one.
if filename in ["index.html", "index.md"]:
return public # already a good name
else:
print("HERE:", os.path.join(path, basename, "index."+ext))
log.info("basename=%r path=%r filename=%s", basename, path, filename)
return os.path.join(path, basename, "index."+ext)
def mkdir(self, path):
"""Create a directory and log it."""
if not os.path.isdir(path):
log.info("mkdir: %s", path)
os.makedirs(path, mode=0o755)
if __name__ == "__main__":
App()

31
config.toml Normal file
View File

@ -0,0 +1,31 @@
baseURL = 'https://noah.is/'
languageCode = 'en-us'
title = 'Noah Petherbridge'
theme = 'noah'
[menu]
[[menu.main]]
name = "Home"
url = "/"
weight = 1
[[menu.main]]
name = "Skills"
url = "/skills"
weight = 2
[[menu.main]]
name = "Portfolio"
url = "/portfolio"
weight = 3
[[menu.main]]
name = "Resume"
url = "/resume"
weight = 4
[[menu.main]]
name = "Contact"
url = "/contact"
weight = 5

60
content/_index.html Normal file
View File

@ -0,0 +1,60 @@
---
title: "Home"
date: 2023-09-13T14:56:47-07:00
draft: false
---
<section class="content">
<img src="/images/photo.jpg" class="circle center" width="320">
<h1>Hello world! 👋</h1>
<p>
You have reached the personal homepage of <strong>Noah Petherbridge</strong>.
</p>
<p>
I'm an introvert and a high-functioning computer nerd who lives near Portland, OR. I
enjoy deep conversations about a wide variety of things -- you could say my pool of
knowledge is (on average) meters deep but kilometers wide. There are a handful of things I get <em>really</em>
passionate and could talk forever about <small>(such as programming,
Linux, and whatever's my latest obsession)</small> but also love to learn anything I
can about the nature of the universe, astrophysics, spirituality, and all kinds of
other rabbit holes.
</p>
<p>
I write about random stuff on my <a href="https://www.kirsle.net/" target="_blank">web blog</a> and
maintain a handful of open source projects on
<a href="https://github.com/kirsle" target="_blank">GitHub</a>
and <a href="https://git.kirsle.net/" target="_blank">git.kirsle.net</a>.
</p>
<h2>Software Development</h2>
<p>
I'm a full stack web developer and I program in Go, Python, and
JavaScript. One of my largest personal projects is
<a href="https://www.rivescript.com/" target="_blank">RiveScript</a>,
a scripting language for programming chat bots &mdash; matching a user's
message to a certain response. I programmed five different ports of
RiveScript in different programming languages: Perl, Java, JavaScript,
Python, and Go.
</p>
<p>
My web blog, <a href="https://www.kirsle.net/" target="_blank">Kirsle.net</a>,
is written in Go and I keep that source code <a href="https://github.com/kirsle/blog" target="_blank">here</a>
for now. Previously it was written in
<a href="https://git.kirsle.net/apps/rophako" target="_blank">Python</a>
and its <a href="https://git.kirsle.net/kirsle/kirsle.net" target="_blank">HTML pages</a>
are readable too. The site you're reading is a simple Python-generated
static site <a href="https://git.kirsle.net/kirsle/noah.is">here</a>.
</p>
<p>
You may learn a little more about my projects and check out some examples
of my work on my <a href="/portfolio">Portfolio</a> page. Also see my
<a href="/a-software-developer">software development skills</a> page
and <a href="/social">get in touch</a> with me if you want!
</p>
</section>

View File

@ -1,7 +1,9 @@
{% extends "layout/base.html" %}
{% block title %}Contact Me{% endblock %}
{% block content %}
<section class="first content">
---
title: "Contact"
date: 2023-09-13T15:08:12-07:00
draft: false
---
<section class="content">
<h1>Contact Me</h1>
<p>
@ -10,6 +12,20 @@
</p>
<aside class="menu">
<p class="menu-label">
<strong class="has-text-dark is-size-7">Websites</strong>
</p>
<ul class="menu-list">
<li>
<a href="https://www.kirsle.net" target="_blank">
<i class="fa fa-blog mr-1"></i>
<strong>Web blog:</strong>
Kirsle.net<br>
<small>my personal homepage, tech blog, &amp; creative projects</small>
</a>
</li>
</ul>
<p class="menu-label">
<strong class="has-text-dark is-size-7">Social Links</strong>
</p>
@ -100,12 +116,4 @@
</li>
</ul>
</aside>
<h2>External Links</h2>
<ul>
<li><a href="https://www.kirsle.net/">Kirsle.net</a>, my web blog.</a></li>
<li><a href="https://github.com/kirsle">GitHub</a></li>
</ul>
</section>
{% endblock %}

View File

@ -1,7 +1,9 @@
{% extends "layout/base.html" %}
{% block title %}Portfolio{% endblock %}
{% block content %}
<section class="first content">
---
title: "Portfolio"
date: 2023-09-13T15:08:12-07:00
draft: false
---
<section class="content">
<h1>Portfolio</h1>
<p>
@ -136,4 +138,3 @@
</div>
</section>
{% endblock %}

338
content/resume.html Normal file
View File

@ -0,0 +1,338 @@
---
title: "Resume"
date: 2023-09-13T15:08:12-07:00
draft: false
---
<section class="content">
<h1>Resume</h1>
<ul>
<li>
<a href="#work-experience">Work Experience</a>
</li>
<li>
<a href="#education">Education</a>
</li>
</ul>
<h3 id="work-experience" class="anchor">Work Experience</h3>
</section>
<!-- Meta -->
<div class="columns is-mobile mb-0">
<div class="column is-narrow pr-1">
<img src="/img/meta.jpg" width="32" height="32" alt="Meta company logo">
</div>
<div class="column pl-1">
<h4 class="subtitle mb-0">Software Engineer <small class="has-text-grey">@ Meta</small></h4>
<p>
<small>Mar 2023 - Present | Portland, OR (Remote)</small>
</p>
</div>
</div>
<div class="content smaller ml-5">
<p>
Supernatural was <a href="https://www.latest.oculus.com/blog/within-to-join-meta/" target="_blank">acquired by Meta</a>
in March 2023 to bring our VR application in-house as a first-party Oculus studio.
</p>
<ul>
<li>
I helped spearhead the data migration effort (along with a few other senior engineers) to adapt Supernatural's
database and API servers into Meta's infrastructure (rewriting back-end services from Python into Hack).
</li>
<li>
<strong>Technologies:</strong>
<i class="fab fa-python"></i> Python (Flask, SQLAlchemy); <i class="fab fa-js"></i> JavaScript (Vue.js);
<i class="fab fa-php"></i> Hack (like PHP); Graph API; GraphQL; several proprietary internal tools for CI/CD,
issue management, code review, etc.
</li>
</ul>
</div>
<!-- Supernatural -->
<div class="columns is-mobile mb-0">
<div class="column is-narrow pr-1">
<img src="/img/supernatural.jpg" width="32" height="32" alt="Supernatural company logo">
</div>
<div class="column pl-1">
<h4 class="subtitle mb-0">Principal Software Engineer <small class="has-text-grey">@ Supernatural</small></h4>
<p>
<small>Oct 2018 - Mar 2023 | Los Angeles, CA</small>
</p>
</div>
</div>
<div class="content smaller ml-5">
<p>
Within rebranded to Supernatural named after the Oculus VR app of the same title after finding a
market fit with that application.
</p>
<ul>
<li>
I helped build out the back-end Python API server for Supernatural and its deployment pipeline on
AWS Elastic Beanstalk <small>(and later in <abbr title="Amazon Elastic Kubernetes Service">EKS</abbr>)</small>.
</li>
<li>
I extended the Within CMS to support managing content &amp; data for Supernatural before forking
the CMS into a dedicated app for Supernatural.
</li>
<li>
I built an internal Music Curation tool <small>(named Wormhole)</small> to help the content team
identify and manage licensed music to use with the app. It provided a user interface to peruse
the massive volume of music data delivered to us by our partner labels (sent in <abbr title="Digital Data Exchange">DDEX</abbr> feed
format). Behind the web app was a pipeline of Python worker scripts that ingested the DDEX feeds
and handled licensing updates and metadata sync (with Spotify and Music Reports, Inc). Wormhole
was backed by a Mongo DB which was the best fit for the loosely structured music data we were working with.
</li>
<li>
<strong>Technologies:</strong>
<i class="fab fa-python"></i> Python (Flask, SQLAlchemy); <i class="fab fa-golang"></i> Go;
<i class="fab fa-js"></i> JavaScript (Vue.js); <i class="fab fa-github"></i> GitHub;
<i class="fab fa-docker"></i> Docker; MongoDB; PostgreSQL; Redis; AWS
</li>
</ul>
</div>
<!-- Within -->
<div class="columns is-mobile mb-0">
<div class="column is-narrow pr-1">
<img src="/img/within.jpg" width="32" height="32" alt="Within company logo">
</div>
<div class="column pl-1">
<h4 class="subtitle mb-0">Senior Software Engineer <small class="has-text-grey">@ Within (Virtual Reality)</small></h4>
<p>
<small>Apr 2017 - Mar 2023 | Los Angeles, CA</small>
</p>
</div>
</div>
<div class="content smaller ml-5">
<p>
I joined Within back when their primary product was a <abbr title="Virtual Reality">VR</abbr> 360&deg; video
streaming platform <small>(with multiple web &amp; native apps)</small>, where videos were published via hand-edited JSON
files (unique format per platform) and there were no dynamic web apps within the company. Within had ambitions to create a
"Lobby" app for you &amp; your friends to hang out in VR and join multiplayer "interactive experiences" together.
</p>
<ul>
<li>
I built out a Python microservice architecture that included an Authentication service (centralized
user accounts for the Lobby app) and a Matchmaking service to coordinate multiplayer VR games. I also
created a custom Push Notification service (written in Go) to target our desktop apps and website,
which did not have a native push mechanism like Android or iOS do.
</li>
<li>
I built a Content Management System (CMS) in Python to consolidate and automate the content
publishing pipeline for the 360&deg; VR streaming platform. I studied the various legacy JSON config
formats (for the Android, iOS, PS VR, web player, and Unity stand-alone VR player apps) to determine
the commonalities and data requirements to translate into a relational (PostgreSQL) database and
CMS platform.
<ul>
<li>The video transcoding pipeline was based on <code>ffmpeg</code> via a third party API called Hybrik.</li>
<li>The CMS also managed Unity asset bundles and content publishing for our VR interactive experiences.</li>
</ul>
</li>
<li>
<strong>Technologies:</strong>
<i class="fab fa-python"></i> Python (Flask, SQLAlchemy); <i class="fab fa-golang"></i> Go;
<i class="fab fa-js"></i> JavaScript (Vue.js, Photon); <i class="fab fa-github"></i> GitHub;
<i class="fab fa-docker"></i> Docker; ffmpeg; PostgreSQL; Redis;
<abbr title="Amazon Web Services">AWS</abbr> (Elastic Beanstalk, S3)
</li>
</ul>
</div>
<!-- Media Temple -->
<div class="columns is-mobile mb-0">
<div class="column is-narrow pr-1">
<img src="/img/mediatemple.jpg" width="32" height="32" alt="Media Temple company logo">
</div>
<div class="column pl-1">
<h4 class="subtitle mb-0">Software Developer <small class="has-text-grey">@ (mt) Media Temple</small></h4>
<p>
<small>Dec 2015 - Apr 2017 | Culver City, CA</small>
</p>
</div>
</div>
<div class="content smaller ml-5">
<ul class="mt-0">
<li>
Built out Python microservices (Tornado framework) to translate between Media Temple and parent company
GoDaddy's systems (for example, a Payments service that ran within a secure server on GoDaddy's infrastructure
and was called out to from legacy Perl apps at Media Temple).
</li>
<li>
Helped maintain and add new features to a legacy Perl codebase (including the Account Center web app).
</li>
<li>
<strong>Technologies:</strong>
<i class="fab fa-python"></i> Python (Tornado);
<img src="/images/perl.png" width="12" height="12"> Perl (Template::Toolkit, Moose);
Puppet; RabbitMQ; cgit; Atlassian FishEye &amp; Crucible.
</li>
</ul>
</div>
<!-- ZEFR -->
<div class="columns is-mobile mb-0">
<div class="column is-narrow pr-1">
<img src="/img/zefr.jpg" width="32" height="32" alt="ZEFR company logo">
</div>
<div class="column pl-1">
<h4 class="subtitle mb-0">Software Engineer <small class="has-text-grey">@ ZEFR</small></h4>
<p>
<small>May 2013 - Dec 2015 | Venice, CA</small>
</p>
</div>
</div>
<div class="content smaller ml-5">
<ul class="mt-0">
<li>
Built out a Python/Flask web app called <abbr title="Brand ID">BrandID</abbr> that provided search and
notifications for brand managers regarding YouTube. The idea was that if a video was about to go
viral about your brand, you should hear about it from us first. <small>(We had code that would deeply crawl
YouTube daily and make predictions based on view counts and trends detected).</small>
</li>
<li>
Also built out a free-to-use, consumer facing app called BrandID Pulse where users could input topics
they're interested in and get daily digest e-mails of new and trending videos that match their interests.
</li>
<li>
Helped build out an advertising platform that helped match advertisers to specific YouTube videos that
we detected are about to go viral. <small>(On Google's ad platform, you can either target general demographics
or you can target specific Video IDs, but the latter feature is rarely used because it was tedious and unpredictable;
ZEFR's product helped match advertisers to specific videos relevant to their brand that were detected to be going
viral, e.g. the same data that powered BrandID).</small>
</li>
<li>
Upgraded several codebases from Python 2 to 3;
</li>
<li>
<strong>Technologies:</strong>
<i class="fab fa-python"></i> Python (Flash, Celery); <i class="fab fa-js"></i> JavaScript (jQuery, Knockout.js, Angular, MEAN stack);
<i class="fab fa-github"></i> GitHub; MongoDB; PostgreSQL; Redis; Amazon Web Services (EC2, S3, SQS, SES, Elastic Beanstalk, RDS);
HTML/CSS (Bootstrap); <i class="fab fa-docker"></i> Docker; Jenkins
</li>
</ul>
</div>
<!-- DreamHost -->
<div class="columns is-mobile mb-0">
<div class="column is-narrow pr-1">
<img src="/img/dreamhost.jpg" width="32" height="32" alt="DreamHost company logo">
</div>
<div class="column pl-1">
<h4 class="subtitle mb-0">Senior Hosting Developer <small class="has-text-grey">@ DreamHost</small></h4>
<p>
<small>Feb 2012 - Apr 2013 | Los Angeles, CA</small>
</p>
</div>
</div>
<div class="content smaller ml-5">
<ul class="mt-0">
<li>
I helped maintain and add features to web apps written in Perl (using a custom <abbr title="Object Relational Mapper">ORM</abbr>
and templating system for server-side rendered pages) and HTML/JavaScript (jQuery).
</li>
<li>
Projects included work on the customer Control Panel, report automations for financial &amp; marketing,
and integration for customer sites and <i class="fab fa-cloudflare"></i> Cloudflare.
</li>
<li>
<strong>Technologies:</strong>
<img src="/images/perl.png" width="12" height="12"> Perl;
<i class="fab fa-javascript"></i> JavaScript;
Chef; RabbitMQ; cgit.
</li>
</ul>
</div>
<!-- Fonality -->
<div class="columns is-mobile mb-0">
<div class="column is-narrow pr-1">
<img src="/img/fonality.jpg" width="32" height="32" alt="Fonality company logo">
</div>
<div class="column pl-1">
<h4 class="subtitle mb-0">Software Engineer <small class="has-text-grey">@ Fonality</small></h4>
<p>
<small>Jun 2008 - Feb 2012 | Culver City, CA</small>
</p>
</div>
</div>
<div class="content smaller ml-5">
<ul class="mt-0">
<li>
Maintained and contributed features for a customer control panel (written in Perl) for
Asterisk <abbr title="Private Branch Exchange (Business telephone system)">PBX</abbr> servers
(running a custom CentOS-based operating system branded as PBXtra and Trixbox).
</li>
<li>
One project had me port our PBXtra OS to newer Dell server blades after our OEM discontinued
the model we were selling. PBXtra was based on the (already outdated) CentOS 4 which lacked hardware
drivers to support the new blades. I troubleshooted and created new installation ISOs that slipstreamed
an updated Linux kernel and CD-ROM driver to function on these newer servers.
</li>
<li>
Worked on an HTML5 web front-end for Fonality HUD (an in-house softphone and productivity tool that
showed online/call status of your co-workers and managed chat and calls).
</li>
<li>
<strong>Technologies:</strong>
<img src="/images/perl.png" width="12" height="12"> Perl (Template::Toolkit, Moose);
<i class="fab fa-javascript"></i> HTML/JavaScript (jQuery in some places, mostly vanilla JS, AJAX);
<i class="fab fa-asterisk"></i> Asterisk; MySQL; Linux (CentOS)
</li>
</ul>
</div>
<!-- Liquid Web-->
<div class="columns is-mobile mb-0">
<div class="column is-narrow pr-1">
<img src="/img/liquidweb.jpg" width="32" height="32" alt="Liquid Web company logo">
</div>
<div class="column pl-1">
<h4 class="subtitle mb-0">Linux Systems Administrator <small class="has-text-grey">@ Liquid Web</small></h4>
<p>
<small>Jan 2008 - May 2008 | Lansing, MI</small>
</p>
</div>
</div>
<div class="content smaller ml-5">
<p>
The job description was tech support and tech support at a web hosting company is synonymous with
systems administration. A large portion of our customer base ran Linux servers (CentOS). My aim was
to get hired as a software developer but as I had no prior work experience they started me out in
support.
</p>
<ul>
<li>
Helped customers debug issues with their Apache config, managed cPanel installations,
reading exim logs, and wrote custom Perl scripts to help me troubleshoot their e-mail
servers and other such tasks.
</li>
<li>
After a couple months I transitioned to the software dev team and worked on some internal
tools and the customer control panel written in Perl.
</li>
<li>
<strong>Technologies:</strong>
<img src="/images/perl.png" width="12" height="12"> Perl (Template::Toolkit, POE);
<i class="fab fa-javascript"></i> HTML/JavaScript (jQuery); CVS version control;
MySQL; Linux (CentOS)
</li>
</ul>
</div>
<hr>
<section class="content">
<h3 id="education" class="anchor">Education</h3>
<h5 class="mb-0">ITT Technical Institute</h5>
<p class="smaller">
<em>Associates, Computer Network Systems</em><br>
<small>2006 - 2009 | Swartz Creek, MI | Culver City, CA | Torrance, CA</small>
</p>
<h5 class="mb-0">Flushing High School</h5>
<p class="smaller">
<small>2002 - 2006 | Flushing, MI</small>
</p>
</section>

View File

@ -1,14 +1,17 @@
{% extends "layout/base.html" %}
{% block title %}Software Development{% endblock %}
{% block content %}
<section class="first content">
<h1>Software Development</h1>
---
title: "Skills"
date: 2023-09-13T15:08:12-07:00
draft: false
---
<section class="content">
<h1>Skills</h1>
<p>
For pretty much all of my career (apart from some retail jobs early on while I went to college)
I've worked as a software engineer (professionally since 2008). I taught myself to program since
I was a young teenager, and my first 'real' language was Perl which I first learned because I
wanted to build my own chatbots for AOL Instant Messenger.
I was a young teenager (having learned HTML and created my first website at 12 years old), and
then my first 'real' language was Perl which I first learned because I wanted to build my own
chatbots for AOL Instant Messenger.
</p>
<p>
@ -27,11 +30,98 @@
</p>
<ul>
<li><a href="#skills">Technical Skills</a></li>
<li><a href="#web-development">Web Development</a></li>
<li><a href="#technical">Technical Skills</a></li>
<li><a href="#examples">Example Projects</a></li>
</ul>
<h2 id="skills" class="anchor">Technical Skills</h2>
<h2 id="web-development" class="anchor">Web Development</h2>
<p>
I call myself a "full stack" web developer and have a varied skillset to tackle both front-end
and back-end concerns of web applications. I am most at home on the back-end side (everything
from developing the app itself to getting it deployed on a server or cloud provider) but have
also been known to create a nice front-end web design or Single Page App (SPA) from time to time.
</p>
</section>
<div class="columns">
<div class="column">
<div class="card">
<div class="card-header has-background-info">
<p class="card-header-title has-text-light">
<i class="fa fa-server mr-2"></i> Back-end (server side)
</p>
</div>
<div class="card-content content">
<h6>Languages</h6>
<p>
<i class="fab fa-golang"></i> Go,
<i class="fab fa-python"></i> Python,
<i class="fab fa-node-js"></i> JavaScript,
<img src="/images/perl.png" width="16" height="16"> Perl
</p>
<h6>Frameworks</h6>
<p>
<i class="fab fa-golang"></i> <a href="https://gorm.io" target="_blank">GORM</a>,
<a href="https://github.com/urfave/negroni" target="_blank">Negroni</a>,
<a href="https://github.com/gin-gonic/gin" target="_blank">Gin</a><br>
<i class="fab fa-python"></i> <a href="https://flask.palletsprojects.com/en/2.3.x/" target="_blank">Flask</a>,
<a href="https://www.tornadoweb.org/en/stable/" target="_blank">Tornado</a>,
<a href="https://www.sqlalchemy.org/" target="_blank">SQLAlchemy</a><br>
<i class="fab fa-node-js"></i> <a href="https://expressjs.com/" target="_blank">Express.js</a>
</p>
<h6>Technologies</h6>
<p>
<i class="fab fa-docker"></i> Docker, <i class="fab fa-github"></i> GitHub, <i class="fab fa-linux"></i> Linux,
RESTful API, server-side templates,
DevOps/systems administration, Amazon AWS <small>(EC2, S3, SQS, SES, EKS, Elastic Beanstalk)</small>
</p>
</div>
</div>
</div>
<div class="column">
<div class="card">
<div class="card-header has-background-info">
<p class="card-header-title has-text-light">
<i class="fa fa-brush mr-2"></i> Front-end (web design)
</p>
</div>
<div class="card-content content">
<h6>Languages</h6>
<p>
<i class="fab fa-html5"></i> HTML,
<i class="fab fa-css3"></i> CSS,
<i class="fab fa-node-js"></i> JavaScript
</p>
<h6>Frameworks</h6>
<p>
<i class="fab fa-node-js"></i> Vue.js, Angular, React, Knockout, vanilla<br>
<i class="fab fa-css3"></i> Bootstrap, Bulma, Tailwind
</p>
<h6>Technologies</h6>
<p>
Ajax, WebSockets, WebRTC, responsive design (mobile friendly), Progressive
Web Apps (PWAs), Single Page Apps (SPAs), localStorage, Cross Origin Resource Sharing (CORS)
</p>
</div>
</div>
</div>
</div>
<section class="content">
<h2 id="technical" class="anchor">Technical Skills</h2>
<ul>
<li>
@ -43,7 +133,7 @@
(npm and web) and use these languages regularly for work and side projects.
</li>
<li>
I also once knew <img src="/images/perl.png" width="16" height="16"> <strong>Perl 5</strong> well (13 years straight)
I also once knew <img src="/images/perl.png" width="16" height="16"> <strong>Perl 5</strong> well (13 years straight!)
but may be a bit rusty now!
</li>
<li>
@ -193,4 +283,3 @@
</li>
</ul>
</section>
{% endblock %}

View File

@ -1,6 +1,8 @@
{% extends "layout/base.html" %}
{% block title %}Welcome{% endblock %}
{% block content %}
---
title: "Home Page"
date: 2023-09-13T14:56:47-07:00
draft: false
---
<section class="first content">
<img src="/images/photo.jpg" class="circle center" width="320">
@ -56,4 +58,3 @@
and <a href="/social">get in touch</a> with me if you want!
</p>
</section>
{% endblock %}

BIN
static/img/dreamhost.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
static/img/fonality.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
static/img/liquidweb.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
static/img/mediatemple.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
static/img/meta.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
static/img/supernatural.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
static/img/within.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
static/img/zefr.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,50 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="/css/bulma.min.css">
<link rel="stylesheet" type="text/css" href="/fontawesome-free-6.1.2-web/css/all.min.css">
<link rel="stylesheet" type="text/css" href="/theme/style.css">
<link rel="shortcut icon" href="/images/photo.jpg">
<title>{% block title %}Untitled{% endblock %} - {{ site.name }}</title>
</head>
<body>
<header>
<nav class="navbar is-fullwidth" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item is-tab {% if filename == 'index.html'%} is-active{% endif %}" href="/">{{ site.name }}</a>
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="myNavbar">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="myNavbar" class="navbar-menu">
<div class="navbar-start">
</div>
<div class="navbar-end">
<a class="navbar-item is-tab{% if filename == 'a-software-developer.html'%} is-active{% endif %}" href="/a-software-developer">Development</a></li>
<a class="navbar-item is-tab{% if filename == 'portfolio.html'%} is-active{% endif %}" href="/portfolio">Portfolio</a></li>
<a class="navbar-item is-tab{% if filename == 'social.html'%} is-active{% endif %}" href="/social">Contact</a></li>
</div>
</div>
</nav>
</header>
<main>
{% block content %}{% endblock %}
</main>
<script src="/js/bulma.js"></script>
</body>
</html>

View File

@ -0,0 +1,2 @@
+++
+++

View File

@ -0,0 +1 @@
<h1>Not Found</h1>

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
{{- partial "head.html" . -}}
<body>
{{- partial "header.html" . -}}
{{- block "main" . }}{{- end }}
{{- partial "footer.html" . -}}
</body>
</html>

View File

@ -0,0 +1,10 @@
{{ define "main" }}
<h1>{{ .Title }}</h1>
{{ range .Pages.ByPublishDate.Reverse }}
<p>
<h3><a class="title" href="{{ .RelPermalink }}">{{ .Title }}</a></h3>
{{ partial "metadata.html" . }}
<p>{{ .Summary }}</p>
</p>
{{ end }}
{{ end }}

View File

@ -0,0 +1,10 @@
{{ define "main" }}
<main aria-role="main">
<div class="first">
{{ if .Params.Toc }}
{{.TableOfContents}}
{{ end }}
{{ .Content }}
</div>
</main>
{{ end }}

View File

@ -0,0 +1,14 @@
{{ define "main" }}
<main aria-role="main">
<section class="first">
<!-- Note that the content for index.html, as a sort of list page, will pull from content/_index.md -->
{{ .Content }}
<!-- </div>
<div>
{{ range first 10 .Site.RegularPages }}
{{ .Render "summary" }}
{{ end }}
</div> -->
</section>
</main>
{{ end }}

View File

@ -0,0 +1,8 @@
<div class="container px-4">
<div class="notification is-dark has-text-centered has-text-grey smaller my-4 py-3">
Copyright &copy; {{ now.Format "2006"}} Noah Petherbridge.
All rights reserved.
</div>
</div>
<script src="/js/bulma.js"></script>

View File

@ -0,0 +1,12 @@
<head>
{{ $title := print .Title " | " .Site.Title }}
{{ if .IsHome }}{{ $title = .Site.Title }}{{ end }}
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="canonical" href="{{ .Permalink }}">
<link rel="stylesheet" type="text/css" href="/css/bulma.min.css">
<link rel="stylesheet" type="text/css" href="/fontawesome-free-6.1.2-web/css/all.min.css">
<link rel="stylesheet" type="text/css" href="/css/style.css">
<link rel="shortcut icon" href="/images/photo.jpg">
<title>{{ $title }}</title>
</head>

View File

@ -0,0 +1,22 @@
<header>
<nav class="navbar is-fullwidth" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item is-tab {% if filename == 'index.html'%} is-active{% endif %}" href="/">{{ .Site.Title }}</a>
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="myNavbar">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="myNavbar" class="navbar-menu">
<div class="navbar-start">
</div>
{{- partial "navbar.html" . -}}
</div>
</nav>
</header>

View File

@ -0,0 +1,13 @@
<div class="mb-4">
{{ if .PublishDate }}
{{ $dateTime := .PublishDate.Format "2006-01-02" }}
{{ $dateFormat := .Site.Params.dateFormat | default "Jan 2, 2006" }}
<time datetime="{{ $dateTime }}">{{ .PublishDate.Format $dateFormat }}</time>
{{ end }}
{{ with .Params.tags }}
{{ range . }}
{{ $href := print (absURL "tags/") (urlize .) }}
<a class="btn btn-sm btn-outline-dark tag-btn" href="{{ $href }}">{{ . }}</a>
{{ end }}
{{ end }}
</div>

View File

@ -0,0 +1,6 @@
{{ $Root := . }}
<div class="navbar-end">
{{ range .Site.Menus.main }}
<a class="navbar-item is-tab{{if eq .Name $Root.Title}} is-active{{end}}" href="{{ .URL }}">{{ .Name }}</a>
{{ end }}
</div>

View File

@ -0,0 +1,2 @@
<!-- raw html -->
{{.Inner}}

View File

@ -31,6 +31,7 @@ header {
top: 0;
left: 0;
right: 0;
z-index: 9000;
line-height: 3rem;
background-color: rgba(255, 153, 255, 0.9);
box-shadow: 0px 2px 2px rgba(128, 0, 128, 0.4);
@ -62,15 +63,10 @@ header nav a {
main {
min-height: 100%;
margin: 0 24px;
margin: 0 1rem;
background-color: rgba(255, 255, 255, 0.9);
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.5);
}
section {
padding: 1.5rem;
}
section.first {
padding-top: 5rem;
padding: 5rem 1.5rem 1.5rem 1.5rem;
}
footer {
@ -83,6 +79,10 @@ footer {
font-style: italic;
}
.smaller {
font-size: smaller;
}
.center {
display: block;
text-align: center;