关于 code-style
code-style 是为 WordPress ActivityPub 插件准备的开发规范技能,面向编写和审查插件代码的开发者。它汇总命名、架构模式、WordPress 函数复用和插件专属约定。
主要功能
- 01PHP 文件与命名空间规范
- 02优先复用 WordPress 核心功能
- 03Transformer、Handler 与 Collection 模式
- 04REST API 控制器约定
- 05注释、钩子与版本号规则
适用场景
- 01实现 ActivityPub 对象转换
- 02编写传入活动处理器
- 03添加集合或 REST API 端点
- 04审查插件代码是否遵循项目惯例
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ automattic/ wordpress-activitypub --skill code-style安装后在 Claude Code 中输入/code-style确认已加载。
详细介绍
ActivityPub PHP 约定
ActivityPub 插件特有的约定和架构模式。
首要规则:先复用,再编写。 优先使用 WordPress 核心函数,然后是现有插件辅助工具(includes/functions*.php、Sanitize、src/shared/),而不是编写新的实现;绝不要用自定义逻辑替换基于核心函数的检查。参见 docs/php-coding-standards.md 中的“优先复用核心功能”。
快速参考
文件命名
class-{name}.php # Regular classes.
trait-{name}.php # Traits.
interface-{name}.php # Interfaces.
命名空间模式
namespace Activitypub;
namespace Activitypub\Transformer;
namespace Activitypub\Collection;
namespace Activitypub\Handler;
namespace Activitypub\Activity;
namespace Activitypub\Rest;
文本域
翻译始终使用 'activitypub':
\__( 'Text', 'activitypub' );
\_e( 'Text', 'activitypub' );
WordPress 全局函数
在命名空间中,始终使用反斜杠转义 WordPress 函数:\get_option()、\add_action() 等。
导入和类引用
以下两条对称规则都会在代码审查中检查:
// Plugin classes: import with `use`, never reference inline.
use Activitypub\Collection\Outbox;
Outbox::add( $activity ); // ✅
\Activitypub\Collection\Outbox::add( $activity ); // ❌ no inline namespaces
// Global (WordPress/PHP) classes: reference inline with a backslash, never import.
$query = new \WP_Query( $args ); // ✅
class Command extends \WP_CLI_Command {} // ✅
use WP_Query; // ❌ no `use` for global classes
注释
- 多行注释使用
/* */,单行注释使用//;不要连续堆叠多行//注释。 - 每条注释放在其所说明的代码行旁,而不是放在一段代码上方作为整体说明。可以写得详细,但应按语句分别说明。
- 解释某行代码不可或缺的非显而易见机制,而不是它背后的错误或工单。代码本身已足够清楚的行无需注释。
插件惯用模式
- 不要使用
try/catch或try/finally。围绕调用按add_filter→ 调用 →remove_filter的顺序挂接过滤器,并通过返回值(WP_Error、false)报告失败。 - 标识符、文件名和代码注释中不要使用 “C2S”;官方名称是 “ActivityPub API”,对于使用方,使用 “client” 即可。
- 所有离开服务器的内容(REST 响应、投递)都使用
$activity->to_array( false, false )渲染:不包含每个条目的@context,也不包含bto/bcc。存储时保留to_array( true, true ),以便往返转换。 - 在两个调用点重复几行代码,胜过新增辅助函数;但不要在同级类中重复整个方法体。
完整标准
完整的 WordPress 编码标准请参阅 docs/php-coding-standards.md。
详细的目录组织说明请参阅 docs/php-class-structure.md。
目录结构
includes/
├── class-*.php # Core classes.
├── activity/ # Activity type classes.
├── collection/ # Collection classes.
├── handler/ # Activity handlers.
├── rest/ # REST API endpoints.
├── transformer/ # Content transformers.
└── wp-admin/ # Admin functionality.
integration/ # Third-party integrations (root level).
ActivityPub 架构模式
转换器
将 WordPress 内容转换为 ActivityPub 对象。
适用场景: 将文章、评论、用户或自定义内容类型转换为 ActivityPub 格式。
基类: includes/transformer/class-base.php
模式:
namespace Activitypub\Transformer;
class Custom extends Base {
/**
* Transform object to ActivityPub format.
*
* @return array The ActivityPub representation.
*/
public function transform() {
$object = parent::transform();
// Custom transformation logic.
return $object;
}
}
示例:
includes/transformer/class-post.php- 文章转换。includes/transformer/class-comment.php- 评论转换。includes/transformer/class-user.php- 用户/参与者转换。
处理器
处理来自远程服务的传入 ActivityPub 活动。
适用场景: 处理传入的 Follow、Like、Create、Delete、Update 等活动。
模式: 每个处理器负责处理收件箱中的一种活动类型。
示例:
includes/handler/class-follow.php- 处理 Follow 活动。includes/handler/class-create.php- 处理 Create 活动。includes/handler/class-delete.php- 处理 Delete 活动。includes/handler/class-like.php- 处理 Like 活动。
集合
实现 ActivityPub 集合(Followers、Following 等)。
适用场景: 通过 ActivityPub 提供参与者、活动或对象列表。
示例:
includes/collection/class-followers.php- Followers 集合。includes/collection/class-following.php- Following 集合。
REST API 控制器
提供 ActivityPub 端点。
命名空间: ACTIVITYPUB_REST_NAMESPACE
示例:
includes/rest/class-actors-controller.php- 参与者端点。includes/rest/class-inbox-controller.php- 收件箱端点。includes/rest/class-outbox-controller.php- 发件箱端点。includes/rest/class-followers-controller.php- Followers 集合端点。
插件专用辅助函数
// Get remote actor metadata.
$metadata = get_remote_metadata_by_actor( $actor_url );
// Convert ActivityPub object to URI string.
$uri = object_to_uri( $object );
// Enrich content with callbacks.
$content = enrich_content_data( $content, $pattern, $callback );
// Resolve WebFinger handle to actor URL.
$resource = Webfinger::resolve( $handle );
// Check whether a post is disabled for ActivityPub (the federation pipeline gate).
$disabled = is_post_disabled( $post );
真实代码库示例
核心类:
includes/class-activitypub.php- 插件主初始化。includes/class-dispatcher.php- 向关注者分发活动。includes/class-scheduler.php- 用于异步任务的 WP-Cron 集成。includes/class-signature.php- 联邦通信的 HTTP 签名。
活动类型:
includes/activity/class-activity.php- 活动类(Create、Follow、Undo 等均基于此构建)。includes/activity/class-base-object.php- 基础对象类。includes/activity/extended-object/- 扩展对象类型(例如 Event)。
集成(参见 集成模式):
integration/class-buddypress.php- BuddyPress 集成。integration/class-jetpack.php- Jetpack 集成。integration/class-opengraph.php- OpenGraph 集成。
常见初始化模式
静态初始化
class Feature {
/**
* Initialize the class.
*/
public static function init() {
\add_action( 'init', array( self::class, 'register' ) );
\add_filter( 'activitypub_the_content', array( self::class, 'filter' ) );
}
}
单例模式
class Manager {
private static $instance = null;
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->init();
}
}
自定义钩子模式
操作:
\do_action( 'activitypub_handled_create', $activity, $user_ids, $success, $result );
\do_action( 'activitypub_followers_pre_remove_follower', $follower, $user_id, $actor );
筛选器:
$array = \apply_filters( 'activitypub_activity_object_array', $array, $class, $id, $object );
$content = \apply_filters( 'activitypub_the_content', $content, $post );
$types = \apply_filters( 'activitypub_actor_types', $types );
版本号
新代码中的版本字符串一律使用 'unreleased'。发布脚本会在发布过程中自动将其替换为实际版本号。
PHPDoc 标签:
/**
* New function description.
*
* @since unreleased
*/
function new_feature() {}
/**
* Old function.
*
* @deprecated unreleased Use new_feature() instead.
*/
function old_feature() {}
弃用函数:
\_deprecated_function( __METHOD__, 'unreleased', 'New_Class::new_method' );
\_deprecated_argument( __METHOD__, 'unreleased', \esc_html__( 'Message', 'activitypub' ) );
\_doing_it_wrong( __METHOD__, \esc_html__( 'Message', 'activitypub' ), 'unreleased' );
不要硬编码版本号,例如 '5.1.0' —— 一律使用 'unreleased'。