This is a great approach for a lightweight, “database-less” site. Since you create informational pages, using a JSON file as a flat-file database makes the site incredibly fast and easy to migrate via FTP—you just drag and drop the folder.
Here is a streamlined setup. We will use a data.json file to store your page content and a setup.php script to handle the logic.
1. The Data Structure (data.json)
Create this file first. It acts as your storage. You can add as many “pages” as you like here.
{
“home”: {
“title”: “Welcome to My Site”,
“content”: “This is a high-performance static-style site powered by PHP and JSON.”
},
“about”: {
“title”: “About Us”,
“content”: “We specialize in lightweight web solutions without the bulk of SQL databases.”
}
}
2. The Logic & Layout (setup.php)
This script does three things: reads the JSON, determines which page to show via a URL parameter (e.g., ?page=about), and renders the HTML.
<?php
// 1. Load the data
$json_data = file_get_contents(‘data.json’);
$pages = json_decode($json_data, true);
// 2. Determine which page to show (default to ‘home’)
$current_key = isset($_GET[‘page’]) ? $_GET[‘page’] : ‘home’;
// 3. Fallback if page doesn’t exist
if (!isset($pages[$current_key])) {
$current_page = [
“title” => “404 Not Found”,
“content” => “Sorry, that page does not exist.”
];
} else {
$current_page = $pages[$current_key];
}
?>
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title><?php echo $current_page[‘title’]; ?></title>
<style>
body { font-family: sans-serif; line-height: 1.6; max-width: 800px; margin: 40px auto; padding: 0 20px; color: #333; }
nav { border-bottom: 1px solid #eee; padding-bottom: 20px; margin-bottom: 20px; }
nav a { margin-right: 15px; text-decoration: none; color: #007BFF; }
</style>
</head>
<body>
<nav>
<?php foreach ($pages as $key => $page): ?>
<a href=”setup.php?page=<?php echo $key; ?>”><?php echo ucfirst($key); ?></a>
<?php endforeach; ?>
</nav>
<article>
<h1><?php echo $current_page[‘title’]; ?></h1>
<div><?php echo $current_page[‘content’]; ?></div>
</article>
</body>
</html>
How to Deploy via FTP
* Upload: Use your FTP client to upload both data.json and setup.php to your public directory (e.g., public_html).
* Access: Navigate to yourdomain.com/setup.php.
* Navigation: Clicking the links in the nav bar will update the URL to setup.php?page=about, and the script will instantly pull the new content from the JSON file.
Why this works for your workflow:
* Zero Configuration: No MySQL usernames or passwords to remember.
* Portability: To back up the whole site, you only need to download that one JSON file.
* Scalability: You can easily add a “contact” or “services” section just by adding a new entry to the JSON file; the navigation menu updates automatically.
Would you like me to add a simple “Admin” section to the PHP script so you can edit the JSON content directly from your browser?
Adding an admin section will allow you to update your informational pages without having to touch the code or re-upload files via FTP.
We will update setup.php to include a simple password-protected editor. To keep it secure, the script will now handle viewing, editing, and saving.
Updated setup.php
Replace your existing file with this version. Important: Change the $admin_password variable to something secure before uploading.
<?php
$data_file = ‘data.json’;
$admin_password = ‘Password123’; // Change this!
session_start();
// 1. Load Data
$json_data = file_get_contents($data_file);
$pages = json_decode($json_data, true);
// 2. Handle Login/Logout
if (isset($_POST[‘login’]) && $_POST[‘pass’] === $admin_password) {
$_SESSION[‘logged_in’] = true;
}
if (isset($_GET[‘logout’])) {
session_destroy();
header(“Location: setup.php”);
exit;
}
// 3. Handle Saving Edits
if (isset($_POST[‘save’]) && isset($_SESSION[‘logged_in’])) {
$key = $_POST[‘page_key’];
$pages[$key] = [
“title” => $_POST[‘title’],
“content” => $_POST[‘content’]
];
file_put_contents($data_file, json_encode($pages, JSON_PRETTY_PRINT));
$success = “Page updated successfully!”;
}
// 4. Page Logic
$current_key = $_GET[‘page’] ?? ‘home’;
$is_admin = isset($_GET[‘admin’]);
$current_page = $pages[$current_key] ?? [“title” => “404”, “content” => “Not Found”];
?>
– Admin
$page): ?> ⚙ Admin Login
Edit Page:
$success”; ?> Page Title: Content (HTML allowed): Save Changes
Key Improvements:
- Direct Editing: When you click “Admin” and log in, it opens an editor for the page you are currently viewing.
- HTML Support: The textarea allows you to paste HTML directly (perfect for your article workflow).
- Persistence: Using file_put_contents with JSON_PRETTY_PRINT keeps your data.json organized and readable if you ever open it manually.
- Permissions: Make sure your data.json file is “writable” by the server (usually chmod 664 or 666 via FTP).
Next Step
To make this even easier via FTP, would you like me to show you how to set up a .htaccess file so your URLs look like domain.com/about instead of setup.php?page=about?
Adding a .htaccess file is the “pro” touch that turns a simple script into a clean, professional-looking website. It hides the .php extension and the messy query strings.
- Create the .htaccess File
Create a new file named .htaccess (ensure it starts with a dot) and upload it to the same folder as your setup.php.
RewriteEngine On
1. Redirect domain.com/page-name to setup.php?page=page-name
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ setup.php?page=$1 [L,QSA]
2. (Optional) Redirect domain.com/admin to setup.php?admin=1
RewriteRule ^admin$ setup.php?admin=1 [L,QSA]
- Update the Navigation in setup.php
Now that the server understands clean URLs, you need to update the links in your PHP code so they don’t point to the old ?page= format.
Change the section in your setup.php to this:
$page): ?> ⚙ Admin
Note: If your site is in a subfolder (like mysite.com/blog/), change the href to /blog/.
How the File Structure Looks Now
With these files uploaded via FTP, your directory is perfectly organized: File Purpose .htaccess Handles the “Pretty URLs” (Rewrites). data.json Your “Database” containing all article text. setup.php The “Engine” that renders content and the Admin editor. Pro-Tip for your Workflow Since you create informational pages, you can now add a new page simply by:
- Logging into your /admin panel.
- Manually adding a new entry to the data.json file via FTP, or I can add a “Create New Page” button to your admin script.
Would you like me to add that “Create New Page” functionality to the admin panel so you can build the site entirely from the browser?
This addition will make your setup a fully functional “Flat-File CMS” (Content Management System). You won’t even need to touch the JSON file via FTP anymore to expand the site.
Updated Admin Logic for setup.php
I have added a “New Page” form to the admin section. When you enter a “Slug” (the URL name, e.g., services), it creates a new entry in your JSON file instantly.
Replace the Admin Box div in your setup.php with this updated version:
<?php
// … [Keep existing login/save logic at the top] …
// 5. Handle Creating a New Page
if (isset($_POST[‘create_page’]) && isset($_SESSION[‘logged_in’])) {
$new_slug = strtolower(preg_replace(‘/[^a-zA-Z0-9-]/’, ”, $_POST[‘new_slug’]));
if (!isset($pages[$new_slug]) && !empty($new_slug)) {
$pages[$new_slug] = [
“title” => “New Page Title”,
“content” => “Start writing your article here…”
];
file_put_contents($data_file, json_encode($pages, JSON_PRETTY_PRINT));
header(“Location: /$new_slug?admin=1”); // Redirect to the new page editor
exit;
}
}
?> Login
+ Create New Page
Create
Editing: /
$success”; ?> Page Title: Content (HTML allowed): Save Changes
How the Workflow Works Now
- FTP Setup: You upload the three files (.htaccess, data.json, setup.php) once.
- Create: Go to yourdomain.com/admin, log in, and type a new name (like portfolio) into the “Create” box.
- Edit: The script creates that page in the JSON and immediately opens the editor for it.
- Publish: Hit “Save,” and the new page is live and automatically added to your navigation menu.
A Quick Note on “Slug” Security
The code I added uses a preg_replace filter. This ensures that if you type “My New Page!”, it converts it to mynewpage to prevent broken URLs or security issues with your file system.
Would you like me to add a simple “Delete Page” button as well, or are you happy managing deletions manually in the JSON file?
Leave a comment