Skip to content

Commit

Permalink
prep build 02/07
Browse files Browse the repository at this point in the history
  • Loading branch information
bph committed Feb 7, 2024
2 parents feb094d + c8ddc57 commit 1295b3c
Show file tree
Hide file tree
Showing 95 changed files with 2,816 additions and 3,239 deletions.
16 changes: 16 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
== Changelog ==

= 17.6.3 =

## Changelog

### Bug Fixes

#### Block Editor
- Navigation: Update the fallback block list to avoid a PHP Warning ([58588](https://github.com/WordPress/gutenberg/pull/58588))

## Contributors

The following contributors merged PRs in this release:

@dd32


= 17.6.2 =


Expand Down
53 changes: 29 additions & 24 deletions docs/getting-started/fundamentals/markup-representation-block.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,51 @@
# Markup representation of a block

When stored in the database or in templates as HTML files, blocks are represented using a [specific HTML grammar](https://developer.wordpress.org/block-editor/explanations/architecture/key-concepts/#data-and-attributes), which is technically valid HTML based on HTML comments that act as explicit block delimiters
Blocks are stored in the database or within HTML templates using a unique [HTML-based syntax](https://developer.wordpress.org/block-editor/explanations/architecture/key-concepts/#data-and-attributes), distinguished by HTML comments that serve as clear block delimiters. This ensures that block markup is technically valid HTML.

These are some of the rules for the markup used to represent a block:
Here are a few guidelines for the markup that defines a block:

- All core block comments start with a prefix and the block name: `wp:blockname`
- For custom blocks, `blockname` is `namespace/blockname`
- Core blocks begin with the `wp:` prefix, followed by the block name (e.g., `wp:image`). Notably, the `core` namespace is omitted.
- Custom blocks begin with the `wp:` prefix, followed by the block namespace and name (e.g., `wp:namespace/name`).
- The comment can be a single line, self-closing, or wrapper for HTML content.
- Custom block settings and attributes are stored as a JSON object inside the block comment.
- Block settings and attributes are stored as a JSON object inside the block comment.

_Example: Markup representation of an `image` core block_
The following is the simplified markup representation of an Image block:

```
<!-- wp:image -->
<figure class="wp-block-image"><img src="source.jpg" alt="" /></figure>
```html
<!-- wp:image {"sizeSlug":"large"} -->
<figure class="wp-block-image size-large">
<img src="source.jpg" alt="" />
</figure>
<!-- /wp:image -->
```

The [markup representation of a block is parsed for the Block Editor](https://developer.wordpress.org/block-editor/explanations/architecture/data-flow/) and the block's output for the front end:

- In the editor, WordPress parses this block markup, captures its data and loads its `edit` version
- In the front end, WordPress parses this block markup, captures its data and generates its final HTML markup

Whenever a block is saved, the `save` function, defined when the [block is registered in the client](https://developer.wordpress.org/block-editor/getting-started/fundamentals/registration-of-a-block/#registration-of-the-block-with-javascript-client-side), is called to return the markup that will be saved into the database within the block delimiter's comment. If `save` is `null` (common case for blocks with dynamic rendering), only a single line block delimiter's comment is stored, along with any attributes
The markup for a block is crucial both in the Block Editor and for displaying the block on the front end:

The Post Editor checks that the markup created by the `save` function is identical to the block's markup saved to the database:
- WordPress analyzes the block's markup within the Editor to extract its data and present the editable version to the user.
- On the front end, WordPress again parses the markup to extract data and render the final HTML output.

- If there are any differences, the Post Editor triggers a [block validation error](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#validation).
- Block validation errors usually happen when a block’s `save` function is updated to change the markup produced by the block.
- A block developer can mitigate these issues by adding a [**block deprecation**](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-deprecation/) to register the change in the block.
<div class="callout callout-tip">
Refer to the <a href="https://developer.wordpress.org/block-editor/explanations/architecture/data-flow/">Data Flow</a> article for a more in-depth look at how block data is parsed in WordPress.
</div>

The markup of a **block with dynamic rendering** is expected to change so the markup of these blocks is not saved to the database. What is saved in the database as representation of the block, for blocks with dynamic rendering, is a single line of HTML consisting on just the block delimiter's comment (including block attributes values). That HTML is not subject to the Post Editor’s validation.
When a block is saved, the `save` function—defined when the [block is registered in the client](https://developer.wordpress.org/block-editor/getting-started/fundamentals/registration-of-a-block/#registration-of-the-block-with-javascript-client-side)is executed to generate the markup stored in the database, wrapped in block delimiter comments. For dynamically rendered blocks, which typically set `save` to `null`, only a placeholder comment with block attributes is saved.

_Example: Markup representation of a block with dynamic rendering (`save` = `null`) and attributes_
Here is the markup representation of a dynamically rendered block (`save` = `null`). Notice there is no HTML markup besides the comment.

```html
<!-- wp:latest-posts {"postsToShow":4,"displayPostDate":true} /-->
```

## Additional Resources
When a block has a `save` function, the Block Editor checks that the markup created by the `save` function is identical to the block's markup saved to the database:

- Discrepancies will trigger a [validation error](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#validation), often due to changes in the `save` function's output.
- Developers can address potential validation issues by implementing [block deprecations](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-deprecation/) to account for changes.

As the example above shows, the stored markup is minimal for dynamically rendered blocks. Generally, this is just a delimiter comment containing block attributes, which is not subject to the Block Editor's validation. This approach reflects the dynamic nature of these blocks, where the actual HTML is generated server-side and is not stored in the database.

## Additional resources

- [Data Flow and Data Format](https://developer.wordpress.org/block-editor/explanations/architecture/data-flow/)
- [Static vs. dynamic blocks: What’s the difference?](https://developer.wordpress.org/news/2023/02/27/static-vs-dynamic-blocks-whats-the-difference/)
- [Block deprecation – a tutorial](https://developer.wordpress.org/news/2023/03/10/block-deprecation-a-tutorial/)
- [Static vs. dynamic blocks: What’s the difference?](https://developer.wordpress.org/news/2023/02/27/static-vs-dynamic-blocks-whats-the-difference/) | Developer Blog
- [Block deprecation – a tutorial](https://developer.wordpress.org/news/2023/03/10/block-deprecation-a-tutorial/) | Developer Blog
- [Introduction to Templates > Block markup](https://developer.wordpress.org/themes/templates/introduction-to-templates/#block-markup) | Theme Handbook
5 changes: 2 additions & 3 deletions lib/compat/wordpress-6.5/fonts/class-wp-font-library.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,13 @@ public function get_font_collections() {
* @since 6.5.0
*
* @param string $slug Font collection slug.
* @return WP_Font_Collection|WP_Error Font collection object,
* or WP_Error object if the font collection doesn't exist.
* @return WP_Font_Collection|null Font collection object, or null if the font collection doesn't exist.
*/
public function get_font_collection( $slug ) {
if ( $this->is_collection_registered( $slug ) ) {
return $this->collections[ $slug ];
}
return new WP_Error( 'font_collection_not_found', __( 'Font collection not found.', 'gutenberg' ) );
return null;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,9 @@ public function get_item( $request ) {
$slug = $request->get_param( 'slug' );
$collection = WP_Font_Library::get_instance()->get_font_collection( $slug );

// If the collection doesn't exist returns a 404.
if ( is_wp_error( $collection ) ) {
$collection->add_data( array( 'status' => 404 ) );
return $collection;
// @TODO: remove `is_wp_error` check once WP trunk is updated to return null when a collection is not found.
if ( ! $collection || is_wp_error( $collection ) ) {
return new WP_Error( 'rest_font_collection_not_found', __( 'Font collection not found.' ), array( 'status' => 404 ) );
}

return $this->prepare_item_for_response( $collection, $request );
Expand All @@ -158,38 +157,38 @@ public function get_item( $request ) {
*
* @since 6.5.0
*
* @param WP_Font_Collection $collection Collection object.
* @param WP_REST_Request $request Request object.
* @return WP_REST_Response Response object.
* @param WP_Font_Collection $item Font collection object.
* @param WP_REST_Request $request Request object.
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function prepare_item_for_response( $collection, $request ) {
public function prepare_item_for_response( $item, $request ) {
$fields = $this->get_fields_for_response( $request );
$item = array();
$data = array();

if ( rest_is_field_included( 'slug', $fields ) ) {
$item['slug'] = $collection->slug;
$data['slug'] = $item->slug;
}

// If any data fields are requested, get the collection data.
$data_fields = array( 'name', 'description', 'font_families', 'categories' );
if ( ! empty( array_intersect( $fields, $data_fields ) ) ) {
$collection_data = $collection->get_data();
$collection_data = $item->get_data();
if ( is_wp_error( $collection_data ) ) {
$collection_data->add_data( array( 'status' => 500 ) );
return $collection_data;
}

foreach ( $data_fields as $field ) {
if ( rest_is_field_included( $field, $fields ) ) {
$item[ $field ] = $collection_data[ $field ];
$data[ $field ] = $collection_data[ $field ];
}
}
}

$response = rest_ensure_response( $item );
$response = rest_ensure_response( $data );

if ( rest_is_field_included( '_links', $fields ) ) {
$links = $this->prepare_links( $collection );
$links = $this->prepare_links( $item );
$response->add_links( $links );
}

Expand All @@ -198,17 +197,15 @@ public function prepare_item_for_response( $collection, $request ) {
$response->data = $this->filter_response_by_context( $response->data, $context );

/**
* Filters a font collection returned from the REST API.
*
* Allows modification of the font collection right before it is returned.
* Filters the font collection data for a REST API response.
*
* @since 6.5.0
*
* @param WP_REST_Response $response The response object.
* @param WP_Font_Collection $collection The Font Collection object.
* @param WP_REST_Request $request Request used to generate the response.
* @param WP_REST_Response $response The response object.
* @param WP_Font_Collection $item The font collection object.
* @param WP_REST_Request $request Request used to generate the response.
*/
return apply_filters( 'rest_prepare_font_collection', $response, $collection, $request );
return apply_filters( 'rest_prepare_font_collection', $response, $item, $request );
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@
* Class to access font faces through the REST API.
*/
class WP_REST_Font_Faces_Controller extends WP_REST_Posts_Controller {

/**
* The latest version of theme.json schema supported by the controller.
*
* @since 6.5.0
* @var int
*/
const LATEST_THEME_JSON_VERSION_SUPPORTED = 2;

/**
* Whether the controller supports batching.
*
Expand Down Expand Up @@ -233,9 +242,8 @@ public function validate_create_font_face_settings( $value, $request ) {
*
* @since 6.5.0
*
* @param string $value Encoded JSON string of font face settings.
* @param WP_REST_Request $request Request object.
* @return array Decoded array of font face settings.
* @param string $value Encoded JSON string of font face settings.
* @return array Decoded and sanitized array of font face settings.
*/
public function sanitize_font_face_settings( $value ) {
// Settings arrive as stringified JSON, since this is a multipart/form-data request.
Expand Down Expand Up @@ -328,7 +336,7 @@ public function create_item( $request ) {
'update_post_term_cache' => false,
)
);
if ( ! empty( $query->get_posts() ) ) {
if ( ! empty( $query->posts ) ) {
return new WP_Error(
'rest_duplicate_font_face',
__( 'A font face matching those settings already exists.', 'gutenberg' ),
Expand Down Expand Up @@ -418,7 +426,7 @@ public function delete_item( $request ) {
return new WP_Error(
'rest_trash_not_supported',
/* translators: %s: force=true */
sprintf( __( "Font faces do not support trashing. Set '%s' to delete.", 'gutenberg' ), 'force=true' ),
sprintf( __( 'Font faces do not support trashing. Set "%s" to delete.', 'gutenberg' ), 'force=true' ),
array( 'status' => 501 )
);
}
Expand All @@ -443,7 +451,7 @@ public function prepare_item_for_response( $item, $request ) {
$data['id'] = $item->ID;
}
if ( rest_is_field_included( 'theme_json_version', $fields ) ) {
$data['theme_json_version'] = 2;
$data['theme_json_version'] = static::LATEST_THEME_JSON_VERSION_SUPPORTED;
}

if ( rest_is_field_included( 'parent', $fields ) ) {
Expand Down Expand Up @@ -504,9 +512,9 @@ public function get_item_schema() {
'theme_json_version' => array(
'description' => __( 'Version of the theme.json schema used for the typography settings.', 'gutenberg' ),
'type' => 'integer',
'default' => 2,
'default' => static::LATEST_THEME_JSON_VERSION_SUPPORTED,
'minimum' => 2,
'maximum' => 2,
'maximum' => static::LATEST_THEME_JSON_VERSION_SUPPORTED,
'context' => array( 'view', 'edit', 'embed' ),
),
'parent' => array(
Expand Down Expand Up @@ -699,14 +707,16 @@ public function get_collection_params() {
$query_params = parent::get_collection_params();

// Remove unneeded params.
unset( $query_params['after'] );
unset( $query_params['modified_after'] );
unset( $query_params['before'] );
unset( $query_params['modified_before'] );
unset( $query_params['search'] );
unset( $query_params['search_columns'] );
unset( $query_params['slug'] );
unset( $query_params['status'] );
unset(
$query_params['after'],
$query_params['modified_after'],
$query_params['before'],
$query_params['modified_before'],
$query_params['search'],
$query_params['search_columns'],
$query_params['slug'],
$query_params['status']
);

$query_params['orderby']['default'] = 'id';
$query_params['orderby']['enum'] = array( 'id', 'include' );
Expand Down Expand Up @@ -803,7 +813,7 @@ protected function prepare_links( $post ) {
* @since 6.5.0
*
* @param WP_REST_Request $request Request object.
* @return stdClass|WP_Error Post object or WP_Error.
* @return stdClass Post object.
*/
protected function prepare_item_for_database( $request ) {
$prepared_post = new stdClass();
Expand Down Expand Up @@ -831,7 +841,6 @@ protected function prepare_item_for_database( $request ) {
* @since 6.5.0
*
* @param string $value Font face src that is a URL or the key for a $_FILES array item.
*
* @return string Sanitized value.
*/
protected function sanitize_src( $value ) {
Expand All @@ -845,7 +854,7 @@ protected function sanitize_src( $value ) {
* @since 6.5.0
*
* @param array $file Single file item from $_FILES.
* @return array Array containing uploaded file attributes on success, or error on failure.
* @return array|WP_Error Array containing uploaded file attributes on success, or WP_Error object on failure.
*/
protected function handle_font_file_upload( $file ) {
add_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) );
Expand Down
Loading

0 comments on commit 1295b3c

Please sign in to comment.