Skip to content

Add Activity Library — activity_kit post type, archive, single pages, stats dashboard#3496

Open
Piyopiyo-Kitsune wants to merge 7 commits into
trunkfrom
feature/activity-library
Open

Add Activity Library — activity_kit post type, archive, single pages, stats dashboard#3496
Piyopiyo-Kitsune wants to merge 7 commits into
trunkfrom
feature/activity-library

Conversation

@Piyopiyo-Kitsune
Copy link
Copy Markdown
Collaborator

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)

  • activity_kit post type with archive slug activity-library, REST support, and custom capabilities
  • Post meta: _activity_duration, _activity_guide_pdf_id, _activity_slides_pdf_id, _activity_zip_id, _view_count, _download_count, _activity_feedback_url
  • REST endpoint POST /activity-kits/v1/track — records views (every page load) and downloads (rate-limited to one per IP per 24 h via transient)
  • Stats dashboard (Activity Kits → Stats) — Chart.js bar chart, sortable table, time-range filters, custom date-range picker with Apply/Clear, Export CSV; blueberry design-system colours throughout
  • Settings page (Activity Kits → Settings) — global feedback form URL stored as activity_kit_feedback_url site option
  • Block editor sidebar panel — PDF pickers (Facilitator Guide, Slide Deck), ZIP picker, duration field, per-kit feedback URL override, experience-level radio
  • WP-CLI import commandwp activity-kit import seeds 11 draft kits
  • Admin list columns — sortable Views and Downloads columns

Theme (wporg-learn-2024)

  • Archive template — 3-column card grid with Topic/Level/Language filter dropdowns, search bar, 12-per-page pagination
  • wporg/activity-kit-card block — server-rendered card with featured image, excerpt, clock-icon duration, level, outlined View + filled Download buttons
  • Single kit pattern — breadcrumb, meta row, PDF tab toggle (Facilitator Guide / Slide Deck), per-browser PDF UX (#toolbar=0 for Chromium; #view=FitH + tracked "Download PDF" link for Firefox/Safari), feedback strip below preview, "What's included" grid, "Download this kit" box
  • Search resultsrender_block_core/template-part filter replaces the generic card template with the full activity kit card when post_type = activity_kit, keeping View/Download buttons consistent with the archive
  • SCSS_activity-kit.scss with BEM components using design-system CSS variables; feedback strip with blueberry outlined button and visible focus ring

Test plan

  • Visit /activity-library/ — 12 cards render with image, excerpt, duration, level, View + Download buttons
  • Filter by Topic, Level, or Language — grid filters correctly; pagination carries filters
  • Search "accessibility" from archive search bar — results show activity kit cards (not generic cards)
  • Visit a single kit page — breadcrumb, PDF tabs switch between Facilitator Guide and Slide Deck, feedback strip links to configured form with ?kit={slug}
  • Click Download kit — stats increment download count (check Stats page)
  • Stats page (Activity Kits → Stats) — chart renders, time range buttons work, Custom range Apply/Clear work, table rows link to single kit
  • Settings page (Activity Kits → Settings) — save a feedback URL, confirm it appears on kit pages; clear it, confirm strip disappears
  • Block editor — open an activity_kit post; sidebar shows Activity Kit Details panel with PDF pickers and feedback URL field
  • Run composer run lint — 0 new errors
  • Run yarn workspace wporg-learn-plugin lint:js — 0 errors

🤖 Generated with Claude Code

Piyopiyo-Kitsune and others added 3 commits May 22, 2026 13:19
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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_kit CPT, 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.

Comment on lines +16 to +25
const postMeta = useSelect(
( select ) =>
select( 'core/editor' ).getEditedPostAttribute( 'meta' ) || {},
[]
);
const { editPost } = useDispatch( 'core/editor' );

const setMeta = ( key, value ) =>
editPost( { meta: { ...postMeta, [ key ]: value } } );

Comment on lines +212 to +215
const levelTermIds = useSelect(
( select ) =>
select( 'core/editor' ).getEditedPostAttribute( 'level' ) || [],
[]
Comment on lines +201 to +210
if ( ! empty( $_GET['language'] ) ) {
$meta_query = array(
array(
'key' => 'language',
'value' => sanitize_text_field( wp_unslash( $_GET['language'] ) ),
'compare' => '=',
),
);
$query->set( 'meta_query', $meta_query );
}
Comment on lines +189 to +195
if ( ! empty( $_GET['level'] ) && 'all' !== $_GET['level'] ) {
$tax_query[] = array(
'taxonomy' => 'level',
'field' => 'slug',
'terms' => sanitize_text_field( wp_unslash( $_GET['level'] ) ),
);
}
Comment on lines +323 to +330
document.querySelectorAll( '[data-track-download="1"]' ).forEach( function ( btn ) {
btn.addEventListener( 'click', function () {
fetch( '/wp-json/activity-kits/v1/track', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify( { post_id: parseInt( btn.dataset.postId, 10 ), action: 'download' } ),
keepalive: true,
} ).catch( function () {} );
Comment on lines +657 to +670
function handle_activity_kit_sortable_columns( $query ) {
if ( ! is_admin() || 'activity_kit' !== $query->get( 'post_type' ) ) {
return;
}

$orderby = $query->get( 'orderby' );

if ( 'views' === $orderby ) {
$query->set( 'meta_key', '_view_count' );
$query->set( 'orderby', 'meta_value_num' );
} elseif ( 'downloads' === $orderby ) {
$query->set( 'meta_key', '_download_count' );
$query->set( 'orderby', 'meta_value_num' );
}
Comment on lines +24 to +26
'https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js',
array(),
'4.4.0',
Comment on lines +30 to +34
wp_enqueue_script(
'activity-kit-stats',
\WPOrg_Learn\PLUGIN_URL . 'js/activity-kit-stats/index.js',
array( 'chartjs' ),
(string) filemtime( \WPOrg_Learn\PLUGIN_DIR . 'js/activity-kit-stats/index.js' ),
Comment on lines +46 to +47

wp_add_inline_style( 'wp-admin', '' );
Comment on lines +497 to +505
// -------------------------------------------------------------------------
// Activity Kit Stats Admin Page
// -------------------------------------------------------------------------
.activity-kit-stats-page {
h1 {
margin-bottom: 1.5rem;
}

.activity-kit-stats-summary {
Piyopiyo-Kitsune and others added 4 commits May 26, 2026 15:25
- 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants