PRC Datasets
Provides Datasets functionality for PRC Platform, a hybrid post type that combines the features of a traditional post type with a taxonomy along with a digital rights management system for managing access to dataset files.
by Seth Rubenstein · github.com/pewresearch/prc-datasets · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/pewresearch/prc-datasets/archive/refs/heads/trunk.zipReadme
PRC Datasets
Canonical docs: docs/plugins/prc-datasets/
Manages the dataset post type and datasets taxonomy as a linked pair (via prc/term-data-store, namespace PRC\TDS), providing a digital-rights-management layer for file downloads, an ATP legal-acceptance gate, download telemetry, and newsletter audience building via Firebase Cloud Functions.
What it does
- Registers the
datasetCPT anddatasetstaxonomy and binds them viaprc/term-data-storeso each taxonomy term has a corresponding post that holds the content and metadata. - Adds
prc-datasetspost type support topost,feature, andchartso those post types can be tagged with dataset terms. - Gated downloads — resolves the download file URL (media library attachment or legacy
dataset_download_urlmeta) only after verifying Firebase identity (X-PRC-User-Id/X-PRC-User-Tokenheaders) and per-IP rate limiting onget-download. Page-baked WordPress nonces are not used (they expire on edge-cached pages). A failed public resolve stamps_download_unavailableso editors can filter those datasets in DataViews. - ATP (American Trends Panel) legal gate — marks individual datasets as ATP-restricted; users must accept the ATP Terms of Service before a download URL is returned.
- Download telemetry — tracks a cumulative total (
_total_downloads), a per-year monthly breakdown (_downloads_{year}), and (from 2026-08-01) day buckets in_downloads_daily_{year}; also logs each download against the Firebase user record. Replacing a dataset file can setnew_data_uploadedso the editor stats panel splits the affected month into before/after counts. - Newsletter audiences — Dataset Options sidebar can Generate / Rebuild / Delete downloader audiences (async job; no draft email).
wp prc datasets build-audiencestarts the same job, waits at the terminal, and can still create a draft transactional email. - Custom rewrite rules for
/datasets/,/datasets/{year}/, and research-team-prefixed URLs like/politics/dataset/{slug}/. - Includes datasets in sitewide search results and ElasticPress-backed archive faceting.
- Injects dataset terms into
prc_platform_post_report_package_materialsso datasets appear in report package sidebars. - Block editor sidebar panel (
Dataset Options) for uploading the download file, toggling the ATP flag, viewing the monthly download heatmap, and managing downloader audiences. - Three Gutenberg blocks and one block bindings source (see below).
- DataViews admin list —
Datasets > All Datasets(prc-datasets-library) registers on the shared@prc/wp-admin-dataviewshell. Rows exposehasZip,downloadUnavailable,totalDownloads, andisAtpcolumns; ZIP-status and download-unavailable filters map to_download_attachment_idand_download_unavailablemeta. Provider assets live inbuild/admin-dataview/.
Key files
| File | Purpose |
|---|---|
includes/class-content-type.php |
CPT/taxonomy registration, prc/term-data-store relationship, meta field registration, rewrite rules, research team URL config, search/EP archive inclusion |
includes/class-dataset-list.php |
DataViews admin list registration, row shaping, and ZIP / download-unavailable filters |
includes/class-rest-api.php |
REST endpoint registration and all download/ATP/logging handlers |
includes/class-ability-categories.php |
Registers the datasets WP Abilities category for MCP discovery |
includes/class-ability.php |
WP Abilities API prc-datasets/get-analytics and prc-datasets/get-download-url tools (MCP + REST) |
includes/class-audience-service.php |
Shared build / list / delete for dataset downloader audiences (CLI + REST) |
includes/class-cli.php |
WP-CLI commands under wp prc datasets |
includes/class-cli-build-audience.php |
wp prc datasets build-audience — thin CLI wrapper around Audience_Service |
includes/class-plugin.php |
Bootstrap: loads classes, registers blocks, wires block bindings source, enqueues inspector panel |
includes/inspector-sidebar-panel/src/index.js |
Editor sidebar plugin — file upload (MediaDropZone), new-data confirm modal, ATP toggle, pre-publish panel, prc-datasets/options-after slot |
includes/inspector-sidebar-panel/src/stats-panel.js |
Download heatmap with year/month selectors, day drill-down, and new-data before/after split |
includes/inspector-sidebar-panel/src/audience-panel.js |
Downloader audience Generate / Rebuild / Delete via AudienceBuildPanel |
build/download-block/ |
prc-platform/dataset-download block — interactive download button |
build/dataset-atp-legal-acceptance-block/ |
prc-platform/dataset-atp-legal-acceptance block — ATP opt-in form |
build/dataset-description-block/ |
prc-platform/dataset-description block — editor-only block that pulls post content via block bindings |
Blocks
| Block name | Description |
|---|---|
prc-platform/dataset-download |
Renders the download button. Uses the Interactivity API for the client-side download flow (Firebase auth headers, ATP gate check, file URL resolution). Dynamic (render.php). |
prc-platform/dataset-atp-legal-acceptance |
Renders the ATP terms acceptance form. Injected automatically by the download block when a dataset is ATP-restricted and the user has not yet accepted. Not directly insertable. |
prc-platform/dataset-description |
Editor-only. Registers a block bindings source (prc-platform/dataset-description) that pulls post_content from the related dataset post into a core/paragraph block on taxonomy archive or single-dataset pages. |
REST API endpoints
All endpoints are registered under prc-api/v3 on rest_api_init.
| Method | Route | Auth | Description |
|---|---|---|---|
POST |
/prc-api/v3/datasets/get-download |
Firebase UID + rate limit | Resolves and returns the download file URL; increments counters and logs the download |
POST |
/prc-api/v3/datasets/check-atp |
Firebase UID in request | Returns whether the user has accepted the ATP agreement |
POST |
/prc-api/v3/datasets/accept-atp |
Firebase UID in request | Records ATP acceptance on the user's Firebase record |
POST |
/prc-api/v3/datasets/log-download |
Firebase UID in request | Separately logs a download (total + monthly + user record) without resolving a URL |
GET |
/prc-api/v3/datasets/download-stats |
edit_posts capability |
Returns { total, log, daily, new_data_uploaded, splits } for a dataset; cached 24 h via transient |
GET |
/prc-api/v3/datasets/audiences |
edit_post on dataset |
Lists system audiences for a dataset (meta snapshots) |
POST |
/prc-api/v3/datasets/build-audience |
edit_post on dataset |
Starts an async downloader audience job (202 job view; persists list when ready; no draft email) |
GET |
/prc-api/v3/datasets/audience-jobs/{job_id} |
edit_post on source dataset |
Poll a ds_ audience job |
DELETE |
/prc-api/v3/datasets/audiences |
edit_post on dataset |
Deletes a dataset audience option + _meta |
The dataset post type also gets a _downloads REST field that exposes the same stats structure on the standard WP REST response.
WP Abilities API
| Ability ID | Input | Description |
|---|---|---|
prc-datasets/get-analytics |
post_id (integer, required) |
Returns { post_id, title, total, log, daily, new_data_uploaded, splits } download analytics for a dataset. Requires edit_post on that dataset. Exposed via REST and MCP. |
prc-datasets/get-download-url |
post_id (integer, required) |
Returns { post_id, title, file_url, attachment_id } without incrementing download counters. Requires Author+ (publish_posts) and edit_post on the dataset. Does not stamp _download_unavailable. |
Authenticated download requests
User-facing endpoints (get-download, check-atp, accept-atp, log-download) require Firebase identity via request headers (not query args or page nonces):
| Header | Description |
|---|---|
X-PRC-User-Id |
Firebase UID of the signed-in user |
X-PRC-User-Token |
Firebase ID token; validated server-side before any user-scoped action |
get-download additionally enforces per-IP rate limiting via PRC\Platform\rate_limit_hit().
Filters and hooks
Filters this plugin exposes
| Hook | Type | Description |
|---|---|---|
prc_platform__datasets_enabled_post_types |
Filter | Extend the list of post types that support the datasets taxonomy. Receives and should return array of post type slugs. Post types that call add_post_type_support( $pt, 'prc-datasets' ) are automatically included without this filter. |