- At least 1 code block with
- 1 blockquote with key insight
- 3 FAQ items as JSON
- Keywords: 5-10 terms
- No scripts, no inline handlers, no iframes
3. HTML Body Template
Ready-to-paste skeleton with:
- h2 with id attributes
- table.post-table
- pre > code
- blockquote
- ul.checklist
- FAQ note (auto-generated from FAQ field)
7. MANAGING POSTS
=================
Edit a post:
- Click title in dashboard, or
- Click "Edit" button
Duplicate a post:
- Click "Duplicate" — creates copy with "-copy" suffix
- Edit the copy immediately
Toggle published/draft:
- Click "Toggle" — switches status instantly
Delete a post:
- Click "Delete" — confirms before removing
- Deletes blog// folder and all files
- Rebuilds sitemap, RSS, hub, llms-full.txt
Bulk actions:
1. Check multiple post checkboxes
2. Select action from bulk bar
3. Click "Apply"
View live post:
- Click "View" — opens in new tab
- URL: https://jhasanr.top/blog//
Search/Filter/Sort:
- Type in search box → filters by title/description
- Select category → filters by category
- Select status → filters by published/draft
- Select sort → changes order
8. UPLOAD HTML PAGES
====================
URL: https://jhasanr.top/admin/upload.php
Upload any HTML file → creates a subfolder → gives you a live link.
Tab 1: Upload File
- Type folder name (e.g., "landing-page")
- Click/drag HTML file
- Click "Upload & Create"
- File saves to /folder-name/page.html
Tab 2: Paste HTML
- Type folder name
- Paste raw HTML content
- Click "Save & Create Link"
- Content saves to /folder/page.html
Tab 3: Uploaded Pages
- Lists all uploaded pages
- Shows: link, file size, date
- Delete button per file
Security:
- Scripts stripped automatically
- Event handlers (onclick, etc.) blocked
- iframes blocked
Use cases:
- Landing pages
- Portfolio pieces
- Client demos
- Temporary pages
- A/B test variants
Access: https://jhasanr.top/folder-name/page.html
9. FIELD REFERENCE
==================
Title:
- Max 150 characters
- Shows as , H1, OG title
- Keep under 60 chars for Google
Description:
- Max 300 characters
- Ideal: 155-160 for Google snippet
- Shows as meta description, OG description
Slug:
- Auto-generated from title
- Pattern: a-z, 0-9, hyphens only
- Min 3, max 80 characters
- Lock checkbox prevents auto-change
Category:
- Pick from existing or type new
- Default: GA4 & Server-Side
- Shows in blog hub filter
Date:
- Format: YYYY-MM-DD
- Default: today
- Used in sitemap, RSS, JSON-LD
OG Image:
- Default: hero-profile.jpg
- Recommended: 1200×630
- Upload file or paste URL
- Shows in social media previews
TL;DR:
- Plain text, 2-3 sentences
- Shows in summary box with data-llm-summary
- Used by LLMs for citation
Keywords:
- Comma separated
- Used in meta keywords, JSON-LD, llms.txt
- 5-10 terms ideal
Key Takeaways:
- One per line
- 3 bullets ideal
- Shows in takeaways box with data-llm-takeaways
- Used by LLMs for citation
FAQ:
- JSON format: [{"q":"Question","a":"Answer"}]
- Renders as FAQPage schema
- Shows as expandable details/summary
- Used by LLMs for citation
Body HTML:
- Clean HTML only
- Allowed tags: h2, h3, p, ul, ol, li, a, code, pre, blockquote, table, thead, tbody, tr, th, td, details, summary, strong, em
- Scripts stripped on save
- Inline event handlers stripped
- Use id attributes on h2 for TOC links
Read Time:
- Auto-calculated from word count
- Override manually if needed
- Format: "4 min read"
10. OUTPUT & REBUILD
====================
Each post generates:
- blog//index.html — full HTML page
- blog//index.md — Markdown version
The system also rebuilds:
- blog/index.html — hub page (lists all posts)
- blog/rss.xml — RSS 2.0 feed
- sitemap.xml — all URLs with images
- llms.txt — LLM entry point
- llms-full.txt — all posts concatenated as Markdown
- index.html — homepage blog preview section
11. SITE STRUCTURE
==================
public_html/
├── index.html — homepage
├── styles.css — all styles
├── hero-icon.jpg — profile icon
├── hero-profile.jpg — OG image
├── .htaccess — security headers
├── identity.json — LLM identity
├── llms.txt — LLM entry point
├── llms-full.txt — all posts Markdown
├── sitemap.xml — all URLs
├── robots.txt — AI crawler rules
├── pricing/
│ └── index.html — pricing page
├── blog/
│ ├── index.html — blog hub
│ ├── rss.xml — RSS feed
│ ├── ga4-server-side-tracking-ios17/
│ │ ├── index.html — post page
│ │ └── index.md — Markdown version
│ ├── meta-capi-pixel-setup/
│ │ ├── index.html
│ │ └── index.md
│ └── google-ads-enhanced-conversions/
│ ├── index.html
│ └── index.md
├── admin/
│ ├── login.php — login page
│ ├── index.php — dashboard
│ ├── editor.php — post editor
│ ├── upload.php — HTML upload manager
│ ├── save.php — save handler
│ ├── delete.php — delete handler
│ ├── duplicate.php — duplicate handler
│ ├── toggle.php — toggle status
│ ├── bulk.php — bulk actions
│ ├── logout.php — logout handler
│ ├── auth.php — auth helpers
│ ├── config.php — core functions
│ └── readme.txt — this file
├── data/
│ ├── users.json — admin credentials
│ ├── posts.json — all post data
│ └── .htaccess — blocks direct access
└── .well-known/
├── jhasanr.json — LLM identity
└── identity.json — LLM identity
12. SECURITY
============
Login:
- bcrypt password hashing (cost 12)
- 3-step human check (math, sequence, slider)
- Honeypot field (bots fill it, humans don't)
- Time trap (must wait 3 seconds)
- Rate limiting: 5 attempts per 15 minutes
- Session-based auth
CSRF:
- Token generated per session
- Validated on every POST request
- 64-character hex string
HTML Sanitization:
- Allowed tags whitelist only
- Scripts stripped:
- Event handlers stripped: onclick, onerror, etc.
- iframes blocked
- Attributes filtered
File Upload:
- Only .html and .htm accepted
- Filenames sanitized (a-z, 0-9, hyphens)
- Path traversal protection (realpath check)
- Content sanitized before save
Directory Protection:
- data/.htaccess: "Require all denied"
- Blocks direct access to JSON files
Password:
- Stored as bcrypt hash
- Never stored in plain text
- Change in data/users.json
13. TROUBLESHOOTING
===================
Can't login:
- Check credentials: admin / Admin@123!
- Wait 15 minutes if rate limited
- Clear browser cookies
- Check PHP session directory is writable
Post not saving:
- Check PHP version (7.4+ required)
- Check data/ directory is writable
- Check file permissions (644 for files, 755 for dirs)
Upload not working:
- Check upload directory is writable
- Check file size limit (PHP upload_max_filesize)
- Only .html/.htm files accepted
Styles look broken:
- Re-run: python reinline.py
- Or re-upload styles.css
- Hard refresh: Ctrl+F5
Blog post not showing:
- Check "Published" checkbox is checked
- Rebuild: save any post to trigger rebuild
- Check blog/index.html exists
Upload page not found:
- Upload admin/upload.php to cPanel
- Access: /admin/upload.php
AI paste not working:
- Must use modern browser (Chrome/Firefox/Safari)
- Check JavaScript is enabled
- Try pasting clean HTML instead of markdown
14. FILE REFERENCE
==================
admin/login.php — 3-step human check login
admin/index.php — dashboard with stats, search, filter, sort, bulk
admin/editor.php — post editor with AI paste, image prompt, template
admin/upload.php — HTML page upload manager
admin/save.php — save/update post handler
admin/delete.php — delete post handler
admin/duplicate.php — duplicate post handler
admin/toggle.php — toggle published/draft status
admin/bulk.php — bulk action handler
admin/logout.php — destroy session handler
admin/auth.php — authentication helpers (login, logout, csrf)
admin/config.php — core functions (build_post_html, rebuild_indexes, slugify, esc)
admin/readme.txt — this file
data/users.json — admin credentials (bcrypt hash)
data/posts.json — all post data (title, slug, body, etc.)
data/.htaccess — blocks direct HTTP access
blog/rss.xml — RSS 2.0 feed
blog/index.html — blog hub (auto-rebuilt)
sitemap.xml — all URLs (auto-rebuilt)
llms.txt — LLM entry point
llms-full.txt — all posts concatenated Markdown
robots.txt — AI crawler rules
styles.css — all site styles
index.html — homepage
identity.json — LLM identity (jhasanr = Jahid Hasan Ratul)
.well-known/ — LLM identity files