CNL-PR-2025-005 Protocol

CWC Blog Infrastructure Protocol

Michael P. Hamilton , Ph.D.
Published: December 4, 2025 Version: 1

CWC Blog Infrastructure Protocol

A Reusable LAMP-Based Content Management System

Document ID: CNL-PR-2025-005
Version: 1.0
Date: December 4, 2025
Author: Michael P. Hamilton, Ph.D.


AI Assistance Disclosure: This protocol was developed with assistance from Claude (Anthropic, claude-sonnet-4-20250514). The AI contributed to code development, documentation drafting, and systematic refactoring patterns. The author takes full responsibility for the content, accuracy, and conclusions.


Abstract

This protocol documents the Coffee with Claude (CWC) blog infrastructure, a lightweight LAMP-based content management system designed for personal publishing, essay archiving, and newsletter distribution. The system emphasizes simplicity, maintainability, and portability across multiple website deployments. Originally developed for coffeewithclaude.com, the architecture has been successfully adapted for digitalnaturalist.com migration, demonstrating its reusability. This document provides specifications for database schema, file structure, configuration patterns, and migration methodology suitable for deploying additional instances.


1. Introduction

1.1 Purpose

The CWC infrastructure addresses a specific need: a simple, maintainable blog system for long-form essay publishing with supporting features (images, citations, tags, newsletters) without the complexity of WordPress or similar platforms. The system is designed for:

  • Single-author publishing workflows
  • Essay-centric content with academic citation support
  • Image management with metadata
  • Optional newsletter functionality
  • Markdown-based content storage
  • Easy migration and multi-site deployment

1.2 Scope

This protocol covers:

  • Database schema design
  • PHP file architecture
  • Configuration and path management
  • Migration methodology for new deployments
  • Import/export workflows

1.3 Technology Stack

Component Specification
Web Server Apache 2.x
PHP 8.3+ (mysqli, no PDO)
Database MySQL 8.4+
Content Format Markdown
Styling Custom CSS (no frameworks)
JavaScript Vanilla JS, Chart.js for analytics

2. Database Schema

2.1 Core Tables

The system uses eight primary tables with supporting junction tables for many-to-many relationships.

2.1.1 posts

Primary content storage for essays.

Column Type Description
id int, PK, auto Primary key
title varchar(255) Essay title
slug varchar(255), unique URL-safe identifier
content text Markdown content
excerpt text Homepage preview text
published_date date Publication date
is_pinned tinyint(1) Pin to top of listing
display_order int Manual sort order
created_date datetime Record creation
updated_date datetime Last modification
status enum('draft','published') Publication status
visibility enum('visible','hidden') Display visibility
view_count int Page view counter
featured_image varchar(255) Hero image path
newsletter_sent_date datetime Newsletter tracking

2.1.2 tags

Content categorization.

Column Type Description
id int, PK, auto Primary key
tag_name varchar(100) Display name
slug varchar(100), unique URL-safe identifier
created_date datetime Record creation

2.1.3 post_tags

Junction table for post-tag relationships.

Column Type Description
post_id int, FK References posts.id
tag_id int, FK References tags.id

2.1.4 citations

Academic citation storage.

Column Type Description
id int, PK, auto Primary key
citation_text text Full formatted citation
source_url varchar(500) Source URL
author varchar(255) Author name(s)
publication varchar(255) Publication venue
date_published date Publication date
access_date date Access date for URLs
notes text Internal notes
created_date timestamp Record creation
updated_date timestamp Last modification

2.1.5 post_citations

Junction table for post-citation relationships.

Column Type Description
id int, PK, auto Primary key
post_id int, FK References posts.id
citation_id int, FK References citations.id
display_order int Citation order in post
assigned_date timestamp Assignment date

2.1.6 images

Image metadata storage.

Column Type Description
id int, PK, auto Primary key
filename varchar(255) Stored filename
original_filename varchar(255) Upload filename
title varchar(255) Display title
description text Caption/description
alt_text varchar(255) Accessibility text
photographer varchar(100) Photo credit
photo_date date Date taken
location varchar(255) Location metadata
upload_date datetime Upload timestamp
file_size int File size in bytes
width int Image width pixels
height int Image height pixels
mime_type varchar(50) MIME type

2.1.7 image_tags and image_tag_assignments

Parallel tagging system for images (structure mirrors post tags).

2.1.8 pages

Static page content (About, Contact, etc.).

Column Type Description
id int, PK, auto Primary key
title varchar(255) Page title
slug varchar(255), unique URL identifier
content text Markdown content
featured_image varchar(500) Header image
updated_date datetime Last modification

2.1.9 subscribers

Newsletter subscriber management.

Column Type Description
id int, PK, auto Primary key
email varchar(255), unique Email address
name varchar(255) Subscriber name
confirmation_token varchar(64) Email verification
status enum('pending','active','unsubscribed') Subscription state
subscribed_date datetime Initial signup
confirmed_date datetime Email confirmed
unsubscribed_date datetime Opt-out date
ip_address varchar(45) Signup IP

2.1.10 admin_users

