WebsiteTemplate/README.md
2026-01-25 11:39:04 -04:00

14 KiB

Website Template

A modern, clean website template with blog, cheatsheets, quick reference guides, search integration, and analytics. Built with pure HTML, CSS, and JavaScript - no frameworks, no build process, just code that works.

Features

  • Homepage - Dynamic time-based greetings and theme switcher
  • Complete Blog System - Full blogging platform with RSS, reactions, and analytics
  • Quick Reference Guides - Programming language refs (Bash, Python)
  • Cheatsheets - Command-line and security tool cheatsheets (nmap, ssh)
  • Search Integration - SearXNG theme customization
  • Privacy-Focused Analytics - Self-hosted, no third-party tracking
  • Theme System - Dark/light mode with smooth transitions
  • Fast & Lightweight - Pure HTML/CSS/JS, no bloat

File Structure

website-template/
├── README.md
├── index.html
├── 404.html
├── favicon.ico
├── assets/
│   ├── css/
│   ├── js/
│   ├── fonts/
│   └── icons/
├── blog/
│   ├── admin/            # Blog admin interface (protect this!)
│   │   ├── index.php     # Script to convert .md posts to JSON
│   │   └── example-post.md
│   ├── api/
│   ├── data/
│   └── js/
├── api/
├── analytics/
├── cheatsheets/
├── quickref/
├── search/
└── data/
    ├── analytics/
    └── reactions/

Installation & Setup

Step 1: Get the Template

Option A: Extract from Tarball

tar -xzf WebsiteTemplate.tar.gz
cd WebsiteTemplate

Option B: Clone with Git

git clone https://git.fraggle.lol/fraggle/WebsiteTemplate.git
cd WebsiteTemplate

If you're setting up your own repository:

git init
git add .
git commit -m "Initial commit"

Step 2: Set Up Your Web Server

  1. Install Nginx and PHP:

    Debian/Ubuntu:

    sudo apt update
    sudo apt install nginx php-fpm php-json php-mbstring
    

    Fedora/RHEL/CentOS:

    sudo dnf install nginx php-fpm php-json php-mbstring
    

    Arch Linux:

    sudo pacman -S nginx php-fpm php
    

    openSUSE:

    sudo zypper install nginx php-fpm php-json php-mbstring
    

    Alpine Linux:

    sudo apk add nginx php-fpm php-json php-mbstring
    

    macOS (Homebrew):

    brew install nginx php
    

    FreeBSD:

    sudo pkg install nginx php82 php82-json php82-mbstring
    
  2. Configure Nginx: Create /etc/nginx/sites-available/your-site (or edit the default):

    server {
        listen 80;
        server_name your-domain.com www.your-domain.com;
        root /var/www/html;
        index index.html;
    
        # PHP handling
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php-fpm.sock;
        }
    
        # Deny access to hidden files and data directories
        location ~ /\. {
            deny all;
        }
    
        location ~ /data/ {
            deny all;
        }
    
        # Main location
        location / {
            try_files $uri $uri/ =404;
        }
    }
    
  3. Enable the site:

    Debian/Ubuntu:

    sudo ln -s /etc/nginx/sites-available/your-site /etc/nginx/sites-enabled/
    sudo nginx -t
    sudo systemctl reload nginx
    

    Other Linux distributions:

    # Edit /etc/nginx/nginx.conf directly or create config in /etc/nginx/conf.d/
    sudo nginx -t
    sudo systemctl reload nginx
    

    macOS:

    # Edit /usr/local/etc/nginx/nginx.conf
    brew services restart nginx
    

    FreeBSD:

    # Edit /usr/local/etc/nginx/nginx.conf
    sudo service nginx reload
    
  4. Copy files and set permissions:

    Linux (most distributions):

    sudo cp -r * /var/www/html/
    sudo chown -R www-data:www-data /var/www/html/  # or nginx:nginx on some systems
    sudo chmod -R 755 /var/www/html/
    sudo chmod 775 /var/www/html/data /var/www/html/data/analytics /var/www/html/data/reactions
    sudo chmod 775 /var/www/html/blog/data
    

    macOS:

    sudo cp -r * /usr/local/var/www/
    sudo chown -R _www:_www /usr/local/var/www/
    sudo chmod -R 755 /usr/local/var/www/
    sudo chmod 775 /usr/local/var/www/data /usr/local/var/www/data/analytics /usr/local/var/www/data/reactions
    sudo chmod 775 /usr/local/var/www/blog/data
    

    FreeBSD:

    sudo cp -r * /usr/local/www/nginx/
    sudo chown -R www:www /usr/local/www/nginx/
    sudo chmod -R 755 /usr/local/www/nginx/
    sudo chmod 775 /usr/local/www/nginx/data /usr/local/www/nginx/data/analytics /usr/local/www/nginx/data/reactions
    sudo chmod 775 /usr/local/www/nginx/blog/data
    

