Skip to content

Make footnotes support opt-in. #6043

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 0 additions & 21 deletions src/wp-includes/blocks/footnotes.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,27 +68,6 @@ function render_block_core_footnotes( $attributes, $content, $block ) {
* @since 6.3.0
*/
function register_block_core_footnotes() {
$post_types = get_post_types(
array(
'show_in_rest' => true,
'public' => true,
)
);
foreach ( $post_types as $post_type ) {
// Only register the meta field if the post type supports the editor, custom fields, and revisions.
if ( post_type_supports( $post_type, 'editor' ) && post_type_supports( $post_type, 'custom-fields' ) && post_type_supports( $post_type, 'revisions' ) ) {
register_post_meta(
$post_type,
'footnotes',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'revisions_enabled' => true,
)
);
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will cause the tests to fail but is required for testing wp_register_footnotes_meta_field works as expected.

register_block_type_from_metadata(
__DIR__ . '/footnotes',
array(
Expand Down
17 changes: 17 additions & 0 deletions src/wp-includes/class-wp-post-type.php
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,23 @@ public function set_props( $args ) {
*/
public function add_supports() {
if ( ! empty( $this->supports ) ) {
/*
* Move footnotes last.
*
* Footnotes are a special case and require other features to be supported:
* 'editor', 'revisions' and 'custom-fields'. This moves the footnotes to
* be added last so that the other features are already added before the
* check in `add_post_type_support` is made.
*/
if ( isset( $this->supports['footnotes'] ) ) {
$footnotes = $this->supports['footnotes'];
unset( $this->supports['footnotes'] );
$this->supports['footnotes'] = $footnotes;
} elseif ( in_array( 'footnotes', $this->supports, true ) ) {
$index = array_search( 'footnotes', $this->supports, true );
unset( $this->supports[ $index ] );
$this->supports[] = 'footnotes';
}
Comment on lines +665 to +681
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest moving this code to its method and then invoking it here before the loop. What's going on here as a very specific purpose beyond but in support of add_supports(). It's like the prep work for before adding the supports.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That said, +1 for the approach.

foreach ( $this->supports as $feature => $args ) {
if ( is_array( $args ) ) {
add_post_type_support( $this->name, $feature, $args );
Expand Down
2 changes: 2 additions & 0 deletions src/wp-includes/default-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,8 @@

// CPT wp_block custom postmeta field.
add_action( 'init', 'wp_create_initial_post_meta' );
// Registers the footnotes meta field for post types that support it.
add_action( 'init', 'wp_register_footnotes_meta_field', 100 );

// Include revisioned meta when considering whether a post revision has changed.
add_filter( 'wp_save_post_revision_post_has_changed', 'wp_check_revisioned_meta_fields_have_changed', 10, 3 );
Expand Down
81 changes: 79 additions & 2 deletions src/wp-includes/post.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function create_initial_post_types() {
'rewrite' => false,
'query_var' => false,
'delete_with_user' => true,
'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'post-formats' ),
'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'post-formats', 'footnotes' ),
'show_in_rest' => true,
'rest_base' => 'posts',
'rest_controller_class' => 'WP_REST_Posts_Controller',
Expand All @@ -62,7 +62,7 @@ function create_initial_post_types() {
'rewrite' => false,
'query_var' => false,
'delete_with_user' => true,
'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'comments', 'revisions' ),
'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'comments', 'revisions', 'footnotes' ),
'show_in_rest' => true,
'rest_base' => 'pages',
'rest_controller_class' => 'WP_REST_Posts_Controller',
Expand Down Expand Up @@ -2215,13 +2215,36 @@ function add_post_type_support( $post_type, $feature, ...$args ) {
global $_wp_post_type_features;

$features = (array) $feature;
if ( in_array( 'footnotes', $features, true ) ) {
$index = array_search( 'footnotes', $features, true );
unset( $features[ $index ] );
$features[] = 'footnotes';
}
Comment on lines +2218 to +2222
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this code will run 2x, as it's also being done in WP_Post_Type::add_supports() which first moves it to last and then invokes add_post_type_support(). Wondering if it can be combined to do this only once.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking more about this ...

How about moving the "move to last" code in WP_Post_Type::add_supports() to here?

What might the impact be within WP_Post_Type's usage of its supports property? Hmm


foreach ( $features as $feature ) {
if ( $args ) {
$_wp_post_type_features[ $post_type ][ $feature ] = $args;
} else {
$_wp_post_type_features[ $post_type ][ $feature ] = true;
}
}

/*
* Special case for footnotes.
*
* If footnotes are supported, the post type must also support `editor`, `revisions` and `custom-fields`.
*/
if ( in_array( 'footnotes', $features, true ) ) {
if (
! isset(
$_wp_post_type_features[ $post_type ]['editor'],
$_wp_post_type_features[ $post_type ]['revisions'],
$_wp_post_type_features[ $post_type ]['custom-fields']
)
) {
unset( $_wp_post_type_features[ $post_type ]['footnotes'] );
}
}
}

/**
Expand All @@ -2237,6 +2260,11 @@ function add_post_type_support( $post_type, $feature, ...$args ) {
function remove_post_type_support( $post_type, $feature ) {
global $_wp_post_type_features;

if ( in_array( $feature, array( 'editor', 'revisions', 'custom-fields' ), true ) ) {
// Also remove footnotes support if any of the required features are removed.
unset( $_wp_post_type_features[ $post_type ]['footnotes'] );
}

unset( $_wp_post_type_features[ $post_type ][ $feature ] );
}

Expand Down Expand Up @@ -2274,6 +2302,22 @@ function get_all_post_type_supports( $post_type ) {
function post_type_supports( $post_type, $feature ) {
global $_wp_post_type_features;

if ( 'footnotes' === $feature ) {
/*
* Footnotes require additional items to be supported.
*
* The post type must also support `editor`, `revisions` and `custom-fields`.
*/
$required_features = array( 'footnotes', 'editor', 'revisions', 'custom-fields' );
foreach ( $required_features as $required_feature ) {
if ( ! isset( $_wp_post_type_features[ $post_type ][ $required_feature ] ) ) {
return false;
}
}

return true;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the snowflake code in add|remove_post_type_support this block may no be needed. It accounts for developers modifying $_wp_post_type_features directly but it may be possible to consider doing so out of warranty.

If it's decided to keep this then similar code will probably be needed in get_all_post_type_supports() and get_post_types_by_support().

return ( isset( $_wp_post_type_features[ $post_type ][ $feature ] ) );
}

Expand Down Expand Up @@ -8208,3 +8252,36 @@ function wp_create_initial_post_meta() {
)
);
}

/**
* Registers the footnotes meta field for post types that support it.
*
* @since 6.5.0
*
* @link https://github.com/WordPress/gutenberg/pull/57353
*/
function wp_register_footnotes_meta_field() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this use get_post_types_by_support()?

$post_types = get_post_types( array( 'show_in_rest' => true ) );
$post_types = array_filter( $post_types, 'is_post_type_viewable' );
foreach ( $post_types as $post_type ) {
if ( ! post_type_supports( $post_type, 'footnotes' ) ) {
// Post type does not support footnotes, continue.
continue;
}
$post_type_meta_keys = get_registered_meta_keys( 'post', $post_type );
if ( isset( $post_type_meta_keys['footnotes'] ) ) {
// Footnotes meta key is already registered, continue.
continue;
}
register_post_meta(
$post_type,
'footnotes',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'revisions_enabled' => true,
)
);
}
}