Skip to content

Instantly share code, notes, and snippets.

@sethrubenstein
Last active October 11, 2025 14:07
Show Gist options
  • Select an option

  • Save sethrubenstein/fc71d1b22c1aa5e5b2b4ded4dd356edc to your computer and use it in GitHub Desktop.

Select an option

Save sethrubenstein/fc71d1b22c1aa5e5b2b4ded4dd356edc to your computer and use it in GitHub Desktop.
GitHub Copilot WordPress

AGENTS.md

This file provides guidance to AI agents when working with code in this repository.

PRC Platform Architecture

This is a WordPress VIP platform for Pew Research Center's digital publishing. It's built as a monorepo with:

  • WordPress multisite structure with subdirectory setup
  • Monorepo architecture using npm workspaces
  • Plugin-based modular system - most functionality is in custom plugins prefixed with prc-
  • Block-based content and user interface components using Gutenberg blocks for rich content creation
  • VIP hosting optimized for WordPress VIP infrastructure with edge cache, memcached object cache, and Vary Cache

Development Commands

Environment Setup

npm run bootstrap         # Setup project (run once)

Documentation

npm run docs               # Generate all documentation
npm run docs:blocks        # Generate block library documentation
npm run docs:platform      # Generate platform matrix documentation

Playground

The playground is a local development environment that allows you to develop and test blocks and plugins in a real WordPress environment. The playground is configured to automatically mount the plugins, themes, and private directories in the root of the repository.

npm run playground:start   # Start playground server

Individual Plugin Development

Because this is a monorepo with workspaces, run these commands from the repo root with npm run --w @prc/<plugin-name> <command> Most plugins have their own package.json with these standard commands:

npm run build              # Build production assets
npm run start              # Start development with file watching
npm run format             # Format code
npm run lint:css           # Lint CSS/SCSS files

Development Guidelines

WordPress VIP Optimization

  • Optimize for WordPress VIP infrastructure
  • Consider edge cache, memcached object cache, and Vary Cache
  • Use VIP-approved functions and avoid restricted functions.

Block Development

Core Block Architecture Principles

  • Block-first mindset: Every UI component should be evaluated as a potential block or block pattern
  • Block Context API: Use providesContext/usesContext in block.json for parent-child data flow between nested blocks (e.g., Query blocks providing post data to child blocks)
  • Block Supports API: Leverage native block supports (spacing, colors, typography) over custom implementations for consistency
  • WordPress Interactivity API: Use data-wp-interactive, data-wp-context, data-wp-bind directives for frontend state management
  • Editor-Frontend Parity: Maintain 1:1 visual consistency between editor and frontend.

Block Development Patterns

  • Prefer dynamic blocks (render.php) for data-driven content
  • Use InnerBlocks for composable block structures
  • Implement block variations over duplicate blocks
  • Follow progressive enhancement: static HTML base, JavaScript enhancement via Interactivity API
  • Share rendering logic between edit.js and save.js/render.php

Block Context Patterns

When developing blocks that share data:

// Parent block's block.json
{
  "providesContext": {
    "prc/postId": "postId",
    "prc/datasetId": "selectedDataset"
  }
}

// Child block's block.json
{
  "usesContext": ["prc/postId", "prc/datasetId"]
}

Common PRC context patterns:

  • prc-quiz-builder → provides quiz state to question, answer, and result blocks and block bindings.
  • prc-block-library/dialog → provides id to inner dialog-element and dialog-trigger blocks for interactivity.
  • prc-religious-landscape-study → provides complex data structure via block context to a variety of project specific blocks for data visualization.

Using block context is also a great way to share data between blocks in the editor. As well as hydrating interactivity API state or context on the frontend.

Block Integration Patterns

Cross-Plugin Block Communication

Many PRC plugins provide blocks that work together through:

  1. Block Context: Parent blocks from one plugin providing data to child blocks from another
  2. Interactivity API Context: Frontend state sharing between blocks via data-wp-context and wp_interactivity_state.
  3. Block Hooks: Using WordPress block filters to extend functionality

Example integrations:

  • prc-facets plugin blocks prc-platform/facets-* utilizes form-input-* blocks from prc-block-library for building it's interface.

Block-First Development Checklist

