diff --git a/navLinks.json b/navLinks.json index 7e46ff3..974ae74 100644 --- a/navLinks.json +++ b/navLinks.json @@ -35,10 +35,17 @@ }, { "label": "Projects", + "href": "/projects", "submenu": [ { - "href": "/games/word-guesser", - "label": "A Word Guessing Game" + "href": "/projects/word-guesser", + "label": "A Word Guessing Game", + "submenu": [ + { + "href": "/games/word-guesser", + "label": "The Game" + } + ] }, { "href": "/projects/telemetry", diff --git a/pages/about-blog.md b/pages/about-blog.md deleted file mode 100644 index 273fd37..0000000 --- a/pages/about-blog.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "About this blog" -date: "2025-07-17" -slug: "about/blog" -published: true -layout: "page" -repository: "https://github.com/jpoage1/expressjs-blog" -tags: - - blog philosophy - - minimalism - - static site - - markdown - - software craftsmanship - - content management - - self-hosting - - simplicity - - custom engine - - tech writing ---- - -# Introduction - -This blog exists as a straightforward, no-frills platform to share ideas, code, and reflections on technology without the overhead of typical web frameworks. It is designed to prioritize clarity, performance, and maintainability over bells and whistles. - -## Philosophy - -I build and maintain this site as a personal technical artifact, emphasizing manual control of content and presentation. This approach keeps the process transparent and predictable, avoiding abstraction layers that often obscure or complicate straightforward tasks. - -## Content Approach - -Posts focus on practical topics: programming, systems design, project notes, and occasionally, commentary on software tools and infrastructure. The content is written directly in Markdown, keeping it portable, searchable, and version-controlled. - -## Technology Stack - -The site is powered by a minimal custom engine that parses Markdown on demand, sanitizes output, and renders with lightweight templating. This allows rapid iteration without runtime dependencies or third-party plugins. - -## Why This Matters - -Maintaining a simple, static-driven site reduces security risks, minimizes resource consumption, and increases the longevity of the content. It reflects a deliberate choice to reject complexity and keep infrastructure and workflow lean. diff --git a/pages/projects.md b/pages/projects.md deleted file mode 100644 index 8c8c141..0000000 --- a/pages/projects.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: "Projects" -created: "2025-06-19" -date: "2025-06-19" -slug: "projects" -published: false -layout: "page" -# tags: ---- - -# My Projects - -This site hosts a collection of ongoing and completed technical work. Each project reflects deliberate design choices aligned with minimalism, control, and clarity. - -express-blog -Custom static-first blog engine. Built from scratch for predictable rendering, minimal dependencies, and direct content ownership. README | GitHub - -Additional projects will be listed here as they are finalized. diff --git a/pages/projects/about-blog.md b/pages/projects/about-blog.md new file mode 100644 index 0000000..81f7dbd --- /dev/null +++ b/pages/projects/about-blog.md @@ -0,0 +1,41 @@ +--- +title: "A Custom Blog Powered by Express.js" +date: "2025-07-17" +slug: "about/blog" +published: true +layout: "page" +demo_url: "/blog" +demo_label: "Check out my blog" +repository: "https://github.com/jpoage1/expressjs-blog" +tags: + - blog philosophy + - minimalism + - static site + - markdown + - software craftsmanship + - content management + - self-hosting + - simplicity + - custom engine + - tech writing +--- + +# Introduction + +This blog exists as a straightforward, no-frills platform to share ideas, code, and reflections on technology without the overhead of typical web frameworks. It is designed to prioritize clarity, performance, and maintainability over bells and whistles. + +## Philosophy + +I build and maintain this site as a personal technical artifact, emphasizing manual control of content and presentation. This approach keeps the process transparent and predictable, avoiding abstraction layers that often obscure or complicate straightforward tasks. + +## Content Approach + +Posts focus on practical topics: programming, systems design, project notes, and occasionally, commentary on software tools and infrastructure. The content is written directly in Markdown, keeping it portable, searchable, and version-controlled. + +## Technology Stack + +The site is powered by a minimal custom engine that parses Markdown on demand, sanitizes output, and renders with lightweight templating. This allows rapid iteration without runtime dependencies or third-party plugins. + +## Why This Matters + +Maintaining a simple, static-driven site reduces security risks, minimizes resource consumption, and increases the longevity of the content. It reflects a deliberate choice to reject complexity and keep infrastructure and workflow lean. diff --git a/pages/projects/lisp_interpreter.md b/pages/projects/lisp_interpreter.md index 781e14d..e21041b 100644 --- a/pages/projects/lisp_interpreter.md +++ b/pages/projects/lisp_interpreter.md @@ -2,7 +2,7 @@ title: "Lisp Interpereter" date: "2026-03-18" slug: "projects/xmonad" -published: false +published: true layout: "page" repository: "https://github.com/jpoage1/lisp_interpreter" tags: diff --git a/pages/projects/word-guesser.md b/pages/projects/word-guesser.md new file mode 100644 index 0000000..147a281 --- /dev/null +++ b/pages/projects/word-guesser.md @@ -0,0 +1,53 @@ +--- +title: "The Word Guessing Game" +date: "2026-03-19" +slug: "projects/word-guesser" +published: true +demo_url: "/games/word-guesser" +demo_label: "Play the Game" +layout: "page" +tags: + - javascript + - dom manipulation + - test-driven development + - class design +--- + +## Building a Word Guesser + +### A Study in Class Architecture and Testing + +The "Word Guessing Game" was initially assigned as an introductory project to demonstrate basic DOM manipulation and event handling in JavaScript. However, writing a flat script that mutates global state to update a UI is brittle and difficult to scale. + +Instead of writing a standard functional script, I used this assignment to practice and apply my skills **Test-Driven Development (TDD)** and **Object-Oriented Architecture** in JavaScript. + +### Decoupling Logic from the DOM + +The core design philosophy was strict separation of concerns. The game logic needed to be entirely unaware of the HTML Document Object Model. + +I architected a dedicated `WordGuesser` class. This class handles the actual mechanics: maintaining the array of the target word, logging `goodGuesses` and `badGuesses`, tracking the placeholder array (`currentWord`), and calculating the win condition. + +By isolating the logic, the `WordGuesser` class became highly testable. It takes inputs and throws specific, structured errors (e.g., `DuplicateBadGuessError`, `InvalidGuessError`). It never touches a `document.getElementById()`. + +### Bridging the Gap: The `Game` Class + +To handle the interface, I created a higher-level `Game` class. This acts as the controller. It instantiates the `WordGuesser` logic engine and takes a `GameFields` configuration object (which maps the DOM IDs). + +When the user submits a guess, the `Game` class passes the input to the `WordGuesser` engine. The engine processes the logic and returns a state or throws an error. The `Game` class catches these errors and translates them into UI updates—specifically, rendering the hostile and sarcastic notification messages. + +### Writing a Custom Testing Suite + +Because I isolated the `WordGuesser` logic, I could subject it to rigorous testing. Rather than importing a heavy framework like Jest for a single-page school project, I built a custom **TestRunner class** (`content/html/word-guesser/scripts/tests.js`). + +The custom testing suite implements a chainable API, mimicking professional frameworks: + +```javascript +testWordGuesserLogic + .expect("accepts a good guess and does not increase the guess count") + .value(() => { + wordGuesser.guessLetter(validLetter); + return wordGuesser.guessCount(); + }) + .toBe(1) + .assert(); +``` diff --git a/pages/tools.md b/pages/tools.md index d9fdb18..e9801c7 100644 --- a/pages/tools.md +++ b/pages/tools.md @@ -14,6 +14,7 @@ - tmux - shell scripting - git + - c++ - node.js - express - php @@ -25,7 +26,9 @@ - backend - system administration - python + - svelte - clojure + - homelab --- # My Developer Toolkit @@ -48,12 +51,18 @@ - **Git:** Daily version control. Proficient with branches, commits, rebases, and collaboration workflows. +- **Methodologies:** Test-Driven Development (TDD) is strictly required for general-purpose programming. Automated fuzzing is implemented systematically to generate unexpected inputs, validate system stability, and isolate edge cases including memory overflows. + --- ## Backend & Database Technologies Strong foundation in backend systems and data persistence: +- **C++:** Primary language for high-performance, system-level execution, memory management, and custom toolchains. + +- **Python:** Utilized for backend API development, automation, and system-level orchestration. + - **Node.js:** Runtime for building scalable network applications. Used with Express.js for APIs. - **Express.js:** Minimalist web framework for Node.js. Ideal for RESTful services.