Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
0904ce2
Comments: Introduce a register_comment_type() API.
adamsilverstein Jun 24, 2026
ebb51c5
Comments: Add tests for the comment type registration API.
adamsilverstein Jun 24, 2026
506e9c6
Comments: Fix default labels for comment types registered without a l…
adamsilverstein Jun 24, 2026
81eceff
Comments: Escape the comment type label in comment_type().
adamsilverstein Jun 25, 2026
3e1551b
Tests: Reset comment types between tests in the shared test framework.
adamsilverstein Jul 11, 2026
2c7c495
Comments: Remove the unused 'show_ui' argument from comment type regi…
adamsilverstein Jul 11, 2026
bb81be9
Comments: Reject re-registration of built-in comment types.
adamsilverstein Jul 11, 2026
9efe27b
Docs: Correct and clarify comment type registration documentation.
adamsilverstein Jul 11, 2026
6a1ea10
Comments: Keep post-type-only labels out of comment type labels objects.
adamsilverstein Jul 11, 2026
bacdf27
Merge remote-tracking branch 'origin/trunk' into feature/register-com…
adamsilverstein Aug 12, 2026
413d677
Build/Test Tools: Reset the whole comment type registry between tests.
adamsilverstein Aug 12, 2026
11a4975
Comments: Ignore a hierarchical argument when registering a comment t…
adamsilverstein Aug 12, 2026
e9e894c
Comments: Reserve the query token names and spell out the argument co…
adamsilverstein Aug 12, 2026
1504bdf
Comments: Stop get_comment_type_labels() from modifying the passed ob…
adamsilverstein Aug 23, 2026
8a21e22
Docs: Describe the internal comment type flag as intent, not behavior.
adamsilverstein Aug 23, 2026
16b2c4f
Build/Test Tools: Drop the unused _unregister_comment_type() helper.
adamsilverstein Aug 23, 2026
1473c5b
Comments: Stamp the comment type API for 7.2.0.
adamsilverstein Aug 23, 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
240 changes: 240 additions & 0 deletions src/wp-includes/class-wp-comment-type.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
<?php
/**
* Comment API: WP_Comment_Type class
*
* @package WordPress
* @subpackage Comments
* @since 7.2.0
*/