Authentication for admin interface.

Column Type Description
id int, PK, auto Primary key
username varchar(50), unique Login username
password_hash varchar(255) bcrypt hash
email varchar(255) Admin email
created_date datetime Account creation

2.2 Foreign Key Constraints

All junction tables use CASCADE DELETE to maintain referential integrity when parent records are removed.


3. File Architecture

3.1 Directory Structure

/Library/WebServer/Documents/[SITE]/
├── css/
│   ├── style.css          # Public styles
│   └── admin.css          # Admin interface styles
├── js/
│   └── lightbox.js        # Image lightbox
├── images/
│   ├── heroes/            # Featured images (auto-generated)
│   └── thumbnails/        # Thumbnail images (auto-generated)
├── includes/
│   ├── config.php         # Site configuration
│   ├── functions.php      # Shared functions
│   ├── header.php         # HTML header template
│   ├── footer.php         # HTML footer template
│   ├── cache.php          # Page caching
│   └── newsletter_functions.php  # Email utilities
├── admin/
│   ├── index.php          # Admin dashboard
│   ├── login.php          # Authentication
│   ├── logout.php         # Session termination
│   ├── essays.php         # Essay editor
│   ├── images.php         # Image manager
│   ├── pages.php          # Static page editor
│   ├── tags.php           # Tag management
│   ├── citations.php      # Citation management
│   ├── subscribers.php    # Subscriber management
│   ├── newsletter.php     # Newsletter composition
│   ├── send_notification.php  # Email dispatch
│   ├── analytics.php      # Corpus analytics
│   ├── import.php         # Markdown import
│   └── export.php         # Collection export
├── index.php              # Homepage/essay listing
├── post.php               # Single essay view
├── about.php              # About page
├── contact.php            # Contact form
├── subscribe.php          # Newsletter signup
├── confirm.php            # Email confirmation
└── unsubscribe.php        # Newsletter opt-out

3.2 Configuration (config.php)

The configuration file defines site-wide constants:

<?php
// Database credentials (external file)
require_once('/Library/WebServer/secure/credentials/[site]_db_config.php');

// Site configuration
define('BASE_PATH', '/NDN');  // Subdirectory or empty for root
define('SITE_NAME', 'Site Title');
define('SITE_TAGLINE', 'Site Subtitle');
define('ADMIN_EMAIL', 'admin@example.com');

// Database connection
$conn = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
mysqli_set_charset($conn, 'utf8mb4');

// Session management
session_start();

3.3 Credential Storage

Database credentials stored outside web root:

/Library/WebServer/secure/credentials/[site]_db_config.php

Format:

<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'site_user');
define('DB_PASS', 'secure_password');
define('DB_NAME', 'site_database');
?>

4. Migration Methodology

4.1 Overview

Deploying a new site instance requires:

  1. Database creation and schema import
  2. Credential file setup
  3. File copying and path refactoring
  4. Color scheme customization
  5. Content migration

4.2 Database Setup

CREATE DATABASE newsite_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'newsite_user'@'localhost' IDENTIFIED BY 'secure_password';
GRANT ALL PRIVILEGES ON newsite_db.* TO 'newsite_user'@'localhost';
FLUSH PRIVILEGES;

Import schema from reference SQL file.

4.3 Path Refactoring Pattern

All files require systematic updates for new deployment:

Pattern Find Replace
Header comment path /Documents/CwC/ /Documents/[SITE]/
Stylesheet paths href="/css/ href="<?php echo BASE_PATH; ?>/css/
Navigation links href="/ href="<?php echo BASE_PATH; ?>/
Admin links href="/admin/ href="<?php echo BASE_PATH; ?>/admin/
Form actions action="/admin/ action="<?php echo BASE_PATH; ?>/admin/
PHP redirects Location: /admin/ Location: ' . BASE_PATH . '/admin/
Site name Hardcoded text <?php echo SITE_NAME; ?>

4.4 Color Scheme Customization

Two primary colors define site identity:

Element CSS Variable Example
Primary accent Links, buttons, highlights #5c8a4d (sage green)
Dark accent Headers, footer #2d3b2d (forest green)

