Overview
FeatherFeed is a minimalist blogging system that adds dynamic content to static HTML sites without databases, admin panels, or complex build processes.
Core Principles
- No Database: Content stored as JSON files
- No Admin Panel: Manage content via FTP or API
- No Framework: Just PHP includes and HTML
- SEO Friendly: Server-side rendered content
- AI Compatible: LLMs can generate and manage content
How It Works
- JSON files store your blog posts
- PHP includes read and display these files
- Your existing HTML/CSS provides the design
- Clean URLs via simple .htaccess rules
Installation
Installing FeatherFeed takes less than 2 minutes.
Requirements
- PHP 7.0 or higher
- Apache with mod_rewrite enabled
- FTP access to your server
Quick Install
- Download the FeatherFeed starter pack
- Upload all files to your web server
- Ensure
.htaccess
is in your root directory - Create your first JSON post in
/content/posts/
- Include the PHP snippet where you want posts to appear
<?php include('includes/recent-posts.php'); ?>
File Structure
FeatherFeed uses a simple, logical file structure:
your-website/
âââ .htaccess # URL rewriting rules
âââ render.php # Individual post renderer
âââ post.html # Post template
âââ featherfeed.css # Basic blog styles
âââ includes/
â âââ recent-posts.php # Recent posts widget
â âââ collection.php # Collection renderer
âââ content/
â âââ posts/ # Your blog posts (JSON)
â â âââ 1735000000.json
â â âââ 1735001000.json
â â âââ ...
â âââ collections/ # Custom collections
â âââ featured.json
â âââ ...
âââ your-pages/ # Your existing HTML
Key Files Explained
- .htaccess: Enables pretty URLs and PHP in HTML files
- render.php: Displays individual blog posts
- post.html: Template for blog post pages
- recent-posts.php: Include this to show blog posts
- collection.php: For custom post groupings
JSON Post Format
Each blog post is a JSON file with these fields:
{
"timestamp": 1735000000,
"slug": "my-first-post",
"title": "My First Post",
"excerpt": "A brief summary of the post",
"content": "<p>Full HTML content goes here...</p>",
"status": "published",
"featured_image_url": "https://example.com/image.jpg",
"tags": "web development, php, blogging"
}
Field Reference
Field | Type | Required | Description |
---|---|---|---|
timestamp |
integer | Yes | Unix timestamp for sorting |
slug |
string | Yes | URL-friendly identifier |
title |
string | Yes | Post title |
excerpt |
string | Yes | Brief summary |
content |
HTML string | Yes | Full post content |
status |
string | Yes | "published" or "draft" |
featured_image_url |
string | No | Hero image URL |
tags |
string | No | Comma-separated tags |
File Naming Convention
Files are named using Unix timestamps (e.g., 1735000000.json
). This provides:
- Automatic chronological sorting
- No naming conflicts
- Easy date derivation
PHP Includes
Display blog posts anywhere with simple PHP includes.
Recent Posts
<?php include('includes/recent-posts.php'); ?>
Limit Posts Shown
<?php
$limit = 3;
include('includes/recent-posts.php');
?>
Custom Collections
<?php
include_once('includes/collection.php');
renderCollection('featured');
?>
Collections System
Group posts into custom collections for different displays.
Collection Format
{
"name": "featured",
"title": "Featured Articles",
"class": "featured-grid",
"posts": [1735000000, 1735001000, 1735002000],
"limit": 3
}
Common Collection Types
- Featured Posts: Homepage highlights
- Category Collections: Posts by topic
- Author Collections: Posts by writer
- Series: Related post sequences
URL Routing
FeatherFeed uses clean, SEO-friendly URLs.
How URLs Work
/my-post
â Shows the post with slug "my-post"/blog.html
â Your blog listing page/about.html
â Regular HTML pages work normally
The File Scanning Approach
When someone visits /my-post
:
- .htaccess redirects to
render.php?slug=my-post
- render.php scans JSON files for matching slug
- Post is rendered using the template
Performance Note: Scanning 100 JSON files takes ~15-30ms on typical hosting. For sites with 500+ posts, consider adding an index file.
Template System
The post.html
template wraps individual blog posts.
Template Structure
<!DOCTYPE html>
<html>
<head>
<title>{{POST_TITLE}} - My Site</title>
<link rel="stylesheet" href="/style.css">
<link rel="stylesheet" href="/featherfeed.css">
</head>
<body>
<!-- Your site header -->
<main>
{{POST_CONTENT}}
</main>
<!-- Your site footer -->
</body>
</html>
Available Placeholders
{{POST_TITLE}}
- The post title{{POST_CONTENT}}
- Complete rendered post
FeatherFTP Integration
Automate content publishing with our companion tool.
API Example
{
"ftp": {
"host": "ftp.yoursite.com",
"username": "user",
"password": "pass"
},
"destination": "/public_html/content/posts",
"post": {
"title": "New Blog Post",
"excerpt": "Summary here",
"content": "<p>Full content...</p>",
"tags": "news, updates"
}
}
Benefits
- Automatic timestamp generation
- Slug creation from title
- Direct FTP deployment
- AI agent compatibility
Troubleshooting
Common Issues
PHP includes not working
Solution: Ensure your server processes .html files as PHP. Check the .htaccess file includes:
AddType application/x-httpd-php .html
404 errors on blog posts
Solution: Verify .htaccess is in the root directory and mod_rewrite is enabled.
Posts not appearing
Solution: Check that:
- JSON files are valid (use a JSON validator)
- Status is set to "published"
- Files are in /content/posts/ directory
Styling issues
Solution: Include featherfeed.css in your pages:
<link rel="stylesheet" href="/featherfeed.css">