When implementing new features:

  1. ✅ Can this be a block or block pattern?
  2. ✅ Does an existing block meet the need?
  3. ✅ Can a block binding for a core block be created and used instead?
  4. ✅ Does it need Block Context for parent-child communication?
  5. ✅ Should it provide context to potential child blocks?
  6. ✅ Does it need frontend interactivity via Interactivity API?
  7. ✅ Can it leverage existing Block Supports (colors, spacing, typography)? If not, what additional colors and styling attributes are needed?
  8. ✅ Is there a need for custom block variations?
  9. ✅ Is there visual parity between editor and frontend?
  10. ✅ Does it follow progressive enhancement principles?

Code Standards

  • PHP: Follow WordPress VIP coding standards
  • JavaScript/TypeScript: Use functional programming patterns, avoid classes
  • CSS: Use SCSS with BEM methodology where applicable
  • Accessibility: Implement ARIA roles and attributes as priority
  • Performance: Optimize for readability while maintaining efficiency

File Structure

Standard block structure in plugins:

/prc-{plugin-name}/
  /src/
    /{block-name}/
      - block.json         # Metadata, attributes, provides/usesContext
      - index.js          # Block registration
      - edit.js           # Editor component
      - save.js           # Static markup (or null for dynamic)
      - render.php        # Server-side rendering
      - view.js           # Interactivity API frontend
      - style.scss        # Frontend + editor styles
      - editor.scss       # Editor-only styles
  • Plugin-specific functionality goes in respective prc-* plugins
  • Shared utilities in prc-platform-core
  • Custom blocks in prc-block-library
  • Each plugin follows WordPress Plugin Boilerplate structure with main PHP file, loader, includes, assets, and tests. See: plugins/.plugin-bootstrap-template for reference.

Architecture Decisions

Why Block-First?

  • Composability: Blocks can be combined to create complex layouts
  • Reusability: Block patterns and variations reduce code duplication
  • User Empowerment: Editorial teams can build without developer intervention
  • Consistency: Block Supports ensure design system adherence

Context vs Props vs Attributes

  • Block Attributes: User-configurable settings stored in post content
  • Block Context: Parent-to-child data flow without prop drilling
  • Interactivity API Context: Frontend reactive state management
  • PHP Context: Server-side data passed via render_callback

Testing Strategy

All modules should have tests in /tests directory using Playwright. Run tests with environment started:

npm run env:start && npm run test

Common Gotchas for AI Agents

  1. Block Context ≠ Interactivity API Context: Block Context is for editor/PHP data sharing, Interactivity API is for frontend state
  2. Dynamic blocks need render.php: If using server-side rendering, save.js should return null
  3. VIP restrictions: Some WordPress functions are restricted on VIP (e.g., direct file writes)
  4. Multisite considerations: Block registration happens network-wide but content is site-specific
  5. Edge caching: Dynamic blocks should consider cache invalidation strategies

Core PRC Platform Components

All prc-* plugins are developed as an integrated system with frequent cross-plugin integrations:

  • prc-platform-core: Core platform functionality and shared utilities
  • prc-analytics: Analytics and tracking integration
  • prc-art-direction: Art direction and visual design system
  • prc-attachments-inspector: Media attachment management tools
  • prc-block-area-modules: Block area and module system
  • prc-block-library: Custom Gutenberg blocks for content creation
  • prc-chart-builder: Data visualization and chart editing tools
  • prc-charting-library: Chart rendering and visualization Javascript library
  • prc-collections: Content organization and curation
  • prc-copilot: AI-powered content assistance
  • prc-data-table-builder: Data table creation and management
  • prc-datasets: Dataset management and publishing
  • prc-elasticpress: Enhanced search functionality
  • prc-elasticpress-external-content: External content search integration
  • prc-external-channels: External publishing and syndication
  • prc-facets: Content filtering and faceted search
  • prc-google-tag-manager: Google Tag Manager integration
  • prc-help-center: Help and documentation system
  • prc-homepages: Homepage management and customization
  • prc-icon-library: Icon management and library
  • prc-interactive-features: Interactive content features
  • prc-legacy-content: Legacy content migration and management
  • prc-legacy-self-healing-system: Automated legacy content repair and update system
  • prc-newsletter-builder: Newsletter creation and management
  • prc-office-365-sync: Office 365 integration and synchronization
  • prc-page-like-types: Page-like custom post types
  • prc-post-like-types: Post-like custom post types
  • prc-quiz-builder: Interactive quiz system using WordPress Interactivity API
  • prc-quiz-political-typology: Political typology quiz implementation
  • prc-quiz-religious-typology: Religious typology quiz implementation
  • prc-quote-sorter-builder: Quote sorting and organization tool
  • prc-related-posts: Related content recommendations
  • prc-religious-landscape-study: Religious Landscape Study database
  • prc-report-package: Report packaging and distribution
  • prc-schema-academic-identity: Academic identity schema implementation
  • prc-schema-sitemap: Sitemap generation and schema
  • prc-slack: Slack integration and notifications
  • prc-staff-bylines: Staff byline management
  • prc-user-accounts: User account management
  • prc-user-surveys: User survey system
  • prc-wiki: Internal wiki and documentation
  • prc-newrelic.php: New Relic monitoring integration
  • prc-non-public-redirect.php: Non-public content redirection