Search and replace in CSS and inline styles:

  • CWC blue (#3498db) → Site primary
  • CWC dark (#2c3e50) → Site dark

4.5 Admin User Creation

Generate bcrypt hash:

echo password_hash('password_here', PASSWORD_DEFAULT);

Insert via SQL:

INSERT INTO admin_users (username, email, password_hash, created_date) 
VALUES ('username', 'email@example.com', '$2y$...hash...', NOW());

4.6 Directory Permissions

mkdir -p /Library/WebServer/Documents/[SITE]/images/heroes
mkdir -p /Library/WebServer/Documents/[SITE]/images/thumbnails
sudo chown -R _www:_www /Library/WebServer/Documents/[SITE]/images
chmod 755 /Library/WebServer/Documents/[SITE]/images

5. Content Import Format

5.1 Markdown Essay Format

Essays are imported via standardized markdown with metadata header:

**Title:** Essay Title Here
**Date:** Month Day, Year
**Excerpt:** 1-2 sentence preview for homepage display.
**Suggested Tags:** tag1, tag2, tag3
**Citations:**
- Author (Year). "Title." *Publication*. URL
- Additional citations on separate lines

## Markdown Content

![Image alt text](/SITE/images/filename.jpg)

Essay body in standard markdown format...

## Section Heading

Additional content with **bold** and *italic* formatting.

5.2 Import Processing

The parse_imported_essay() function in functions.php:

  1. Splits content on ## Markdown Content delimiter
  2. Extracts metadata fields via regex
  3. Parses tags into array
  4. Parses citations into structured data
  5. Returns associative array for database insertion

5.3 Image Handling

Images referenced in markdown:

  • Must exist in /[SITE]/images/ directory
  • Alt text becomes accessibility attribute
  • First image can optionally become featured image
  • Database lookup provides captions for registered images

6. Feature Summary

6.1 Public Features

Feature Description
Essay listing Paginated homepage with excerpts
Single essay view Full content with citations
Tag filtering Browse by topic
Static pages About, Contact
Newsletter signup Double opt-in subscription
Image lightbox Enlarged image viewing

6.2 Admin Features

Feature Description
Essay editor Rich editing with image/citation browsers
Image manager Upload, resize, metadata, tagging
Tag manager CRUD with merge capability
Citation manager Structured citation storage
Page editor Static page management
Subscriber management View, add, manage subscribers
Newsletter composition Full-essay email distribution
Analytics dashboard Corpus statistics, word frequency, charts
Import Markdown essay ingestion
Export Full collection backup

7. Deployment Checklist

7.1 New Site Deployment

  • [ ] Create MySQL database and user
  • [ ] Import schema SQL
  • [ ] Create credential file outside web root
  • [ ] Copy PHP files to site directory
  • [ ] Update BASE_PATH in config.php
  • [ ] Update SITE_NAME and SITE_TAGLINE
  • [ ] Refactor all path references
  • [ ] Apply color scheme
  • [ ] Create image directories with permissions
  • [ ] Create admin user
  • [ ] Test login and all admin functions
  • [ ] Remove unused features (e.g., newsletter links)

7.2 Content Migration

  • [ ] Copy images to /images/ directory
  • [ ] Convert legacy content to markdown format
  • [ ] Import via admin interface
  • [ ] Set publication status and visibility
  • [ ] Assign featured images
  • [ ] Verify all internal links

8. Known Limitations

  1. Single-author design: No multi-user permissions
  2. No WYSIWYG editor: Markdown-only content
  3. Manual image registration: Imported images need database entry for captions
  4. No media library browser: Images selected by path
  5. Basic caching: File-based, no Redis/Memcached

9. References

[1] PHP Documentation. "mysqli Extension." https://www.php.net/manual/en/book.mysqli.php (accessed December 4, 2025).

[2] MySQL Documentation. "MySQL 8.4 Reference Manual." https://dev.mysql.com/doc/refman/8.4/en/ (accessed December 4, 2025).

[3] Gruber, J. "Markdown: Syntax." https://daringfireball.net/projects/markdown/syntax (accessed December 4, 2025).


Appendix A: Complete SQL Schema

See accompanying file: CNL-PR-2025-005_schema.sql


Appendix B: Color Scheme Reference

B.1 CWC Original (Blue)

  • Primary: #3498db
  • Dark: #2c3e50

B.2 NDN Adaptation (Green)

  • Primary: #5c8a4d (sage green)
  • Dark: #2d3b2d (forest green)

B.3 Suggested Palettes

Site Type Primary Dark
Nature/Environment #5c8a4d #2d3b2d
Technology #3498db #2c3e50
Academic #8b4513 #2f1810
Creative #9b59b6 #4a235a

Document History

Version Date Changes
1.0 2025-12-04 Initial release

End of Protocol

Permanent URL: https://canemah.org/archive/CNL-PR-2025-005

Cite This Document

Michael P. Hamilton, Ph.D. (2025). "CWC Blog Infrastructure Protocol." Canemah Nature Laboratory Protocol CNL-PR-2025-005. https://canemah.org/archive/CNL-PR-2025-005

BibTeX

@manual{hamilton2025cwc, author = {Hamilton, Michael P., Ph.D.}, title = {CWC Blog Infrastructure Protocol}, institution = {Canemah Nature Laboratory}, year = {2025}, number = {CNL-PR-2025-005}, month = {december}, url = {https://canemah.org/archive/document.php?id=CNL-PR-2025-005}, abstract = {This protocol documents the Coffee with Claude (CWC) blog infrastructure, a lightweight LAMP-based content management system designed for personal publishing, essay archiving, and newsletter distribution. The system emphasizes simplicity, maintainability, and portability across multiple website deployments. Originally developed for coffeewithclaude.com, the architecture has been successfully adapted for digitalnaturalist.com migration, demonstrating its reusability. This document provides specifications for database schema, file structure, configuration patterns, and migration methodology suitable for deploying additional instances.} }

Permanent URL: https://canemah.org/archive/document.php?id=CNL-PR-2025-005