Option B: Apache

  1. Install Apache and PHP:

    Debian/Ubuntu:

    sudo apt install apache2 libapache2-mod-php php-json php-mbstring
    

    Fedora/RHEL/CentOS:

    sudo dnf install httpd php php-json php-mbstring
    

    Arch Linux:

    sudo pacman -S apache php
    sudo systemctl enable --now httpd
    

    openSUSE:

    sudo zypper install apache2 php php-json php-mbstring
    

    Alpine Linux:

    sudo apk add apache2 php php-json php-mbstring
    

    macOS (Homebrew):

    brew install httpd php
    

    FreeBSD:

    sudo pkg install apache24 php82 php82-json php82-mbstring
    
  2. Enable PHP and mod_rewrite:

    Debian/Ubuntu:

    sudo a2enmod php
    sudo a2enmod rewrite
    

    Fedora/RHEL/CentOS/Arch/openSUSE/Alpine:

    # PHP module is usually enabled by default
    # Enable rewrite module (method varies by distro)
    # Check your distribution's documentation for specific commands
    

    macOS:

    # Edit /usr/local/etc/httpd/httpd.conf
    # Uncomment: LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so
    

    FreeBSD:

    # Edit /usr/local/etc/apache24/httpd.conf
    # Uncomment: LoadModule rewrite_module libexec/apache24/mod_rewrite.so
    
  3. Configure Apache: Edit /etc/apache2/sites-available/000-default.conf (or create a new virtual host):

    <VirtualHost *:80>
        ServerName your-domain.com
        DocumentRoot /var/www/html
    
        <Directory /var/www/html>
            Options -Indexes +FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>
    
        # Protect data directories
        <Directory /var/www/html/data>
            Require all denied
        </Directory>
    </VirtualHost>
    
  4. Copy files and set permissions:

    Linux (most distributions):

    sudo cp -r * /var/www/html/
    sudo chown -R www-data:www-data /var/www/html/  # or httpd:httpd on some systems
    sudo chmod -R 755 /var/www/html/
    sudo chmod 775 /var/www/html/data /var/www/html/data/analytics /var/www/html/data/reactions
    sudo chmod 775 /var/www/html/blog/data
    

    macOS:

    sudo cp -r * /usr/local/var/www/
    sudo chown -R _www:_www /usr/local/var/www/
    sudo chmod -R 755 /usr/local/var/www/
    sudo chmod 775 /usr/local/var/www/data /usr/local/var/www/data/analytics /usr/local/var/www/data/reactions
    sudo chmod 775 /usr/local/var/www/blog/data
    

    FreeBSD:

    sudo cp -r * /usr/local/www/apache24/data/
    sudo chown -R www:www /usr/local/www/apache24/data/
    sudo chmod -R 755 /usr/local/www/apache24/data/
    sudo chmod 775 /usr/local/www/apache24/data/data /usr/local/www/apache24/data/data/analytics /usr/local/www/apache24/data/data/reactions
    sudo chmod 775 /usr/local/www/apache24/data/blog/data
    
  5. Restart Apache:

    # Linux (systemd)
    sudo systemctl restart apache2    # Debian/Ubuntu
    sudo systemctl restart httpd     # Fedora/RHEL/Arch/openSUSE
    
    # macOS
    brew services restart httpd
    
    # FreeBSD
    sudo service apache24 restart
    

Step 3: Configure PHP

Edit your PHP configuration to set the timezone:

# Find your php.ini location
php --ini

# Edit php.ini (location varies by OS and installation method)
# Common locations:
#   Linux: /etc/php/8.x/fpm/php.ini or /etc/php.ini
#   macOS: /usr/local/etc/php/8.x/php.ini
#   FreeBSD: /usr/local/etc/php.ini

# Set your timezone (replace with your actual timezone)
date.timezone = "America/New_York"

# Restart PHP-FPM (or PHP service)
# Linux (systemd):
sudo systemctl restart php-fpm  # or php8.x-fpm

# macOS:
brew services restart php

# FreeBSD:
sudo service php-fpm restart

Step 4: Test It Out

  1. Start a local PHP server for testing:

    cd /var/www/html
    php -S localhost:8000
    
  2. Visit in your browser:

    • Homepage: http://localhost:8000
    • Blog: http://localhost:8000/blog/index.html
    • Analytics: http://localhost:8000/analytics/index.html (IP-restricted by default)

Step 5: Secure the Admin Interface

IMPORTANT: The blog admin interface at /blog/admin/ should be protected. Use one of these methods:

Option 1: HTTP Basic Auth (Nginx)

location /blog/admin/ {
    auth_basic "Admin Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

Create the password file:

sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd your-username

Option 2: HTTP Basic Auth (Apache) Create /var/www/html/blog/admin/.htaccess:

AuthType Basic
AuthName "Admin Area"
AuthUserFile /var/www/html/blog/admin/.htpasswd
Require valid-user

Create the password file:

sudo htpasswd -c /var/www/html/blog/admin/.htpasswd your-username

Adding Blog Posts

You have three options for adding blog posts:

The template includes a PHP script to convert markdown files to the JSON format used by the blog.

  1. Create a markdown file following this format:

    ---
    title: Your Amazing Blog Post Title
    excerpt: A brief excerpt that appears on the blog listing page
    ---
    
    This is your blog post content. You can write as much as you want here.
    
    Use double newlines to separate paragraphs. The script will handle the rest.
    
  2. Run the conversion script:

    cd /var/www/html/blog/admin
    php index.php /path/to/your-post.md
    

    Or if you're in the blog/admin directory:

    php index.php your-post.md
    

    The script will:

    • Parse the frontmatter (title, excerpt)
    • Extract the content
    • Generate a unique ID
    • Add today's date
    • Append to blog/data/posts.json
  3. Example:

    # Create a post
    nano my-new-post.md
    
    # Convert it
    php index.php my-new-post.md
    
    # Done! Your post is now in the blog
    

Option 2: Edit JSON Directly

Edit blog/data/posts.json directly. Each post needs:

  • id: Unique number (increment from existing posts)
  • title: Post title
  • date: Date in YYYY-MM-DD format
  • excerpt: Short description for listings
  • content: Full post content (use \n\n for paragraph breaks)

Example:

{
  "id": 1,
  "title": "My Second Post",
  "date": "2025-01-15",
  "excerpt": "This is what shows up on the blog listing",
  "content": "This is the full content of my post.\n\nThis is a second paragraph."
}

Option 3: Use the Admin Interface

Visit /blog/admin/ in your browser (after securing it) and use the web interface.

Security Checklist

  • Protect /blog/admin/ with authentication (see Step 5 above)
  • Set proper file permissions (755 for directories, 644 for files, 775 for data dirs)
  • Use HTTPS (Let's Encrypt is free and easy)
  • Analytics is already IP-restricted to local networks (check api/analytics.php)
  • Review and customize CSP headers in HTML files if needed
  • Don't expose /data/ directory in web server config
  • Keep PHP updated

Customization

Change Colors

Edit assets/css/style.css and modify the CSS variables:

:root {
    --bg-primary: #your-color;
    --text-primary: #your-color;
    /* ... etc */
}

Update Site Information

  • RSS Feed: Edit blog/api/feed.php - change domain and title
  • Homepage Links: Edit index.html - customize the link sections
  • ASCII Art Logo: Replace the logo in all HTML files (search for the ASCII art)

Timezone

The site uses the user's local timezone for display. Server-side PHP uses UTC by default - adjust in:

  • api/analytics.php
  • api/track.php
  • blog/api/feed.php

Set your server's timezone in php.ini (see Step 3).

Requirements

  • Web Server: Nginx (recommended) or Apache
  • PHP: 7.4+ with php-json and php-mbstring extensions
  • Browser: Modern browser
  • Permissions: Write access to data/ and blog/data/ directories

Troubleshooting

Blog posts not loading?

  • Make sure PHP is running: sudo systemctl status php-fpm
  • Check file permissions: ls -la blog/data/posts.json
  • Verify PHP can read the file: php -r "echo file_exists('blog/data/posts.json') ? 'OK' : 'NOT FOUND';"
  • Check browser console for JavaScript errors

Analytics not working?

  • Analytics is IP-restricted by default (local networks only)
  • Check api/analytics.php for IP filtering rules
  • Verify data/analytics/ directory is writable

404 errors?

  • Check web server configuration
  • Verify file paths are correct
  • Make sure mod_rewrite is enabled (Apache) or try_files is configured (Nginx)

PHP errors?

  • Check PHP error logs: /var/log/php-fpm/error.log or Apache error log
  • Verify PHP extensions are installed: php -m | grep json
  • Check file permissions

What Makes This Special

  • No frameworks - Pure, readable code
  • No build process - Edit files, refresh browser, done
  • Privacy-first - Self-hosted analytics, no third-party tracking
  • Actually organized - Clean structure that makes sense, I don't want to talk about how we got there.
  • JSON-based storage - Blog posts and data stored in JSON files

License

This project is licensed under the GNU General Public License v3.0. See LICENSE.md for details.


Built with a healthy dose of cynicism.

Extract it. Deploy it. Make it yours.