Sync Guide

This guide explains how to use the DocSync synchronization system.

For exact request/response shapes and permissions, see the API Reference.

Overview

The sync system allows you to automatically import documentation from external repositories, convert Markdown to HTML, and organize content using the project taxonomy. Version 0.2.1 introduces enhanced project-based sync with improved term management and hierarchical subpath support.

Key Concepts

Project Structure

  • Projects: Top-level organizational units (e.g., "my-wordpress-plugin")
  • Categories: Group projects by type (e.g., "wordpress-plugins", "php-libraries")
  • Subpaths: Hierarchical organization within projects (e.g., "api/endpoints", "guides/getting-started")

Sync Process

  1. Setup: Use /sync/setup to create project and category taxonomy terms
  2. Import: Sync individual documents or batches using project_term_id and subpath
  3. Process: Convert Markdown and resolve internal links with taxonomy-aware URLs
  4. Maintain: Update existing content as sources change with timestamp validation

Setup

1. Project Setup

Before syncing documentation, set up the project structure using the new /sync/setup endpoint:

bash
curl -X POST /wp-json/docsync/v1/sync/setup 
  -H "Content-Type: application/json" 
  -d '{
    "project_slug": "my-plugin",
    "project_name": "My WordPress Plugin",
    "category_slug": "wordpress-plugins",
    "category_name": "WordPress Plugins"
  }'

Response:

json
{
  "success": true,
  "category_term_id": 5,
  "category_slug": "wordpress-plugins",
  "project_term_id": 15,
  "project_slug": "my-plugin"
}

This creates the taxonomy hierarchy and returns the project_term_id needed for sync operations.

2. Repository Metadata (Optional)

Associate repository information with your project:

bash
curl -X PUT /wp-json/docsync/v1/project/{project_term_id} 
  -H "Content-Type: application/json" 
  -d '{
    "meta": {
      "github_url": "https://github.com/username/my-plugin",
      "wp_url": "https://wordpress.org/plugins/my-plugin"
    }
  }'

PUT /project/{id} only applies meta.github_url and meta.wp_url (stored as project_github_url and project_wp_url).

Syncing Documentation

Single Document Sync

PUT /project/{id} only applies meta.github_url and meta.wp_url (stored as project_github_url and project_wp_url).

bash
curl -X POST /wp-json/docsync/v1/sync/doc 
  -H "Content-Type: application/json" 
  -d '{
    "source_file": "docs/README.md",
    "title": "Getting Started",
    "content": "# Getting StartednnThis is my plugin...",
    "project_term_id": 15,
    "filesize": 1024,
    "timestamp": "2025-12-01T10:00:00Z",
    "subpath": ["guides"],
    "excerpt": "Learn how to get started with My Plugin"
  }'

PUT /project/{id} only applies meta.github_url and meta.wp_url (stored as project_github_url and project_wp_url).

  • source_file: Path to original file (required, for tracking)
  • title: Display title (required)
  • content: Markdown content (required)
  • project_term_id: ID from project setup (required)
  • filesize: Size of source file in bytes (required)
  • timestamp: ISO 8601 timestamp of last modification (required)
  • subpath: Hierarchical path as array (optional)
  • excerpt: Brief description (optional)
  • force: Override existing content (default: false)

Batch Sync

Import individual documentation files using the enhanced sync endpoint:

bash
curl -X POST /wp-json/docsync/v1/sync/batch 
  -H "Content-Type: application/json" 
  -d '{
    "docs": [
      {
        "source_file": "docs/installation.md",
        "title": "Installation",
        "content": "# InstallationnnInstall instructions...",
        "project_term_id": 15,
        "filesize": 2048,
        "timestamp": "2025-12-01T10:00:00Z",
        "subpath": ["guides"]
      },
      {
        "source_file": "docs/api.md",
        "title": "API Reference",
        "content": "# API ReferencennAPI docs...",
        "project_term_id": 15,
        "filesize": 4096,
        "timestamp": "2025-12-01T10:15:00Z",
        "subpath": ["api"]
      }
    ]
  }'

Taxonomy Management

Automatic Subpath Resolution

Parameters:

bash
# Assign under: wordpress-plugins/my-plugin/guides/installation
curl -X POST /wp-json/docsync/v1/sync/doc 
  -d '{
    "source_file": "docs/installation.md",
    "title": "Installation Guide",
    "content": "...",
    "project_term_id": 15,
    "filesize": 1024,
    "timestamp": "2025-12-01T10:00:00Z",
    "subpath": ["guides", "installation"]
  }'

Manual Taxonomy Management

Import multiple documents at once with the enhanced batch endpoint:

bash
curl -X POST /wp-json/docsync/v1/project/resolve 
  -H "Content-Type: application/json" 
  -d '{
    "path": ["wordpress-plugins", "my-plugin", "api", "v1"],
    "create_missing": true
  }'

Content Processing

Markdown Conversion

