Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
fd2b520
Abillities API: Block Framework
n7studios Apr 20, 2026
a0ff1b0
Include block framework classes
n7studios Apr 20, 2026
f876f5d
Set `get_category` to not be abstract
n7studios Apr 20, 2026
a4f501f
Fetch input schema from block fields/attributes
n7studios Apr 20, 2026
afa1e7e
Register Form Insertion Ability
n7studios Apr 20, 2026
1c5b9c3
Abilities: Prefix with `block-`
n7studios Apr 20, 2026
db3eec1
Insert Block: Use `index`
n7studios Apr 20, 2026
89968ba
Merge branch 'abilities-api' into abilities-api-block-framework
n7studios Apr 23, 2026
bf522cc
Use ConvertKit_Block_Post_Helper class
n7studios Apr 23, 2026
3ed5446
Fix static method arguments
n7studios Apr 23, 2026
fc4d1ed
Simplify block post helper method
n7studios Apr 23, 2026
63042f1
Move annotations to higher classes
n7studios Apr 23, 2026
a3d689e
Simplify input/output schema
n7studios Apr 23, 2026
81b58e3
Register all block abilities and set correct parameters
n7studios Apr 23, 2026
0fadf1c
Tidy up comments
n7studios Apr 23, 2026
e636b9d
Merge branch 'abilities-api' into abilities-api-block-framework
n7studios Apr 23, 2026
96a704d
Merge branch 'abilities-api' into abilities-api-block-framework
n7studios May 5, 2026
2777e8e
Merge branch 'abilities-api' into abilities-api-block-framework
n7studios May 8, 2026
f72942e
Merge branch 'abilities-api' into abilities-api-block-framework
n7studios May 15, 2026
678d681
Merge remote-tracking branch 'origin/abilities-api-block-post-helper'…
n7studios May 15, 2026
fcd156f
Remove block post helper class
n7studios May 15, 2026
c618f4f
PHPStan compat.
n7studios May 15, 2026
8a26dbc
Merge branch 'abilities-api-block-post-helper' into abilities-api-blo…
n7studios May 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions includes/blocks/class-convertkit-block.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,28 @@ public function register( $blocks ) {

}

/**
* Registers this block's MCP abilities.
*
* @since 3.4.0
*
* @param array $abilities Abilities to Register.
* @return array
*/
public function register_abilities( $abilities ) {

return array_merge(
$abilities,
array(
new ConvertKit_MCP_Ability_Block_List( $this ),
new ConvertKit_MCP_Ability_Block_Insert( $this ),
new ConvertKit_MCP_Ability_Block_Update( $this ),
new ConvertKit_MCP_Ability_Block_Delete( $this ),
)
);

}

/**
* Returns this block's programmatic name, excluding the convertkit- prefix.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php
/**
* Kit MCP Ability: Delete a block from a post.
*
* @package ConvertKit
* @author ConvertKit
*/