/**
* Core class used for interacting with comment types.
*
* @since 7.2.0
*
* @see register_comment_type()
*/
#[AllowDynamicProperties]
final class WP_Comment_Type {
/**
* Comment type key.
*
* @since 7.2.0
* @var string
*/
public $name;

/**
* Name of the comment type. Usually plural.
*
* @since 7.2.0
* @var string
*/
public $label;

/**
* Labels object for this comment type.
*
* If not set, the default comment labels are used.
*
* @see get_comment_type_labels()
*
* @since 7.2.0
* @var stdClass
*/
public $labels;

/**
* Default labels.
*
* @since 7.2.0
* @var (string|null)[][] $default_labels
*/
protected static $default_labels = array();

/**
* A short descriptive summary of what the comment type is for.
*
* @since 7.2.0
* @var string
*/
public $description = '';

/**
* Whether a comment type is intended for use publicly either via the admin interface or by front-end users.
*
* Core does not currently act on this property, but it is the intended default
* for future visibility-related arguments. It defaults to true so that
* registering a type in order to provide labels never hides comments that are
* already publicly visible.
*
* Default true.
*
* @since 7.2.0
* @var bool
*/
public $public = true;

/**
* Whether the comment type is for internal use only.
*
* Analogous to the `internal` argument of register_post_status(). Internal types
* are meant to be excluded from comment queries and counts by default. Core does
* not currently act on this flag.
*
* Default false.
*
* @since 7.2.0
* @var bool
*/
public $internal = false;

/**
* Whether this comment type is a native or "built-in" comment type.
*
* Default false.
*
* @since 7.2.0
* @var bool
*/
public $_builtin = false;

/**
* Whether the comment type is hierarchical.
*
* Comment types are never hierarchical. This property exists so the shared label
* helper {@see _get_custom_object_labels()} can resolve default labels, and
* set_props() forces it to false so a provided value cannot resolve them to null.
*
* @since 7.2.0
* @var bool
*/
public $hierarchical = false;

/**
* Constructor.
*
* See the register_comment_type() function for accepted arguments for `$args`.
*
* Will populate object properties from the provided arguments and assign other
* default properties based on that information.
*
* @since 7.2.0
*
* @see register_comment_type()
*
* @param string $comment_type Comment type key.
* @param array|string $args Optional. Array or string of arguments for registering a comment type.
* Default empty array.
*/
public function __construct( $comment_type, $args = array() ) {
$this->name = $comment_type;

$this->set_props( $args );
}

/**
* Sets comment type properties.
*
* See the register_comment_type() function for accepted arguments for `$args`.
*
* @since 7.2.0
*
* @param array|string $args Array or string of arguments for registering a comment type.
*/
public function set_props( $args ) {
$args = wp_parse_args( $args );

/**
* Filters the arguments for registering a comment type.
*
* @since 7.2.0
*
* @param array $args Array of arguments for registering a comment type.
* See the register_comment_type() function for accepted arguments.
* @param string $comment_type Comment type key.
*/
$args = apply_filters( 'register_comment_type_args', $args, $this->name );

$comment_type = $this->name;

/**
* Filters the arguments for registering a specific comment type.
*
* The dynamic portion of the filter name, `$comment_type`, refers to the comment type key.
*
* Possible hook names include:
*
* - `register_comment_comment_type_args`
* - `register_pingback_comment_type_args`
*
* @since 7.2.0
*
* @param array $args Array of arguments for registering a comment type.
* See the register_comment_type() function for accepted arguments.
* @param string $comment_type Comment type key.
*/
$args = apply_filters( "register_{$comment_type}_comment_type_args", $args, $this->name );

/*
* Note: 'label' is intentionally omitted from the defaults. Leaving the property
* unset (null) lets get_comment_type_labels() fall back to the default labels, the
* same way WP_Post_Type and WP_Taxonomy behave. A 'label' default of false would be
* treated as a provided value and overwrite the default name with false.
*/
$defaults = array(
'labels' => array(),
'description' => '',
'public' => true,
'internal' => false,
'_builtin' => false,
);

$args = array_merge( $defaults, $args );

$args['name'] = $this->name;

/*
* Comment types are never hierarchical. The property exists only so the shared
* label helper can pick a slot, and the hierarchical slot is deliberately null,
* so honoring a provided value would resolve every default label to null.
*/
$args['hierarchical'] = false;

foreach ( $args as $property_name => $property_value ) {
$this->$property_name = $property_value;
}

$this->labels = get_comment_type_labels( $this );
$this->label = $this->labels->name;
}

/**
* Returns the default labels for comment types.
*
* @since 7.2.0
*
* @return (string|null)[][] The default labels for comment types.
*/
public static function get_default_labels() {
if ( ! empty( self::$default_labels ) ) {
return self::$default_labels;
}

self::$default_labels = array(
'name' => array( _x( 'Comments', 'comment type general name' ), null ),
'singular_name' => array( _x( 'Comment', 'comment type singular name' ), null ),
);

return self::$default_labels;
}

/**
* Resets the cache for the default labels.
*
* @since 7.2.0
*/
public static function reset_default_labels() {
self::$default_labels = array();
}
}
18 changes: 17 additions & 1 deletion src/wp-includes/comment-template.php
Original file line number Diff line number Diff line change
Expand Up @@ -1179,12 +1179,17 @@ function get_comment_type( $comment_id = 0 ) {
* Displays the comment type of the current comment.
*
* @since 0.71
* @since 7.2.0 The default output for a registered non-built-in comment type
* falls back to the type's singular name label.
*
* @param string|false $comment_text Optional. String to display for comment type. Default false.
* @param string|false $trackback_text Optional. String to display for trackback type. Default false.
* @param string|false $pingback_text Optional. String to display for pingback type. Default false.
*/
function comment_type( $comment_text = false, $trackback_text = false, $pingback_text = false ) {
// Whether the caller supplied custom text for the default comment label.
$comment_text_overridden = ( false !== $comment_text );

if ( false === $comment_text ) {
$comment_text = _x( 'Comment', 'noun' );
}
Expand All @@ -1203,7 +1208,18 @@ function comment_type( $comment_text = false, $trackback_text = false, $pingback
echo $pingback_text;
break;
default:
echo $comment_text;
/*
* For a registered, non-built-in comment type, fall back to its singular label
* when the caller did not supply custom text. Built-in types and explicit
* overrides keep their existing output.
*/
$comment_type_object = $comment_text_overridden ? null : get_comment_type_object( $type );

if ( $comment_type_object && ! $comment_type_object->_builtin && isset( $comment_type_object->labels->singular_name ) ) {
echo esc_html( $comment_type_object->labels->singular_name );
} else {
echo $comment_text;
}
}
}

Expand Down
Loading
Loading