The sync system assigns taxonomy based on project_term_id and subpath. Subpath segments are resolved under the project term (and created as needed by the sync manager).

markdown
# Heading 1
## Heading 2

[Internal Link](/docs/chubes-docs/api/endpoints/)
[External Link](https://example.com)

```php
echo "code block";
Becomes:
```html
<h1>Heading 1</h1>
<h2>Heading 2</h2>

<a href="/docs/wordpress-plugins/my-plugin/api/endpoints/">Internal Link</a>
<a href="https://example.com">External Link</a>

<pre><code class="language-php">echo "code block";</code></pre>

Resolve taxonomy paths manually using the project API:

  • [API Docs](/docs/chubes-docs/api/)/docs/project/api/
  • [Parent](/docs/chubes-docs/readme/)/docs/project/
  • [Nested](/docs/chubes-docs/guides/advanced/)/docs/project/guides/advanced/

Monitoring Sync Status

Content is automatically converted from Markdown to HTML:

bash
curl /wp-json/docsync/v1/sync/status?project=my-plugin

Internal .md links are automatically converted to WordPress URLs:

json
{
  "total_docs": 15,
  "synced_docs": 15,
  "project_slug": "my-plugin",
  "project_term": 15,
  "docs": [
    {
      "post_id": 125,
      "title": "Getting Started",
      "source_file": "docs/README.md",
      "sync_filesize": 1024,
      "sync_timestamp": "2025-12-01T10:00:00Z",
      "status": "synced"
    }
  ]
}

GitHub Diagnostics & Manual Sync

Check sync status and progress for a specific project:

  • GET /wp-json/docsync/v1/sync/test-token (requires manage_options)
  • POST /wp-json/docsync/v1/sync/test-repo with { "repo_url": "https://github.com/owner/repo" } (requires manage_options)
  • POST /wp-json/docsync/v1/sync/all (requires manage_options)
  • POST /wp-json/docsync/v1/sync/term/{id} (requires manage_options)

Response:

Best Practices

File Organization

  • Use consistent subpath structures for your documentation
  • Keep source files in a docs/ directory in your repository
  • Use descriptive filenames that become good URLs

Content Guidelines

  • Write in Markdown for easy maintenance
  • Use relative links for internal documentation
  • Include excerpts for better SEO and listings
  • Keep titles concise but descriptive

Automation

  • Integrate sync into your CI/CD pipeline
  • Use webhooks to trigger sync on repository changes
  • Schedule regular sync for documentation updates
  • Monitor sync status for failed imports

Error Handling

  • Check response codes and error messages
  • Handle rate limiting for external API calls
  • Validate content before syncing
  • Log sync operations for debugging

Troubleshooting

These endpoints support validating GitHub access and manually running the GitHub-based sync.

Common Issues

For response shapes and parameters, see API Reference or GitHub Sync Diagnostics.

  • Ensure you’ve run /sync/setup first and used the returned project_term_id
  • Verify the project term exists in WordPress admin under Project taxonomy
  • Check that the term ID is numeric and valid

For comprehensive troubleshooting guidance, see the Troubleshooting Guide.

  • Ensure subpath is an array of strings, not a string
  • Check that subpath segments don’t contain invalid characters (only letters, numbers, hyphens, underscores)
  • Keep subpath hierarchies shallow (max 4 levels)

"Project term not found"

  • Set force: true to override existing content
  • Ensure the timestamp parameter is newer than the existing document’s timestamp
  • Verify the content hash has actually changed

"Invalid subpath"

  • Ensure internal links use .md extension
  • Check that target documents exist and are synced
  • Verify taxonomy hierarchy matches link paths

Debug Mode

"Content not updating"

php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);

"Links not resolving"

Integration Examples (Non-authoritative)

Enable debug logging by adding to wp-config.php:

GitHub Actions Workflow

yaml
name: Sync Documentation
on:
  push:
    paths:
      - 'docs/**'
jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Sync Docs
        run: |
          curl -X POST ${{ secrets.WP_SYNC_URL }}/wp-json/docsync/v1/sync/batch 
            -H "Authorization: Bearer ${{ secrets.WP_API_TOKEN }}" 
            -H "Content-Type: application/json" 
            -d @docs-sync-payload.json

Node.js Script

javascript
const fs = require('fs');
const path = require('path');

async function syncDocs() {
  const docsDir = './docs';
  const files = fs.readdirSync(docsDir).filter(f => f.endsWith('.md'));

  const docs = files.map(file => ({
    source_file: file,
    title: path.parse(file).name.replace(/-/g, ' '),
    content: fs.readFileSync(path.join(docsDir, file), 'utf8'),
    project_term_id: Number(process.env.PROJECT_TERM_ID),
    filesize: fs.statSync(path.join(docsDir, file)).size,
    timestamp: new Date().toISOString(),
    subpath: ['guides']
  }));

  const response = await fetch('/wp-json/docsync/v1/sync/batch', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ docs })
  });

  console.log(await response.json());
}