Skip to content

WordPress Integration

The WordPress layer in src/wordpress/ handles article publishing, content conversion, and taxonomy management.

Modules

Client (client.py)

REST API client for WordPress with retry logic (exponential backoff on 429/5xx).

Method Purpose
create_post() Create a new post
update_post() Update an existing post
get_post() Fetch a post by ID
get_posts_by_slug() Find posts matching a slug
upload_media() Upload images/files to the media library
get_taxonomy_terms() Fetch all terms for a taxonomy
create_taxonomy_term() Create a new taxonomy term

Content type endpoints are mapped via CPT_ENDPOINTS (satellite, cornerstone, research_news).

Publisher (publisher.py)

Orchestrates the full publishing sequence:

  1. Upload featured image (if provided)
  2. Convert markdown to Gutenberg blocks
  3. Create or update WordPress post (idempotent via stored wordpress_post_id)
  4. Classify and assign taxonomy terms (LLM-driven)
  5. Set ACF custom fields
  6. Set Polylang language
  7. Link translation counterpart (if applicable)

Gutenberg Converter (gutenberg.py)

Converts article markdown to WordPress Gutenberg block format. Pure Python, no I/O.

Supported blocks: headings, paragraphs, tables, blockquotes, ordered/unordered lists, and custom callout blocks. Also handles citation superscripts and reference anchors.

Taxonomy (taxonomy.py)

Manages WordPress taxonomy terms with a TaxonomyMapper class:

  • Warm cache — fetches taxonomies from WordPress API on startup
  • Resolve terms — looks up term IDs by slug
  • Classify — Claude Haiku selects best terms from the available pool per article
  • Bootstrapbootstrap_taxonomy_terms() creates canonical terms on first deploy (idempotent)
  • Dynamic discovery — new terms from WordPress are detected automatically on cache refresh

Canonical taxonomy structure:

Taxonomy Terms
topic causes, treatments, lifestyle, research, myths, coping, habituation
audience newly-diagnosed, chronic, carers
evidence_level strong, moderate, weak, anecdotal

Polylang (polylang.py)

Sets post language and links translation pairs via the Polylang REST API.

ACF (acf.py)

Builds Advanced Custom Fields payloads via build_acf_payload():

  • Returns WpArticleAcfPayload (articles) or WpResearchAcfPayload (research news)
  • extract_summary() generates summary from title + first two sentences of content
  • Fields: summary, reading time, evidence level, related treatments, review date

Schema (schema.py)

Pydantic models for WordPress REST API payloads: WpPostPayload, WpTaxonomyMapping, WpArticleAcfPayload, WpResearchAcfPayload.