Book 9.2) Miracle Code Project BOOK – Better
Book Subtitle:
The Complete Guide to Creating a Miracle Code Project That Actually Works -
Using AI-Assisted Development
A Fully Modular Blog Editor You Can Recreate
From 14 Simple Prompts
You don’t
need WordPress. You don’t need a database. And you definitely don’t need
complicated frameworks.
With just 14 clean prompts and a simple Windows + WAMP setup, you can build a
full-featured, modular blog editor that’s completely yours. This is your
project. Your code. Your system.
This book teaches you not just how to build it—but how to understand it,
duplicate it, and teach it to others.
Strict UTF-8 support ensures everything works globally, reliably, and cleanly.
You’re not just learning code. You’re building something that lasts.
PART 1 – THE FRONTEND SYSTEM
CHAPTER 1: Introducing The CMS Editor That Builds
Itself
CHAPTER 2: The Heartbeat of the Editor: Load, Save, and Auto-Save
CHAPTER 3: Giving Your Editor Style: Bold, Italic, Underline
CHAPTER 4: Giving Structure to Expression: Text Alignment
CHAPTER 5: Uploading Images: File Input and Visual Insertion
CHAPTER 6: Drag, Drop, Done: Uploading Images Effortlessly
CHAPTER 7: Choosing from Existing Images: The Reusable Image Picker
CHAPTER 8: Adding Links to Text: Turning Words Into Actions
CHAPTER 9: Undo, Exit Warnings, and Upload Errors: Protecting the Work
CHAPTER 10: The Clear Button: Reset with Confidence
CHAPTER 11: The Core HTML: Where It All Comes Together
PART 2 – THE BACKEND SYSTEM
CHAPTER 12: Saving the Post to File: The Most Important
Action
CHAPTER 13: Uploading Images Safely and Effectively
CHAPTER 14: Listing Uploaded Images for Reuse
CHAPTER 15: Loading Posts By ID for a Scalable System
PART 3 – WRAPPING IT ALL UP
CHAPTER 16: Project Wrap Up & Success Overview
CHAPTER 17: You’ve Made It To The End!
CHAPTER 18: The Future of Code Projects – Using This
'Miracle' Process for Everything Else Too
CHAPTER 19: Guide to Next-Level Coding With AI, That
Never Fails – A
CHAPTER 20: Guide to Next-Level Coding With AI, That Never Fails – B
PART
1 – THE FRONTEND SYSTEM
The User
Interface – All JavaScript + HTML Logic for Editing, Saving, and Display
The first part of this book focuses on constructing the
visual interface of your Miracle CMS—the editable environment where users
write, format, and enhance their content. You begin by creating the foundation:
an editor that automatically loads and saves content in real time, offering a
seamless and reassuring writing experience. This auto-save feature sets the
tone for everything else, showing that each function you build will have a
purpose, be modular, and feel natural.
Once the core loading and saving mechanics are
established, the editor becomes more expressive. You add formatting
capabilities like bold, italic, and underline, giving users the power to shape
their message. You then bring structure to the layout through alignment
tools—left, center, right—so that headlines, paragraphs, and quotes can
visually align with the writer’s intent. Each feature is built in isolation,
through clean, readable JavaScript files that integrate smoothly.
As your editor evolves, it gains the ability to handle
media. Users can upload images via button or drag-and-drop, and then reuse
those same images without ever needing to upload again. You empower your editor
to become not just a writing tool, but a creative canvas where visual content
plays a central role.
With these editing features complete, you layer in
helpful tools like hyperlink insertion, undo functionality, exit warnings, and
even a reset button to clear content cleanly. Finally, all of these frontend
modules are tied together inside a single HTML file—index.php—where buttons,
containers, and scripts converge to form a fully working, intuitive interface.
It’s simple, fast, and entirely yours.
The
Power of Modular, Connectable Files, & Rebuildable Projects
How
one prompt at a time becomes a miracle system that anyone can build, reuse, and
understand—fully modular, totally yours, and ready to grow.
There’s
something powerful about the moment when the pieces begin to fit together. When
something that seemed too big, too complicated, or too abstract suddenly
becomes small, manageable, and crystal clear. That moment is what this entire
book is about.
This isn’t
just a book on coding. It’s a transformation. It’s the shift from feeling like
software development is only for “tech experts,” to realizing that you, yes
you, can build a clean, working, professional-grade CMS blog editor from
scratch. Not someday. Not maybe. But right now. From the first file to the last
line of code, you’ll build it. And better yet, you’ll understand it.
Miracle CMS
is not a collection of scripts—it’s a mindset. It’s a system that builds itself
because it’s built from modular prompts—14 simple
instructions you can reuse, reissue, regenerate, and re-teach. Each one creates
one file. That’s it. One feature. One purpose. One step forward. And when you
follow them, what you get is something beautiful, lightweight, understandable,
and powerful.
You’ll never
need to ask again, “Where is this buried?” or “What just broke when I edited
that?” Every feature is in its own place. Every file is plug-and-play. And yes,
every part enforces UTF-8, so your content is protected and consistent
worldwide.
Let’s start
with the vision. Then we’ll walk through the system. And then, we’ll get you
excited about what you’re going to create.
The core
philosophy behind this system is this: Every file should do one thing
well—and be rebuildable by a single prompt. That’s the
reason we created Miracle CMS around 14 prompts. Not 50, not
one giant mess. Fourteen clear, reproducible instructions—each with a job, each
generating a single file, and each contributing to a larger ecosystem.
When you open
a project that follows this model, there’s no fear. No confusion. You’ll see
exactly where every behavior lives. Want to change image upload? Open editor-4.js
. Want to
update your HTML? Edit index.php
. Need to
regenerate the save function? Just run Prompt 11.
And all of it
ties together because you understand the system. You don’t just run the
project—you own the architecture. That’s why this book is structured the way it
is.
Each of the
next 11 chapters will walk you through one prompt per chapter, with real
explanations—not just what to paste, but why it works and how it connects. Then
we’ll wrap up with the final two chapters that review the system and celebrate
your completion.
You are not
just learning a project. You are stepping into a way of building that gives you
authority, clarity, and replicability.
Here they
are. Commit these to memory. These are the core of everything. The entire
Miracle CMS blog editor is made from these:
1.
editor-1.js – Load &
auto-save post content to the server
2.
editor-2.js – Add bold,
italic, underline formatting
3.
editor-3.js – Add left,
center, right alignment
4.
editor-4.js – Upload
image from a file input
5.
editor-5.js – Upload
image via drag-and-drop
6.
editor-6.js – Choose
from existing uploaded images
7.
editor-7.js – Insert a
hyperlink on selected text
8.
editor-8.js – Undo
content, exit warning, error box
9.
editor-9.js – Clear
editor content
10. index.php – Full HTML
+ Font Awesome toolbar + script loading
11. save-post.php – Save
content from editor to flat file (with UTF-8 BOM)
12. upload-image.php – Upload
image and return safe path (UTF-8 safe)
13. list-images.php – Return all
image filenames as UTF-8-safe JSON
14. function-1.php – Load
content from saved post with strict UTF-8 enforcement
Each one of
these will get its own chapter. And each one can be generated by a simple AI
prompt—meaning, you’ll never again have to copy-paste dozens of functions from
tutorials or YouTube videos. This system is yours. It’s clear, it’s modular,
and it’s smart.
We begin, of
course, with the first file that makes the whole system breathe: editor-1.js
.
This file is
the heart of the editor. It loads the content from your saved file and writes
changes back to the server every five seconds using an auto-save mechanism. It
communicates with the backend save-post.php
using fetch()
, and handles
all communication using UTF-8, ensuring multibyte content is never lost or
corrupted.
It wraps
everything in DOMContentLoaded
so it only
runs once the page has loaded, and it logs every save attempt for clear
debugging. No mystery, no magic—just clean, readable, and replicable
JavaScript.
When you
write Prompt 1, you’re not just creating a file—you’re bringing the editor to
life. From this point forward, the editor will “know” what to load and when to
save.
And from this
point forward, every feature you add will plug directly into this heartbeat
without ever overriding or damaging it.
From the very
beginning, Miracle CMS is designed with UTF-8 enforcement built into every
prompt.
Why? Because your content deserves to work in every language. Your filenames,
JSON responses, editor data, and PHP scripts must respect multibyte characters.
And most CMS systems fail here—because they treat encoding as an afterthought.
We treat it
as a design philosophy.
Every
JavaScript file assumes UTF-8 content in the DOM. Every PHP script explicitly
sets headers to Content-Type: application/json; charset=UTF-8
. Every file
save includes a UTF-8 BOM, and every read uses htmlspecialchars(...,
ENT_QUOTES, 'UTF-8')
.
This isn’t
just technical correctness. It’s moral clarity. You are building something that can
serve the whole world, not just your local machine.
UTF-8 is your
boundary. And boundaries are good.
Let’s talk
plainly.
You’re not
just building a CMS. You’re building a clean system you can hand
to a church, a student, a developer, or a creative—and they’ll understand it.
You’re building an editor that:
·
Works offline with flat files
·
Supports simple WAMP installs
·
Requires no database
·
Can be re-generated with AI prompts anytime
·
Gives you total control, file by file
·
Can be taught in classrooms or teams
·
Can be deployed in ministry, journaling, blogging, or business
·
Will never break from plugin bloat or mystery settings
This is a
miracle system because it’s so clear.
We’ve lost
clarity in software. That ends now.
If you’ve
ever felt like coding wasn’t for you, like CMS systems were too complex, or
like WordPress was the only way to publish—this book was written for you.
You don’t
need to be an engineer to build something beautiful. You don’t need to memorize
frameworks or chase the latest JavaScript trends. You just need a system you
can understand and a way to rebuild it when needed.
You now have
both.
Let this be
your turning point. Let this be the moment you realized: “Wait, I really can
build this myself.” Because you can. And because you now know how.
Over the next
11 chapters, we’re going to walk through every single prompt. Each chapter will
focus on one file. You’ll learn what it does, why it works, and how it
connects. Then we’ll show you the exact prompt you can give to recreate that
file anytime.
And when
we’re done, we’ll show you the full system:
·
The folder structure
·
The JS logic
·
The PHP backend
·
The UTF-8 enforcement
·
The entire regenerate-from-zero strategy
You’ll not
only have the working CMS—you’ll have the method.
So get ready.
Get inspired. Get your tools open and your text editor ready. You’re not just
following instructions. You’re building something you’ll be proud of—something
you can expand, teach, or even productize.
This is your
beginning.
This is the
CMS editor that builds itself.
And you’re
going to build it. One prompt at a time. One page at a time. One breakthrough
at a time.
Let’s go to
Prompt 1. Let’s bring this to life.
Creating
editor-1.js
– The Core
Script That Starts the Miracle
This
single script loads your content, keeps it saved every five seconds, and
creates the heartbeat of your CMS system. One file. One prompt. Total control.
Every system
has a heartbeat. Something invisible that keeps it alive. In your CMS, that
heartbeat is this: the content loads cleanly, and it saves—automatically,
safely, and reliably.
That’s what editor-1.js
does. It
doesn’t just get your project started. It makes the project feel real. With this
one file, your editor becomes alive. You’ll type, and behind the scenes, your
content will be saved—over and over—without asking for permission and without
needing a database. It just works. Silently. Faithfully. Constantly.
This is where
the system comes to life.
In this
chapter, you’ll write the code that loads the saved post from the backend,
places it into your contenteditable editor, and sends changes back to the
server using fetch()
every five seconds. It’s simple.
Elegant. Modular. And above all—UTF-8 safe.
We begin with
a single JavaScript file. One prompt will generate all the code you need. It’s
the first real file of your frontend, and it’s what makes your CMS not just
usable—but stable.
Let’s unpack
it all now.
Here’s what
Prompt 1 builds:
·
Waits for the page to fully load with DOMContentLoaded
·
Finds the editor div (#editor
)
·
On page load, it calls loadPost(1)
and fills
the editor with the saved content
·
Every five seconds, it runs savePost()
using fetch()
to send
content to save-post.php
·
It logs each save attempt and result
·
It ensures UTF-8 safe communication at all times
The user
never needs to click “Save.” They don’t need to understand encoding. They just
type—and their work is protected in the background.
It’s powerful
because it’s invisible.
Let’s break
it down further.
DOMContentLoaded
Your script
begins with:
js
CopyEdit
document.
addEventListener(
'DOMContentLoaded',
function () {
// all logic here
});
This ensures
that the DOM (your HTML structure) has finished loading before the script tries
to access elements like #editor
. Without
this, your script might run too early—and fail.
It’s a simple
safeguard, but it’s what makes everything else possible.
Within this
listener, you’ll run two main operations:
·
Load existing content into the editor
·
Start an interval timer to auto-save every 5 seconds
This creates
the heartbeat rhythm that keeps your CMS healthy.
fetch()
To load your
saved blog post content, we use fetch('/blog-data/post-1.txt')
. This
assumes that a file called post-1.txt
exists on
your server, saved as UTF-8 with a BOM (Byte Order Mark).
We don’t need
a database. We don’t need JSON. Just a .txt
file saved
from a prior session, waiting to be restored into the editor.
The script
reads the file and puts its content into #editor.innerHTML
. Like this:
js
CopyEdit
fetch(
'/blog-data/post-1.txt')
.
then(
response => response.
text())
.
then(
data => {
editor.
innerHTML = data;
});
The entire
save/load logic is designed for UTF-8 content—including multibyte characters
like emojis, Hebrew, Chinese, or accents. That’s critical for real-world
reliability.
fetch()
and Auto-TimerNow the most
powerful feature: auto-save.
Every five
seconds, your script will grab the current editor.innerHTML
, and send it
to save-post.php
via POST
.
You’ll use fetch()
like this:
js
CopyEdit
fetch(
'save-post.php', {
method:
'POST',
headers: {
'Content-Type':
'application/x-www-form-urlencoded; charset=UTF-8'
},
body:
'content=' +
encodeURIComponent(editor.
innerHTML)
});
This ensures
the content is properly encoded in UTF-8 during transmission. The backend then
saves it to the flat file system using file_put_contents()
with a UTF-8
BOM (we’ll cover this in Prompt 11).
Even if the
user doesn’t press a save button—even if they refresh or close the tab—their
content is already saved.
This is how
you create peace of mind. This is how you build a system people trust.
Each save
attempt also logs a message in the console:
js
CopyEdit
console.
log(
'Attempting to save...');
And when the
save succeeds, it logs:
js
CopyEdit
console.
log(
'Save successful.');
If something
goes wrong, you’ll log an error. This makes debugging easy without confusing
the user. You can even expand this to show a visual “saved” icon or timestamp
in future chapters.
The point
here is transparency. As a developer, you want to see what your
system is doing without overwhelming the user.
This gives
you that power.
This file
does one thing only: load and save content.
It doesn’t
touch formatting. It doesn’t handle images. It doesn’t clear content. It
doesn’t even validate input.
Why?
Because each feature
deserves its own space.
This is the
core philosophy behind modular files. If something breaks, you know where to
look. If you want to improve a feature, you know what file to rewrite. If you
want to teach this to someone else, they won’t get lost in one giant block of
code.
This is why
we name the file editor-1.js
. In Chapter
3, we’ll create editor-2.js
. And in
Chapter 4, editor-3.js
. Every file
is plug-and-play. And they’re all loaded in index.php
using <script
defer>
so they don’t interfere with each other.
It’s calm.
It’s clean. It’s yours.
Here’s what
you’ll give an AI (or reuse yourself) to recreate this exact file at any time:
Prompt
1 – Create editor-1.js – Base Save, Load, Auto-Save
Create a JavaScript file named editor-1.js
to handle
loading and saving content in a blog editor system.
Assumptions:
·
The HTML includes a <div id="editor"
contenteditable="true">
·
This script is loaded via <script
src="js/editor-1.js" defer></script>
·
Use DOMContentLoaded
to ensure
elements exist before accessing them
Features
to Implement:
·
On page load, load content from /blog-data/post-1.txt
via fetch()
and place it
inside #editor
·
Auto-save the contents of #editor
every 5
seconds by sending it via POST
to save-post.php
·
Save should send a content string as application/x-www-form-urlencoded
with charset=UTF-8
·
Console log save attempts and success/failure
·
All content is UTF-8 and multibyte safe
Output:
·
Output full, working editor-1.js
·
Wrap logic in DOMContentLoaded
·
Keep code under 100 lines
This is the
exact prompt that generates your first live file.
It will take
a static HTML shell and turn it into a functioning editor that remembers what
you typed, even when you leave the page.
It’s a
miracle moment.
Once you’ve
loaded the HTML and linked this JS file, something magical happens.
You open your
editor, type a few lines, and walk away.
Then you come
back—and it’s still there.
No WordPress.
No MySQL. No login screen. No setup wizard. Just your content, alive and
waiting. Flat files. UTF-8. Total control.
That feeling?
That’s empowerment.
That’s why we
build.
You’ve now
built the first, most critical piece of the puzzle. Your editor loads and saves
content. It protects the user’s work. It runs on a flat file system. And it
does it all automatically.
In the next
chapter, we’ll add something visual: formatting.
Bold. Italic.
Underline. The kind of styling people expect from any editor.
You’ll learn
how to hook buttons to formatting commands, how to preserve the content’s
structure, and how to keep the experience smooth, modular, and UTF-8 safe.
You’ve built
the heartbeat. Now let’s give it style.
Ready for
Chapter 3? Let’s go.
Creating
editor-2.js
– The
Formatting Tools That Make Editing Feel Real
Your
users want more than typing—they want control. These buttons give them the
power to express, edit, and enhance with ease.
Now that your
editor can load and save content, it’s time to bring it to life. The user
experience isn't complete until the user can shape their text. They need to
emphasize. They need to express. They need the formatting tools that make
writing feel like
writing.
That’s where
this chapter—and this next file—comes in.
You’re about
to build editor-2.js
. This
modular JavaScript file adds toolbar buttons that let users apply bold, italic, and underline to their
content inside the editor. With this in place, your editor will go from
functional to powerful. From plain to polished.
But we won’t
do it the messy way.
We won’t cram
these tools into the same file that handles saving. We won’t overload a single
script with a dozen jobs. Instead, like every other part of Miracle CMS, we’ll
give this feature its own file. One file. One prompt. One purpose.
And yes—it
will all respect UTF-8.
Think about
every editor you’ve ever used. Whether it’s Google Docs, Microsoft Word, or
WordPress—one of the first things you notice is the toolbar. It gives you
confidence. It gives you creative control.
Formatting
tools give your user freedom.
And even if
you’re building this for yourself, these buttons matter. They give you the
ability to turn text into meaning. A bolded phrase. An italic quote. An
underlined header. This is what transforms content into communication.
Our goal with
this chapter is to create three toolbar buttons and wire them up so they apply
formatting to the selected text inside the editor.
Before
writing any code, you need a toolbar in your HTML. That’s coming in Chapter 11
when we create index.php
. But for now, assume your page
includes the following:
html
CopyEdit
<div
id=
"toolbar">
<button
id=
"boldBtn">
<i
class=
"fas fa-bold">
</i>
</button>
<button
id=
"italicBtn">
<i
class=
"fas fa-italic">
</i>
</button>
<button
id=
"underlineBtn">
<i
class=
"fas fa-underline">
</i>
</button>
</div>
<div
id=
"editor"
contenteditable=
"true">
</div>
This
structure is clean and minimal. The buttons each have a unique ID. And they use
Font Awesome icons to show their purpose visually.
Your job in editor-2.js
is to
connect each button to its behavior. When clicked, the bold button should apply
bold formatting to the selected text. The same goes for italic and underline.
execCommand()
The magic
happens through an old but effective browser command: document.execCommand()
.
Yes, it’s
technically deprecated—but it still works in every major browser, and for basic
formatting like this, it’s reliable and easy to implement. Since you’re
building your own editor, you can always swap it out later if needed.
Each button
will call:
·
execCommand('bold')
·
execCommand('italic')
·
execCommand('underline')
This tells
the browser to wrap the selected text in the appropriate HTML tag:
·
<b>
or <strong>
for bold
·
<i>
or <em>
for italic
·
<u>
for
underline
Once
inserted, this formatting becomes part of the editor.innerHTML
, which gets
auto-saved by the script you built in Chapter 2.
That’s the
beauty of separation: one file handles formatting, another handles saving.
Together, they build a full system—without stepping on each other’s toes.
Inside editor-2.js
, you’ll wait
for DOMContentLoaded
just like
before. Then you’ll grab references to your buttons:
js
CopyEdit
const boldBtn =
document.
getElementById(
'boldBtn');
const italicBtn =
document.
getElementById(
'italicBtn');
const underlineBtn =
document.
getElementById(
'underlineBtn');
You’ll also
grab the editor element:
js
CopyEdit
const editor =
document.
getElementById(
'editor');
Now attach click
event
listeners to each button. When clicked, they will call execCommand()
and
immediately re-focus the editor so the user can keep typing without
interruption:
js
CopyEdit
boldBtn.
addEventListener(
'click',
() => {
document.
execCommand(
'bold',
false,
null);
editor.
focus();
});
Repeat that
for italic and underline.
That’s it.
Your formatting system is live.
While execCommand()
itself
doesn’t modify encoding, it interacts with the DOM content that is later saved
via innerHTML
. This means everything the user
types or styles is still saved in UTF-8—because editor-1.js
sends it
using encodeURIComponent()
, and save-post.php
stores it
with UTF-8 BOM encoding.
In other
words, even if a user types accented characters, emojis, or non-English
scripts, bolding them will not break the encoding. This is vital.
Your system
works globally because every piece respects UTF-8.
It might seem
easier to just put this formatting logic into the same file as editor-1.js
. But we
don’t. Why?
Because
modularity matters.
If you ever
want to change formatting logic, you can now go straight to editor-2.js
. If you want
to remove the feature later, just delete the file and remove the button
references. No side effects. No save logic touched.
This is what
makes your CMS maintainable.
Here’s the AI
prompt that can generate your complete formatting script anytime:
Prompt
2 – Create editor-2.js – Text Formatting Buttons
Create a JavaScript file named editor-2.js
to add text
formatting behavior to the blog editor.
Assumptions:
·
The HTML includes the following buttons inside #toolbar
:
o
#boldBtn
, #italicBtn
, #underlineBtn
·
The editable area is a <div id="editor"
contenteditable="true">
·
This file is loaded via <script
src="js/editor-2.js" defer></script>
Features
to Implement:
·
Use document.execCommand()
to apply
formatting when a button is clicked
·
Add click event listeners to each formatting button
·
Focus #editor
after executing a command
·
Keep formatting behavior UTF-8 safe and DOM-friendly
Output:
·
Output the full editor-2.js
file
·
Wrap all logic in DOMContentLoaded
·
Keep code clean and well-commented
Once this
file is generated and linked in index.php
, your editor
instantly supports formatting.
And because
the content is saved automatically by editor-1.js
, every
formatting change is preserved.
You now have
a complete editing and saving experience—and we’re only two files in.
When a user
arrives at your editor, they’ll now see a familiar toolbar. They can click
Bold, type. Click Italic, type. Hit Underline, type. They’ll feel at home.
They’ll feel in control.
They won’t
have to understand how it works—but you will.
And that’s
what gives you power.
Because now,
when someone says, “Can we add font color next?” or “How does underline work
under the hood?”, you’ll know where to go. You’ll know what file handles it.
You’ll know that no part of this system is hidden or tangled.
You’re
building software like a craftsman builds a tool bench. One drawer. One tool.
One purpose.
If formatting
doesn’t seem to work, check the following:
·
Make sure the button IDs match in both your HTML and JavaScript
·
Ensure that the JS file is properly loaded in index.php
using <script
src="js/editor-2.js" defer></script>
·
Make sure #editor
is contenteditable="true"
·
Open DevTools and confirm there are no JS errors on load
Once working,
try selecting text in the editor and clicking Bold. You should see the result
immediately. Check the DOM with DevTools—you’ll see <b>
or <strong>
tags in your
live content.
And yes—it’s
saved every five seconds. You’ve built that.
Now that
we’ve added formatting, it’s time to help users visually organize their
thoughts.
In the next
chapter, we’ll add alignment tools: left, center, and right.
These
features give writers better control over headlines, quotes, and visual flow.
And once again, we’ll give them their own file: editor-3.js
.
Let’s move
from formatting style to formatting structure.
You’re doing
great. Let’s keep going.
Creating
editor-3.js
– Add Left,
Center, and Right Alignment
Help
users visually structure their writing with simple, intuitive alignment
controls that feel familiar—and function cleanly.
By now, your
editor loads, saves, and even supports rich formatting like bold, italic, and
underline. But today’s users expect more. They want control—not just over the
style of the words, but the structure and presentation of their message.
Think of
someone writing a quote. They want it centered. Think of someone designing a
blog post with a photo caption. It should be right-aligned. Think of someone
setting up a body paragraph. That should stay left-aligned.
This is about
visual layout. It’s about expression through structure. And it’s about
empowering the writer to see their ideas the way they imagine them.
So in this
chapter, we’re going to give users the tools to align their content with three
buttons: Left, Center, and Right. Each one
will apply classic alignment logic to the selected block of text, using
built-in browser capabilities and clean modular JavaScript.
You’ll build
this entire feature inside a single file: editor-3.js
. One file.
One responsibility. One new capability added to your CMS editor.
Let’s start
by understanding how it works.
Your editor
hasn’t changed. It’s still:
html
CopyEdit
<div
id=
"editor"
contenteditable=
"true">
</div>
Inside that
div, the user writes all their content. This content becomes part of the innerHTML
, which is
saved automatically by your auto-save logic (editor-1.js
), and
formatted by editor-2.js
.
In this new
chapter, we’re simply extending the functionality of the editor—not modifying
how it saves or formats text. We’re layering new features on top of a stable
core. That’s what modular files allow.
We’re not
adding complexity. We’re adding options.
And the tools
we’ll use are once again built into every modern browser.
When you want
to change the alignment of selected text, you don’t need to manually apply CSS
or mess with classes.
Instead, you
can use:
js
CopyEdit
document.
execCommand(
'justifyLeft');
document.
execCommand(
'justifyCenter');
document.
execCommand(
'justifyRight');
Each of these
commands aligns the current selection or block
element accordingly.
·
justifyLeft
: aligns the
block to the left (default)
·
justifyCenter
: centers the
block
·
justifyRight
: aligns the
block to the right
This is fast.
This is browser-native. This is exactly what we want for a CMS focused on
clarity and simplicity.
In index.php
, you’ll
define three new toolbar buttons (we’ll cover that in full in Chapter 11). Each
one will have a unique ID:
html
CopyEdit
<button
id=
"alignLeftBtn">
<i
class=
"fas fa-align-left">
</i>
</button>
<button
id=
"alignCenterBtn">
<i
class=
"fas fa-align-center">
</i>
</button>
<button
id=
"alignRightBtn">
<i
class=
"fas fa-align-right">
</i>
</button>
These buttons
display icons using Font Awesome. They show your users—instantly—what each
button does.
Your job in
this chapter is to make those buttons work.
You’ll write
a script that listens for clicks on each button and runs the appropriate execCommand()
with one of
the three alignment options.
Simple.
Direct. Clean.
Open a new
file called editor-3.js
.
Wrap your
logic inside this block:
js
CopyEdit
document.
addEventListener(
'DOMContentLoaded',
function () {
// logic goes here
});
Inside this
function, you’ll:
1.
Get references to each alignment button
2.
Attach click
event
listeners
3.
Call the proper execCommand()
function
4.
Refocus the editor after alignment is applied
You’ll also
want to get a reference to #editor
again so you
can keep focus after alignment.
You might be
wondering: does text alignment affect UTF-8?
Great
question—and here’s the answer:
No.
But you should still care.
Even though
alignment changes don’t modify encoding directly, you want to be sure your
text—whether it’s Arabic, English, Japanese, or Hebrew—remains structurally
sound and correctly rendered. That means:
·
Ensuring #editor
content
remains in innerHTML
·
Making sure nothing is being overridden or stripped
·
Keeping saving logic separate so alignment doesn't break your
backend saves
In other
words, your system will still rely on UTF-8 at the saving layer, and that’s
already enforced through the auto-save script (editor-1.js
) and the PHP
script (save-post.php
).
You’re not
creating new encoding risks—but you are responsible for not interfering with
what already works. Modularity protects that.
Could you
have added alignment to editor-2.js
?
Sure.
Should you?
Absolutely
not.
Here’s why:
formatting and alignment are two different concerns. One styles
individual characters. The other structures full paragraphs or blocks.
Keeping
alignment logic in its own file means:
·
You can easily find and adjust this logic later
·
You can remove or disable it without affecting formatting
·
You can teach it to someone else faster
·
Your project stays clean and understandable
Every file in
this system has one job. And that’s what makes this system feel like a
miracle—you never feel lost.
This is the
prompt you’ll use to regenerate the alignment feature any time you need it:
Prompt
3 – Create editor-3.js – Text Alignment
Create a JavaScript file named editor-3.js
to implement
text alignment tools in a blog editor.
Assumptions:
·
The HTML includes buttons with IDs:
o
#alignLeftBtn
, #alignCenterBtn
, #alignRightBtn
·
The editor is a <div id="editor"
contenteditable="true">
·
This script is loaded via <script
src="js/editor-3.js" defer></script>
Features:
·
Use execCommand()
with:
o
justifyLeft
, justifyCenter
, justifyRight
·
Add event listeners to each button
·
Focus #editor
after alignment is applied
·
Preserve UTF-8 safe DOM structure and functionality
Output:
·
Output the complete editor-3.js
·
Wrap logic in DOMContentLoaded
·
Code should be clean and modular
Once you’ve
created this file and loaded it via <script defer>
, your users
can visually organize content exactly how they want.
And it just
works.
Want to take
it even further?
Try adding
these enhancements after the base script is working:
·
Active state toggles: highlight
which alignment is currently active
·
Tooltips: use title="Align
Left"
on each button
·
Keyboard shortcuts: let users
press Ctrl + L
, Ctrl
+ E
,
Ctrl + R
for align left, center, right
·
Mobile-friendly icons: test Font
Awesome icons at different screen sizes
None of these
are required—but they’re easy to layer on once your base system is in place.
Again,
because of modularity, improvements like these are never scary. You know where
to make changes. You’re not sifting through a 2,000-line script.
You’re in
control.
You now have
a full-featured alignment system:
·
Three buttons
·
Three alignment modes
·
Browser-native behavior
·
Full UTF-8 compatibility
·
Completely independent of saving and formatting logic
Your editor
now looks and feels more like a professional tool—and users can visually shape
their writing without any HTML knowledge.
And we’re
still only on file 3.
Now that your
editor can structure content visually, it’s time to add a major leap forward: image upload.
In the next
chapter, you’ll build editor-4.js
. It will:
·
Trigger a hidden file input
·
Let users upload images
·
Insert the uploaded image at the cursor position
·
Connect to the backend script upload-image.php
·
Handle errors and give visual feedback
It’s the most
advanced feature so far—and it’s going to be fun.
You’re
building something powerful, piece by piece. And the best part? You understand
all of it.
Let’s move
forward. You’re doing this.
Creating
editor-4.js
– The Hidden
File Upload That Brings Media to Life
Your
editor becomes a full-featured publishing tool when users can add images. This
chapter builds that upgrade—with a file input, a seamless upload flow, and
instant image placement.
Let’s face
it: no modern editor is complete without image support. Users expect it.
Whether they’re blogging, journaling, writing tutorials, or creating content
for ministry, images bring their stories to life. And it’s your job now to
deliver that ability in the simplest, cleanest way possible.
You’re about
to write editor-4.js
, the fourth
modular JavaScript file in your Miracle CMS project. This file allows users to
click a toolbar button, select an image file from their device, and upload it
to the server. Once uploaded, the image is inserted directly at the cursor
within the #editor
.
No extra
pages. No complex dialogs. Just simple image upload that feels natural.
And here’s
the best part: you don’t need a CMS plugin, a media library manager, or an
entire JavaScript framework. All you need is a button, a hidden file input, a
fetch call to upload-image.php
, and clean
DOM logic.
Let’s walk
through how it works—and then write the full prompt to generate this file
anytime you need it.
Here’s the
full user experience we’re about to create:
1.
User clicks the image button in the toolbar
2.
That triggers a hidden <input
type="file">
3.
The user selects an image
4.
The image is uploaded via fetch()
to upload-image.php
5.
When the server responds with a URL, the image is inserted into
the editor at the cursor
6.
If the upload fails, an error message appears on the screen
This is all
happening without any page reloads and without breaking the user’s writing
flow.
It’s a
natural extension of the work we’ve done so far.
In your HTML
file (index.php
, which we’ll build fully in
Chapter 11), you’ll include:
html
CopyEdit
<button
id=
"insertImageBtn">
<i
class=
"fas fa-image">
</i>
</button>
<input
type=
"file"
id=
"imageInput"
style=
"display: none;"
accept=
"image/*">
<div
id=
"uploadErrorMsg">
</div>
The insertImageBtn
is the
toolbar button the user clicks to upload an image.
The imageInput
is a hidden
file input element that will open the file picker dialog.
The uploadErrorMsg
div is where
we’ll display upload errors, if any.
These
elements are all needed to support the JavaScript logic you’ll build now.
As always,
start your editor-4.js
file by
wrapping everything inside a DOMContentLoaded
listener:
js
CopyEdit
document.
addEventListener(
'DOMContentLoaded',
function () {
// image upload logic goes here
});
Then you’ll
select the elements you need:
js
CopyEdit
const insertImageBtn =
document.
getElementById(
'insertImageBtn');
const imageInput =
document.
getElementById(
'imageInput');
const uploadErrorMsg =
document.
getElementById(
'uploadErrorMsg');
const editor =
document.
getElementById(
'editor');
This gives
you full access to all the pieces needed to manage the upload process.
When the user
clicks the image button, we don’t open a dialog manually. Instead, we trigger a
click on the hidden file input:
js
CopyEdit
insertImageBtn.
addEventListener(
'click',
() => {
imageInput.
click();
});
This keeps
the UI clean while still letting the user choose an image.
fetch()
When the user
selects a file, we handle it with an event listener:
js
CopyEdit
imageInput.
addEventListener(
'change',
() => {
const file = imageInput.
files[
0];
if (!file)
return;
const formData =
new
FormData();
formData.
append(
'image', file);
fetch(
'upload-image.php', {
method:
'POST',
body: formData
})
.
then(
response => response.
json())
.
then(
data => {
if (data.
success) {
insertImageAtCursor(data.
url);
}
else {
showError(data.
message ||
'Upload failed.');
}
})
.
catch(
err => {
showError(
'Upload error. Please try again.');
});
});
This code
does everything:
·
Builds a FormData
object
·
Sends it via POST
to upload-image.php
·
Expects a JSON response with a url
key
·
Inserts the image into the editor
·
Displays errors when something fails
Everything
about this interaction happens using UTF-8-safe fetch operations. The backend
script (upload-image.php
) will
enforce UTF-8 in its response using header('Content-Type:
application/json; charset=UTF-8');
, and return clean JSON.
The key to
good UX is inserting the image exactly where the cursor was before the upload.
Here’s a
function to do that:
js
CopyEdit
function
insertImageAtCursor(
url) {
const img =
document.
createElement(
'img');
img.
src = url;
img.
alt =
'Uploaded Image';
img.
style.
maxWidth =
'100%';
const range =
window.
getSelection().
getRangeAt(
0);
range.
deleteContents();
range.
insertNode(img);
}
This DOM
logic uses the Selection
API to insert the image wherever
the user had their cursor. No extra steps. It feels natural.
The style.maxWidth
= '100%'
ensures images don’t overflow on mobile or smaller screens.
If something
fails, the user should see a clear message.
js
CopyEdit
function
showError(
message) {
uploadErrorMsg.
textContent = message;
uploadErrorMsg.
style.
color =
'red';
setTimeout(
() => {
uploadErrorMsg.
textContent =
'';
},
4000);
}
This keeps
things clean. Errors disappear after 4 seconds, and they’re only shown when
needed.
With this,
your image upload logic is complete.
editor-4.js
Again, the
principle is simple: one file per feature.
This file
handles the image upload from a file input. It has nothing to do with:
·
Saving posts
·
Formatting text
·
Aligning paragraphs
·
Clearing the editor
·
Drag-and-drop image uploads (that’s coming in the next chapter)
By isolating
this functionality into its own JS file, you gain all the benefits:
·
Easy debugging
·
Easy removal
·
Easy upgrades
·
Clear responsibilities
·
Seamless plugin-style development
You can test
this file independently. You can reuse it in other projects. You can explain it
to someone in two minutes.
That’s the
power of modular development.
Here’s the
single prompt that can regenerate this entire image upload system:
Prompt
4 – Create editor-4.js – Image Upload via File Input
Create a JavaScript file named editor-4.js
that allows
users to upload an image and insert it into the editor.
Assumptions:
·
There is a toolbar button with ID #insertImageBtn
·
There is a hidden file input #imageInput
·
Upload is handled by upload-image.php
(via POST
with FormData)
·
The editor is #editor
, and the
script is loaded with defer
·
There is a div #uploadErrorMsg
to show
errors
Features:
·
On #insertImageBtn
click →
trigger #imageInput.click()
·
On file select, upload image using fetch()
to upload-image.php
·
Insert <img src="...">
at the
cursor in #editor
·
If upload fails, show error inside #uploadErrorMsg
·
All operations should be UTF-8 safe
Output:
·
Output complete editor-4.js
·
Wrap logic in DOMContentLoaded
Run that
prompt anytime you need to restore or regenerate this logic. It will always
output the same, self-contained file—ready to plug into your system.
With this one
file, your Miracle CMS becomes image-ready.
Your users
can now:
·
Enhance their content
·
Add visual storytelling
·
Include charts, screenshots, or art
·
Embed photos into tutorials, blog posts, or devotionals
·
Create richer experiences for every reader
And it all
happens in seconds, without database dependencies, media library complexities,
or WYSIWYG plugin chaos.
You’ve built
a clean, fast, intuitive image upload flow—modular and maintainable.
You’re doing
this.
Now that
we’ve mastered uploading images via file input, let’s make it even smoother.
In the next
chapter, we’ll create editor-5.js
—which allows
users to drag and drop images
directly into the editor.
That feature
will:
·
Handle dragover and drop events
·
Upload dropped images
·
Insert the image on drop
·
Show errors if something fails
It’s clean.
It’s modern. It’s intuitive.
And it’s what
you’re building next.
Let’s keep
going. Your CMS is becoming incredible.
Creating
editor-5.js
–
Drag-and-Drop Uploading That Feels Natural
Let
users upload images with a single gesture. No clicks. No pop-ups. Just drop the
file in, and let the magic happen.
When you’re
writing, there’s something satisfying about dragging a file and just dropping
it in place. No searching through folders. No clicking multiple buttons. Just
instant action. That’s what modern users expect from a professional content
editor—and in this chapter, that’s what you’ll deliver.
You’ve
already built a file input image uploader in Chapter 5. That gave users the
ability to select a file and insert it. But now we’re taking it to the next
level. We’re going to let users drag images directly into the editor. The
system will catch the file, upload it behind the scenes, and display it where
the drop happened.
This chapter
creates editor-5.js
, a modular
JavaScript file dedicated entirely to drag-and-drop uploads. It works perfectly
with your existing upload infrastructure (upload-image.php
), uses the
same UTF-8-safe logic, and builds on top of the same design philosophy we’ve
followed since Chapter 1.
Let’s turn
your editor into something that feels as smooth as Google Docs—and just as
reliable.
When editor-5.js
is active,
your editor will gain these new capabilities:
·
Detects when a file is dragged over the #editor
·
Prevents the browser from hijacking the file and displaying it
·
Accepts image files dropped directly into the contenteditable area
·
Uploads the dropped image via fetch()
to upload-image.php
·
On success, inserts the uploaded image exactly where the drop
occurred
·
On failure, displays a clear error message in #uploadErrorMsg
The result? A
workflow that feels so smooth, most users won’t even think about it.
That’s the
goal. Seamless UX. Minimal code. Real results.
This chapter
doesn’t require any new HTML, assuming you’ve already added this in a prior
chapter:
html
CopyEdit
<div
id=
"editor"
contenteditable=
"true">
</div>
<div
id=
"uploadErrorMsg">
</div>
These two
elements are all you need. The #editor
is where the
content lives, and where the drop will happen. The #uploadErrorMsg
is where
you’ll display any issues if something goes wrong.
Everything
else will be handled in the script.
You might
wonder: isn’t the file input upload enough?
Not quite.
Here’s why
drag-and-drop is worth adding:
1.
It’s expected. Users try
it even if you don’t tell them to.
2.
It’s faster. One gesture
instead of multiple clicks.
3.
It’s delightful. It feels
like magic. That matters.
4.
It’s empowering. It makes
your CMS feel like it was built for them.
And here’s
the best part: the logic is simple. You already have the backend upload script.
You’re just extending how files are sent to it.
Inside your editor-5.js
file, start
with:
js
CopyEdit
document.
addEventListener(
'DOMContentLoaded',
function () {
const editor =
document.
getElementById(
'editor');
const uploadErrorMsg =
document.
getElementById(
'uploadErrorMsg');
editor.
addEventListener(
'dragover',
function (
e) {
e.
preventDefault();
editor.
classList.
add(
'dragging');
});
editor.
addEventListener(
'dragleave',
function () {
editor.
classList.
remove(
'dragging');
});
editor.
addEventListener(
'drop',
function (
e) {
e.
preventDefault();
editor.
classList.
remove(
'dragging');
const file = e.
dataTransfer.
files[
0];
if (!file)
return;
const formData =
new
FormData();
formData.
append(
'image', file);
fetch(
'upload-image.php', {
method:
'POST',
body: formData
})
.
then(
response => response.
json())
.
then(
data => {
if (data.
success) {
insertImageAtCursor(data.
url, e.
clientX, e.
clientY);
}
else {
showError(data.
message ||
'Upload failed.');
}
})
.
catch(
() => {
showError(
'Upload error. Please try again.');
});
});
function
showError(
message) {
uploadErrorMsg.
textContent = message;
uploadErrorMsg.
style.
color =
'red';
setTimeout(
() => {
uploadErrorMsg.
textContent =
'';
},
4000);
}
function
insertImageAtCursor(
url, x, y) {
const img =
document.
createElement(
'img');
img.
src = url;
img.
alt =
'Dropped Image';
img.
style.
maxWidth =
'100%';
const range =
getRangeFromPoint(x, y);
if (range) {
range.
insertNode(img);
}
else {
editor.
appendChild(img);
}
}
function
getRangeFromPoint(
x, y) {
let range;
if (
document.
caretRangeFromPoint) {
range =
document.
caretRangeFromPoint(x, y);
}
else
if (
document.
caretPositionFromPoint) {
const pos =
document.
caretPositionFromPoint(x, y);
range =
document.
createRange();
range.
setStart(pos.
offsetNode, pos.
offset);
}
return range;
}
});
This code
does a lot—but it does it clearly.
You handle
drag events. You process the drop. You send the image. You show errors. You
insert the image at the correct cursor position.
And every
part is modular, readable, and UTF-8 compatible.
Image uploads
don’t include text directly—but they still touch the UTF-8 system in two ways:
1.
The backend response must use header('Content-Type:
application/json; charset=UTF-8');
2.
The inserted <img src="...">
becomes part
of the editor.innerHTML
, which is
later saved and restored in UTF-8 via save-post.php
This means
that even though the image itself isn’t text, it’s part of a text document that
depends on consistent encoding.
We always
think UTF-8. It’s not optional. It’s the rule.
editor-5.js
You already
have editor-4.js
to handle
file input uploads.
Why not
combine drag-and-drop with that?
Because
they’re different gestures. Different event types. Different UX flows. They
deserve their own space.
By keeping
drag-and-drop logic in editor-5.js
, you:
·
Avoid bloating your upload logic
·
Keep each file laser-focused
·
Make debugging easier
·
Allow future upgrades without breaking anything
This is how
professional tools are built—by design, not by accident.
Here’s the
full prompt that will regenerate this script at any time:
Prompt
5 – Create editor-5.js – Drag-and-Drop Image Upload
Create a JavaScript file named editor-5.js
that enables
drag-and-drop image uploading into the editor.
Assumptions:
·
The editor is a <div id="editor"
contenteditable="true">
·
File uploads are sent to upload-image.php
·
This JS file is loaded via <script
src="js/editor-5.js" defer></script>
·
There is a div #uploadErrorMsg
to display
errors
Features:
·
Handle dragover
and drop
events on #editor
·
Prevent default behavior
·
Upload dropped file via fetch()
POST with FormData
·
Insert image using returned URL at cursor drop point
·
Show errors in #uploadErrorMsg
if upload
fails
·
Ensure UTF-8 safe HTML is preserved
Output:
·
Output full editor-5.js
·
Wrap all logic in DOMContentLoaded
That’s the
only prompt you need. Copy, paste, and generate. Your editor instantly supports
drag-and-drop.
And it feels
great.
Once the base
version is working, try adding:
·
Visual feedback on dragover: style the #editor
background
slightly to show it’s ready
·
Multiple image support: allow
dropping multiple files at once
·
File type checks: validate
image MIME types before uploading
·
Loading spinner or progress bar: give
feedback while uploading
These aren’t
necessary—but they’re easy to add when your code is modular. That’s why we do
it this way.
You’ve built
the foundation. Now you can refine.
With editor-5.js
, your
Miracle CMS now has:
·
Full drag-and-drop image support
·
Realtime feedback
·
Natural content insertion
·
Modular logic
·
UTF-8 reliability
·
Zero external dependencies
And you’re
still under 200 lines of total JavaScript across five files.
Let that sink
in.
What if users
could upload images once—and then reinsert them later?
In the next
chapter, we’ll build editor-6.js
, which
connects to a backend PHP script (list-images.php
) that
returns a list of available images.
Users will be
able to:
·
View all their uploaded images
·
Click one
·
Instantly insert it into the editor
We’ll call it
the image picker. It’s fast. It’s visual. It’s yours.
You’re over
one-third of the way through your build—and your CMS is already amazing.
Let’s keep
going.
Creating
editor-6.js
– View,
Select, and Insert Any Uploaded Image
This
chapter gives your editor a visual image browser, letting users reinsert images
they’ve already uploaded—with a simple click.
Your CMS is
becoming more powerful with each chapter. Right now, you’ve already allowed
users to upload images with a button (Chapter 5) and drag them in (Chapter 6).
But there’s still a missing piece. What happens after an image is uploaded? Can
the user find it again? Can they reuse it in a new post without uploading
again?
This chapter
answers that.
In this
build, we’ll add the ability to browse previously uploaded images, and click
to insert them into the editor. This isn’t just convenient. It’s crucial. Users
might want to reuse logos, headshots, illustrations, or previous
graphics—without duplicating files or wasting storage.
That’s
exactly what editor-6.js
delivers.
It will load
a JSON list of available images using a backend script (list-images.php
), display
them in a simple image picker, and allow one-click insertion into the #editor
. It's
intuitive. It's fast. And it’s a key part of making your CMS feel professional.
When this
feature is active, here’s what the user flow looks like:
1.
User clicks a toolbar button called “Choose Image”
2.
The system fetches the list of images from list-images.php
3.
A lightweight popup (or section) appears, showing all available
images
4.
The user clicks on any image to insert it directly into the editor
5.
The popup disappears—and the user keeps writing
No drag. No
input field. Just a fast visual picker that feels clean and modern.
And like
every chapter before, we’ll build this in its own file: editor-6.js
.
One feature.
One responsibility. One clean file.
Make sure
your index.php
file (which we’ll complete in
Chapter 11) contains the following elements:
html
CopyEdit
<button
id=
"chooseImageBtn">
<i
class=
"fas fa-images">
</i>
</button>
<div
id=
"imagePickerContainer"
style=
"display: none;">
</div>
·
The #chooseImageBtn
triggers the
image browser
·
The #imagePickerContainer
is where the
image list will appear
You don’t
need modals, libraries, or animations yet. Just structure. You can enhance it
later.
Here’s how
your JavaScript logic works:
·
On button click, make a fetch()
request to list-images.php
·
Expect a UTF-8 JSON array of filenames
·
Dynamically build and display <img>
elements
using those filenames
·
Add a click event to each image so it gets inserted into #editor
That’s the
full concept. Now let’s build the script step by step.
editor-6.js
Wrap your
code in a DOMContentLoaded
block like
always:
js
CopyEdit
document.
addEventListener(
'DOMContentLoaded',
function () {
const chooseImageBtn =
document.
getElementById(
'chooseImageBtn');
const imagePickerContainer =
document.
getElementById(
'imagePickerContainer');
const editor =
document.
getElementById(
'editor');
chooseImageBtn.
addEventListener(
'click',
() => {
fetch(
'list-images.php')
.
then(
response => response.
json())
.
then(
data => {
showImagePicker(data);
})
.
catch(
() => {
imagePickerContainer.
innerHTML =
'Failed to load images.';
imagePickerContainer.
style.
display =
'block';
});
});
function
showImagePicker(
images) {
imagePickerContainer.
innerHTML =
'';
images.
forEach(
url => {
const img =
document.
createElement(
'img');
img.
src = url;
img.
alt =
'Uploaded Image';
img.
style.
maxWidth =
'100px';
img.
style.
margin =
'5px';
img.
style.
cursor =
'pointer';
img.
addEventListener(
'click',
() => {
insertImage(url);
imagePickerContainer.
style.
display =
'none';
});
imagePickerContainer.
appendChild(img);
});
imagePickerContainer.
style.
display =
'block';
}
function
insertImage(
url) {
const img =
document.
createElement(
'img');
img.
src = url;
img.
alt =
'Inserted Image';
img.
style.
maxWidth =
'100%';
editor.
appendChild(img);
}
});
This code
does the entire job:
·
Loads available images
·
Displays them visually
·
Allows the user to select one
·
Inserts it instantly into the content
No complex UI
frameworks. Just JavaScript and DOM.
The script
depends on a PHP file: list-images.php
.
You’ll create
that backend file in Prompt 13. It will:
·
Scan the /blog-data/images/
folder
·
Return a JSON array of file URLs
·
Use strict UTF-8 in the response headers
It’s simple
and fast. That’s what makes this entire image picker possible.
The frontend
script (editor-6.js
) doesn’t
care how the images are stored—it just wants a UTF-8 JSON array of URLs.
Although no
text input is being typed here, UTF-8 is still crucial:
·
The server responds using Content-Type:
application/json; charset=UTF-8
·
The image filenames are returned and inserted into the DOM
·
The full HTML of the editor (including <img
src="...">
) is saved later by editor-1.js
This means if
your image files include non-English characters—like foto-über.png
or イメージ
.jpg
—they will
still work.
UTF-8 isn’t
optional. It’s foundational. And your whole system respects it.
editor-6.js
Could you
build this directly into the upload script from Chapter 5? Technically, yes.
But that
violates the one-feature-per-file rule.
Instead, we
keep the logic clean:
·
editor-4.js
handles
image uploads via file input
·
editor-5.js
handles
drag-and-drop
·
editor-6.js
handles
browsing and re-inserting saved images
This
separation makes your code easier to maintain, debug, and upgrade. And it makes
your CMS feel professionally designed.
One button.
One script. One experience.
Use this
prompt any time you want to regenerate or share this script:
Prompt
6 – Create editor-6.js – Choose Existing Image
Create a JavaScript file named editor-6.js
to implement
an image picker that lets users insert saved images.
Assumptions:
·
Button ID: #chooseImageBtn
·
Server file: list-images.php
returns a
UTF-8 JSON array of available images
·
The editor is #editor
·
Image list should appear in a container #imagePickerContainer
·
File is loaded via <script
src="js/editor-6.js" defer></script>
Features:
·
On button click, fetch list from list-images.php
·
Show image results visually in a container
·
On image click, insert <img src="...">
into the
editor
·
Handle UTF-8 image paths safely
·
Minimal styling is acceptable (image width, margin, cursor)
Output:
·
Output full editor-6.js
·
Wrap in DOMContentLoaded
Copy that
prompt, paste it into ChatGPT or another AI, and the entire file will be
rebuilt—ready to plug in.
Modular.
Reliable. Future-proof.
You now have:
·
An image picker
·
A visual browser for existing uploads
·
A simple one-click insert tool
·
Clean DOM logic
·
UTF-8 safety
·
Fully modular architecture
This makes
your CMS not just a writer’s tool, but a real content creation environment.
And your
users will feel it. That’s what makes all of this worth it.
Now that
users can add images with ease, let’s give them the ability to hyperlink their
text.
In the next
chapter, you’ll build editor-7.js
—a tool for
inserting links into selected text. It will:
·
Detect if the user selected text
·
Prompt them for a URL
·
Insert an anchor tag using execCommand('createLink')
·
Validate and handle user input
·
Respect the modular, UTF-8-friendly design
This small
feature makes a huge difference. Blog posts, tutorials, and calls-to-action all
rely on good links.
Let’s build
that next. You’re doing great. Let’s keep going.
Creating
editor-7.js
– Insert
Hyperlinks Using a Simple Prompt Flow
Let
your users turn their words into doorways. This chapter gives them the ability
to add links with one click—and real clarity.
When you
write something impactful, sometimes you want the reader to go somewhere next.
A resource. A scripture. A shop. A reference. That’s what links are for. And
now that you’ve empowered users to format text and insert images, it’s time to
give them the ability to add hyperlinks—directly into selected content.
This chapter
introduces editor-7.js
. It’s a
small file, but it adds one of the most critical features in your blog editor: the Insert
Link function.
It gives
users a toolbar button. When clicked, it checks if text is selected, asks the
user for a URL, and applies the link with execCommand('createLink')
.
It’s
intuitive. It’s consistent. It makes your CMS feel complete.
Let’s build
this new module.
Once added,
your blog editor will allow:
·
Selection of a word or phrase inside the content area
·
Clicking a toolbar button to open a simple prompt
·
Typing or pasting in a URL
·
Wrapping the selected text in an anchor tag
·
Inserting it into the #editor
instantly
It will also
warn the user if no text is selected. That kind of helpful validation is what
makes the tool user-friendly.
And as
always, you’ll write all this in a single file: editor-7.js
.
Make sure
you’ve added this button to your editor toolbar (inside index.php
, finalized
in Chapter 11):
html
CopyEdit
<button
id=
"insertLinkBtn">
<i
class=
"fas fa-link">
</i>
</button>
This button
will be the trigger for the entire feature.
It uses a
Font Awesome icon so users can visually understand its function right away.
Here’s the
outline of what editor-7.js
will do:
1.
Wait for the DOM to load
2.
Add a click listener to #insertLinkBtn
3.
Check if any text is selected inside #editor
4.
If not, show an alert
5.
If text is selected, prompt the user for a URL
6.
Use document.execCommand('createLink')
to apply the
link
7.
Optionally refocus the editor
It’s one
interaction, one command, and one clear improvement to your CMS.
Let’s break
down the implementation.
editor-7.js
Start by
wrapping all your logic in the standard DOMContentLoaded
event:
js
CopyEdit
document.
addEventListener(
'DOMContentLoaded',
function () {
const insertLinkBtn =
document.
getElementById(
'insertLinkBtn');
const editor =
document.
getElementById(
'editor');
insertLinkBtn.
addEventListener(
'click',
() => {
const selection =
window.
getSelection();
const selectedText = selection.
toString();
if (!selectedText) {
alert(
'Please select the text you want to turn into a link.');
return;
}
const url =
prompt(
'Enter the URL:');
if (!url)
return;
document.
execCommand(
'createLink',
false, url);
editor.
focus();
});
});
This script
covers all the key behavior:
·
Detects whether the user actually selected text
·
Uses prompt()
to get a valid link
·
Inserts the hyperlink at the current selection using execCommand()
·
Keeps the user in the flow without needing extra forms or popups
And it all
happens in a lightweight file that works instantly once loaded.
At first
glance, it might not seem like adding a link has anything to do with encoding.
But remember:
the content inside #editor
is being saved to a flat file
using UTF-8. If the selected text includes emojis, Arabic, Japanese, Hebrew, or
any special characters, your entire system must still preserve every
character—correctly.
So, once
again:
·
Your editor.innerHTML
will contain
<a href="...">selected
text</a>
·
That will be saved by editor-1.js
·
It will be stored and retrieved via save-post.php
and loadPost()
·
All content is managed using strict UTF-8 enforcement
This is why
you always build with UTF-8 in mind—even for features that seem simple.
editor-7.js
You’ve
already seen the pattern:
·
editor-1.js
: handles
saving
·
editor-2.js
: formatting
(bold, italic, underline)
·
editor-3.js
: text
alignment
·
editor-4.js
: image
uploads (file input)
·
editor-5.js
: image
uploads (drag and drop)
·
editor-6.js
: insert
existing images
Now, editor-7.js
gives you
hyperlink functionality.
Each file is
focused, clear, and re-creatable through a single prompt. That’s your strength.
You’ve built a modular miracle.
Once you’ve
got the basic prompt working, here are some optional upgrades:
·
Validate the URL (e.g., auto-prepend https://
if missing)
·
Open links in a new tab (target="_blank"
)
·
Add a dialog box instead of prompt()
·
Automatically highlight active links in the editor
·
Let users edit or remove links by clicking on them
But even
without these upgrades, this feature adds major functionality.
It brings
your CMS from writing-only into full publishing mode.
You can
regenerate the full script at any time using this exact prompt:
Prompt
7 – Create editor-7.js – Insert Link
Create editor-7.js
to allow
inserting hyperlinks into the editor.
Assumptions:
·
Button ID: #insertLinkBtn
·
The user selects text inside #editor
·
File loaded with defer
·
Uses prompt()
to collect the link URL
·
Applies the link using execCommand('createLink')
·
Focuses back to the editor after insertion
·
Shows alert if no text is selected
Output:
·
Output complete editor-7.js
·
Wrap in DOMContentLoaded
That’s the
only instruction you need. One prompt. One file. Full functionality.
This is the
benefit of modular CMS development.
By completing
this chapter, your editor now supports:
·
Link creation
·
Prompting for URLs
·
Validating selected text
·
Inserting hyperlinks without breaking the flow
·
UTF-8-compliant content handling
·
Clean modular design that’s easy to maintain
And all of it
happens in under 50 lines of JavaScript.
That’s real
progress.
We’re about
to add something very special: memory.
In the next
chapter, you’ll create editor-8.js
, which
handles:
·
Undoing the last change
·
Warning the user if they try to leave the page with unsaved
changes
·
Displaying error messages when uploads fail
These aren’t
just extras—they’re the foundation of a great editing experience.
You’ve
empowered users to write. Now you’ll protect what they’ve written.
Let’s keep
building. Your CMS is becoming extraordinary.
Creating
editor-8.js
– Saving
Users From Losing Their Content
What
good is a CMS if users lose their work? This chapter adds core safety features:
undo, exit warnings, and visual upload error handling.
You’ve
already added features for formatting, uploading, inserting, and linking. Now
it’s time to think about user safety. What
happens if someone makes a mistake? What happens if they try to leave the page
without saving their work? What happens if an upload fails? Will they be
informed? Will they feel secure?
These are not
small details. These are the kinds of things that turn a decent editor into a
professional one. These are the features that show your CMS was built with
care. Because real users don’t just want more buttons—they want peace of mind.
That’s why in
this chapter, you’ll create editor-8.js
. This file
is your safety net module.
With just one
script, you’ll deliver:
·
An undo function that reverts to the last saved state
·
A beforeunload warning that prevents accidental data loss
·
A simple way to show error messages (especially for failed
uploads)
This chapter
adds a layer of emotional comfort that users can feel every time they work
inside your editor.
Here’s a
clear breakdown of what this file adds to your CMS:
1.
Undo
o
Captures the current editor content whenever it changes
o
Allows the user to revert back by clicking a toolbar button
2.
Exit Warning
o
Detects if the editor content has changed
o
Warns the user with a confirmation dialog if they try to close or
refresh the page
3.
Upload Error Display
o
Centralizes error messages inside the #uploadErrorMsg
div
o
Displays temporary warnings in red when uploads fail
o
Allows other scripts (like image uploads) to safely trigger error
display
You’ll be
protecting your users from themselves, from browser accidents, and from network
issues—all in a small, modular script.
Make sure
your editor page (index.php
) includes the following:
html
CopyEdit
<button
id=
"undoBtn">
<i
class=
"fas fa-undo">
</i>
</button>
<div
id=
"uploadErrorMsg">
</div>
These two
elements are simple but essential:
·
The undo button allows quick recovery
·
The error message container provides visible, centralized feedback
You don’t
need complex modals or alerts—just clean, visible, timed messages and helpful
safety logic.
editor-8.js
Start with
the usual DOMContentLoaded
wrapper and
define the key elements:
js
CopyEdit
document.
addEventListener(
'DOMContentLoaded',
function () {
const editor =
document.
getElementById(
'editor');
const undoBtn =
document.
getElementById(
'undoBtn');
const uploadErrorMsg =
document.
getElementById(
'uploadErrorMsg');
let lastState = editor.
innerHTML;
let hasChanged =
false;
// Save last state on input
editor.
addEventListener(
'input',
() => {
hasChanged =
true;
});
// Undo button functionality
undoBtn.
addEventListener(
'click',
() => {
editor.
innerHTML = lastState;
hasChanged =
false;
showMessage(
'Content reverted to last saved state.');
});
// Exit warning
window.
addEventListener(
'beforeunload',
function (
e) {
if (hasChanged) {
e.
preventDefault();
e.
returnValue =
'';
}
});
// Error display
window.
showError =
function (
message) {
uploadErrorMsg.
textContent = message;
uploadErrorMsg.
style.
color =
'red';
setTimeout(
() => {
uploadErrorMsg.
textContent =
'';
},
4000);
};
// Message display
function
showMessage(
msg) {
uploadErrorMsg.
textContent = msg;
uploadErrorMsg.
style.
color =
'green';
setTimeout(
() => {
uploadErrorMsg.
textContent =
'';
},
3000);
}
});
Here’s what
this script accomplishes:
·
Tracks whether the editor content has been modified
·
Captures and restores the last saved content
·
Alerts the user if they try to leave the page
·
Displays helpful error messages from any script that calls showError()
·
Makes undo and alerts intuitive and visual
And all of
this lives cleanly in just one file.
Even though
this script doesn’t directly interact with files, it deals with your editor.innerHTML
. That
content includes everything the user writes—including images, symbols, emojis,
and text in any language.
The innerHTML
value will
later be saved by editor-1.js
using fetch()
and sent to save-post.php
, which will
write to a flat file using UTF-8.
So if undo
restores Japanese, Greek, or emoji content, it must match the original UTF-8
characters perfectly. That’s why consistency across your system matters.
Even undo and
warnings rely on correct encoding flow.
editor-8.js
You’ve
followed a modular strategy from the beginning:
·
Formatting lives in editor-2.js
·
Image uploads live in editor-4.js
and editor-5.js
·
Link logic lives in editor-7.js
So these
logic flows—undo, warnings, and error displays—deserve their own space.
Why?
·
They aren’t formatting
·
They aren’t media
·
They are editor safety functions
Grouping them
into one file gives you a self-contained system of content protection. That
makes your app more organized, maintainable, and professional.
Once you
complete the base system, here are some enhancements you might try:
·
Automatically update lastState
every time
the post is auto-saved
·
Add a keyboard shortcut for Undo (e.g., Ctrl+Z
)
·
Support multiple undo levels with an array of past states
·
Add severity levels to error messages (info, warning, danger)
·
Extend showError()
to support
custom error containers
Each one of
these ideas can improve user trust. But the foundation is what matters—and
that’s what you’re building now.
Use this
exact prompt to regenerate the entire file anytime you want:
Prompt
8 – Create editor-8.js – Undo, Exit Warning, Upload Errors
Create editor-8.js
to implement
Undo, exit warnings, and upload error messaging.
Assumptions:
·
Undo button has ID: #undoBtn
·
Error display container has ID: #uploadErrorMsg
·
Editable content is in: #editor
·
The JS file is loaded using <script
src="js/editor-8.js" defer></script>
Features:
·
Store editor’s last state
·
On input, mark editor as "changed"
·
Undo button reverts to last saved state and clears change flag
·
Show browser exit warning if editor has changed
·
Add global showError()
function to
display red error text in #uploadErrorMsg
for 4
seconds
·
Add internal success message handler for undo feedback
Output:
·
Output complete editor-8.js
·
Wrap all logic in DOMContentLoaded
This prompt
produces your protection layer—ready to save content, prevent disasters, and
inform users clearly.
This is how
great CMS tools are built.
This chapter
helped you build a layer of content security:
·
Undo functionality
·
Exit warning to prevent accidental loss
·
Upload error feedback
·
Consistent UTF-8 content tracking
·
Modular, maintainable JavaScript
You’re not
just helping people write—you’re helping them keep what they’ve
written.
You’re
building trust into your platform.
In the next
chapter, we’ll write editor-9.js
—a tool that
gives users a Clear button.
This tool
will:
·
Confirm the user’s intent
·
Clear the editor to a default starting state
·
Save the cleared state immediately
·
Use the same UTF-8 logic and save triggers as before
It’s a small
feature, but a very important one for people who want to start fresh.
Let’s keep
moving. Your CMS is almost complete—and every chapter is making it stronger.
Creating
editor-9.js
– Giving
Users a Fresh Start When They Need It
Sometimes
you just want to start over. This chapter adds the functionality to instantly
clear the editor, save the cleared state, and give users a clean slate—with
confidence.
In the real
world of writing, sometimes we need a reset. Maybe the direction changed. Maybe
the content got too messy. Maybe the writer just had a better idea. That’s when
the Clear button
becomes a gift.
This chapter
gives your editor a simple but powerful tool—one that clears the content,
resets the user’s mind, and ensures nothing gets lost in the process. It isn’t
just about removing text. It’s about providing clarity, offering a
way out, and letting the user choose a clean beginning with zero
confusion.
We’ll do it
by building a new script: editor-9.js
. Like every
other part of this CMS, it will follow our modular, UTF-8-compliant, user-first
approach. This script will be small—but mighty.
Let’s build a
better reset button.
By the end of
this chapter, your CMS will allow users to:
·
Click a "Clear" button
·
Get a confirmation prompt before clearing
·
Instantly reset the editor to its default value (e.g., <p>Start
writing here...</p>
)
·
Trigger the save function immediately after clearing
·
Display any relevant success or error messages
It’s just one
button, but it adds clarity, control, and confidence.
Most
importantly, it does all this safely. Users will never accidentally
lose their work—and when they clear, they’ll know it’s truly saved.
Ensure your
HTML has this button and structure already in place:
html
CopyEdit
<button
id=
"clearBtn">
<i
class=
"fas fa-eraser">
</i>
</button>
<div
id=
"uploadErrorMsg">
</div>
As with our
other tools, the icon helps communicate the purpose visually. The #uploadErrorMsg
will once
again be used for error or success messaging.
No extra
elements are needed. No popups, no modals, no complex forms. Simplicity wins.
editor-9.js
Let’s jump
into the script. Start with the usual structure:
js
CopyEdit
document.
addEventListener(
'DOMContentLoaded',
function () {
const editor =
document.
getElementById(
'editor');
const clearBtn =
document.
getElementById(
'clearBtn');
const uploadErrorMsg =
document.
getElementById(
'uploadErrorMsg');
clearBtn.
addEventListener(
'click',
() => {
const confirmClear =
confirm(
'Are you sure you want to clear the editor? This action will overwrite your content.');
if (!confirmClear)
return;
editor.
innerHTML =
'<p>Start writing here...</p>';
uploadErrorMsg.
textContent =
'';
if (
typeof savePost ===
'function') {
try {
savePost();
showMessage(
'Editor cleared and saved.');
}
catch (e) {
showError(
'Failed to save cleared state.');
}
}
else {
showError(
'Save function not available.');
}
});
function
showError(
message) {
uploadErrorMsg.
textContent = message;
uploadErrorMsg.
style.
color =
'red';
setTimeout(
() => {
uploadErrorMsg.
textContent =
'';
},
4000);
}
function
showMessage(
msg) {
uploadErrorMsg.
textContent = msg;
uploadErrorMsg.
style.
color =
'green';
setTimeout(
() => {
uploadErrorMsg.
textContent =
'';
},
3000);
}
});
This script
gives users:
·
A safe confirmation prompt
·
A known default editor state
·
Immediate integration with the existing save system
·
Clear visual feedback after the action
And once
again—it’s all encapsulated in a single, focused JS file.
This file
assumes that a global savePost()
function is
already defined.
That’s the
same function we wrote in earlier chapters, which:
·
Gathers editor.innerHTML
·
Sends it via POST to save-post.php
·
Saves it as a UTF-8 flat file
By calling it
after the clear action, you guarantee the new empty state is stored
safely—without relying on auto-save alone.
That’s
real-time feedback and permanent action.
Even though
this feature appears to be a reset, it still touches everything that matters:
·
The cleared content (<p>Start writing
here...</p>
) is sent to the backend
·
It’s saved in the flat file with UTF-8 encoding
·
Any future editing will start from that encoded default
This makes
UTF-8 enforcement just as important as in every other chapter.
You want your
clear state to be readable, valid, and error-free—no matter what language or
characters are used next.
UTF-8 is your
foundation. Keep using it everywhere.
editor-9.js
You’ve kept
every file laser-focused so far.
So it makes
perfect sense to:
·
Keep clearing logic in its own script
·
Keep confirmation prompts local to the file
·
Keep success/error messages scoped to this feature
·
Keep your code clean and maintainable
This is the
last of your JavaScript modules. When you finish this file, your editor will be
fully
feature-complete on the frontend.
That’s a
milestone worth celebrating.
Use this
final frontend prompt to regenerate this file anytime:
Prompt
9 – Create editor-9.js – Clear Editor
Create editor-9.js
to add the
"Clear" editor feature.
Assumptions:
·
Button ID: #clearBtn
·
Editor: #editor
·
Error display container: #uploadErrorMsg
·
File loaded via <script
src="js/editor-9.js" defer></script>
·
There exists a global savePost()
function
Features:
·
On click, prompt user with a confirm message
·
If confirmed:
o
Reset editor content to <p>Start writing
here...</p>
o
Clear error container text
o
Call savePost()
o
Display success or failure message in #uploadErrorMsg
Output:
·
Output full editor-9.js
·
Wrap in DOMContentLoaded
Copy and
paste that into ChatGPT or your chosen generator, and you’ll always be able to
recreate the Clear button.
One feature.
One prompt. One clean module.
With this
chapter, your CMS now includes:
·
A full Clear button
·
User confirmation for irreversible actions
·
Triggered saving to preserve new states
·
Modular logic
·
UTF-8-compatible content
·
Professional error messaging
It’s a small
feature. But it delivers big trust.
You’re giving
users clarity, control, and peace of mind.
Now that
you’ve completed all the core JavaScript files, it’s time to build the
structure that brings everything to life.
In the next
chapter, we’ll create the index.php
file.
This single
HTML file will:
·
Include the toolbar with all necessary buttons
·
Add the #editor
and all
required containers
·
Link all 9 JS files using <script
src="...">
with defer
·
Load your font icons and establish the layout
It’s the
front door to your CMS. And it’s the final piece before moving on to backend
logic.
Let’s finish
strong. The frontend is almost done—and it’s already remarkable.
Creating
index.php
– The Editor
Layout That Ties All Modules into One
Every
feature you’ve built lives here. This chapter constructs the main HTML file
that brings your modular CMS to life—organized, clear, and powerful.
By now,
you've created nine feature-rich JavaScript modules—each one focused, powerful,
and built to work independently. But without a proper home to hold it all, your
blog editor is incomplete. That’s what this chapter delivers.
This is where
you build your central HTML file: index.php
.
This file
brings everything together. It defines the toolbar. It includes the editor
space. It connects every JavaScript file with defer
. It loads
your font icons. It initializes your entire user experience.
It’s not just
structure. It’s the final assembly of everything you’ve built so far in Part 1.
Let’s build
the front-end shell that transforms nine separate pieces into one unified,
working CMS.
index.php
Will DoThis file
will:
·
Create a toolbar with buttons for each editor feature
·
Create a contenteditable area (#editor
)
·
Include visual containers like #uploadErrorMsg
and #imagePickerContainer
·
Link all 9 JavaScript files in the correct order
·
Enforce UTF-8 in the HTML headers
·
Load Font Awesome for icon-based buttons
·
Ensure the layout is readable, usable, and clean
This is not
just scaffolding—it’s an intelligent interface.
Before we
write any HTML, let’s remember one core rule: strict UTF-8
enforcement everywhere. That means:
·
Setting the document’s character set to UTF-8 using <meta
charset="UTF-8">
·
Ensuring the PHP file is saved with UTF-8 BOM encoding
·
Designing every piece to properly display multibyte characters
This
guarantees that no matter what your users write—whether in English, Arabic,
emojis, or Mandarin—it displays perfectly, saves safely, and loads reliably.
UTF-8 isn’t
an afterthought. It’s part of the very first line.
Now let’s
walk through the key parts of the file.
php
CopyEdit
<!DOCTYPE html>
<html lang=
"en">
<head>
<meta charset=
"UTF-8">
<title>Miracle CMS Editor</title>
<link rel=
"stylesheet" href=
"styles.css">
<script src=
"https://kit.fontawesome.com/your-fontawesome-kit.js" crossorigin=
"anonymous"></script>
</head>
This head
section does three things:
·
Declares the document as UTF-8
·
Loads your custom stylesheet (styles.css
)
·
Pulls in Font Awesome for toolbar icons
Inside the <body>
, we define
the main toolbar:
html
CopyEdit
<body>
<div
id=
"toolbar">
<button
id=
"boldBtn">
<i
class=
"fas fa-bold">
</i>
</button>
<button
id=
"italicBtn">
<i
class=
"fas fa-italic">
</i>
</button>
<button
id=
"underlineBtn">
<i
class=
"fas fa-underline">
</i>
</button>
<button
id=
"alignLeftBtn">
<i
class=
"fas fa-align-left">
</i>
</button>
<button
id=
"alignCenterBtn">
<i
class=
"fas fa-align-center">
</i>
</button>
<button
id=
"alignRightBtn">
<i
class=
"fas fa-align-right">
</i>
</button>
<button
id=
"insertImageBtn">
<i
class=
"fas fa-image">
</i>
</button>
<input
type=
"file"
id=
"imageInput"
style=
"display: none;"
accept=
"image/*">
<button
id=
"chooseImageBtn">
<i
class=
"fas fa-images">
</i>
</button>
<button
id=
"insertLinkBtn">
<i
class=
"fas fa-link">
</i>
</button>
<button
id=
"undoBtn">
<i
class=
"fas fa-undo">
</i>
</button>
<button
id=
"clearBtn">
<i
class=
"fas fa-eraser">
</i>
</button>
</div>
Each button
is wired to a JavaScript file from earlier chapters. These are visual,
intuitive, and efficient.
html
CopyEdit
<div
id=
"editor"
contenteditable=
"true">
<p>Start writing here...
</p>
</div>
<div
id=
"uploadErrorMsg">
</div>
<div
id=
"imagePickerContainer"
style=
"display: none;">
</div>
This is the
writing space. It’s where the user types, formats, inserts, and edits content.
Below it are the containers for:
·
Upload errors
·
The visual image picker
Simple
structure. Strong functionality.
Finally, we
include all 9 JavaScript files with defer
:
html
CopyEdit
<script
src=
"js/editor-1.js"
defer>
</script>
<script
src=
"js/editor-2.js"
defer>
</script>
<script
src=
"js/editor-3.js"
defer>
</script>
<script
src=
"js/editor-4.js"
defer>
</script>
<script
src=
"js/editor-5.js"
defer>
</script>
<script
src=
"js/editor-6.js"
defer>
</script>
<script
src=
"js/editor-7.js"
defer>
</script>
<script
src=
"js/editor-8.js"
defer>
</script>
<script
src=
"js/editor-9.js"
defer>
</script>
</body>
</html>
defer
ensures each script waits for the
DOM to load before running. It also keeps your loading performance clean and
non-blocking.
That’s the
final piece of the frontend puzzle.
index.php
is Its Own
ChapterThis file is
more than just HTML.
It is:
·
A summary of everything you've built
·
The hub that makes every JS module functional
·
A testable, launchable, working page
·
Your user’s entire interface
It deserves
its own attention. Its own structure. Its own clarity.
When someone
opens your project, this is what they’ll see first. And now you’ve made it
clean, clear, and deeply functional.
Here is the
complete prompt that generates this file on demand:
Prompt
10 – Create index.php – HTML Structure with Toolbar and Script Loading
Create an HTML file named index.php
for a blog
editor.
Requirements:
·
Use <!DOCTYPE html>
and set <meta
charset="UTF-8">
·
Load Font Awesome using <script
src="https://kit.fontawesome.com/...">
·
Link to styles.css
·
Create a #toolbar
containing:
o
Buttons with IDs and icons:
§ boldBtn
, italicBtn
, underlineBtn
, alignLeftBtn
, alignCenterBtn
, alignRightBtn
, insertImageBtn
, chooseImageBtn
, insertLinkBtn
, undoBtn
, clearBtn
o
A hidden file input: #imageInput
·
Create a #editor
div
(contenteditable)
·
Include a #uploadErrorMsg
and a hidden
#imagePickerContainer
·
Include 9 JS files using <script
src="js/editor-X.js" defer></script>
for editor-1
through editor-9
·
Ensure all JS files work together and are referenced in correct
order
Output:
·
Output complete index.php
file
·
Keep under 150 lines if possible
·
Include basic structure and logic only
You can copy
that into any AI generator or use it for your own backup systems. This ensures
the whole frontend can always be rebuilt—quickly, cleanly, and completely.
This chapter
brings it all together:
·
A full HTML page
·
A clean toolbar
·
A ready-to-use content editor
·
Script loading for all 9 features
·
Proper UTF-8 enforcement
·
Professional layout and usability
You now have
a fully working frontend CMS system—designed modularly, rebuilt with prompts,
and styled for clarity.
It’s
complete.
But we’re not
done yet.
Now that the
frontend is complete, it’s time to build the backend logic. In the next
chapter, we’ll begin Part 2 – Backend of your CMS.
You’ll
create:
·
save-post.php
·
upload-image.php
·
list-images.php
·
function-1.php
to load
saved content
These PHP
files will make everything work behind the scenes—while still preserving the
same modular, prompt-driven, UTF-8-safe architecture you've built in every
other part.
You've now
completed Part 1 – Frontend of the
project. Take a deep breath. You're doing something extraordinary.
Now, let’s
power it all with the server side.
PART
2 – THE BACKEND SYSTEM
Flat File PHP
Endpoints – Save, Upload, List, and Load
After the frontend is fully functional, your next focus
becomes the backend—the flat-file engine that powers everything invisibly. It
begins with the most critical server-side task: saving the user’s post content.
You create a PHP script that receives the editor’s HTML, secures it with proper
UTF-8 encoding, and stores it in a flat text file. This gives your system
permanence, clarity, and complete freedom from databases.
With content saving in place, you turn to managing
media. You build a secure backend script to handle image uploads, ensuring only
safe, valid image types are accepted and saved with unique filenames. This
script connects with your frontend drag-and-drop and file input tools,
completing the visual pipeline. You also establish a strong folder structure,
storing all images in a dedicated location.
To further improve the user experience, you then build
a script that scans your images folder and returns a list of all uploaded media
as a UTF-8-safe JSON array. This powers your image picker tool, making reuse
effortless. No more redundant uploads—users can browse their existing files and
insert them instantly into the editor.
Finally, you write a reusable function that loads post
content by its ID. This scalable architecture makes it easy to expand your CMS
to support multiple blog entries or dynamic loading across views. By the end of
this part, you have a full backend ecosystem—modular, secure, and completely
database-free—working in perfect harmony with your frontend.
Creating
save-post.php
– Safely
Writing Editor Content to a UTF-8 File
Every
word typed in the editor needs a destination. This chapter builds the PHP
endpoint that takes user content and securely stores it—permanently.
Your user
writes. They format. They edit. They add images. They insert links. But at the
end of all this creativity, something must happen behind the scenes: the
content needs to be saved.
That’s the
job of your first backend file: save-post.php
.
In this
chapter, you’ll write the PHP logic that receives HTML content from the editor,
sanitizes it, converts it safely to UTF-8, and saves it as a flat .txt
file on your
server.
This isn’t
just a backend utility. It’s the lifeline of your CMS.
When done
correctly, this file makes the difference between a toy and a tool—between a
quick demo and a real content platform.
save-post.php
Will DoHere’s what
this script is responsible for:
·
Accept a POST request from your frontend containing the blog
content
·
Ensure the content is UTF-8 safe and HTML-safe
·
Write the content to a file, e.g., blog-data/post-1.txt
·
Add a UTF-8 BOM to ensure maximum compatibility
·
Respond with success or failure
It sounds
simple, but these steps matter more than anything else. Your entire app’s value
is built on this one action: saving content reliably.
You’re
storing all post content in .txt
files inside
a subdirectory like this:
bash
CopyEdit
/blog-data/post-1.txt
Later, you’ll
support different post IDs or slugs. But for now, you’ll just save everything
to post-1.txt
.
This system
keeps your CMS flat-file based—no database
required, easy to back up, and ideal for developers who want to control their
content without relying on SQL.
You’ll write
to this file using PHP’s file_put_contents()
function—but
with special encoding precautions.
Most
developers use UTF-8 without the BOM (Byte Order Mark). But for maximum
compatibility—especially with Windows-based editors and flat-file
systems—you’ll want to add the UTF-8 BOM manually.
Here’s what
the BOM looks like in PHP:
php
CopyEdit
$utf8Bom =
"\xEF\xBB\xBF";
By prepending
that to your file content, you make sure that even emoji-rich or multibyte text
renders correctly—even in Notepad.
That’s a win
for safety and compatibility.
save-post.php
Here’s the
core logic, step-by-step:
1.
Accept $_POST['content']
from a
frontend fetch()
2.
Sanitize it with htmlspecialchars()
3.
Prepend the UTF-8 BOM
4.
Save it to blog-data/post-1.txt
5.
Respond with a JSON status message
And all of
this should happen with error handling and good
developer hygiene.
save-post.php
Here’s what a
proper save-post.php
file looks
like:
php
CopyEdit
<?php
header(
'Content-Type: application/json; charset=UTF-8');
try {
if (!
isset(
$_POST[
'content'])) {
throw
new
Exception(
'No content provided.');
}
$rawContent =
$_POST[
'content'];
$sanitizedContent =
htmlspecialchars(
$rawContent, ENT_QUOTES | ENT_HTML5,
'UTF-8');
$utf8Bom =
"\xEF\xBB\xBF";
$fullContent =
$utf8Bom .
$sanitizedContent;
$filePath =
__DIR__ .
'/../blog-data/post-1.txt';
if (!
file_exists(
dirname(
$filePath))) {
mkdir(
dirname(
$filePath),
0775,
true);
}
file_put_contents(
$filePath,
$fullContent);
echo
json_encode([
'success' =>
true,
'message' =>
'Post saved successfully.']);
}
catch (
Exception
$e) {
http_response_code(
500);
echo
json_encode([
'success' =>
false,
'message' =>
$e->
getMessage()]);
}
Let’s break
it down.
·
UTF-8 Header: Ensures
that PHP sends and receives UTF-8-encoded content
·
Sanitization: Uses htmlspecialchars()
with full
UTF-8 encoding to avoid broken characters
·
BOM Injection: Adds the
UTF-8 BOM to the beginning of the content
·
Safe File Path: Uses __DIR__
and ../blog-data/
to store
files one level above the web root
·
Error Handling: Provides
structured feedback via JSON and HTTP status codes
·
Automatic Folder Creation: Creates blog-data
directory if
it doesn’t exist
This is
secure, simple, and perfectly suited for your flat-file system.
Let’s remind
ourselves how the frontend JavaScript interacts with this script.
In editor-1.js
, we used
this pattern:
js
CopyEdit
fetch(
'php/save-post.php', {
method:
'POST',
headers: {
'Content-Type':
'application/x-www-form-urlencoded; charset=UTF-8'
},
body:
new
URLSearchParams({
content: editor.
innerHTML
})
});
This is what
hits save-post.php
. The content
travels from the browser to the server. And from the server to a file. And from
that file, your blog post becomes permanent.
That’s the
miracle of this CMS system. You write once, and it lasts.
Use this AI
prompt anytime to recreate this file instantly:
Prompt
11 – Create save-post.php – Save Editor Content to Flat File
Create a PHP script named save-post.php
with these
EXACT requirements:
·
Accept $_POST['content']
from the
frontend
·
Sanitize content using htmlspecialchars()
with UTF-8
·
Prepend UTF-8 BOM (\xEF\xBB\xBF
)
·
Save content to a file named ../blog-data/post-1.txt
·
Ensure the folder exists before writing
·
Return a JSON success or error message
·
Set HTTP response code to 500 if an exception occurs
·
Add Content-Type: application/json; charset=UTF-8
·
Max 30 lines of code
·
Must work on Windows (WAMP) environment
This prompt
will generate your PHP save logic every time—whether for debugging, rebuilding,
or future CMS upgrades.
You’re never
locked out of your own system again.
This chapter
gave you the power to:
·
Capture content from the browser
·
Sanitize and secure it
·
Encode it for compatibility
·
Save it with UTF-8 integrity
·
Build a backend that just works
You now have
a real save function. Real permanence. Real CMS functionality.
This one file
turns your editor into a real publishing tool.
In the next
chapter, you’ll write upload-image.php
.
This script
will:
·
Accept file uploads
·
Rename files securely
·
Return a usable image URL
·
Enforce safe file types and sizes
·
Work with drag-and-drop and file inputs
You’ve built
the writing part. Now you’ll build the media part. Let’s keep going. Your CMS
is now alive—and growing.
Creating
upload-image.php
– Handling
Media Uploads With UTF-8 and Server-Side Protection
Every
image upload is a potential risk—or a beautiful enhancement. This chapter
builds a secure, UTF-8-compliant upload system for your CMS using flat-file
logic.
You’ve
already created the logic for inserting images into your editor through both
drag-and-drop and button input. But none of that matters unless your CMS can actually
receive the files and save them.
This chapter
builds the secure backend process to handle all image uploads: upload-image.php
.
The goal here
isn’t just functionality. It’s safety.
You need to
let users upload images—quickly and easily—without compromising the server. You
also need to make sure the file names don’t break, the format remains clean,
and the data responds correctly across browsers and devices.
That’s what
this script does. It receives a file, gives it a safe name, stores it in the
right place, and returns the image path back to the JavaScript caller.
And yes, we
will strictly enforce UTF-8 compatibility every step of the way.
upload-image.php
Will DoHere’s what
this script accomplishes:
·
Accepts an uploaded file from a POST
request
·
Validates that it’s an image (JPEG, PNG, GIF, WebP)
·
Assigns it a new, safe filename using uniqid()
·
Saves it in the blog-data/images/
folder
·
Returns the image URL in a UTF-8-encoded JSON response
·
If anything fails, returns an appropriate error
This is your
CMS’s file receiving endpoint. It’s small, but powerful.
You’ll store
uploaded images like this:
arduino
CopyEdit
/blog-data/images/my-random-id.jpg
This
structure ensures:
·
All images are stored in a single folder
·
No overwriting of user-uploaded images
·
Easy to list or insert later
·
No database needed to track uploads
Your editor-4.js
and editor-5.js
scripts both
point to this PHP file, and expect a JSON response with the uploaded image URL.
Let’s build
it.
Every file
upload is a potential exploit. Hackers often upload scripts with .jpg
extensions.
So you need to:
·
Only accept real image MIME types
·
Reject oversized or empty files
·
Prevent overwriting filenames
·
Reject if $_FILES
is missing
or malformed
Never trust
file input. Always verify on the server side.
upload-image.php
Here’s the
full script with UTF-8 enforcement:
php
CopyEdit
<?php
header(
'Content-Type: application/json; charset=UTF-8');
try {
if (!
isset(
$_FILES[
'image'])) {
throw
new
Exception(
'No file uploaded.');
}
$image =
$_FILES[
'image'];
if (
$image[
'error'] !== UPLOAD_ERR_OK) {
throw
new
Exception(
'Upload error: ' .
$image[
'error']);
}
$validTypes = [
'image/jpeg',
'image/png',
'image/gif',
'image/webp'];
if (!
in_array(
mime_content_type(
$image[
'tmp_name']),
$validTypes)) {
throw
new
Exception(
'Invalid image type.');
}
$ext =
pathinfo(
$image[
'name'], PATHINFO_EXTENSION);
$newName =
uniqid(
'img_',
true) .
'.' .
$ext;
$uploadDir =
__DIR__ .
'/../blog-data/images/';
if (!
file_exists(
$uploadDir)) {
mkdir(
$uploadDir,
0775,
true);
}
$destination =
$uploadDir .
$newName;
move_uploaded_file(
$image[
'tmp_name'],
$destination);
$urlPath =
'blog-data/images/' .
$newName;
echo
json_encode([
'success' =>
true,
'url' =>
$urlPath], JSON_UNESCAPED_UNICODE);
}
catch (
Exception
$e) {
http_response_code(
500);
echo
json_encode([
'success' =>
false,
'message' =>
$e->
getMessage()]);
}
Let’s break
it down.
·
Content-Type Header: Ensures
response is UTF-8 encoded
·
File Checks: Confirms
that the file is an image and that no upload errors occurred
·
MIME Type Validation: Confirms
the actual file type using mime_content_type()
·
File Renaming: Uses uniqid()
to prevent
collisions
·
Folder Creation:
Auto-creates the images/
folder if needed
·
Secure Save: Uses move_uploaded_file()
to save
files
·
UTF-8 Output: Sends a
proper JSON response with Unicode intact
All this in
just 40 lines of code.
This is
industrial-strength backend development made beautifully simple.
Your frontend
editor modules (editor-4.js
, editor-5.js
) use fetch()
and FormData()
to send the
image:
js
CopyEdit
const formData =
new
FormData();
formData.
append(
'image', file);
fetch(
'php/upload-image.php', {
method:
'POST',
body: formData
})
.
then(
res => res.
json())
.
then(
data => {
if (data.
success) {
// insert image at cursor
}
else {
showError(data.
message);
}
});
This script
is expecting a valid JSON response that looks like this:
json
CopyEdit
{
"success":
true,
"url":
"blog-data/images/img_65c2eaf1a.jpg"
}
Or, if
there’s a problem:
json
CopyEdit
{
"success":
false,
"message":
"Invalid image type."
}
Clean,
readable, consistent.
Here is the
exact prompt to generate this file on demand:
Prompt
12 – Create upload-image.php – Upload Image and Return Path
Create a PHP script named upload-image.php
that handles
image uploads.
Requirements:
·
Accept a file named image
via $_FILES
·
Check for upload errors using UPLOAD_ERR_OK
·
Validate MIME type: must be jpeg, png, gif, or webp
·
Rename file using uniqid()
with
extension
·
Store in ../blog-data/images/
·
Auto-create folder if it doesn’t exist
·
Return JSON { success: true, url: '...' }
·
On error, return { success: false, message: '...' }
·
Use header('Content-Type: application/json;
charset=UTF-8')
·
Save the file using move_uploaded_file()
·
Max 40 lines
·
Works in Windows (WAMP) environment
·
Ensure UTF-8 compatibility everywhere
Use this
prompt to rebuild your image upload endpoint whenever needed. It’s your safety
net and your upgrade tool.
This chapter
added the ability to:
·
Receive and validate images from the frontend
·
Rename and store them with no risk of collisions
·
Deliver usable URLs back to the editor
·
Handle every upload with UTF-8-safe, secure PHP
·
Create a smooth experience from drag-and-drop to finished post
You’ve now
given your users a full media experience—one that feels modern, fast, and
reliable.
Your CMS can
now receive content. And now, it can receive visuals, too.
In the next
chapter, we’ll write list-images.php
.
This script
will:
·
Scan the images/
folder
·
Create a JSON list of all uploaded files
·
Return the image paths for use in your image picker
It’s the
final step in the image upload pipeline.
After this,
your CMS will be able to upload, display, choose, and reinsert images like any
real blog editor out there.
Let’s finish
it. You’re almost there.
Write the new chapter 14 -- Knowing about the prompt 13 of 14, of
the final 14 prompts / Write it in the same style, referencing that prompt, in
2000 words, in 4 pages. -- taking into account referencing the single code
prompt ------------ AVOID: using a long dash before headings. ------------ WHAT
TO DO: (A) Make sure to use large font for the chapter title (the same size as
it is when an h1 tag is used in html), (B) use a Chapter subtitle, and a 2nd
chapter subtitle that gives the reader a better preview on what the chapter is
about. (C) Write everything horizontally on the screen, and not in another
file, so I can see everything easily on the current page.
Certainly!
Here's Chapter
14
in the OFFICIAL
CHAPTER FORMAT, using the analyzed writing style, based on Prompt 13 of
14:
Creating
list-images.php
– Scanning
and Returning a JSON List of Available Images
Image
reuse saves time, boosts creativity, and speeds up workflow. This chapter
builds the backend script that lets your users see everything they’ve already
uploaded—fast.
Uploading an
image is helpful. Reusing that same image across multiple posts is powerful.
When someone
uploads a logo, a team photo, or a product image, they shouldn’t have to upload
it again. They should be able to click one button, browse all previous uploads,
and instantly reinsert anything they’ve used before.
In this
chapter, we’ll write the script that makes that possible: list-images.php
.
This PHP file
will scan the images/
folder, find all valid image
files, and return a UTF-8-safe JSON array of those filenames. Your JavaScript
can then turn that list into clickable previews for your users.
This small
file gives your CMS a massive usability upgrade. And it only takes a few lines
of code.
list-images.php
Will DoLet’s define
the goals clearly. This file must:
·
Locate all valid image files in blog-data/images/
·
Return the list as a JSON array of paths
·
Use UTF-8 encoding in the output
·
Only include valid image extensions (e.g., .jpg, .png, .gif,
.webp)
·
Sort the list in reverse chronological order (most recent first)
·
Respond to GET requests, with no user input required
It sounds
simple—and it is—but this functionality unlocks a new user experience.
Now your
users don’t have to remember filenames or re-upload. They click. They choose.
Done.
This file
will be called by your editor-6.js
script,
which adds the Choose Existing Image feature.
Here’s what
happens:
1.
The user clicks the “Choose Image” button in the toolbar
2.
That triggers a fetch request to list-images.php
3.
The returned list is shown visually in a popup or modal
4.
Clicking an image inserts it into the editor
You’ve
already built most of this behavior on the frontend. This file is the backend
piece that powers it.
Let’s write
it.
list-images.php
Here’s the
complete and secure code:
php
CopyEdit
<?php
header(
'Content-Type: application/json; charset=UTF-8');
try {
$imageDir =
__DIR__ .
'/../blog-data/images/';
$webPath =
'blog-data/images/';
if (!
file_exists(
$imageDir)) {
throw
new
Exception(
'Image directory does not exist.');
}
$files =
scandir(
$imageDir);
$validExt = [
'jpg',
'jpeg',
'png',
'gif',
'webp'];
$images =
array_filter(
$files, function (
$file)
use ($
imageDir, $
validExt) {
$
ext =
strtolower(
pathinfo($
file,
PATHINFO_EXTENSION));
return
in_array(
$ext,
$validExt) &&
is_file(
$imageDir .
$file);
});
usort(
$images, function (
$a,
$b)
use ($
imageDir) {
return
filemtime($
imageDir . $
b) -
filemtime($
imageDir . $
a);
});
$urls =
array_map(function (
$filename)
use ($
webPath) {
return $
webPath . $
filename;
},
$images);
echo
json_encode(
$urls, JSON_UNESCAPED_UNICODE);
}
catch (
Exception
$e) {
http_response_code(
500);
echo
json_encode([
'success' =>
false,
'message' =>
$e->
getMessage()]);
}
This file
does five things extremely well:
·
Reads the image directory
·
Filters only real image files
·
Sorts them by modification time
·
Converts them to web paths
·
Returns a UTF-8-safe JSON array
And it
responds instantly with exactly what the frontend needs.
As with all
your backend files, this one starts with:
php
CopyEdit
header(
'Content-Type: application/json; charset=UTF-8');
This is
critical for JSON correctness. If even one filename contains multibyte
characters, you need UTF-8 to preserve it.
You also use:
php
CopyEdit
JSON_UNESCAPED_UNICODE
That keeps
non-English filenames legible in your developer console and in frontend
previews.
Even in this
small script, UTF-8 remains the backbone of your CMS’s reliability.
Notice how
the script uses:
php
CopyEdit
usort(
$images, function (
$a,
$b) {
return
filemtime(...) -
filemtime(...);
});
This means
the newest uploads appear first. It’s a minor feature—but users love it. They
usually want to use what they just uploaded. So put it first.
This is
thoughtful CMS design. Every line has a purpose.
Here’s the
complete AI prompt that will recreate this file on command:
Prompt
13 – Create list-images.php – Return JSON List of Available Images
Create a PHP script named list-images.php
that does
the following:
Requirements:
·
Scans the folder ../blog-data/images/
·
Filters only valid image files (.jpg, .jpeg, .png, .gif, .webp)
·
Uses scandir()
and filemtime()
·
Sorts images so the newest file appears first
·
Converts file names into web paths like blog-data/images/filename.jpg
·
Returns a JSON array of strings
·
Use Content-Type: application/json; charset=UTF-8
·
Include JSON_UNESCAPED_UNICODE
to preserve
multibyte characters
·
On error, return { success: false, message: '...' }
·
Max 40 lines of code
·
Compatible with WAMP (Windows) environment
·
Fully UTF-8 compliant
This prompt
ensures this script can always be recreated—whether you need to fix a bug or
launch another instance of your CMS.
You’re
building for the long run.
With this
chapter, you now have:
·
A script that scans your images folder
·
A sorted, UTF-8-safe list of reusable image URLs
·
A backend service your editor can call
·
A frontend that feels modern and fast
·
A completely self-sufficient image reuse system
This is one
of the most “invisible” parts of your CMS—but it may be one of the most loved.
You’ve saved
your users from unnecessary clicks, frustration, and re-uploads. That’s a
powerful win.
You’ve built
the frontend. You’ve built the uploader. You’ve added reusability.
Now, in the
next chapter, we’ll give your CMS the ability to load any post by its ID.
The file
we’ll write is function-1.php
. It contains
a simple reusable function: loadPost($postId)
. This lets
your system scale up to handle multiple blog posts in the future.
This will
close out the full 14-prompt system and bring your project full
circle—editable, savable, reloadable.
You’ve built
something remarkable. Let’s finish it strong.
Creating
function-1.php
– Reusable
PHP to Load Any Post File by Number
If
saving makes your content real, loading gives it life again. This chapter
builds a reusable PHP function that loads post content dynamically, the right
way, every time.
You’ve come
so far. Your CMS can write, format, upload, reuse, and store. But until now,
it’s only been dealing with one post—usually post-1.txt
.
It’s time to
go scalable.
You’re
building a real CMS. That means being able to support multiple blog posts.
Today, it’s one. Tomorrow, it’s one hundred. That’s where function-1.php
comes in.
This file
doesn’t produce output directly. It gives you a single, powerful function: loadPost($postId)
.
With that one
function, you can load any saved post by its number. Whether you integrate it
with a front-end menu, a preview system, or even a full blog page display—this
function is your foundation.
function-1.php
Will DoLet’s make it
clear. This file will:
·
Define a single PHP function: loadPost($postId)
·
Accept an integer post ID
·
Load content from blog-data/post-{$postId}.txt
·
Return the content as a UTF-8-safe string
·
Handle missing files gracefully
·
Sanitize the output
·
Include test cases to validate the function
This small
file is built for reuse. It can be required into any page—admin panels, view
pages, previews—and called like a standard utility.
Think of it
as your content loader for everything that comes next.
This function
must respect every character your users type. Whether they’re writing in
French, Korean, or adding emoji, your loader must never corrupt the content.
That’s why we
read files with UTF-8 encoding. And that’s why we sanitize again before
displaying output.
Remember: not
all environments treat encoding the same. But your CMS will
always do it right.
loadPost()
Let’s imagine
a view-post.php
page that
shows the contents of post 7. It could look like this:
php
CopyEdit
require_once
'function-1.php';
echo
loadPost(
7);
And just like
that, your saved blog post comes back to life—formatted, editable, and ready to
be read or reloaded into the editor.
That’s what
this chapter delivers.
function-1.php
Here’s the
complete file:
php
CopyEdit
<?php
function
loadPost(
int
$postId):
string {
$filePath =
__DIR__ .
'/../blog-data/post-' .
$postId .
'.txt';
if (!
file_exists(
$filePath)) {
return
'<p><em>Post not found.</em></p>';
}
$content =
file_get_contents(
$filePath);
if (
$content ===
false) {
return
'<p><em>Could not load content.</em></p>';
}
$sanitized =
htmlspecialchars_decode(
$content, ENT_QUOTES | ENT_HTML5);
return
$sanitized;
}
// Test cases
if (
php_sapi_name() ===
'cli') {
echo
"Test 1: Valid Post\n";
echo
loadPost(
1) .
"\n\n";
echo
"Test 2: Missing Post\n";
echo
loadPost(
9999) .
"\n\n";
echo
"Test 3: Edge Case\n";
echo
loadPost(-
1) .
"\n\n";
}
This is
elegant and clear. It reads. It checks. It sanitizes. It returns.
It’s the
perfect final piece to your system.
When saving,
you encoded the post content using htmlspecialchars()
. That was
the right choice—it prevents malicious HTML from being saved directly.
But when
loading, we want to decode the content back to its original
form, so it displays cleanly. That’s why we use:
php
CopyEdit
htmlspecialchars_decode(
$content, ENT_QUOTES | ENT_HTML5)
It brings
back all the real characters—quotes, ampersands, and more.
Now your
editor can load posts that look exactly as the user wrote them.
Notice how we
added a testing block:
php
CopyEdit
if (
php_sapi_name() ===
'cli') {
// Run test cases here
}
This allows
you to run this file from the command line like this:
javascript
CopyEdit
php
function-
1.php
It’s a smart
way to validate that your logic works before plugging it into a full page.
Add new test
cases as needed. You’ll be glad you have them.
Here’s the
exact AI prompt you can use to recreate this file:
Prompt
14 – Create function-1.php – Define loadPost($postId) to Load Saved Content
Create a PHP file named function-1.php
with the
following requirements:
Requirements:
·
Define a function loadPost(int $postId): string
·
Load content from ../blog-data/post-{$postId}.txt
·
If file doesn’t exist, return <p><em>Post
not found.</em></p>
·
Use file_get_contents()
to read
content
·
Decode content using htmlspecialchars_decode()
·
Return UTF-8-safe output
·
Add test cases that run if the script is executed via CLI
·
Use php_sapi_name() === 'cli'
to detect
CLI
·
Keep the file under 50 lines
·
Fully UTF-8 compliant
·
Designed for Windows + WAMP
This prompt
closes the loop. With this one reusable function, your CMS becomes dynamic,
scalable, and extendable.
You now have:
·
A reusable loader function
·
CLI test cases for quality checks
·
Full UTF-8 safety on both read and decode
·
A future-proof structure that supports multiple blog posts
·
One more reason this CMS is not just “working,” but built right
With function-1.php
, you’ve
given your system the final backend utility it needs to grow.
Whether you
want to load posts into view pages, preview panels, or a multi-post admin
panel—this function handles it cleanly and correctly.
This is the
final functional file in the system.
You now have:
·
A frontend editor that writes
·
A backend system that saves
·
A media system that uploads and reuses
·
A post loader that brings it all back
And all of it
was built with 14 simple, smart prompts.
Your CMS is
real.
But your
journey isn’t over.
In the next
and final chapter—Chapter 16: You’ve Made It to the End!—we’ll
reflect on what you’ve created, and I’ll give you your next steps to grow,
expand, and use this as your launching pad.
You’ve just
completed something extraordinary. And we’re about to celebrate it.
PART
3 – WRAPPING IT ALL UP
With all the pieces in place, the final part of the
book takes a step back to reflect on what you’ve built—and how you built it.
You’ve created a complete content management system: modular, prompt-driven,
UTF-8 compliant, and fully rebuildable. This section begins by reviewing the
system’s structure and summarizing the 14 modular prompts that created every
core file in the project.
From there, the focus shifts to understanding the
deeper philosophy behind the system. You didn’t just build an editor—you
created a new way of thinking about software. By using one prompt per file and
never overlapping logic, you gained control, clarity, and the ability to
regenerate any part of the project instantly. That approach is
transformative—and you’re encouraged to carry it into every future coding
project you take on.
You’re also given a vision for what comes next. This
system can be expanded with themes, post indexing, authentication, or even
markdown support. The same modular process applies to every new feature: write
a focused prompt, generate a single file, and plug it into the system. That
means you’re never starting from scratch again—you're always extending
something solid.
The final chapters wrap up with two sets of guiding
principles. One highlights the core practices that made this CMS project
succeed. The other outlines the “miracles” behind the process—clarity,
modularity, regeneration, UTF-8 safety, and prompt-based thinking. Together,
they form a repeatable pattern for AI-assisted software development. You didn’t
just finish a book. You started a movement.
How
We Built A Complete CMS Using Only Modular Prompts and AI
A
working, professional-grade blog editor—with full frontend and backend—crafted
from 14 simple AI prompts. Here’s what we created, how we did it, and why this
changes everything.
Congratulations.
You didn’t just finish a coding project. You redefined how one can be built.
Over the last
15 chapters, you created a fully functional, UTF-8-enforced, secure, and
extendable content management system. You did it without dragging through
thousands of lines of code, without a bloated framework, and without any
guesswork.
Instead, you
used a method that’s now available to every developer, educator, entrepreneur,
and team member: AI-generated modular prompts—cleanly
written, individually testable, and infinitely rebuildable.
This project
wasn’t just a blog editor. It was a proof-of-concept that became
a full product. You built it. Prompt by prompt.
You started
with a blank editor. Then you added auto-saving, formatting, image uploading,
linking, alignment, and even error handling. But you didn’t hard-code it all
into one massive JS file.
Instead, you
wrote nine focused, minimal, readable JavaScript modules:
·
editor-1.js
: Load, Save,
Auto-save
·
editor-2.js
: Text
Formatting Buttons
·
editor-3.js
: Alignment
Tools
·
editor-4.js
: Upload via
File Input
·
editor-5.js
: Drag &
Drop Upload
·
editor-6.js
: Choose
Existing Image
·
editor-7.js
: Insert
Hyperlink
·
editor-8.js
: Undo, Exit
Warning
·
editor-9.js
: Clear
Editor
Each one does
exactly one job, but together, they form a complete frontend experience. And
every script is pulled into your index.php
using <script
defer>
—meaning zero collisions, zero complexity, and full compatibility.
You designed
an editor system that’s readable and expandable. And you did it all with
prompts that can regenerate those files instantly.
The backend
wasn’t built with databases. It didn’t require frameworks. It was just smart PHP—designed to
be portable, minimal, and powerful.
Here’s what
you added:
·
save-post.php
: Securely
save post content with UTF-8 BOM
·
upload-image.php
: Receive
image uploads and return file paths
·
list-images.php
: Return a
JSON list of all uploaded images
·
function-1.php
: Load any
post content dynamically by ID
Each script
respects encoding, responds with structured JSON, and handles errors
gracefully. The system is bulletproof and flexible—and it works flawlessly on
Windows + WAMP.
And just like
with the frontend, each file was written using a single, crystal-clear AI
prompt. No guesswork. No cut-and-paste. Just reproducible, understandable
logic.
At the heart
of this book was a simple, radical idea:
“What
if we could generate an entire working project using just 14 modular AI
prompts?”
And that’s
exactly what you did.
Each prompt
was written with:
·
Clear purpose
·
Minimal code length
·
Explicit requirements
·
Compatibility for WAMP and Windows
·
Strict UTF-8 enforcement
·
Rebuildability from scratch
You didn’t
just code. You designed reliable modular infrastructure—generated on
demand. It’s a new blueprint for working on code, whether solo or in a team.
Sure,
technically this is a blog editor. It loads content, lets you edit it, and
saves it back to the server.
But in
reality, you built something else entirely:
·
A blueprint for modular
AI-based development
·
A workflow that uses
prompts as self-documenting components
·
A teaching tool that any new
coder can use to learn the logic of real projects
·
A production-ready app that others
can build upon, extend, or redesign
And perhaps
most importantly, you created something that removes friction.
You don’t
have to dig into 3,000 lines of tangled spaghetti code anymore. You just pull
out the prompt that builds the one piece you need—and you’re done.
This is the
future of maintainable, human-scale software.
Let’s
summarize why this worked so well.
1.
Each prompt builds a full file
o
You never needed to merge or manually piece together files. Every
prompt starts clean and ends clean.
2.
No files ever overlap
o
Frontend JS is separated into modular scripts. Backend PHP stays
isolated. Your HTML loads only what it needs.
3.
UTF-8 enforced everywhere
o
From meta charset
to PHP
headers to file BOMs, everything is safe, multilingual, and emoji-ready.
4.
Flat-file structure
o
Easy to deploy. No MySQL required. Works on any host. Backups are
as easy as dragging a folder.
5.
Prompt regeneration
o
Lose a file? Regenerate it. Update one function? Rewrite just the
prompt. Versioning becomes natural.
6.
Each chapter = one working step
o
Readers never felt lost. They saw the purpose, the goal, and the
result—every time.
This is a new
model of creation. And it worked.
You’ve built
the editor. You’ve got the backend. But you’re just getting started.
Here are a
few next directions you can take:
·
Add user authentication with a
simple login prompt
·
Build a blog post list view for managing
multiple posts
·
Generate a markdown version of the
editor
·
Add theming support with CSS
variables
·
Build a mobile-first layout for phones
and tablets
·
Export posts as PDF or HTML files
And the best
part? Each of those can be built with a new prompt—just like the 14 you used
here.
You're not
tied down. You're free to keep expanding, feature by feature, prompt by prompt.
If you're
working with others—or even training new coders—this book gives you a secret
weapon.
You now have:
·
A shared codebase that’s easy
to explain
·
A set of prompts that double
as documentation
·
A teaching model for walking
through real software building
·
A way to contribute without
stepping on each other’s code
This isn’t
just for solo devs. It’s for anyone who wants to make coding simpler, cleaner,
and more modular.
Whether
you’re launching a product, training a team, or teaching students—this method
works.
You called it
Miracle CMS—and rightly so.
Because this
wasn’t about a miracle in the magical sense. It was about achieving the
seemingly impossible—with elegance and clarity.
And you did
it.
You created a
complete blog CMS:
·
With clean modular files
·
With strict UTF-8 support
·
With a zero-database flat-file system
·
With 100% prompt-based generation
·
That can be rebuilt from scratch in under an hour
That’s not
just a project. That’s a new development model.
And it’s a
glimpse into the future.
Your project
structure now looks like this:
pgsql
CopyEdit
project-root/
├
── blog-data/
│
├
── post
-1.txt
│ └── images/
│ └── *.jpg
├
── js/
│
├
── editor
-1.js through editor
-9.js
├
── php/
│
├
── save-post.php
│
├
── upload-image.php
│
├
── list-images.php
│ └──
function-1.php
├
──
index.php
It’s tidy.
It’s logical. It’s powerful.
You wrote all
of this, step by step, prompt by prompt, with clarity and care.
You didn’t
just build a CMS. You built a foundation for everything you’ll build next.
This chapter
was a celebration. A wrap-up. A mirror held to the incredible work you’ve done.
But let’s
make one thing very clear:
This
isn’t the end. This is the launchpad.
You’ve now
proven you can build an entire real-world app from 14 modular prompts. And
you’ve done it with high standards, smart structure, and inspiring results.
So what’s
next?
Whatever you
want to create.
Because now
you don’t just understand prompts—you understand prompt-powered
architecture.
And that
means the world is yours.
Let’s build
more.
The
End of the Book Is the Beginning of Something Bigger
You’ve
just built a fully working CMS. Now it’s time to celebrate—and decide what
you’ll build next.
You made it.
Not just through this book, but through an entirely new way of thinking. You
didn’t just read a tutorial. You built something real.
Page by page,
prompt by prompt, decision by decision—you created a working blog editor from
scratch. You didn’t just follow instructions. You learned how modular software
can be designed, built, and understood in a way that feels clean, replicable,
and entirely yours.
You now know
something that most people never figure out: you can build something truly
powerful, even if it starts simple, even if you’re not an expert, even if it’s
your first time.
This was
never just about the code. It was about ownership. And now—you own this
project.
It’s easy to
get lost in huge codebases. It’s easy to think “I’ll never understand all
this.” But this book proved the opposite. You can understand everything. You
can keep it small. You can make every part rebuildable, logical, and clean.
You now have
a fully working CMS—with rich text editing, image uploading, auto-saving, undo,
clear tools, link insertion, and file-based saving—all built using just 14
prompts.
That’s not
just a cool trick. That’s a shift in how software can be created.
This is what
happens when clarity becomes your architecture. When AI is your partner, not
your replacement. When you build a system that actually makes sense.
This whole
project was about setting you up for something greater.
We used this
CMS as our canvas. But the real masterpiece was the process:
·
Thinking modularly
·
Breaking features into self-contained files
·
Using exact prompts to control complexity
·
Ensuring every part is testable and rebuildable
·
Maintaining strict UTF-8 integrity across every system
You now have
a process you can use for anything. Want to build a CRM? A to-do list app? A
social media poster? Start with your file structure. Write a prompt for each
part. Build with clarity and purpose.
You now have
that power.
You’ve earned
this moment. Look at what you’ve built:
·
A completely functional, flat-file blog CMS
·
An AI-prompt-generated frontend + backend
·
Clean HTML, modular JavaScript, simple PHP
·
Strict UTF-8 protection and a clear file system
·
A tool that can be shared, taught, reused, and expanded
This is
something that could easily be hosted, demoed, or shared with clients. It could
be forked and turned into a Markdown editor, a journaling tool, or a developer
blog engine.
You didn’t
cut corners. You made every piece matter. That’s what makes this special.
Let’s be
honest—most people never really learn to manage full-stack apps cleanly. Most
people hack things together. They never understand encoding issues, separation
of concerns, or what it takes to really maintain something.
You now do.
You learned
how to:
·
Build frontend logic in isolated files
·
Use event listeners and the DOM cleanly
·
Create backend endpoints that are secure and specific
·
Use UTF-8 consistently to avoid encoding bugs
·
Rely on prompts to regenerate missing logic
·
Think like a system designer—not just a coder
That’s rare.
And valuable. And you did it the right way.
Now that
you’ve finished this book, you’ve got some amazing next steps:
1.
Teach it.
Show someone else how you did it. Walk them through the prompts. It will
reinforce your understanding—and spread this new modular method.
2.
Build on it.
Add a post list. Add delete. Add user logins. Build themes. You can keep
expanding this system, using new prompts as needed.
3.
Duplicate the method.
Pick another project—something new. Design a file structure. Write out 10–15
prompts. Build that one too.
4.
Host it.
Put your editor online. Let others try it. Make it part of your portfolio. Show
off the clarity you’ve brought to software.
5.
Collaborate.
Use this as a base to start a team project. Let others build modules from your
prompt system. You now have a way to onboard contributors easily.
You’ve proven
that code doesn’t have to be chaos. That development doesn’t have to be
intimidating. That you can work with AI, instead of feeling like it’s replacing
you.
You’ve
created something beautiful and practical, without any fluff, without
frameworks, without mess.
You now know
how to build a professional-grade project from a list of 14 ideas.
That’s
freedom. That’s creative power. That’s software as it was meant to be—modular,
explainable, rebuildable, and yours.
I want to
thank you for making it this far.
You stuck
with it. You wrote the files. You learned the parts. You built the system.
You didn’t
just make a blog editor—you learned a blueprint. And now you’re holding it in
your hands.
You’re ready
for anything. And I mean that.
You now know:
·
How to make a project real
·
How to work clearly and modularly
·
How to protect against encoding disasters
·
How to make software with long-term clarity
·
And how to build something that’s truly yours
That’s the
end of this book. But not your journey.
Because from
this moment forward—you can build anything.
And I can’t
wait to see what you’ll do next.
A
New Way to Build: The Prompt-Based, Modular, Rebuildable Software Revolution
This
chapter reveals how to apply this system to any code project, how to extend
your Miracle CMS easily, and how to carry these 10 award-winning principles
into all future development.
You just
finished building a real, fully working, modular CMS using a method most
developers don’t even know is possible.
And not only
did it work—it worked smoothly, quickly, and with nearly no bugs, because of
one thing: clarity.
This was a
different kind of coding book. One that didn’t dump full source files on you.
One that didn’t expect you to paste things blindly. This was a book of
thinking, design, modularity, and regeneration. You built an app by writing
structured AI prompts—and each one
generated a full, independent, correct file.
Now it’s time
to take this further.
What would it
look like if we used this Miracle Process to build
everything else? What if this wasn’t just how you built one blog editor—but
your new method for all software?
Let’s break
down how it worked, and why it works so well.
Traditional
software tutorials often tangle you up:
·
You follow a long tutorial where everything’s nested together
·
Files depend on other files you haven’t made yet
·
You build one big file and later wish you hadn’t
·
Debugging becomes impossible because there are too many moving
parts
But in this
Miracle CMS, we didn’t do that.
We used a
system based on:
·
Modular thinking
·
Prompt-based generation
·
Independent rebuildability
·
Strict encoding enforcement
·
Progressive logic, one feature at a time
We split the
frontend into nine separate JS files—each one doing only one thing. Then we
separated the backend into five lightweight PHP files, each doing exactly one
clear job.
And we
generated every file with an AI prompt.
That’s the
new model.
Let’s give it
a name:
Prompt-Based
Modular Development (PMD)
It’s not just
a technique—it’s a philosophy.
Here’s what
the Miracle
Process is:
1.
Start with the outcome you want – Know what
your app will do
2.
Break it into clean logical features – Not just
code blocks, but actual goals
3.
Assign each feature to its own file – Make each
part fully self-contained
4.
Write an AI prompt that builds the file – Clear,
testable, and strict
5.
Add UTF-8 enforcement – Avoid
future bugs
6.
Test each module in isolation – Before
integrating
7.
Use defer loading for frontend scripts – To avoid
race conditions
8.
Use file-based architecture whenever possible – It’s
portable and simple
9.
Document your system using the prompts
themselves – Your prompts become your guide
10. Keep
everything rebuildable – If a file breaks, re-run the prompt
These ten
steps were invisible as you followed them through the book—but they’re what
made everything work.
Now they’re
yours to keep, and to reuse in every new project you begin.
These are the
gold-standard rules that we followed—even if you didn’t notice them at first.
Follow these, and future projects will build themselves just as smoothly.
Every file
has a matching prompt. This means zero ambiguity, full regeneration, and
modular upgrades.
Every file,
every request, every header. This prevents the invisible bugs that can destroy
international compatibility.
We never
modified the same file from multiple prompts. This removed merge conflicts,
mistakes, and chaos.
<script defer>
You loaded
every JavaScript file cleanly, ensuring DOM readiness and no race conditions.
You didn’t
use a database. This kept your app portable, easy to back up, and impossible to
break with SQL errors.
If an image
upload fails, it shows an error. If a post can’t be found, it returns a
user-friendly message. No white screens. No stack traces.
Each prompt
is tested independently. You could run the PHP files in CLI, or test the JS
modules one at a time.
Want to add a
new feature? Add a new prompt. That’s it. The system is designed to be
extended, not rewritten.
Anyone
looking at the prompt knows what the file does, what it expects, and what it
returns. That’s living documentation.
Because each
part was built in isolation and explained fully, there’s no “magic.” You could
walk into any file and explain what it does to someone else. That’s power.
You now have
the power to:
·
Design new projects with complete clarity
·
Delegate code files by assigning prompts
·
Train a team to use this method with zero onboarding time
·
Rebuild anything that breaks without guessing
·
Create tools that are future-proof and scale-friendly
What could
you build next?
·
A to-do app?
·
A scheduling assistant?
·
A newsletter sender?
·
A form-builder with drag-and-drop?
·
A secure notes manager?
You can build
any of them in 10–15 prompts using the same exact principles.
And each
time, you’ll understand every part. Your system will always stay under control.
Your codebase will never get out of hand again.
We’re living
in a time where AI can do amazing things—but the human mind is still the
designer.
You didn’t
let AI write messy code. You used it precisely—with
structured prompts that delivered useful, safe, tested results.
That’s the
future. The developer becomes the prompt architect. You design
the blueprint. The AI helps build it.
But you still
understand it. You still shape it. You still own the result.
That’s how
this process becomes sustainable, scalable, and revolutionary.
This was a
system. A blueprint. A working prototype of something bigger.
You can now
build entire
frameworks this way.
You can build teaching curriculums using prompt-based architecture.
You can write your own libraries, plugins, dashboards, analytics tools—and keep
them clean
and effortless.
This book was
a working demo of a system that works better than traditional tutorials, works
faster than most dev teams, and scales more beautifully than frameworks ever
will.
Now it’s
yours.
You’ve seen
the process. You’ve lived it.
You know
what’s possible when you:
·
Write clean prompts
·
Generate single-file features
·
Enforce UTF-8
·
Avoid complexity
·
Embrace modularity
And now, you
don’t just have a working blog CMS.
You have a
working method.
So here’s the
final miracle:
You can use
this same method to build absolutely anything next.
And that is
the future of code projects.
The 10 Most
Important Principles That Make AI-Assisted Code Projects Successful—Every Time
Every code
file is generated from its own standalone prompt, which keeps things clean,
modular, and easy to track. You never have to merge or untangle code across
files, which eliminates the typical complexity of collaborative or iterative
development. This method also ensures each file can be rebuilt at any
time—instantly and without dependencies. It gives you complete control,
clarity, and consistency across your project.
We break down
features into clearly defined units, each with its own responsibility and
scope. This keeps code clean, avoids bloated logic, and makes debugging simple
because you always know where something lives. When a new feature is needed, it
gets its own file—not a patch into a messy pile. Modular thinking sets the tone
for a maintainable, scalable system.
With the
right prompts saved, you can regenerate any part of your system instantly. No
need to dig through Git commits or rewrite broken logic from scratch. The
prompt becomes your version control, documentation, and blueprint—all in one.
This makes updates, bug fixes, and redesigns feel effortless instead of
chaotic.
Strict UTF-8
enforcement ensures your system works across languages, emojis, browsers, and
operating systems. It prevents invisible bugs from showing up months later,
when content suddenly breaks or characters display incorrectly. Every prompt
includes proper encoding at the top, and output files are saved with a UTF-8
BOM where needed. It’s a small discipline that protects the long-term stability
of your entire project.
No two
prompts touch the same file. Every file is generated once, by a single, focused
prompt. This completely eliminates overwrite risk, merge conflicts, and
mysterious bugs caused by shared logic being updated in multiple places. It’s
one of the cleanest and most error-proof coding strategies available.
AI isn’t
blindly writing your app—it’s executing a very specific task based on clear
human intent. You design the system, define the responsibilities, and instruct
the AI with structure. This ensures the code is reliable, explainable, and
consistent with your project vision. It makes AI your assistant, not your
replacement.
Whenever the
project allows, we store data in simple text files instead of databases. This
removes setup friction, increases portability, and lets you easily view, back
up, and share your content. It’s ideal for small to mid-sized apps and is
incredibly compatible with static hosting or serverless backends. It keeps
things human-readable, transparent, and easy to maintain.
Every prompt
describes exactly what a file does, how it works, and what it expects. This
removes the need for separate documentation because your prompts are already
precise blueprints. Anyone on your team—or even your future self—can instantly
understand what each file is for. Prompts become your onboarding, your API
guide, and your changelog.
When
something breaks, you only need to look at the file and prompt for that one
feature. There’s no hunting through multiple locations or tracing shared
functions across files. This makes fixing bugs faster and safer—without
introducing regressions elsewhere. Isolated features give you confidence to
iterate rapidly.
This isn’t
just a project—it’s a method. You can now replicate this
process across any new app, using the same modular prompts, rebuildable files,
and strict structure. It eliminates overwhelm, keeps things focused, and
creates an environment where progress feels inevitable. When you follow this
process, success becomes a matter of execution—not luck.
With these
ten principles, you’re no longer just coding—you’re engineering
systems with precision, clarity, and power.
This is the future of software creation. And now, you know how to lead it.
The
10 Miracles Behind This New Coding Strategy That Make Everything Work Perfectly
The first
miracle is clarity. Every prompt you write generates a single, complete,
standalone file. This eliminates confusion, avoids broken dependencies, and
ensures you always know what each part of the system does. It’s like having a
perfectly labeled tool for every job—ready to go, and replaceable at any time.
The second
miracle is separation. No two prompts write to the same file. That means no
merge conflicts, no overwrites, and no tangled dependencies. This clean
separation turns your project into a puzzle where every piece fits perfectly,
without ever fighting the others.
The third
miracle is transparency. Each prompt describes exactly what it does, how it
does it, and what it requires. No more guessing what a file is for or needing
separate documentation. The prompt is the blueprint—and anyone can follow it.
The fourth
miracle is extendability. Because each feature lives in its own file, you can
add new features at any time without breaking anything. You simply write a new
prompt, generate a new file, and plug it in. This gives you infinite room to
grow without technical debt.
The fifth
miracle is integrity. Every file, request, and output is encoded properly from
day one using strict UTF-8 enforcement. You avoid corruption, weird character
bugs, and silent data issues across platforms, languages, and browsers. Your
system speaks every language—cleanly and consistently.
The sixth
miracle is indestructibility. If a file gets lost, corrupted, or misconfigured,
you don’t panic—you just re-run the prompt. No need to dig through backups or
version control. The prompt becomes a recovery system that never fails.
The seventh
miracle is simplicity. By avoiding databases where possible, your system uses
plain text and folders to store data. It’s easy to move, easy to read, easy to
back up, and easy to understand. Developers of all levels can interact with the
project—because it stays human at every level.
The eighth
miracle is confidence. Each prompt builds a piece that works independently.
That means you can test, debug, or improve a single feature without touching
the others. No more fearing that one tweak will break your entire app.
The ninth
miracle is automation. The system isn’t built by pasting code randomly—it’s generated, piece by
piece, in a repeatable way. You never write the same thing twice. You write the
description, and the AI
delivers the implementation—perfectly scoped and ready to go.
The tenth and
final miracle is reproducibility. This isn’t a one-off trick—it’s a replicable
method you can use for every future project. You’ll never be overwhelmed again.
You’ll simply list your features, write your prompts, and build your systems
one miracle at a time.
These ten
miracles aren’t hype—they’re the real foundations that made your CMS work, and
they’ll do it again and again.
This is your new development superpower. Use it to build better, faster, and
with total clarity—for everything you make from here on out.
Comments for ... 'Book-9.2-How-To-Build-Your-Own-Miracle-CMS-Content-Editor--Better' Page