Skip to content

Commit 89173d8

Browse files
authored
Guidelines: Split singleton REST API into dedicated /content-guidelines route (#77734)
* Guidelines: Split singleton REST API into dedicated /content-guidelines route Move the content guidelines singleton logic to a new Gutenberg_Content_Guidelines_REST_Controller mounted at /wp/v2/content-guidelines so the existing /wp/v2/guidelines collection can behave like a standard post-type endpoint and serve other guideline posts (artifacts) with full title/content/excerpt/author CRUD. The revisions controller now accepts an overrideable parent base and parent controller so it can be mounted under /content-guidelines while keeping the singleton response shape on restore. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Content Guidelines: Restrict singleton routes to content-typed posts Override get_post() and get_parent() so /wp/v2/content-guidelines/{id} and its revisions sub-routes return 404 for guideline posts that aren't tagged with the `content` term — those belong on the standard /wp/v2/guidelines collection. Rename Gutenberg_Guidelines_Revisions_Controller (and its file) to Gutenberg_Content_Guidelines_Revisions_Controller for symmetry with the REST controller now that it's mounted exclusively under /content-guidelines. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Content Guidelines Revisions: Drop unused constructor injection The class is dedicated to the content singleton, so $parent_post_type, $parent_base, and $parent_controller never need overriding from the call site. Hardcode the post type and parent base, and instantiate the singleton controller directly inside restore_revision() when shaping the response. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Register content guideline revisions explicitly * Content Guidelines: Generalize singleton route doc comments Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Guidelines: Inline artifact type in REST controller test * Guidelines: Fix post type array alignment * Guidelines: Add standard REST route coverage * Guidelines: Map publishing capabilities * Content Guidelines Revisions: Lock revision deletion to administrators The inherited WP_REST_Revisions_Controller::delete_item_permissions_check only requires `delete_post` capability, which editors hold on guideline posts. The singleton route is admin-managed for every other write — align revision deletion with that rule. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Guidelines: Rename standard REST test file --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: gziolo <gziolo@git.wordpress.org>
1 parent c35d338 commit 89173d8

10 files changed

Lines changed: 790 additions & 264 deletions

lib/experimental/guidelines/class-gutenberg-guidelines-rest-controller.php renamed to lib/experimental/guidelines/class-gutenberg-content-guidelines-rest-controller.php

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<?php
22
/**
3-
* Guidelines REST API Controller.
3+
* Content Guidelines REST API Controller.
44
*
5-
* Extends WP_REST_Posts_Controller to inherit standard WordPress CRUD behavior,
6-
* permission checks, and response formatting. Follows the pattern used by
7-
* WP_REST_Global_Styles_Controller.
5+
* Specialized controller for the site-wide "content" guideline singleton.
6+
* Exposes a flat `/wp/v2/content-guidelines` endpoint that always reads,
7+
* creates, and updates a single post tagged with the `content` term in
8+
* the `wp_guideline_type` taxonomy. Other guideline posts (artifacts) are
9+
* served by the standard `/wp/v2/guidelines` collection.
810
*
911
* @package gutenberg
1012
*/
@@ -14,9 +16,9 @@
1416
}
1517

1618
/**
17-
* REST API controller for Guidelines.
19+
* REST API controller for the site-wide content guidelines singleton.
1820
*/
19-
class Gutenberg_Guidelines_REST_Controller extends WP_REST_Posts_Controller {
21+
class Gutenberg_Content_Guidelines_REST_Controller extends WP_REST_Posts_Controller {
2022

2123
/**
2224
* Maximum length for guideline text strings.
@@ -32,15 +34,50 @@ class Gutenberg_Guidelines_REST_Controller extends WP_REST_Posts_Controller {
3234
*/
3335
const MAX_LABEL_LENGTH = 200;
3436

37+
/**
38+
* REST base for the singleton route.
39+
*
40+
* @var string
41+
*/
42+
const REST_BASE = 'content-guidelines';
43+
3544
/**
3645
* Constructor.
3746
*/
3847
public function __construct() {
3948
parent::__construct( Gutenberg_Guidelines_Post_Type::POST_TYPE );
49+
$this->rest_base = self::REST_BASE;
50+
}
51+
52+
/**
53+
* Resolves a post ID to a content-typed guideline post.
54+
*
55+
* Restricts /wp/v2/content-guidelines/{id} to posts tagged with the
56+
* `content` term. Other guideline types are addressable only via the
57+
* standard /wp/v2/guidelines collection.
58+
*
59+
* @param int $id Post ID.
60+
* @return WP_Post|WP_Error Post object on success, WP_Error on failure.
61+
*/
62+
protected function get_post( $id ) {
63+
$post = parent::get_post( $id );
64+
if ( is_wp_error( $post ) ) {
65+
return $post;
66+
}
67+
68+
if ( ! Gutenberg_Guidelines_Post_Type::is_content_guideline( $post->ID ) ) {
69+
return new WP_Error(
70+
'rest_post_invalid_id',
71+
__( 'Invalid post ID.', 'gutenberg' ),
72+
array( 'status' => 404 )
73+
);
74+
}
75+
76+
return $post;
4077
}
4178

4279
/**
43-
* Registers the routes for guidelines.
80+
* Registers the routes for the content guidelines singleton.
4481
*
4582
* Calls parent to register standard /{id} CRUD routes, then overrides the
4683
* collection route with a singleton GET endpoint.
@@ -206,9 +243,10 @@ public function get_guidelines( WP_REST_Request $request ) {
206243
}
207244

208245
/**
209-
* Creates guidelines.
246+
* Creates the content guidelines singleton.
210247
*
211-
* Enforces singleton pattern — only one guidelines post per site.
248+
* Enforces the singleton constraint — only one post tagged with the
249+
* `content` term may exist.
212250
*
213251
* @param WP_REST_Request $request Full details about the request.
214252
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error on failure.
@@ -265,7 +303,7 @@ public function create_item( $request ) {
265303
}
266304

267305
/**
268-
* Updates guidelines.
306+
* Updates the content guidelines singleton.
269307
*
270308
* Saves guideline categories to meta before updating the post so that
271309
* the revision captures the updated meta values.
@@ -568,7 +606,7 @@ private function sanitize_blocks_category( array $blocks ): array {
568606
}
569607

570608
/**
571-
* Gets the single guidelines post.
609+
* Gets the single content guidelines post.
572610
*
573611
* @param string|null $status_filter Optional. Filter by status ('publish' or 'draft').
574612
* @return WP_Post|null The guidelines post or null if not found.
@@ -613,7 +651,7 @@ public function get_item_schema() {
613651

614652
$this->schema = array(
615653
'$schema' => 'http://json-schema.org/draft-04/schema#',
616-
'title' => 'guidelines',
654+
'title' => 'content-guidelines',
617655
'type' => 'object',
618656
'properties' => array(
619657
'id' => array(

0 commit comments

Comments
 (0)