Add Activity Library — activity_kit post type, archive, single pages, stats dashboard#3496
Add Activity Library — activity_kit post type, archive, single pages, stats dashboard#3496Piyopiyo-Kitsune wants to merge 22 commits into
Conversation
Introduces a new Activity Library section with downloadable WordPress
activity kits (facilitator guides, slide decks, ZIP downloads) for
educators and meetup organizers.
**Plugin changes (wporg-learn)**
- Register `activity_kit` CPT with archive slug `activity-library`
- Register `activity_language` taxonomy; add `activity_kit` to `topic` and `level`
- Register 6 post meta fields: duration, guide/slides PDF IDs, zip URL, view/download counts
- Add admin list table columns (Views, Downloads, sortable) and Stats submenu page
- REST API: `POST activity-kits/v1/track` (rate-limited), `GET activity-kits/v1/stats`
- Events table for time-range tracking via `dbDelta()`
- WP-CLI `wp activity-kit import` creates 11 initial activity kit posts
- `wporg/activity-kit-card` dynamic block (server-side render with featured image, title, level/duration meta, View + Download buttons)
- `wporg/activity-kits` query block variation
- Editor sidebar panel for PDF pickers, duration, ZIP URL, read-only stats
- Fix: add `function_exists('Sensei')` guard in `restrict_my_courses_page_access()`
- Fix: skip nonce check in `tax_save_term_fields()` when running via WP-CLI
- Fix: wrap `0-sandbox.php` mu-plugin requires in `file_exists()` guards
**Theme changes (wporg-learn-2024)**
- `archive-activity_kit.html` FSE template with pattern reference
- `single-activity_kit.html` FSE template with pattern reference
- `archive-activity-kits-content.php` pattern: heading, search bar, `wporg/query-filter` blocks, card grid with no-results message and pagination
- `single-activity-kit-content.php` pattern: breadcrumb, title, metadata, PDF tab toggle with `<iframe>` previews, content, download button with tracking POST
- Filter options hooks (`activity_kit_topic`, `activity_kit_level`, `activity_kit_language`) in `block-config.php`
- `pre_get_posts` handler in `query.php` for activity kit archive filtering
- Fix: add `function_exists` guard in `sensei-lesson-actions.php` pattern
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Auto-fixed by eslint --fix to bring existing files in line with the project's prettier config (trailing commas, line breaks in argument lists). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…search alignment
Iterative improvements on top of the initial activity-library commit:
Plugin (wporg-learn):
- Add per-kit `_activity_feedback_url` meta and global `activity_kit_feedback_url`
site option with a Settings API page under Activity Kits → Settings
- Feedback strip on single kit pages links to a configurable form URL with
automatic `?kit={slug}` attribution parameter
- PDF tab improvements: hide Chromium native toolbar via `#toolbar=0`,
use `#view=FitH` for Safari/Firefox with a tracked "Download PDF" link
shown only for non-Chromium browsers (via `window.chrome` detection)
- View tracking fires unconditionally on page load (not inside ZIP guard);
download rate-limiting applies to ZIP downloads only (not views)
- Stats dashboard: blueberry design-system colours (#3858e9 / #9fb1ff),
custom date-range picker with Apply + Clear buttons, script version via
filemtime for proper cache-busting
- Activity kit card block: correct image sizing, excerpt display, clock-icon
duration row, View + Download buttons
Theme (wporg-learn-2024):
- Archive page: Topic / Level / Language filter dropdowns; 12 posts per page;
language fallback when WordPressdotorg\Locales is unavailable locally
- Single kit pattern: breadcrumb, meta row, PDF tab toggle, feedback strip,
"What's included" grid, "Download this kit" box with file-size note
- Search results: `render_block_core/template-part` filter swaps the generic
card template with the full activity kit card for `activity_kit` posts,
keeping View + Download buttons and duration/level meta consistent with
the archive grid
- SCSS: `.wporg-activity-kit-*` component styles, `.wporg-activity-kit-
feedback-strip` with blueberry outlined button and visible focus ring
- All PHP auto-fixed via phpcbf (WordPress-Extra ruleset); JS curly-brace
lint errors resolved
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces an “Activity Library” feature to Learn WordPress by adding an activity_kit custom post type in the wporg-learn plugin (including REST tracking, admin stats/settings, editor tooling, and WP‑CLI seeding) and adding theme templates/patterns/styles in wporg-learn-2024 to render an archive + single-kit experience with filtering and consistent cards.
Changes:
- Plugin: Adds
activity_kitCPT, related meta/capabilities, REST endpoints for view/download tracking + stats, admin stats/settings pages, and editor sidebar tooling. - Theme: Adds archive/single templates and patterns for Activity Kits, plus filtering/search alignment and new SCSS for the Activity Kit UI.
- Build/JS: Adds new block variation and multiple JS formatting changes across existing plugin scripts.
Reviewed changes
Copilot reviewed 48 out of 49 changed files in this pull request and generated 19 comments.
Show a summary per file
| File | Description |
|---|---|
| wp-content/themes/pub/wporg-learn-2024/templates/single-activity_kit.html | Adds the single Activity Kit template referencing a dedicated pattern. |
| wp-content/themes/pub/wporg-learn-2024/templates/archive-activity_kit.html | Adds the Activity Kit archive template referencing a dedicated pattern. |
| wp-content/themes/pub/wporg-learn-2024/src/style/style.scss | Imports the new Activity Kit SCSS partial. |
| wp-content/themes/pub/wporg-learn-2024/src/style/_activity-kit.scss | Adds front-end styles for Activity Kit archive cards and single-kit UI. |
| wp-content/themes/pub/wporg-learn-2024/patterns/single-activity-kit-content.php | Implements the single-kit page layout (PDF tabs, feedback strip, download box) and client-side tracking calls. |
| wp-content/themes/pub/wporg-learn-2024/patterns/archive-activity-kits-content.php | Implements the archive layout with search, filters, grid, and pagination. |
| wp-content/themes/pub/wporg-learn-2024/patterns/sensei-lesson-actions.php | Adds a guard to avoid calling Sensei functions when unavailable. |
| wp-content/themes/pub/wporg-learn-2024/inc/query.php | Adds pre_get_posts filtering for Activity Kit archive/search filtering. |
| wp-content/themes/pub/wporg-learn-2024/inc/block-hooks.php | Replaces generic cards with Activity Kit cards on search results for activity_kit. |
| wp-content/themes/pub/wporg-learn-2024/inc/block-config.php | Adds Activity Kit Topic/Level filter options and passes through new query vars. |
| wp-content/plugins/wporg-learn/wporg-learn.php | Loads new Activity Kit include files (REST/settings/stats/import). |
| wp-content/plugins/wporg-learn/webpack.config.js | Adds webpack entries for new Activity Kit-related JS bundles. |
| wp-content/plugins/wporg-learn/views/block-activity-kit-card.php | Adds server-rendered Activity Kit card block markup. |
| wp-content/plugins/wporg-learn/js/workshop-details/src/index.js | Prettier reformatting of block registration strings. |
| wp-content/plugins/wporg-learn/js/workshop-application-form/src/index.js | Prettier reformatting of block registration strings. |
| wp-content/plugins/wporg-learn/js/workshop-application-form/src/edit.js | Prettier reformatting of JSX props. |
| wp-content/plugins/wporg-learn/js/utils.js | Prettier reformatting of function signature. |
| wp-content/plugins/wporg-learn/js/query-activity-kits/src/index.js | Adds a core/query block variation for Activity Kits. |
| wp-content/plugins/wporg-learn/js/locale-notice.js | Refactors object method syntax + formatting changes. |
| wp-content/plugins/wporg-learn/js/lesson-plan-details/src/index.js | Prettier reformatting of block registration strings. |
| wp-content/plugins/wporg-learn/js/lesson-plan-actions/src/index.js | Prettier reformatting of block registration strings. |
| wp-content/plugins/wporg-learn/js/lesson-plan-actions/src/edit.js | Prettier reformatting of JSX props. |
| wp-content/plugins/wporg-learn/js/lesson-featured-meta/index.js | Prettier reformatting of hooks/JSX. |
| wp-content/plugins/wporg-learn/js/language-meta/index.js | Prettier reformatting of hooks. |
| wp-content/plugins/wporg-learn/js/hooks/use-is-block-in-sidebar.js | Prettier reformatting of destructuring. |
| wp-content/plugins/wporg-learn/js/form.js | Prettier reformatting of event listener. |
| wp-content/plugins/wporg-learn/js/expiration-date/index.js | Prettier reformatting of imports and long expressions. |
| wp-content/plugins/wporg-learn/js/duration-meta/index.js | Prettier reformatting of hooks/JSX. |
| wp-content/plugins/wporg-learn/js/course-data/src/index.js | Prettier reformatting of block registration strings. |
| wp-content/plugins/wporg-learn/js/course-data/src/edit.js | Prettier reformatting of JSX props. |
| wp-content/plugins/wporg-learn/js/course-completion-meta/index.js | Prettier reformatting of hooks/JSX. |
| wp-content/plugins/wporg-learn/js/constants.js | Prettier reformatting of i18n strings. |
| wp-content/plugins/wporg-learn/js/activity-kit-stats/index.js | Adds the stats dashboard client-side logic (fetching, chart/table UI, export). |
| wp-content/plugins/wporg-learn/js/activity-kit-sidebar/src/index.js | Adds Gutenberg sidebar panels for Activity Kit meta (PDF/ZIP, duration, feedback URL, level). |
| wp-content/plugins/wporg-learn/js/activity-kit-card/src/index.js | Registers the Activity Kit card dynamic block in the editor. |
| wp-content/plugins/wporg-learn/js/activity-kit-card/block.json | Defines the wporg/activity-kit-card block metadata. |
| wp-content/plugins/wporg-learn/inc/taxonomy.php | Adds activity_kit to shared taxonomies and skips term nonce checks under WP-CLI. |
| wp-content/plugins/wporg-learn/inc/sensei.php | Adds guard for Sensei availability before restricting My Courses. |
| wp-content/plugins/wporg-learn/inc/post-type.php | Registers the activity_kit post type and adds it to Jetpack integrations. |
| wp-content/plugins/wporg-learn/inc/post-meta.php | Registers Activity Kit meta and broadens language meta support; adds locales fallback logic. |
| wp-content/plugins/wporg-learn/inc/capabilities.php | Adds Activity Kit capability mapping to “edit any learn content”. |
| wp-content/plugins/wporg-learn/inc/blocks.php | Registers the Activity Kit card block and editor assets; maps query variation namespace. |
| wp-content/plugins/wporg-learn/inc/admin.php | Adds Activity Kit admin columns, sorting, and a Stats submenu page. |
| wp-content/plugins/wporg-learn/inc/activity-kit-stats-page.php | Adds wp-admin stats page renderer and enqueues Chart.js + stats JS. |
| wp-content/plugins/wporg-learn/inc/activity-kit-settings.php | Adds wp-admin settings page for global Activity Kit feedback URL. |
| wp-content/plugins/wporg-learn/inc/activity-kit-rest.php | Adds REST routes for tracking views/downloads and retrieving stats; creates an events table. |
| wp-content/plugins/wporg-learn/inc/activity-kit-import.php | Adds WP-CLI command to seed initial Activity Kit posts. |
| .wp-env/0-sandbox.php | Adds file_exists() guards for local mu-plugin loading in dev env. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Add `root: true` to plugin .eslintrc.js so CI's generated root config does not override the workspace's own prettier settings - Fix `sort-imports`: reorder `useSelect, useDispatch` → `useDispatch, useSelect` - Fix `id-length`: rename single/two-char parameters `n`, `ds`, `d` to `num`, `dateStr`, `date` in activity-kit-stats helpers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Display the post's last-modified date in the meta row below the kit title, alongside duration, level, and topic. Uses a calendar icon and <time> element with machine-readable datetime attribute. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Point directly to the activity kits section of the Training team handbook rather than the handbook root. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add .prettierrc to plugin dir (printWidth: 80) so CI and local use
the same prettier settings, ending the formatting conflict
- Fix useSelect() dep arrays in sidebar ([] caused stale editor state)
- Fix filter_activity_kit_archive() to merge meta_query instead of
overwriting the one set by add_language_to_archive_queries()
- Sanitize $_GET['level'] before comparing to 'all'
- Add post_status=publish to activity kit filter term lookups
- Add is_main_query() guard to sortable columns pre_get_posts handler
- Remove wp_add_inline_style('wp-admin','') no-op
- Remove data-track-download from PDF tab link (PDF views should not
count as kit downloads); add it to archive card download button
- Replace hard-coded /wp-json/ REST URL with rest_url() in tracking JS
- Add activity_kit post-type validation to card block render callback
- Remove dead .activity-kit-stats-page styles from theme SCSS
(admin page uses its own inline <style>; theme CSS is frontend-only)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The installed @wordpress/editor (v9.26.3) does not export PluginDocumentSettingPanel. It lives in @wordpress/edit-post (v3.25.3), which is the correct package for this project's version of Gutenberg. Fixes the import/named error in CI lint. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aligns with the PR description which states the WP-CLI import command creates 11 draft activity_kit posts. Publishing on import bypassed editorial review; drafts let editors review and publish intentionally. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Expected 5 spaces after 'array' to align with '\WP_Block' parameter. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
I've checked this PR and found no errors. Could you recheck this and merge if everything is working fine? Thank you. |
This isn't viable for WordPress.org, if this kind of stats is needed, a dedicated page-view stats system should be used, not the WordPress Rest API. Pageviews can probably be extracted via Jetpack Stats (Looks like it tracks both page views and downloads, or will, once I connect Jetpack correctly) I think I'm going to strip this out of this PR, and push it into a followup PR, where we can look at alternative options for this. |
|
Note AI-assisted investigation, reviewed before posting. I had an AI agent (Claude) dig into this by querying learn.wordpress.org's live Jetpack Stats connection and reading the Jetpack/WP.com tracker source. I've reviewed the findings below; the empirical claims are against the running site (WP.com blog Can Jetpack Stats replace the removed
|
|
@Piyopiyo-Kitsune @jonathanbossenger Can you take a look at the above-mentioned report and limitation/solution, so we can continue with the merge process if everything looks good? Thank you. |
|
@dd32 I'm reading that if we ensure that updated files have the same name, our download counts will be interrupted-- is that right? If that's the case, I'm ok to try to move forward with this unless a better solution arises. |
|
Picking this up again to work on Dion's workaround suggestion with Claude Code. Will request code review again once ready. |
Per dd32's review: remove custom REST view/download tracking and replace with Jetpack Stats APIs. View tracking was redundant (Jetpack records page views automatically). Download tracking now uses _stq.push() click beacon (c.gif channel), queryable via WPCOM_Stats::get_clicks(). Custom events table and /track endpoint removed entirely. - Remove POST /activity-kits/v1/track endpoint and events table infrastructure - Replace download fetch() in single kit pattern with _stq.push() Jetpack beacon - Remove view-tracking script (Jetpack handles automatically) - Update GET /stats endpoint to query WPCOM_Stats::get_top_posts() for views and WPCOM_Stats::get_clicks() matched by ZIP URL for downloads - Remove custom date range support (relied on events table) - Remove _view_count / _download_count post meta registrations - Remove admin list columns for Views / Downloads - Add graceful fallback notice when Jetpack Stats unavailable Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> # Conflicts: # wp-content/plugins/wporg-learn/js/activity-kit-stats/index.js
- Switch activity-kit-stats enqueue from source file to build output, using activity-kit-stats.asset.php for version/dependencies per the pattern used by all other plugin scripts - Add data-track-download="1" to search-results card download link in block-hooks.php so Jetpack click beacon fires consistently across archive, search, and single-kit pages - Fix JS prettier formatting in activity-kit-sidebar, lesson-plan-details, locale-notice, and workshop-details (object shorthand + printWidth) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- query.php: Extract $_GET['post_type'] into sanitized $requested_post_type (sanitize_key + wp_unslash) and add phpcs:ignore for topic/level reads; use the variable in both early-return and post_type-set checks - activity-kit-stats-page.php: Align legend swatch colors with JS chart dataset colors (#3858e9 views, #9fb1ff downloads were mismatched as #2271b1 / #72aee6) - single-activity-kit-content.php, block-hooks.php, block-activity-kit-card.php: Replace absint($duration) with ctype_digit() check so non-numeric durations (e.g. "60-90 minutes") display as-is instead of being coerced to a single integer Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move \$notice initializer out of the $.extend object literal so the literal contains only shorthand methods. Satisfies both the 'always' (local) and 'consistent' (CI-generated config) variants of the object-shorthand ESLint rule, which reject a mix of shorthand methods and a non-shorthand value property in the same object. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Read per-kit views from Jetpack's summary.postviews (was summary.top-posts, which is never present in the response, so views always rendered as 0) - Walk the Jetpack clicks tree (domain node with nested children) so download counts attribute to kits instead of returning zero for the multi-file case - Map each ZIP URL to an array of kit IDs so kits sharing a ZIP are all credited rather than the last one silently winning - Cap the Jetpack stats REST cache at 1 minute (floored at 1s) via the jetpack_fetch_stats_cache_expiration filter so the dashboard tracks WordPress.com's counts more closely Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…btitle - Rename the "Add New Activity Kit" / "Add New" labels to "Add Activity Kit" - Add author support so the All Activity Kits list shows an Author column - Reword the stats table subtitle to "Click a row to see a single kit's stats" Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…require_once - stats_cache_expiration() is now registered only during the activity kit stats REST request (inside handle_stats()) instead of globally, so it no longer shortens the Jetpack Stats cache for unrelated site-wide consumers (review comment 3535445513) - Remove the load-time require_once of block-activity-kit-card.php in blocks.php: it's a render template that dereferences $block at the top level and is already included by the block's render_callback, so loading it early only emitted PHP warnings (review comment 3535445442) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the required space after the `function` keyword in six anonymous functions / render callbacks (WordPress-Core WhiteSpace.ControlStructureSpacing rule). Whitespace only, no behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
Introduces the Activity Library (`/activity-library/`), a new section of Learn WordPress that surfaces downloadable facilitator kits for educators, meetup organizers, and community facilitators.
Plugin (`wporg-learn`)
Theme (`wporg-learn-2024`)
Test plan
🤖 Generated with Claude Code