Blog Taxonomy
Manage tags, categories, and topic clusters across CMS platforms.
Commands
Tag Suggestion Workflow
Step 1: Parse Content Structure
Read the target file and extract:
- All H2 and H3 headings (primary topic signals)
- Bold and italic phrases (emphasis signals)
- Existing frontmatter tags/categories if present
Step 2: Frequency Analysis
Scan the body text for high-frequency phrases:
- 1-word terms: minimum 4 occurrences (excluding stop words)
- 2-word phrases: minimum 3 occurrences
- 3-word phrases: minimum 2 occurrences
Exclude common non-tag words: articles, prepositions, conjunctions, pronouns.
Step 3: Semantic Grouping
Group related candidates into clusters:
- Merge singular/plural variants (keep the more common form)
- Merge hyphenated and non-hyphenated forms
- Group synonyms under the highest-frequency term
Step 4: Deduplicate and Rank
- Fuzzy match on slugified names (Levenshtein distance <= 2)
- Do not auto-merge short slugs under 5 characters using Levenshtein alone; require token overlap or manual review
- Score each candidate:
(frequency * 2) + (heading_presence * 5) + (emphasis * 1) - Return top 5-10 ranked suggestions
Output Format
CMS Adapters
Adapter Overview
WordPress Adapter
List tags:
Create tag:
List categories (hierarchical, supports parent field):
Create category:
Assign tags to post:
Pagination: follow X-WP-TotalPages header for full listing.
Shopify Adapter
Tags on Shopify are string arrays on the Article object, not first-class entities.
Update article tags (GraphQL Admin API):
List all tags in use (GraphQL):
Auth header: X-Shopify-Access-Token: {token}
Pagination: loop while pageInfo.hasNextPage is true, passing endCursor as
the next $cursor.
Note: REST API marked legacy Oct 2024. GraphQL required for new apps since Apr 2025.
Ghost Adapter
List tags:
Create tag:
JWT generation: sign with admin API key (id:secret format), iat = now, exp = 5 min,
audience = /admin/.
Strapi Adapter
Endpoint auto-generated from content types. Typical setup:
Pagination: increment pagination[page] until all pages are exhausted.
Strapi v4 responses use the data wrapper with attributes; Strapi v5 uses
a flatter response shape. Detect the version or normalize both shapes before
deduplication. Check your content type schema for field names.
Sanity Adapter
Query tags (GROQ):
Create tag (Mutations API):
Default SANITY_API_VERSION to a current tested API date supplied by the
project environment; do not hard-code it in generated requests.
Taxonomy Audit Workflow
Step 1: Inventory
Scan all posts in the target directory (or fetch from CMS). Build a map:
- tag_name -> [list of post files/IDs using this tag]
- category_name -> [list of post files/IDs]
Step 2: Health Checks
Step 3: Recommendations
Group findings by priority:
- Critical: orphan tags creating empty archive pages (crawl waste)
- High: thin tags with < 5 posts after traffic, intent, and link checks
- Medium: tag bloat above the scaled threshold (diluted taxonomy, harder to navigate)
- Low: naming inconsistencies (mixed case, hyphen vs space)
Output Format
Site-Wide Guidelines
- Aim for 5-10 main categories per site (broad topics)
- Tags should have at least 5 posts before creating an archive page
- Use consistent slug format: lowercase, hyphen-separated
- Every post needs exactly 1 primary category
- Tags per post: 3-8 recommended, never exceed 15
Environment Variables
These must be set in the shell environment. Never store credentials in files or
commit them to version control. The skill reads them via $CMS_TYPE, $CMS_URL,
$CMS_USERNAME, $CMS_API_KEY, and optional platform-specific variables at runtime.
Security rule for CMS calls: require HTTPS, allow only http and https
parsing paths but send authenticated requests over HTTPS only, resolve DNS and
block loopback/private/link-local/reserved IPs, validate redirects with the same
checks or disable redirects, cap timeouts at 10 seconds, and enforce
CMS_ALLOWED_HOSTS when set.
Error Handling
- Missing environment variables: If CMS_TYPE, CMS_URL, or CMS_API_KEY is unset, or if WordPress lacks CMS_USERNAME, report which variable is missing and provide the expected format
- Invalid credentials: If the CMS API returns 401/403, report "Authentication failed - check CMS_USERNAME/CMS_API_KEY" and do not retry
- Connection timeouts: If the CMS endpoint is unreachable after 10 seconds, report the timeout and suggest checking CMS_URL
- Duplicate tag slugs: If a tag already exists on the CMS, skip creation and note "Tag already exists: [name]"
- Rate limits: If the CMS API returns 429, honor
Retry-Afterwhen present; otherwise use exponential backoff and retry once. Report if the limit persists - Unsupported CMS: If CMS_TYPE is not one of the 5 supported platforms, list the valid options and exit

