P2026 WP Registry grade C-. High-severity findings · 1 findingWP RegistryHigh-severity findings · 1 findingOpen the reportC-
Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/georgestephanis/p2026/archive/refs/heads/trunk.zipA modern WordPress plugin that adds P2/o2-style team collaboration features by progressively enhancing theme-rendered post lists using React, the Block Editor, and the WordPress REST API.
Current release: 0.4.0. See CHANGELOG.md for release notes.
What It Does
- Real-time feed — Polls for new posts and surfaces them behind a reveal banner without auto-scrolling.
- Unified search — Searches authored posts and comments with a debounced modal UI for logged-in users on main archive-like feeds.
- Unread tracking — Tracks per-user read state and shows an unread badge that reveals pending posts.
- Inline threaded comments — Expand comment threads per post; post top-level comments and replies without leaving the page.
- Inline post editing — Edit existing posts using the Block Editor directly on the front end.
- Post-state workflow module — Optional Normal/Unresolved/Resolved state controls in the post menu, plus an "Open only" feed filter.
- New post creation — A
p2026/new-postdynamic block provides a front-end Block Editor for publishing posts. An admin bar "New Post" button opens the same editor in a modal when the block isn't on the page. - Capability-aware UX — All controls are gated by WordPress capabilities (and an optional Abilities API), so guests, contributors, and editors each see the appropriate UI.
- Mentions module —
@usernameautocomplete and hovercards, server-side linkification, and mention hook emission for downstream notifications. - Notifications module — Bottom-right notification dock for mentions/replies with polling and read management.
- Link-previews module — Internal post/comment links get hover preview cards (title, avatar, date, excerpt) with REST-backed server-side caching.
- Audit-log module — Persists core audit events and provides an admin DataViews browser (day filter, search, sorting, related actor/post/comment links) backed by REST endpoints.
- GitHub-based updates — Supports native
Update URIchecks against GitHub releases, prereleases, and atrunkchannel for direct installs from GitHub. - Theme-agnostic — Works with any block or classic theme without replacing the theme loop.
Recent frontend interaction work now uses a hybrid model:
- React +
@wordpress/datacontinue to power editor-heavy flows and shared async state. - The WordPress Interactivity API now powers delegated event wiring for lightweight interaction islands (for example admin-bar trigger behavior, menu close behavior, notification dock actions, hover interactions, and visibility-driven callbacks).
- Interactivity wiring is loaded via a dedicated Script Module entry (
build/interactivity.module.js) instead of classic script dependencies. - Classic frontend code calls a small bridge API (
src/interactivity/client-bridge.js), while Script Module implementations live undersrc/interactivity/*.
Building a Company Intranet
P2026 works well as the collaboration layer for a private internal site. A few companion plugins round out the setup:
Access control
- WP Force Login — redirects all unauthenticated visitors to the login page, keeping every page of the site internal. Essential first step.
- Domain Restricted Registration — lets you whitelist an email domain (e.g.
@yourcompany.com) so coworkers can self-register without opening the door to outsiders. - WP SAML Auth — single sign-on via your company's identity provider (Google Workspace, Azure AD, Okta, etc.). Employees log in with their existing corporate credentials and never need a separate WordPress password.
People
- Simple Local Avatars — lets users upload profile photos that are stored on your own server. Avoids the Gravatar dependency, which matters on an intranet where employees may not have public Gravatar accounts and external requests are undesirable.
Visibility and compliance
- Stream — keeps a full audit log of who created, edited, or deleted content and when. Useful for regulated industries or any team that needs an activity trail.
Requirements
- WordPress 6.0+
- Any active theme (block or classic)
Installation
- Upload the plugin folder to
wp-content/plugins/. - Activate P2026 in the WordPress admin.
- Add the P2026: New Post block to a page or template to enable front-end post creation.
Classic (non-FSE) themes
For traditional PHP themes, render the new-post block above the loop in your home.php:
<?php
// Render the P2026 new-post editor above the post loop.
if ( function_exists( 'p2026_can_create_posts' ) && p2026_can_create_posts() ) {
echo do_blocks( '<!-- wp:p2026/new-post /-->' );
}
?>
Place this snippet just before your while ( have_posts() ) loop. The block outputs nothing for users who lack the publish_posts capability, so the p2026_can_create_posts() guard is optional but avoids the do_blocks() call for guests entirely.
Development
From the plugin root:
npm install
composer install
npm run build # Production build
npm run start # Watch mode
npm run lint:js # JavaScript lint
npm run lint:css # CSS lint
npm run lint:php # PHP lint
npm run format:js # Auto-fix JS formatting
Build output goes to build/. Do not hand-edit files there.
Releases
- Current stable release:
0.4.0 - Initial release baseline:
0.1.0maps to commitdbf2205587f73c66e3d63a46449ff64b39dc2a2f - Release notes: CHANGELOG.md
Architecture
p2026 uses progressive enhancement:
- Theme markup remains the source of truth for initial rendering.
- React portals inject controls into existing post DOM nodes.
- A shared
@wordpress/datastore (p2026) manages posts, comments, and editor state. - All data flows through the WordPress REST API (
/wp/v2/posts,/wp/v2/comments). - PHP injects
window.p2026Configat page load with capability flags, nonce, and current user data. - Search header widgets mount only when the discovered loop is the main query and the current page is archive-like.
- Shared Interactivity API host wiring lives under
src/interactivity/. - Feature modules keep feature logic and pass handlers into shared interactivity initializers.
- Interactivity implementations are loaded through the Script Modules API and registered in PHP with
wp_register_script_module/wp_enqueue_script_modulewhen available. src/utils/on-dom-ready.jsis the standard DOM-ready bootstrap helper.
Interactivity Loading Model
build/frontend.jsremains a classic script bundle for React/editor/store features.build/interactivity.module.jsis a separate Script Module bundle for Interactivity API stores/host wiring.p2026.phpenqueues both: classic frontend script + interactivity module (when Script Modules API is available).- Script-module limitations are respected: module dependencies are module IDs, not script handles.
- Interactivity module code uses
window.wp.*for script interoperability where needed (for examplewindow.wp.data).
See ARCHITECTURE.md for the full request/data flow diagram and file-level responsibility map.
Search Notes
Current search implementation details:
- Endpoint:
GET /p2026/v1/search. - Auth: logged-in users only.
- Scope: currently filters to authored posts/comments for the current user.
- Query model: SQL
LIKEmatching with pagination caps.
Module System
p2026 modules are discovered from modules/*/index.php and are active by default.
- Option key:
p2026_disabled_modules - Model: opt-out deny-list (new modules auto-enable unless explicitly disabled)
- Settings UI: WP Admin → P2026 menu
Current modules:
mentions—@usernameparsing, linkification, and user lookup REST endpointsnotifications— per-user notifications REST API and dock UIlink-previews— internal post/comment link preview REST endpoint + hover card UIpost-state— Normal/Unresolved/Resolved workflow state + REST endpointaudit-log— audit event persistence backend (file or internal CPT)comment-editor— markdown WYSIWYG comment compose/edit enhancements with server-side markdown renderingsidebar-shell— optional fixed, collapsible sidebar shell with search/feed tools integration for themes without a native sidebar
Module Matrix
| Module | PHP Backend File | Frontend Entrypoint | REST Routes |
|---|---|---|---|
mentions |
modules/mentions/index.php |
src/modules/mentions/index.js |
GET /p2026/v1/users, GET /p2026/v1/users/{id} |
notifications |
modules/notifications/index.php |
src/modules/notifications/index.js |
GET /p2026/v1/notifications, POST /p2026/v1/notifications/{id}/read, POST /p2026/v1/notifications/read-all |
link-previews |
modules/link-previews/index.php |
src/modules/link-previews/index.js |
GET /p2026/v1/link-preview?url=... |
post-state |
modules/post-state/index.php |
Core UI integration (src/components/PostEnhancement.js) |
POST /p2026/v1/posts/{id}/state |
audit-log |
modules/audit-log/index.php |
src/modules/audit-log/audit-log-viewer.js |
GET /p2026/v1/audit-log/days, GET /p2026/v1/audit-log/entries |
comment-editor |
modules/comment-editor/index.php |
Core UI integration (src/components/Comments.js, src/components/Comment.js) |
Extends POST /wp/v2/comments via p2026_format=markdown processing |
sidebar-shell |
modules/sidebar-shell/index.php |
src/modules/sidebar-shell/index.js, src/modules/sidebar-shell/SidebarControls.js |
No dedicated REST routes (theme/layout shell + settings-backed rendering) |
Key Files
| File | Role |
|---|---|
p2026.php |
Bootstrap, block registration, frontend enqueue, config injection, abilities |
src/frontend.js |
Entry point; discovers post nodes and mounts enhancement |
src/store/index.js |
Redux-style store: state, actions, selectors, async thunks |
src/api/index.js |
apiFetch middleware setup and polling utility |
src/components/FeedEnhancer.js |
Polling orchestration and new-posts banner |
src/components/SearchWidget.js |
Debounced post/comment search modal |
src/components/UnreadBadge.js |
Per-user unread count badge and read-state sync |
src/components/PostEnhancement.js |
Per-post controls (comments toggle, edit/delete) |
src/components/Comments.js + Comment.js |
Threaded comment tree and reply forms |
src/components/PostEditor.js |
Inline Block Editor for editing existing posts |
src/components/NewPostEditor.js |
Block Editor for creating new posts |
src/components/NewPostModal.js |
Modal wrapper opened by the admin bar "New Post" button |
src/blocks/new-post/ |
Dynamic block metadata, server render gate, and frontend mount |
modules/post-state/index.php |
Post-state taxonomy, REST field/endpoint, and audit event emission |
modules/audit-log/index.php |
Audit event persistence (uploads JSONL or CPT backend) |
src/modules/audit-log/audit-log-viewer.js |
Admin Audit Log browser app (DataViews + entity-backed related lookups) |
modules/comment-editor/index.php |
Optional markdown comment-editing backend hooks (REST pre/after insert processing + source persistence) |
src/modules/comment-editor/MarkdownCommentEditor.js |
Markdown WYSIWYG editor used by comment create/edit UI when module is active |
modules/mentions/index.php |
Mention user search/detail endpoints and server-side content linkification |
modules/notifications/index.php |
Notifications REST API + auto-create hooks |
modules/link-previews/index.php |
Internal link preview REST endpoint + 3-day transient caching |
admin/settings.php |
Module toggles and audit backend configuration UI |
includes/github-updates.php |
GitHub release/update channel integration for the plugin Update URI |
src/modules/link-previews/ |
Hover/focus preview card UI for internal post/comment links |
src/modules/notifications/ |
Notification dock frontend UI |
src/interactivity/ |
Interactivity API stores + directive host wiring |
src/interactivity/client-bridge.js |
Classic-script bridge API used by frontend/modules to call module-loaded interactivity implementations |
src/interactivity/module-entry.js |
Script-module entry that boots interactivity stores/hosts and flushes queued bridge calls |
src/utils/on-dom-ready.js |
Shared helper for DOM-ready bootstrap without ad hoc listeners |
Update Behavior (Git Checkouts)
- Sites deployed from a git checkout are shown a manual update notice in plugin update UI.
- Automatic update package install is intentionally blocked for git checkouts to protect local branch and worktree state.
- For these installs, updates should be performed via normal git workflows (
git fetch,git checkout/git merge/git pull) based on site policy.
Playground note: .github/setup.php seeds sample users, posts, comments, and starter notifications for the default logged-in admin user.
Permission Model
PHP helpers in p2026.php centralize all capability checks:
p2026_can_create_posts()— checkspublish_posts(abilities-first, falls back tocurrent_user_can)p2026_can_update_posts($post_id)— checksedit_postoredit_posts
If the WordPress Abilities API is available, the plugin registers:
p2026/post-createp2026/post-update
Frontend gating uses window.p2026Config flags: canCreatePosts, canUpdatePosts, canComment, requireNameEmail, isArchiveView, currentUser.
License
GPL-2.0-or-later
Releases
4 releases.
These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.