| analytics | ||
| api | ||
| assets | ||
| blog | ||
| cheatsheets | ||
| docs | ||
| quickref | ||
| search | ||
| 404.html | ||
| favicon.ico | ||
| index.html | ||
| LICENSE.md | ||
| README.md | ||
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
Option A: Nginx (Recommended)
-
Install Nginx and PHP:
Debian/Ubuntu:
sudo apt update sudo apt install nginx php-fpm php-json php-mbstringFedora/RHEL/CentOS:
sudo dnf install nginx php-fpm php-json php-mbstringArch Linux:
sudo pacman -S nginx php-fpm phpopenSUSE:
sudo zypper install nginx php-fpm php-json php-mbstringAlpine Linux:
sudo apk add nginx php-fpm php-json php-mbstringmacOS (Homebrew):
brew install nginx phpFreeBSD:
sudo pkg install nginx php82 php82-json php82-mbstring -
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; } } -
Enable the site:
Debian/Ubuntu:
sudo ln -s /etc/nginx/sites-available/your-site /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginxOther Linux distributions:
# Edit /etc/nginx/nginx.conf directly or create config in /etc/nginx/conf.d/ sudo nginx -t sudo systemctl reload nginxmacOS:
# Edit /usr/local/etc/nginx/nginx.conf brew services restart nginxFreeBSD:
# Edit /usr/local/etc/nginx/nginx.conf sudo service nginx reload -
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/datamacOS:
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/dataFreeBSD:
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
-
Install Apache and PHP:
Debian/Ubuntu:
sudo apt install apache2 libapache2-mod-php php-json php-mbstringFedora/RHEL/CentOS:
sudo dnf install httpd php php-json php-mbstringArch Linux:
sudo pacman -S apache php sudo systemctl enable --now httpdopenSUSE:
sudo zypper install apache2 php php-json php-mbstringAlpine Linux:
sudo apk add apache2 php php-json php-mbstringmacOS (Homebrew):
brew install httpd phpFreeBSD:
sudo pkg install apache24 php82 php82-json php82-mbstring -
Enable PHP and mod_rewrite:
Debian/Ubuntu:
sudo a2enmod php sudo a2enmod rewriteFedora/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 commandsmacOS:
# Edit /usr/local/etc/httpd/httpd.conf # Uncomment: LoadModule rewrite_module lib/httpd/modules/mod_rewrite.soFreeBSD:
# Edit /usr/local/etc/apache24/httpd.conf # Uncomment: LoadModule rewrite_module libexec/apache24/mod_rewrite.so -
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> -
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/datamacOS:
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/dataFreeBSD:
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 -
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
-
Start a local PHP server for testing:
cd /var/www/html php -S localhost:8000 -
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)
- Homepage:
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:
Option 1: Convert Markdown to JSON (Recommended)
The template includes a PHP script to convert markdown files to the JSON format used by the blog.
-
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. -
Run the conversion script:
cd /var/www/html/blog/admin php index.php /path/to/your-post.mdOr if you're in the blog/admin directory:
php index.php your-post.mdThe script will:
- Parse the frontmatter (title, excerpt)
- Extract the content
- Generate a unique ID
- Add today's date
- Append to
blog/data/posts.json
-
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 titledate: Date inYYYY-MM-DDformatexcerpt: Short description for listingscontent: Full post content (use\n\nfor 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.phpapi/track.phpblog/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-jsonandphp-mbstringextensions - Browser: Modern browser
- Permissions: Write access to
data/andblog/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.phpfor 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.logor 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.