Important Notes

  • This is a private repository for Pew Research Center's WordPress based digital publishing platform, "PRC Platform".
  • Uses WordPress multisite with subdirectory configuration
  • VIP hosting requires specific optimization patterns. See https://docs.wpvip.com/, for more details.
  • Gutenberg Block-first approach for content creation and function management. All new features should be implemented as blocks where possible.
  • Monorepo structure with npm workspaces for efficient development. Do not use git submodules, prefer Composer or NPM packages if needed.
  • Integrated plugin system - PRC plugins frequently integrate with each other

Additional Rules

@.github/instructions/javascript-development.mdc

{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"meta": {
"title": "PRC Platform Development Environment",
"description": "A WordPress Playground blueprint that mirrors the PRC Platform wp-env development setup",
"author": "pewresearch"
},
"preferredVersions": {
"php": "8.3",
"wp": "latest"
},
"features": {
"networking": true
},
"constants": {
"PRC_PLATFORM_TESTING_MODE": true,
"PRC_PRIMARY_SITE_ID": 1,
"DEFAULT_TECHNICAL_CONTACT": "[email protected]",
"TAXONOMY_TECHNICAL_CONTACT": "[email protected]"
},
"siteOptions": {
"blogname": "PRC Platform Development"
},
"login": true,
"landingPage": "/wp-admin/",
"steps": [
{
"step": "wp-cli",
"command": "wp plugin activate prc-platform-core"
},
{
"step": "wp-cli",
"command": "wp plugin activate prc-block-library"
},
{
"step": "wp-cli",
"command": "wp theme activate prc-design-system"
},
{
"step": "wp-cli",
"command": "wp rewrite flush"
}
]
}
name: Copilot Setup Steps
# Primes the GitHub Copilot coding agent ephemeral environment.
# Keep this lean: install & cache dependencies needed for typical tasks (lint, build, tests).
# Only the single job named exactly `copilot-setup-steps` is executed by Copilot pre-session.
on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
jobs:
copilot-setup-steps:
runs-on: ubuntu-latest
timeout-minutes: 25
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Setup Node from .nvmrc (with npm cache)
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: npm
cache-dependency-path: |
package-lock.json
plugins/**/package-lock.json
themes/**/package-lock.json
- name: Setup PHP 8.2 + Composer
uses: shivammathur/setup-php@v2
with:
php-version: 8.2
tools: composer
coverage: none
- name: Bootstrap project
env:
{{{ENV VARS AND KEYS GO HERE}}}
run: npm run bootstrap
- name: Cache Playwright browsers (optional tests)
if: hashFiles('package-lock.json') != ''
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
playwright-${{ runner.os }}-
- name: (Optional) Generate docs (non-blocking)
run: npm run docs --if-present
continue-on-error: true
- name: Summary
run: |
echo '## Copilot Setup Summary' >> $GITHUB_STEP_SUMMARY
echo "* Node & Composer dependencies installed (Node $(cat .nvmrc))" >> $GITHUB_STEP_SUMMARY
echo '* Caches primed (npm, composer, playwright)' >> $GITHUB_STEP_SUMMARY
echo '* Environment ready for Copilot coding agent' >> $GITHUB_STEP_SUMMARY
# To scale resources later, change runs-on to a larger Ubuntu runner label (e.g., ubuntu-4-core) if configured.
# Add secrets/vars in repository Settings > Environments > copilot.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment