Blog with Wordpress
by @hugogu
Publish articles to WordPress blogs via REST API. Handles post creation, category/tag management, and SEO-friendly English slug generation. Use when user ask...
clawhub install wordpress-bloggerπ About This Skill
name: wordpress-blogger description: > Publish articles to WordPress blogs via REST API. Handles post creation, category/tag management, and SEO-friendly English slug generation. Use when user asks to publish blog posts, create WordPress articles, or post content to their blog. TRIGGER this skill whenever user mentions publishing to blog, WordPress posting, or creating articles on their WordPress site. license: MIT allowed-tools: Bash
WordPress Blog Publisher
Publish articles to WordPress blogs safely with automatic category/tag management and English URL slugs.
Prerequisites
WordPress credentials must be configured in the workspace .env file:
# WordPress Blog Credentials
WP_BLOG_URL="https://blog.example.com" # Blog base URL (no trailing slash)
WP_USERNAME="your_username" # WordPress admin username
WP_APP_PASSWORD="xxxx xxxx xxxx xxxx xxxx" # Application password
How to create an Application Password: 1. Log in to WordPress admin dashboard 2. Go to Users β Profile 3. Scroll to "Application Passwords" section 4. Click "Add New Application Password" 5. Copy the generated password
Step 1 β Read Credentials
Read credentials from workspace .env:
# Load credentials from .env file
source /root/.openclaw/workspace/.envWP_URL="${WP_BLOG_URL:-https://blog.example.com}"
WP_USER="${WP_USERNAME:-admin}"
WP_PASS="${WP_APP_PASSWORD}"
Verify credentials exist
if [ -z "$WP_PASS" ]; then
echo "β Error: WP_APP_PASSWORD not found in .env file"
exit 1
fi
Step 2 β Analyze Content & Generate Metadata
Before publishing, analyze the article content to generate appropriate metadata:
Generate English Slug
Create a URL-friendly English slug from the article title or content:
Examples:
ryzen-7950x-vs-i9-13900k-benchmark-comparisonoptimize-database-performance-productionunderstanding-container-orchestration-kubernetesSuggest Categories & Tags
Based on article content, suggest appropriate WordPress categories and tags:
| Content Type | Suggested Categories | Suggested Tags | |-------------|---------------------|----------------| | Hardware reviews | Hardware, Reviews | CPU, benchmark, performance, AMD, Intel | | Software development | Development, Programming | coding, best-practices, architecture | | AI/LLM related | AI, Technology | machine-learning, LLM, artificial-intelligence | | Career development | Career | career-growth, soft-skills, productivity | | DevOps/Infrastructure | DevOps, Infrastructure | docker, kubernetes, ci-cd, cloud |
If user doesn't specify, use these reasonable defaults:
Step 3 β Create Category (if needed)
Check if category exists, create if not:
CATEGORY_NAME="Hardware" # Use suggested or user-specified categoryTry to find existing category
CAT_ID=$(curl -s "${WP_URL}/wp-json/wp/v2/categories?search=${CATEGORY_NAME}&per_page=1" \
-u "${WP_USER}:${WP_PASS}" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)Create if not exists
if [ -z "$CAT_ID" ]; then
CAT_RESULT=$(curl -s -X POST "${WP_URL}/wp-json/wp/v2/categories" \
-u "${WP_USER}:${WP_PASS}" \
-H "Content-Type: application/json" \
-d "{\"name\": \"${CATEGORY_NAME}\"}")
CAT_ID=$(echo "$CAT_RESULT" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
fiecho "Category ID: $CAT_ID"
Step 4 β Create Tags (if needed)
For each tag, check existence and create if needed:
TAGS=("CPU" "Benchmark" "AMD" "Performance") # Use suggested or user-specified tags
TAG_IDS=""for TAG in "${TAGS[@]}"; do
# Try to find existing tag
TID=$(curl -s "${WP_URL}/wp-json/wp/v2/tags?search=${TAG}&per_page=1" \
-u "${WP_USER}:${WP_PASS}" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
# Create if not exists
if [ -z "$TID" ]; then
TAG_RESULT=$(curl -s -X POST "${WP_URL}/wp-json/wp/v2/tags" \
-u "${WP_USER}:${WP_PASS}" \
-H "Content-Type: application/json" \
-d "{\"name\": \"${TAG}\"}")
TID=$(echo "$TAG_RESULT" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
fi
TAG_IDS="${TAG_IDS},${TID}"
done
Remove leading comma
TAG_IDS=$(echo "$TAG_IDS" | sed 's/^,//')
echo "Tag IDs: $TAG_IDS"
Step 5 β Create or Update Post
Create New Post
TITLE="AMD Ryzen 9 7950X vs Intel Core i9-13900K: A Detailed Benchmark Comparison"
CONTENT="In this comprehensive benchmark analysis...
" # Convert markdown to HTML
SLUG="ryzen-7950x-vs-i9-13900k-benchmark-comparison"
EXCERPT="We compare two flagship processors across gaming, productivity, and power efficiency."Create post
POST_RESULT=$(curl -s -X POST "${WP_URL}/wp-json/wp/v2/posts" \
-u "${WP_USER}:${WP_PASS}" \
-H "Content-Type: application/json" \
-d "{
\"title\": \"${TITLE}\",
\"content\": \"${CONTENT}\",
\"slug\": \"${SLUG}\",
\"status\": \"publish\",
\"categories\": [${CAT_ID}],
\"tags\": [${TAG_IDS}],
\"excerpt\": \"${EXCERPT}\"
}")POST_ID=$(echo "$POST_RESULT" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
echo "Created post ID: $POST_ID"
Update Existing Post
If updating an existing post (e.g., adding categories/tags to a draft):
POST_ID="123" # Existing post IDUPDATE_RESULT=$(curl -s -X POST "${WP_URL}/wp-json/wp/v2/posts/${POST_ID}" \
-u "${WP_USER}:${WP_PASS}" \
-H "Content-Type: application/json" \
-d "{
\"categories\": [${CAT_ID}],
\"tags\": [${TAG_IDS}],
\"slug\": \"${SLUG}\"
}")
Step 6 β Generate Public URL
Construct the public viewing URL (not the API endpoint):
# WordPress permalink structure: /{slug}/
PUBLIC_URL="${WP_URL}/${SLUG}/"If slug not set, use post ID format
if [ -z "$SLUG" ]; then
PUBLIC_URL="${WP_URL}/?p=${POST_ID}"
fiecho "β
Article published successfully!"
echo ""
echo "π Title: ${TITLE}"
echo "π URL: ${PUBLIC_URL}"
echo "π Category: ${CATEGORY_NAME}"
echo "π·οΈ Tags: ${TAGS[*]}"
Content Conversion
Markdown to HTML
WordPress content field requires HTML. Convert markdown:
| Markdown | HTML |
|----------|------|
| # Title | |
| Title
## Subtitle | |
| Subtitle
### H3 | |
| H3
bold | bold |
| *italic* | italic |
| - list item | |
| 1. item | |
| text | text |
| ` code | code |
| ``code block`` |
code block |Handling Special Characters
Escape double quotes in content when building JSON:
# Escape quotes for JSON
ESCAPED_CONTENT=$(echo "$CONTENT" | sed 's/"/\\"/g')
Complete Workflow Example
#!/bin/bashLoad credentials
source /root/.openclaw/workspace/.env
WP_URL="${WP_BLOG_URL:-https://blog.example.com}"
WP_USER="${WP_USERNAME:-admin}"
WP_PASS="${WP_APP_PASSWORD}"Article content - CPU Benchmark example
TITLE="AMD Ryzen 9 7950X vs Intel Core i9-13900K: A Detailed Benchmark Comparison"
SLUG="ryzen-7950x-vs-i9-13900k-benchmark-comparison"
CATEGORY="Hardware"
TAGS=("CPU" "Benchmark" "AMD" "Intel" "Performance")CONTENT="
The battle for desktop CPU supremacy continues...
Test Methodology
All tests were conducted on identical platforms...
"Step 1: Create/Get Category
CAT_RESULT=$(curl -s -X POST "${WP_URL}/wp-json/wp/v2/categories" \
-u "${WP_USER}:${WP_PASS}" \
-H "Content-Type: application/json" \
-d "{\"name\": \"${CATEGORY}\"}")
CAT_ID=$(echo "$CAT_RESULT" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)Step 2: Create/Get Tags
TAG_IDS=""
for TAG in "${TAGS[@]}"; do
TAG_RESULT=$(curl -s -X POST "${WP_URL}/wp-json/wp/v2/tags" \
-u "${WP_USER}:${WP_PASS}" \
-H "Content-Type: application/json" \
-d "{\"name\": \"${TAG}\"}")
TID=$(echo "$TAG_RESULT" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
TAG_IDS="${TAG_IDS},${TID}"
done
TAG_IDS=$(echo "$TAG_IDS" | sed 's/^,//')Step 3: Create Post
POST_RESULT=$(curl -s -X POST "${WP_URL}/wp-json/wp/v2/posts" \
-u "${WP_USER}:${WP_PASS}" \
-H "Content-Type: application/json" \
-d "{
\"title\": \"${TITLE}\",
\"content\": \"${CONTENT}\",
\"slug\": \"${SLUG}\",
\"status\": \"publish\",
\"categories\": [${CAT_ID}],
\"tags\": [${TAG_IDS}]
}")POST_ID=$(echo "$POST_RESULT" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
PUBLIC_URL="${WP_URL}/${SLUG}/"
echo "β
Published: ${PUBLIC_URL}"
Error Handling
Common Errors
| Error | Cause | Solution |
|-------|-------|----------|
|
401 Unauthorized | Invalid credentials | Check username and app password |
| 403 Forbidden | Insufficient permissions | Use admin account or check user capabilities |
| rest_cannot_create | Missing edit_posts capability | Verify user has publishing permissions |
| term_exists` | Category/tag already exists | Fetch existing ID instead of creating |API Response Check
Always check API responses for errors:
if echo "$RESULT" | grep -q '"code":"'; then
ERROR_CODE=$(echo "$RESULT" | grep -o '"code":"[^"]*"' | head -1)
ERROR_MSG=$(echo "$RESULT" | grep -o '"message":"[^"]*"' | head -1)
echo "β API Error: $ERROR_CODE - $ERROR_MSG"
exit 1
fi
Safety Rules
Response Format
After successful publication, respond with:
β
Article published successfully!π Title: [Article Title]
π URL: [Public Viewing URL]
π Category: [Category Name]
π·οΈ Tags: [Tag List]
βοΈ Configuration
WordPress credentials must be configured in the workspace .env file:
# WordPress Blog Credentials
WP_BLOG_URL="https://blog.example.com" # Blog base URL (no trailing slash)
WP_USERNAME="your_username" # WordPress admin username
WP_APP_PASSWORD="xxxx xxxx xxxx xxxx xxxx" # Application password
How to create an Application Password: 1. Log in to WordPress admin dashboard 2. Go to Users β Profile 3. Scroll to "Application Passwords" section 4. Click "Add New Application Password" 5. Copy the generated password