diff --git a/lib/experimental/class-gutenberg-rest-template-revision-count.php b/lib/experimental/class-gutenberg-rest-template-revision-count.php new file mode 100644 index 0000000000000..82bedd6e0c8ff --- /dev/null +++ b/lib/experimental/class-gutenberg-rest-template-revision-count.php @@ -0,0 +1,75 @@ +get_fields_for_response( $request ); + + $response = parent::prepare_item_for_response( $item, $request ); + + if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { + $links = $this->prepare_revision_links( $template ); + $response->add_links( $links ); + if ( ! empty( $links['self']['href'] ) ) { + $actions = $this->get_available_actions(); + $self = $links['self']['href']; + foreach ( $actions as $rel ) { + $response->add_link( $rel, $self ); + } + } + } + + return $response; + } + + /** + * Adds revisions to links. + * + * @since 6.2.0 + * + * @param WP_Block_Template $template Template instance. + * @return array Links for the given post. + */ + protected function prepare_revision_links( $template ) { + $links = array(); + + if ( post_type_supports( $this->post_type, 'revisions' ) && (int) $template->wp_id ) { + $revisions = wp_get_latest_revision_id_and_total_count( (int) $template->wp_id ); + $revisions_count = ! is_wp_error( $revisions ) ? $revisions['count'] : 0; + $revisions_base = sprintf( '/%s/%s/%s/revisions', $this->namespace, $this->rest_base, $template->id ); + + $links['version-history'] = array( + 'href' => rest_url( $revisions_base ), + 'count' => $revisions_count, + ); + + if ( $revisions_count > 0 ) { + $links['predecessor-version'] = array( + 'href' => rest_url( $revisions_base . '/' . $revisions['latest_id'] ), + 'id' => $revisions['latest_id'], + ); + } + } + + return $links; + } +} diff --git a/lib/experimental/rest-api.php b/lib/experimental/rest-api.php index 8ab4b1ad509fe..31a96b6572f26 100644 --- a/lib/experimental/rest-api.php +++ b/lib/experimental/rest-api.php @@ -28,6 +28,28 @@ function gutenberg_register_block_editor_settings() { } add_action( 'rest_api_init', 'gutenberg_register_block_editor_settings' ); + +/** + * Hook in to the template and template part post types and decorate + * the rest endpoint with the revision count. + * + * When merging to core, this can be removed once Gutenberg_REST_Template_Revision_Count is + * merged with WP_REST_Template_Controller. + * + * @param array $args Current registered post type args. + * @param string $post_type Name of post type. + * + * @return array + */ +function wp_api_template_revision_args( $args, $post_type ) { + if ( 'wp_template' === $post_type || 'wp_template_part' === $post_type ) { + $args['rest_controller_class'] = 'Gutenberg_REST_Template_Revision_Count'; + } + + return $args; +} +add_filter( 'register_post_type_args', 'wp_api_template_revision_args', 10, 2 ); + /** * Shim for get_sample_permalink() to add support for auto-draft status. * diff --git a/lib/load.php b/lib/load.php index 91c52c4bf649a..fd8a7b9057753 100644 --- a/lib/load.php +++ b/lib/load.php @@ -56,6 +56,8 @@ function gutenberg_is_experiment_enabled( $name ) { if ( ! class_exists( 'WP_Rest_Customizer_Nonces' ) ) { require_once __DIR__ . '/experimental/class-wp-rest-customizer-nonces.php'; } + require_once __DIR__ . '/experimental/class-gutenberg-rest-template-revision-count.php'; + require_once __DIR__ . '/experimental/rest-api.php'; } diff --git a/packages/edit-site/src/components/sidebar-edit-mode/template-card/index.js b/packages/edit-site/src/components/sidebar-edit-mode/template-card/index.js index 96333e3ab01f2..da03a769b306c 100644 --- a/packages/edit-site/src/components/sidebar-edit-mode/template-card/index.js +++ b/packages/edit-site/src/components/sidebar-edit-mode/template-card/index.js @@ -1,8 +1,9 @@ /** * WordPress dependencies */ +import { __ } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; -import { Icon } from '@wordpress/components'; +import { PanelRow, Icon } from '@wordpress/components'; import { store as editorStore } from '@wordpress/editor'; import { store as coreStore } from '@wordpress/core-data'; import { decodeEntities } from '@wordpress/html-entities'; @@ -13,6 +14,7 @@ import { decodeEntities } from '@wordpress/html-entities'; import { store as editSiteStore } from '../../../store'; import TemplateActions from './template-actions'; import TemplateAreas from './template-areas'; +import LastRevision from './last-revision'; export default function TemplateCard() { const { @@ -38,20 +40,28 @@ export default function TemplateCard() { } return ( -
- -
-
-

- { decodeEntities( title ) } -

- + <> +
+ +
+
+

+ { decodeEntities( title ) } +

+ +
+
+ { decodeEntities( description ) } +
+
-
- { decodeEntities( description ) } -
-
-
+ + + + ); } diff --git a/packages/edit-site/src/components/sidebar-edit-mode/template-card/last-revision.js b/packages/edit-site/src/components/sidebar-edit-mode/template-card/last-revision.js new file mode 100644 index 0000000000000..3782dccfb7e28 --- /dev/null +++ b/packages/edit-site/src/components/sidebar-edit-mode/template-card/last-revision.js @@ -0,0 +1,75 @@ +/** + * WordPress dependencies + */ +import { Button } from '@wordpress/components'; +import { sprintf, _n } from '@wordpress/i18n'; +import { backup } from '@wordpress/icons'; +import { addQueryArgs } from '@wordpress/url'; +import { PostTypeSupportCheck } from '@wordpress/editor'; + +/** + * Internal dependencies + */ +import useEditedEntityRecord from '../../use-edited-entity-record'; + +const useRevisionData = () => { + const { record: currentTemplate } = useEditedEntityRecord(); + + const lastRevisionId = + currentTemplate?._links?.[ 'predecessor-version' ]?.[ 0 ]?.id ?? null; + + const revisionsCount = + ( currentTemplate?._links?.[ 'version-history' ]?.[ 0 ]?.count ?? 0 ) + + 1; + + return { + currentTemplate, + lastRevisionId, + revisionsCount, + }; +}; + +function PostLastRevisionCheck( { children } ) { + const { lastRevisionId, revisionsCount } = useRevisionData(); + + if ( ! lastRevisionId || revisionsCount < 2 ) { + return null; + } + + return ( + + { children } + + ); +} + +const PostLastRevision = () => { + const { lastRevisionId, revisionsCount } = useRevisionData(); + + return ( + + + + ); +}; + +export default function LastRevision() { + return ( + + + + ); +} diff --git a/packages/edit-site/src/components/sidebar-edit-mode/template-card/style.scss b/packages/edit-site/src/components/sidebar-edit-mode/template-card/style.scss index b02717793bb9b..67054c25d2476 100644 --- a/packages/edit-site/src/components/sidebar-edit-mode/template-card/style.scss +++ b/packages/edit-site/src/components/sidebar-edit-mode/template-card/style.scss @@ -59,6 +59,10 @@ } } +.edit-site-template-revisions { + margin-left: math.div(-$grid-unit-10, 2); +} + h3.edit-site-template-card__template-areas-title { font-weight: 500; margin: 0 0 $grid-unit-10;