/**
* Ability that removes an occurrence of a Kit block from a WordPress post's
* content.
*
* Registered by a block opting in via the `convertkit_abilities` filter and
* produces an ability named `kit/<block-name>-delete` (e.g. `kit/form-delete`).
*
* @package ConvertKit
* @author ConvertKit
*/
class ConvertKit_MCP_Ability_Block_Delete extends ConvertKit_MCP_Ability_Block {

/**
* Sets whether the ability is destructive.
*
* @since 3.4.0
*
* @var bool
*/
private $destructive = true; // @phpstan-ignore-line

/**
* Returns the verb this ability represents.
*
* @since 3.4.0
*
* @return string
*/
public function get_verb() {

return 'delete';

}

/**
* Returns the ability's human-readable label.
*
* @since 3.4.0
*
* @return string
*/
public function get_label() {

return sprintf(
/* translators: %s: block title */
__( 'Delete an existing %s block from a post', 'convertkit' ),
$this->block->get_title()
);

}

/**
* Returns the ability's human-readable description.
*
* @since 3.4.0
*
* @return string
*/
public function get_description() {

return sprintf(
/* translators: 1: block full name e.g. convertkit/form, 2: block title */
__( 'Removes a single occurrence of the %1$s (%2$s) block from the given post.', 'convertkit' ),
'convertkit/' . $this->block->get_name(),
$this->block->get_title()
);

}

/**
* Returns the ability's input JSON Schema.
*
* @since 3.4.0
*
* @return array
*/
public function get_input_schema() {

return array(
'type' => 'object',
'required' => array( 'post_id', 'occurrence_index' ),
'properties' => array(
'post_id' => array(
'type' => 'integer',
'minimum' => 1,
'description' => __( 'ID of the post containing the block.', 'convertkit' ),
),
'occurrence_index' => array(
'type' => 'integer',
'minimum' => 0,
'description' => __( 'The zero-based occurrence index of the block to delete.', 'convertkit' ),
),
),
);

}

/**
* Executes the ability.
*
* @since 3.4.0
*
* @param array $input Ability input.
* @return array|WP_Error
*/
public function execute_callback( $input ) {

// Get Post ID.
$post_id = isset( $input['post_id'] ) ? absint( $input['post_id'] ) : 0;

// Bail if no Post ID is provided.
if ( ! $post_id ) {
return new WP_Error(
'convertkit_mcp_missing_post_id',
__( 'A post_id is required.', 'convertkit' )
);
}

// Get occurrence index.
$occurrence_index = isset( $input['occurrence_index'] ) ? (int) $input['occurrence_index'] : 0;

// Delete block from post.
return ConvertKit_Block_Post_Helper::delete( $post_id, 'convertkit/' . $this->block->get_name(), $occurrence_index );

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php
/**
* Kit MCP Ability: Insert a block into a post.
*
* @package ConvertKit
* @author ConvertKit
*/

/**
* Ability that inserts an occurrence of a Kit block into a WordPress post's
* content.
*
* Registered by a block opting in via the `convertkit_abilities` filter and
* produces an ability named `kit/<block-name>-insert` (e.g. `kit/form-insert`).
*
* @package ConvertKit
* @author ConvertKit
*/
class ConvertKit_MCP_Ability_Block_Insert extends ConvertKit_MCP_Ability_Block {

/**
* Returns the verb this ability represents.
*
* @since 3.4.0
*
* @return string
*/
public function get_verb() {

return 'insert';

}

/**
* Returns the ability's human-readable label.
*
* @since 3.4.0
*
* @return string
*/
public function get_label() {

return sprintf(
/* translators: %s: block title */
__( 'Insert a %s block into a post', 'convertkit' ),
$this->block->get_title()
);

}

/**
* Returns the ability's human-readable description.
*
* @since 3.4.0
*
* @return string
*/
public function get_description() {

return sprintf(
/* translators: 1: block full name e.g. convertkit/form, 2: block title */
__( 'Inserts a new %1$s (%2$s) block into the given post\'s content. The block can be appended (default), prepended, or positioned relative to an existing block using a zero-based index.', 'convertkit' ),
'convertkit/' . $this->block->get_name(),
$this->block->get_title()
);

}

/**
* Returns the ability's input JSON Schema.
*
* @since 3.4.0
*
* @return array
*/
public function get_input_schema() {

return array(
'type' => 'object',
'required' => array( 'post_id', 'attrs' ),
'properties' => array(
'post_id' => array(
'type' => 'integer',
'minimum' => 1,
'description' => __( 'Page / Post / Custom Post Type ID to insert the block into.', 'convertkit' ),
),
'position' => array(
'type' => 'string',
'enum' => array( 'append', 'prepend', 'index' ),
'default' => 'append',
'description' => __( 'Where to insert the new block. "index" requires the "index" property.', 'convertkit' ),
),
'index' => array(
'type' => 'integer',
'minimum' => 0,
'description' => __( 'When position is "index", the zero-based top-level block index at which to insert the new block.', 'convertkit' ),
),
'attrs' => array(
'type' => 'object',
'description' => __( 'Block attributes.', 'convertkit' ),
'properties' => $this->get_input_schema_properties(),
),
),
);

}

/**
* Executes the ability.
*
* @since 3.4.0
*
* @param array $input Ability input.
* @return array|WP_Error
*/
public function execute_callback( $input ) {

// Get Post ID.
$post_id = isset( $input['post_id'] ) ? absint( $input['post_id'] ) : 0;

// Bail if no Post ID is provided.
if ( ! $post_id ) {
return new WP_Error(
'convertkit_mcp_missing_post_id',
__( 'A post_id is required.', 'convertkit' )
);
}

// Get attributes, position and index.
$attrs = isset( $input['attrs'] ) && is_array( $input['attrs'] ) ? $input['attrs'] : array();
$position = isset( $input['position'] ) ? (string) $input['position'] : 'append';
$index = isset( $input['index'] ) ? (int) $input['index'] : 0;

// Insert block into post.
return ConvertKit_Block_Post_Helper::insert( $post_id, 'convertkit/' . $this->block->get_name(), $attrs, $position, $index );

}

}
Loading
Loading