If you run a content-heavy WordPress blog, you have probably looked for a way to stop copy-pasting articles into the editor one by one. This guide walks through a free, no-plugin, no-subscription Python workflow that lets you:
- Write articles as Markdown files (or generate them with AI)
- Add AI image generation prompts as comments inside each file
- Push all articles to WordPress as drafts automatically
- Schedule them across weeks with a single command
The entire system runs on Python 3 with zero external dependencies — no pip installs, no third-party services.
What This System Does
Two Python scripts handle the entire publishing workflow:
add_image_comments.py scans your Markdown article files and inserts structured comment blocks that contain AI image-generation prompts. These comments tell you exactly what image to generate for each section of each article. The comment blocks are visible to you inside the file but are automatically stripped before content is pushed to WordPress.
wp_publish.py reads every Markdown article file, parses the metadata (title, slug, category, tags, meta description, focus keyword), converts the Markdown body to HTML, and sends each article to WordPress as a draft via the WordPress REST API. After creating drafts, it builds a publication schedule and sets future publish dates — spreading your articles across days and weeks automatically.
Both scripts use WordPress Application Passwords for authentication. No OAuth, no plugin, no API key.
Requirements
On your computer:
- Python 3.6 or later (check with
python3 --version) - No additional packages needed
On your WordPress site:
- WordPress 5.6 or later (REST API with Application Passwords support)
- A user account with “Editor” or “Administrator” role
- Application Passwords enabled (they are on by default in WP 5.6+)
Setup: Folder Structure
Organize your project like this:
your-project/
├── scripts/
│ ├── wp_publish.py
│ └── add_image_comments.py
├── month-1/
│ ├── 001-your-first-article.md
│ ├── 002-your-second-article.md
│ └── ...
├── month-2/
│ └── ...
├── month-3/
│ └── ...
└── 000-content-plan.md (optional — skipped by scripts)
Key rules:
- Scripts must be in a folder called
scripts/inside your project root. - Articles go in
month-1/,month-2/,month-3/, ormonth-4/— the month number determines the “Month” column in the publish schedule. - Any file starting with
000is automatically skipped (use this for your planning docs). - Subfolders inside month directories are allowed — the scripts walk them recursively.
Step 1: Create a WordPress Application Password
- Log in to your WordPress dashboard.
- Go to Users → Your Profile.
- Scroll to the Application Passwords section at the bottom.
- Type a name for the password (e.g. “Python Publisher”) and click Add New Application Password.
- Copy the generated password — you will only see it once. Spaces in the password are fine; paste it exactly as shown.
Step 2: Write Your Articles
Each article is a .md file with a YAML frontmatter block at the top, followed by the article body.
Frontmatter format
---
title: "Your Article Title Here"
slug: your-article-url-slug
category: "Your Category Name"
focus_keyword: "your primary focus keyword"
keywords: "keyword one, keyword two, keyword three, keyword four"
description: "Your meta description, 150-160 characters, includes the focus keyword."
excerpt: "One or two sentence excerpt for RSS and search previews."
---
Field notes:
slug— the URL path for this post (e.g.how-to-meditate→yoursite.com/how-to-meditate/). No slashes, no quotes.category— must match your WordPress category name exactly (the script creates it if it doesn’t exist).focus_keyword— used for Yoast SEO and RankMath meta fields automatically.keywords— comma-separated; these become WordPress post tags.description— sent as the Yoast/RankMath meta description.
Article body format
After the closing ---, write the article body in standard Markdown:
# Your Article Title
Intro paragraph here...
## First Section Heading
Content...
## Second Section Heading
Content...
## Frequently Asked Questions
### Question one as a complete sentence?
Answer to question one.
### Question two as a complete sentence?
Answer to question two.
The script converts Markdown to HTML — it handles headings, bold, italic, links, lists, tables, and code blocks.
See sample-article.md in this folder for a complete working example.
Step 3: Add Image Prompts (Automatic)
Run add_image_comments.py from your project root:
python3 scripts/add_image_comments.py
This script will:
- Find all
.mdfiles in your month directories - Skip any file that already has image comments (safe to re-run)
- Insert a
<!-- IMAGE:feature -->block after the H1 heading - Insert up to 2
<!-- IMAGE:midpost -->blocks after strategically chosen H2 sections
Each comment block contains a ready-to-use AI image generation prompt, along with the image title, alt text, and description pre-filled for you.
Customizing image styles for your niche
Open add_image_comments.py and edit the CATEGORY_STYLES dictionary near the top of the file. Add an entry for each WordPress category your site uses:
CATEGORY_STYLES = {
"Your Category Name": {
"colors": "color one, color two, color three",
"mood": "describe the visual mood — what should images feel like",
"accent": "one strong visual concept for the featured image",
},
# add more categories...
}
If a category is not in this dictionary, the script uses DEFAULT_STYLE — the fallback style defined at the bottom of that dictionary.
Step 4: Generate Your Images
After running add_image_comments.py, open any article file. You will see comment blocks like:
<!-- IMAGE:feature
Title: Your Article Title
Alt: Your Article Title — category guide illustration
Description: Feature image for 'Your Article Title'. Category: Your Category. Page: yoursite.com/slug/
Prompt: Professional blog header image (16:9, 1200×628 px). Concept: '...'. Visual mood: ... Color palette: ... Key visual element: ... No people. No text overlay. No watermarks.
-->
To generate the image:
- Copy the text on the
Prompt:line. - Paste it into your AI image tool (Midjourney, DALL-E, Adobe Firefly, Stable Diffusion, etc.).
- Generate and download the image.
- Upload to WordPress (Media Library).
- When uploading, use the
Alt:line as the image’s alt text and theDescription:line as the media description. - Set it as the featured image for that post (for
IMAGE:featureblocks) or insert it inline at the relevant section (forIMAGE:midpostblocks).
The wp_publish.py script strips all <!-- IMAGE:... --> comment blocks automatically before publishing — they will never appear in the live post.
Step 5: Push Articles to WordPress
Run wp_publish.py from your project root:
python3 scripts/wp_publish.py
The script will prompt you for:
- Site URL — e.g.
https://yoursite.com - Username — your WordPress login username
- Application Password — the password you created in Step 1
What the script does automatically
- Fetches all existing posts from WordPress (published, scheduled, draft) and builds a slug index
- Skips any article whose slug already exists in WordPress — no duplicates
- Detects the farthest already-scheduled post date and continues the new schedule from after it
- Lets you filter by month if you only want to push Month 1 first
- Creates drafts for all new articles
- Builds a publication schedule and shows you a preview before applying it
- Sets future publish dates on each post
- Saves a
publish_schedule.csvandpublish_schedule.mdin thescripts/folder
Scheduling options
When the script asks for schedule settings, you choose:
- Posts per week (1–4): how many articles to publish each week
- Publish hour (24h): what hour of day to publish (in your server’s timezone)
- Start date: when to begin — defaults to the day after the last already-scheduled post
Step 6: Using AI to Write Articles
Use the prompt template in ai-article-prompt.md (in this folder) to generate articles in the correct format using any AI assistant.
Workflow with AI:
- Open
ai-article-prompt.mdand copy the SYSTEM PROMPT section. - Paste it into your AI tool’s system prompt or at the start of a conversation.
- Fill in the ARTICLE REQUEST TEMPLATE with your article’s details.
- Send to the AI — it will return a complete, correctly formatted
.mdfile. - Save the output as
NNN-your-slug.mdin the appropriatemonth-N/folder. - Run
add_image_comments.py(or the article may already have image comments if the AI included them). - Run
wp_publish.pyto push to WordPress.
Smart Resume: Running the Script Multiple Times
The script is designed to be run repeatedly without causing problems:
- Already-published posts are detected by slug and shown as “LIVE” in the schedule output — they are never re-created.
- Already-scheduled posts are included in the schedule output with their existing dates and are not re-scheduled.
- The start date for new scheduling always begins after the farthest existing scheduled date, so new articles slot in seamlessly after current ones.
- Existing drafts (if you pushed previously but didn’t schedule) are picked up and scheduled without being recreated.
This means you can run the script each time you add a new batch of articles and it handles everything correctly.
Troubleshooting
“Connection failed” on first run
- Verify the site URL is correct and includes
https:// - Check that the Application Password is copied correctly (spaces are fine)
- Ensure the WordPress REST API is accessible: visit
https://yoursite.com/wp-json/wp/v2/postsin a browser — you should see JSON output
“No title” warning for a file
- The frontmatter
title:field is empty or missing - Make sure the file starts with
---(the YAML opening delimiter) and that thetitle:key is present
Category or tag not appearing in WordPress
- The script creates categories and tags automatically — check for typos in the
category:andkeywords:fields - Verify the WordPress user account has permission to create terms
Schedule shows wrong timezone
- WordPress stores dates in UTC internally; the publish hour you enter is applied as-is
- To publish at 9 AM in your timezone, enter the UTC equivalent (e.g. if you are UTC+5:30, enter
3for 3 AM UTC = 8:30 AM IST, or4for 4 AM UTC = 9:30 AM IST)
Markdown not rendering correctly in WordPress
- The script converts Markdown to HTML before sending to WordPress
- If you see raw Markdown on the live post, your theme may be double-processing content — check for Markdown plugin conflicts
Files in This Resource Package
| File | Purpose |
|---|---|
wp_publish.py | Main publishing script — parses MD files and pushes to WordPress |
add_image_comments.py | Image prompt script — inserts AI image prompts into MD files |
sample-article.md | A complete example article in the correct format |
ai-article-prompt.md | Prompt template for generating articles with AI assistants |
guide-how-to-use.md | This guide |
Quick Reference
# 1. Add image prompts to all articles
python3 scripts/add_image_comments.py
# 2. Push articles to WordPress (interactive — asks for credentials)
python3 scripts/wp_publish.py
# Both scripts are safe to re-run — already-processed files are skipped automatically
