[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/ -> blocks.php (source)

   1  <?php
   2  /**
   3   * Functions related to registering and parsing blocks.
   4   *
   5   * @package WordPress
   6   * @subpackage Blocks
   7   * @since 5.0.0
   8   */
   9  
  10  /**
  11   * Registers a block type.
  12   *
  13   * @since 5.0.0
  14   *
  15   * @param string|WP_Block_Type $name Block type name including namespace, or alternatively
  16   *                                   a complete WP_Block_Type instance. In case a WP_Block_Type
  17   *                                   is provided, the $args parameter will be ignored.
  18   * @param array                $args {
  19   *     Optional. Array of block type arguments. Accepts any public property of `WP_Block_Type`.
  20   *     Any arguments may be defined, however the ones described below are supported by default.
  21   *     Default empty array.
  22   *
  23   *     @type callable $render_callback Callback used to render blocks of this block type.
  24   * }
  25   * @return WP_Block_Type|false The registered block type on success, or false on failure.
  26   */
  27  function register_block_type( $name, $args = array() ) {
  28      return WP_Block_Type_Registry::get_instance()->register( $name, $args );
  29  }
  30  
  31  /**
  32   * Unregisters a block type.
  33   *
  34   * @since 5.0.0
  35   *
  36   * @param string|WP_Block_Type $name Block type name including namespace, or alternatively
  37   *                                   a complete WP_Block_Type instance.
  38   * @return WP_Block_Type|false The unregistered block type on success, or false on failure.
  39   */
  40  function unregister_block_type( $name ) {
  41      return WP_Block_Type_Registry::get_instance()->unregister( $name );
  42  }
  43  
  44  /**
  45   * Removes the block asset's path prefix if provided.
  46   *
  47   * @since 5.5.0
  48   *
  49   * @param string $asset_handle_or_path Asset handle or prefixed path.
  50   * @return string Path without the prefix or the original value.
  51   */
  52  function remove_block_asset_path_prefix( $asset_handle_or_path ) {
  53      $path_prefix = 'file:';
  54      if ( 0 !== strpos( $asset_handle_or_path, $path_prefix ) ) {
  55          return $asset_handle_or_path;
  56      }
  57      return substr(
  58          $asset_handle_or_path,
  59          strlen( $path_prefix )
  60      );
  61  }
  62  
  63  /**
  64   * Generates the name for an asset based on the name of the block
  65   * and the field name provided.
  66   *
  67   * @since 5.5.0
  68   *
  69   * @param string $block_name Name of the block.
  70   * @param string $field_name Name of the metadata field.
  71   * @return string Generated asset name for the block's field.
  72   */
  73  function generate_block_asset_handle( $block_name, $field_name ) {
  74      $field_mappings = array(
  75          'editorScript' => 'editor-script',
  76          'script'       => 'script',
  77          'editorStyle'  => 'editor-style',
  78          'style'        => 'style',
  79      );
  80      return str_replace( '/', '-', $block_name ) .
  81          '-' . $field_mappings[ $field_name ];
  82  }
  83  
  84  /**
  85   * Finds a script handle for the selected block metadata field. It detects
  86   * when a path to file was provided and finds a corresponding asset file
  87   * with details necessary to register the script under automatically
  88   * generated handle name. It returns unprocessed script handle otherwise.
  89   *
  90   * @since 5.5.0
  91   *
  92   * @param array  $metadata   Block metadata.
  93   * @param string $field_name Field name to pick from metadata.
  94   * @return string|bool Script handle provided directly or created through
  95   *                     script's registration, or false on failure.
  96   */
  97  function register_block_script_handle( $metadata, $field_name ) {
  98      if ( empty( $metadata[ $field_name ] ) ) {
  99          return false;
 100      }
 101      $script_handle = $metadata[ $field_name ];
 102      $script_path   = remove_block_asset_path_prefix( $metadata[ $field_name ] );
 103      if ( $script_handle === $script_path ) {
 104          return $script_handle;
 105      }
 106  
 107      $script_handle     = generate_block_asset_handle( $metadata['name'], $field_name );
 108      $script_asset_path = realpath(
 109          dirname( $metadata['file'] ) . '/' .
 110          substr_replace( $script_path, '.asset.php', - strlen( '.js' ) )
 111      );
 112      if ( ! file_exists( $script_asset_path ) ) {
 113          $message = sprintf(
 114              /* translators: %1: field name. %2: block name */
 115              __( 'The asset file for the "%1$s" defined in "%2$s" block definition is missing.', 'default' ),
 116              $field_name,
 117              $metadata['name']
 118          );
 119          _doing_it_wrong( __FUNCTION__, $message, '5.5.0' );
 120          return false;
 121      }
 122      $script_asset = require $script_asset_path;
 123      $result       = wp_register_script(
 124          $script_handle,
 125          plugins_url( $script_path, $metadata['file'] ),
 126          $script_asset['dependencies'],
 127          $script_asset['version']
 128      );
 129      return $result ? $script_handle : false;
 130  }
 131  
 132  /**
 133   * Finds a style handle for the block metadata field. It detects when a path
 134   * to file was provided and registers the style under automatically
 135   * generated handle name. It returns unprocessed style handle otherwise.
 136   *
 137   * @since 5.5.0
 138   *
 139   * @param array  $metadata Block metadata.
 140   * @param string $field_name Field name to pick from metadata.
 141   * @return string|boolean Style handle provided directly or created through
 142   *                        style's registration, or false on failure.
 143   */
 144  function register_block_style_handle( $metadata, $field_name ) {
 145      if ( empty( $metadata[ $field_name ] ) ) {
 146          return false;
 147      }
 148      $style_handle = $metadata[ $field_name ];
 149      $style_path   = remove_block_asset_path_prefix( $metadata[ $field_name ] );
 150      if ( $style_handle === $style_path ) {
 151          return $style_handle;
 152      }
 153  
 154      $style_handle = generate_block_asset_handle( $metadata['name'], $field_name );
 155      $block_dir    = dirname( $metadata['file'] );
 156      $result       = wp_register_style(
 157          $style_handle,
 158          plugins_url( $style_path, $metadata['file'] ),
 159          array(),
 160          filemtime( realpath( "$block_dir/$style_path" ) )
 161      );
 162      return $result ? $style_handle : false;
 163  }
 164  
 165  /**
 166   * Registers a block type from metadata stored in the `block.json` file.
 167   *
 168   * @since 5.5.0
 169   *
 170   * @param string $file_or_folder Path to the JSON file with metadata definition for
 171   *                               the block or path to the folder where the `block.json` file is located.
 172   * @param array  $args {
 173   *     Optional. Array of block type arguments. Accepts any public property of `WP_Block_Type`.
 174   *     Any arguments may be defined, however the ones described below are supported by default.
 175   *     Default empty array.
 176   *
 177   *     @type callable $render_callback Callback used to render blocks of this block type.
 178   * }
 179   * @return WP_Block_Type|false The registered block type on success, or false on failure.
 180   */
 181  function register_block_type_from_metadata( $file_or_folder, $args = array() ) {
 182      $filename      = 'block.json';
 183      $metadata_file = ( substr( $file_or_folder, -strlen( $filename ) ) !== $filename ) ?
 184          trailingslashit( $file_or_folder ) . $filename :
 185          $file_or_folder;
 186      if ( ! file_exists( $metadata_file ) ) {
 187          return false;
 188      }
 189  
 190      $metadata = json_decode( file_get_contents( $metadata_file ), true );
 191      if ( ! is_array( $metadata ) || empty( $metadata['name'] ) ) {
 192          return false;
 193      }
 194      $metadata['file'] = $metadata_file;
 195  
 196      $settings          = array();
 197      $property_mappings = array(
 198          'title'           => 'title',
 199          'category'        => 'category',
 200          'parent'          => 'parent',
 201          'icon'            => 'icon',
 202          'description'     => 'description',
 203          'keywords'        => 'keywords',
 204          'attributes'      => 'attributes',
 205          'providesContext' => 'provides_context',
 206          'usesContext'     => 'uses_context',
 207          'supports'        => 'supports',
 208          'styles'          => 'styles',
 209          'example'         => 'example',
 210          'apiVersion'      => 'api_version',
 211      );
 212  
 213      foreach ( $property_mappings as $key => $mapped_key ) {
 214          if ( isset( $metadata[ $key ] ) ) {
 215              $settings[ $mapped_key ] = $metadata[ $key ];
 216          }
 217      }
 218  
 219      if ( ! empty( $metadata['editorScript'] ) ) {
 220          $settings['editor_script'] = register_block_script_handle(
 221              $metadata,
 222              'editorScript'
 223          );
 224      }
 225  
 226      if ( ! empty( $metadata['script'] ) ) {
 227          $settings['script'] = register_block_script_handle(
 228              $metadata,
 229              'script'
 230          );
 231      }
 232  
 233      if ( ! empty( $metadata['editorStyle'] ) ) {
 234          $settings['editor_style'] = register_block_style_handle(
 235              $metadata,
 236              'editorStyle'
 237          );
 238      }
 239  
 240      if ( ! empty( $metadata['style'] ) ) {
 241          $settings['style'] = register_block_style_handle(
 242              $metadata,
 243              'style'
 244          );
 245      }
 246  
 247      return register_block_type(
 248          $metadata['name'],
 249          array_merge(
 250              $settings,
 251              $args
 252          )
 253      );
 254  }
 255  
 256  /**
 257   * Determine whether a post or content string has blocks.
 258   *
 259   * This test optimizes for performance rather than strict accuracy, detecting
 260   * the pattern of a block but not validating its structure. For strict accuracy,
 261   * you should use the block parser on post content.
 262   *
 263   * @since 5.0.0
 264   *
 265   * @see parse_blocks()
 266   *
 267   * @param int|string|WP_Post|null $post Optional. Post content, post ID, or post object. Defaults to global $post.
 268   * @return bool Whether the post has blocks.
 269   */
 270  function has_blocks( $post = null ) {
 271      if ( ! is_string( $post ) ) {
 272          $wp_post = get_post( $post );
 273          if ( $wp_post instanceof WP_Post ) {
 274              $post = $wp_post->post_content;
 275          }
 276      }
 277  
 278      return false !== strpos( (string) $post, '<!-- wp:' );
 279  }
 280  
 281  /**
 282   * Determine whether a $post or a string contains a specific block type.
 283   *
 284   * This test optimizes for performance rather than strict accuracy, detecting
 285   * the block type exists but not validating its structure. For strict accuracy,
 286   * you should use the block parser on post content.
 287   *
 288   * @since 5.0.0
 289   *
 290   * @see parse_blocks()
 291   *
 292   * @param string                  $block_name Full Block type to look for.
 293   * @param int|string|WP_Post|null $post Optional. Post content, post ID, or post object. Defaults to global $post.
 294   * @return bool Whether the post content contains the specified block.
 295   */
 296  function has_block( $block_name, $post = null ) {
 297      if ( ! has_blocks( $post ) ) {
 298          return false;
 299      }
 300  
 301      if ( ! is_string( $post ) ) {
 302          $wp_post = get_post( $post );
 303          if ( $wp_post instanceof WP_Post ) {
 304              $post = $wp_post->post_content;
 305          }
 306      }
 307  
 308      /*
 309       * Normalize block name to include namespace, if provided as non-namespaced.
 310       * This matches behavior for WordPress 5.0.0 - 5.3.0 in matching blocks by
 311       * their serialized names.
 312       */
 313      if ( false === strpos( $block_name, '/' ) ) {
 314          $block_name = 'core/' . $block_name;
 315      }
 316  
 317      // Test for existence of block by its fully qualified name.
 318      $has_block = false !== strpos( $post, '<!-- wp:' . $block_name . ' ' );
 319  
 320      if ( ! $has_block ) {
 321          /*
 322           * If the given block name would serialize to a different name, test for
 323           * existence by the serialized form.
 324           */
 325          $serialized_block_name = strip_core_block_namespace( $block_name );
 326          if ( $serialized_block_name !== $block_name ) {
 327              $has_block = false !== strpos( $post, '<!-- wp:' . $serialized_block_name . ' ' );
 328          }
 329      }
 330  
 331      return $has_block;
 332  }
 333  
 334  /**
 335   * Returns an array of the names of all registered dynamic block types.
 336   *
 337   * @since 5.0.0
 338   *
 339   * @return string[] Array of dynamic block names.
 340   */
 341  function get_dynamic_block_names() {
 342      $dynamic_block_names = array();
 343  
 344      $block_types = WP_Block_Type_Registry::get_instance()->get_all_registered();
 345      foreach ( $block_types as $block_type ) {
 346          if ( $block_type->is_dynamic() ) {
 347              $dynamic_block_names[] = $block_type->name;
 348          }
 349      }
 350  
 351      return $dynamic_block_names;
 352  }
 353  
 354  /**
 355   * Given an array of attributes, returns a string in the serialized attributes
 356   * format prepared for post content.
 357   *
 358   * The serialized result is a JSON-encoded string, with unicode escape sequence
 359   * substitution for characters which might otherwise interfere with embedding
 360   * the result in an HTML comment.
 361   *
 362   * @since 5.3.1
 363   *
 364   * @param array $block_attributes Attributes object.
 365   * @return string Serialized attributes.
 366   */
 367  function serialize_block_attributes( $block_attributes ) {
 368      $encoded_attributes = json_encode( $block_attributes );
 369      $encoded_attributes = preg_replace( '/--/', '\\u002d\\u002d', $encoded_attributes );
 370      $encoded_attributes = preg_replace( '/</', '\\u003c', $encoded_attributes );
 371      $encoded_attributes = preg_replace( '/>/', '\\u003e', $encoded_attributes );
 372      $encoded_attributes = preg_replace( '/&/', '\\u0026', $encoded_attributes );
 373      // Regex: /\\"/
 374      $encoded_attributes = preg_replace( '/\\\\"/', '\\u0022', $encoded_attributes );
 375  
 376      return $encoded_attributes;
 377  }
 378  
 379  /**
 380   * Returns the block name to use for serialization. This will remove the default
 381   * "core/" namespace from a block name.
 382   *
 383   * @since 5.3.1
 384   *
 385   * @param string $block_name Original block name.
 386   * @return string Block name to use for serialization.
 387   */
 388  function strip_core_block_namespace( $block_name = null ) {
 389      if ( is_string( $block_name ) && 0 === strpos( $block_name, 'core/' ) ) {
 390          return substr( $block_name, 5 );
 391      }
 392  
 393      return $block_name;
 394  }
 395  
 396  /**
 397   * Returns the content of a block, including comment delimiters.
 398   *
 399   * @since 5.3.1
 400   *
 401   * @param string|null $block_name       Block name. Null if the block name is unknown,
 402   *                                      e.g. Classic blocks have their name set to null.
 403   * @param array       $block_attributes Block attributes.
 404   * @param string      $block_content    Block save content.
 405   * @return string Comment-delimited block content.
 406   */
 407  function get_comment_delimited_block_content( $block_name, $block_attributes, $block_content ) {
 408      if ( is_null( $block_name ) ) {
 409          return $block_content;
 410      }
 411  
 412      $serialized_block_name = strip_core_block_namespace( $block_name );
 413      $serialized_attributes = empty( $block_attributes ) ? '' : serialize_block_attributes( $block_attributes ) . ' ';
 414  
 415      if ( empty( $block_content ) ) {
 416          return sprintf( '<!-- wp:%s %s/-->', $serialized_block_name, $serialized_attributes );
 417      }
 418  
 419      return sprintf(
 420          '<!-- wp:%s %s-->%s<!-- /wp:%s -->',
 421          $serialized_block_name,
 422          $serialized_attributes,
 423          $block_content,
 424          $serialized_block_name
 425      );
 426  }
 427  
 428  /**
 429   * Returns the content of a block, including comment delimiters, serializing all
 430   * attributes from the given parsed block.
 431   *
 432   * This should be used when preparing a block to be saved to post content.
 433   * Prefer `render_block` when preparing a block for display. Unlike
 434   * `render_block`, this does not evaluate a block's `render_callback`, and will
 435   * instead preserve the markup as parsed.
 436   *
 437   * @since 5.3.1
 438   *
 439   * @param WP_Block_Parser_Block $block A single parsed block object.
 440   * @return string String of rendered HTML.
 441   */
 442  function serialize_block( $block ) {
 443      $block_content = '';
 444  
 445      $index = 0;
 446      foreach ( $block['innerContent'] as $chunk ) {
 447          $block_content .= is_string( $chunk ) ? $chunk : serialize_block( $block['innerBlocks'][ $index++ ] );
 448      }
 449  
 450      if ( ! is_array( $block['attrs'] ) ) {
 451          $block['attrs'] = array();
 452      }
 453  
 454      return get_comment_delimited_block_content(
 455          $block['blockName'],
 456          $block['attrs'],
 457          $block_content
 458      );
 459  }
 460  
 461  /**
 462   * Returns a joined string of the aggregate serialization of the given parsed
 463   * blocks.
 464   *
 465   * @since 5.3.1
 466   *
 467   * @param WP_Block_Parser_Block[] $blocks Parsed block objects.
 468   * @return string String of rendered HTML.
 469   */
 470  function serialize_blocks( $blocks ) {
 471      return implode( '', array_map( 'serialize_block', $blocks ) );
 472  }
 473  
 474  /**
 475   * Filters and sanitizes block content to remove non-allowable HTML from
 476   * parsed block attribute values.
 477   *
 478   * @since 5.3.1
 479   *
 480   * @param string         $text              Text that may contain block content.
 481   * @param array[]|string $allowed_html      An array of allowed HTML elements
 482   *                                          and attributes, or a context name
 483   *                                          such as 'post'.
 484   * @param string[]       $allowed_protocols Array of allowed URL protocols.
 485   * @return string The filtered and sanitized content result.
 486   */
 487  function filter_block_content( $text, $allowed_html = 'post', $allowed_protocols = array() ) {
 488      $result = '';
 489  
 490      $blocks = parse_blocks( $text );
 491      foreach ( $blocks as $block ) {
 492          $block   = filter_block_kses( $block, $allowed_html, $allowed_protocols );
 493          $result .= serialize_block( $block );
 494      }
 495  
 496      return $result;
 497  }
 498  
 499  /**
 500   * Filters and sanitizes a parsed block to remove non-allowable HTML from block
 501   * attribute values.
 502   *
 503   * @since 5.3.1
 504   *
 505   * @param WP_Block_Parser_Block $block             The parsed block object.
 506   * @param array[]|string        $allowed_html      An array of allowed HTML
 507   *                                                 elements and attributes, or a
 508   *                                                 context name such as 'post'.
 509   * @param string[]              $allowed_protocols Allowed URL protocols.
 510   * @return array The filtered and sanitized block object result.
 511   */
 512  function filter_block_kses( $block, $allowed_html, $allowed_protocols = array() ) {
 513      $block['attrs'] = filter_block_kses_value( $block['attrs'], $allowed_html, $allowed_protocols );
 514  
 515      if ( is_array( $block['innerBlocks'] ) ) {
 516          foreach ( $block['innerBlocks'] as $i => $inner_block ) {
 517              $block['innerBlocks'][ $i ] = filter_block_kses( $inner_block, $allowed_html, $allowed_protocols );
 518          }
 519      }
 520  
 521      return $block;
 522  }
 523  
 524  /**
 525   * Filters and sanitizes a parsed block attribute value to remove non-allowable
 526   * HTML.
 527   *
 528   * @since 5.3.1
 529   *
 530   * @param string[]|string $value             The attribute value to filter.
 531   * @param array[]|string  $allowed_html      An array of allowed HTML elements
 532   *                                           and attributes, or a context name
 533   *                                           such as 'post'.
 534   * @param string[]        $allowed_protocols Array of allowed URL protocols.
 535   * @return string[]|string The filtered and sanitized result.
 536   */
 537  function filter_block_kses_value( $value, $allowed_html, $allowed_protocols = array() ) {
 538      if ( is_array( $value ) ) {
 539          foreach ( $value as $key => $inner_value ) {
 540              $filtered_key   = filter_block_kses_value( $key, $allowed_html, $allowed_protocols );
 541              $filtered_value = filter_block_kses_value( $inner_value, $allowed_html, $allowed_protocols );
 542  
 543              if ( $filtered_key !== $key ) {
 544                  unset( $value[ $key ] );
 545              }
 546  
 547              $value[ $filtered_key ] = $filtered_value;
 548          }
 549      } elseif ( is_string( $value ) ) {
 550          return wp_kses( $value, $allowed_html, $allowed_protocols );
 551      }
 552  
 553      return $value;
 554  }
 555  
 556  /**
 557   * Parses blocks out of a content string, and renders those appropriate for the excerpt.
 558   *
 559   * As the excerpt should be a small string of text relevant to the full post content,
 560   * this function renders the blocks that are most likely to contain such text.
 561   *
 562   * @since 5.0.0
 563   *
 564   * @param string $content The content to parse.
 565   * @return string The parsed and filtered content.
 566   */
 567  function excerpt_remove_blocks( $content ) {
 568      $allowed_inner_blocks = array(
 569          // Classic blocks have their blockName set to null.
 570          null,
 571          'core/freeform',
 572          'core/heading',
 573          'core/html',
 574          'core/list',
 575          'core/media-text',
 576          'core/paragraph',
 577          'core/preformatted',
 578          'core/pullquote',
 579          'core/quote',
 580          'core/table',
 581          'core/verse',
 582      );
 583  
 584      $allowed_blocks = array_merge( $allowed_inner_blocks, array( 'core/columns' ) );
 585  
 586      /**
 587       * Filters the list of blocks that can contribute to the excerpt.
 588       *
 589       * If a dynamic block is added to this list, it must not generate another
 590       * excerpt, as this will cause an infinite loop to occur.
 591       *
 592       * @since 5.0.0
 593       *
 594       * @param array $allowed_blocks The list of allowed blocks.
 595       */
 596      $allowed_blocks = apply_filters( 'excerpt_allowed_blocks', $allowed_blocks );
 597      $blocks         = parse_blocks( $content );
 598      $output         = '';
 599  
 600      foreach ( $blocks as $block ) {
 601          if ( in_array( $block['blockName'], $allowed_blocks, true ) ) {
 602              if ( ! empty( $block['innerBlocks'] ) ) {
 603                  if ( 'core/columns' === $block['blockName'] ) {
 604                      $output .= _excerpt_render_inner_columns_blocks( $block, $allowed_inner_blocks );
 605                      continue;
 606                  }
 607  
 608                  // Skip the block if it has disallowed or nested inner blocks.
 609                  foreach ( $block['innerBlocks'] as $inner_block ) {
 610                      if (
 611                          ! in_array( $inner_block['blockName'], $allowed_inner_blocks, true ) ||
 612                          ! empty( $inner_block['innerBlocks'] )
 613                      ) {
 614                          continue 2;
 615                      }
 616                  }
 617              }
 618  
 619              $output .= render_block( $block );
 620          }
 621      }
 622  
 623      return $output;
 624  }
 625  
 626  /**
 627   * Render inner blocks from the `core/columns` block for generating an excerpt.
 628   *
 629   * @since 5.2.0
 630   * @access private
 631   *
 632   * @param array $columns        The parsed columns block.
 633   * @param array $allowed_blocks The list of allowed inner blocks.
 634   * @return string The rendered inner blocks.
 635   */
 636  function _excerpt_render_inner_columns_blocks( $columns, $allowed_blocks ) {
 637      $output = '';
 638  
 639      foreach ( $columns['innerBlocks'] as $column ) {
 640          foreach ( $column['innerBlocks'] as $inner_block ) {
 641              if ( in_array( $inner_block['blockName'], $allowed_blocks, true ) && empty( $inner_block['innerBlocks'] ) ) {
 642                  $output .= render_block( $inner_block );
 643              }
 644          }
 645      }
 646  
 647      return $output;
 648  }
 649  
 650  /**
 651   * Block currently being parsed.
 652   *
 653   * @type array
 654  */
 655  global $current_parsed_block;
 656  
 657  $current_parsed_block = array(
 658      'blockName'  => null,
 659      'attributes' => null,
 660  );
 661  
 662  /**
 663   * Renders a single block into a HTML string.
 664   *
 665   * @since 5.0.0
 666   *
 667   * @global array    $current_parsed_block Block currently being parsed.
 668   * @global WP_Post  $post                 The post to edit.
 669   * @global WP_Query $wp_query             WordPress Query object.
 670   * @global WP_Query $wp_query             WordPress Query object.
 671   *
 672   * @param array $parsed_block A single parsed block object.
 673   * @return string String of rendered HTML.
 674   */
 675  function render_block( $parsed_block ) {
 676      global $post, $wp_query, $current_parsed_block;
 677  
 678      /**
 679       * Allows render_block() to be short-circuited, by returning a non-null value.
 680       *
 681       * @since 5.1.0
 682       *
 683       * @param string|null $pre_render   The pre-rendered content. Default null.
 684       * @param array       $parsed_block The block being rendered.
 685       */
 686      $pre_render = apply_filters( 'pre_render_block', null, $parsed_block );
 687      if ( ! is_null( $pre_render ) ) {
 688          return $pre_render;
 689      }
 690  
 691      $current_parsed_block = $parsed_block;
 692  
 693      $source_block = $parsed_block;
 694  
 695      /**
 696       * Filters the block being rendered in render_block(), before it's processed.
 697       *
 698       * @since 5.1.0
 699       *
 700       * @param array $parsed_block The block being rendered.
 701       * @param array $source_block An un-modified copy of $parsed_block, as it appeared in the source content.
 702       */
 703      $parsed_block = apply_filters( 'render_block_data', $parsed_block, $source_block );
 704  
 705      $context = array();
 706  
 707      if ( $post instanceof WP_Post ) {
 708          $context['postId'] = $post->ID;
 709  
 710          /*
 711           * The `postType` context is largely unnecessary server-side, since the ID
 712           * is usually sufficient on its own. That being said, since a block's
 713           * manifest is expected to be shared between the server and the client,
 714           * it should be included to consistently fulfill the expectation.
 715           */
 716          $context['postType'] = $post->post_type;
 717      }
 718  
 719      if ( $wp_query instanceof WP_Query && isset( $wp_query->tax_query->queried_terms['category'] ) ) {
 720          $context['query'] = array( 'categoryIds' => array() );
 721          foreach ( $wp_query->tax_query->queried_terms['category']['terms'] as $category_slug_or_id ) {
 722              $context['query']['categoryIds'][] = 'slug' === $wp_query->tax_query->queried_terms['category']['field'] ? get_cat_ID( $category_slug_or_id ) : $category_slug_or_id;
 723          }
 724      }
 725  
 726      /**
 727       * Filters the default context provided to a rendered block.
 728       *
 729       * @since 5.5.0
 730       *
 731       * @param array $context      Default context.
 732       * @param array $parsed_block Block being rendered, filtered by `render_block_data`.
 733       */
 734      $context = apply_filters( 'render_block_context', $context, $parsed_block );
 735  
 736      $block = new WP_Block( $parsed_block, $context );
 737  
 738      return $block->render();
 739  }
 740  
 741  /**
 742   * Parses blocks out of a content string.
 743   *
 744   * @since 5.0.0
 745   *
 746   * @param string $content Post content.
 747   * @return array[] Array of parsed block objects.
 748   */
 749  function parse_blocks( $content ) {
 750      /**
 751       * Filter to allow plugins to replace the server-side block parser
 752       *
 753       * @since 5.0.0
 754       *
 755       * @param string $parser_class Name of block parser class.
 756       */
 757      $parser_class = apply_filters( 'block_parser_class', 'WP_Block_Parser' );
 758  
 759      $parser = new $parser_class();
 760      return $parser->parse( $content );
 761  }
 762  
 763  /**
 764   * Parses dynamic blocks out of `post_content` and re-renders them.
 765   *
 766   * @since 5.0.0
 767   *
 768   * @param string $content Post content.
 769   * @return string Updated post content.
 770   */
 771  function do_blocks( $content ) {
 772      $blocks = parse_blocks( $content );
 773      $output = '';
 774  
 775      foreach ( $blocks as $block ) {
 776          $output .= render_block( $block );
 777      }
 778  
 779      // If there are blocks in this content, we shouldn't run wpautop() on it later.
 780      $priority = has_filter( 'the_content', 'wpautop' );
 781      if ( false !== $priority && doing_filter( 'the_content' ) && has_blocks( $content ) ) {
 782          remove_filter( 'the_content', 'wpautop', $priority );
 783          add_filter( 'the_content', '_restore_wpautop_hook', $priority + 1 );
 784      }
 785  
 786      return $output;
 787  }
 788  
 789  /**
 790   * If do_blocks() needs to remove wpautop() from the `the_content` filter, this re-adds it afterwards,
 791   * for subsequent `the_content` usage.
 792   *
 793   * @access private
 794   *
 795   * @since 5.0.0
 796   *
 797   * @param string $content The post content running through this filter.
 798   * @return string The unmodified content.
 799   */
 800  function _restore_wpautop_hook( $content ) {
 801      $current_priority = has_filter( 'the_content', '_restore_wpautop_hook' );
 802  
 803      add_filter( 'the_content', 'wpautop', $current_priority - 1 );
 804      remove_filter( 'the_content', '_restore_wpautop_hook', $current_priority );
 805  
 806      return $content;
 807  }
 808  
 809  /**
 810   * Returns the current version of the block format that the content string is using.
 811   *
 812   * If the string doesn't contain blocks, it returns 0.
 813   *
 814   * @since 5.0.0
 815   *
 816   * @param string $content Content to test.
 817   * @return int The block format version is 1 if the content contains one or more blocks, 0 otherwise.
 818   */
 819  function block_version( $content ) {
 820      return has_blocks( $content ) ? 1 : 0;
 821  }
 822  
 823  /**
 824   * Registers a new block style.
 825   *
 826   * @since 5.3.0
 827   *
 828   * @param string $block_name       Block type name including namespace.
 829   * @param array  $style_properties Array containing the properties of the style name,
 830   *                                 label, style (name of the stylesheet to be enqueued),
 831   *                                 inline_style (string containing the CSS to be added).
 832   * @return bool True if the block style was registered with success and false otherwise.
 833   */
 834  function register_block_style( $block_name, $style_properties ) {
 835      return WP_Block_Styles_Registry::get_instance()->register( $block_name, $style_properties );
 836  }
 837  
 838  /**
 839   * Unregisters a block style.
 840   *
 841   * @since 5.3.0
 842   *
 843   * @param string $block_name       Block type name including namespace.
 844   * @param array  $block_style_name Block style name.
 845   * @return bool True if the block style was unregistered with success and false otherwise.
 846   */
 847  function unregister_block_style( $block_name, $block_style_name ) {
 848      return WP_Block_Styles_Registry::get_instance()->unregister( $block_name, $block_style_name );
 849  }


Generated: Sun Oct 25 01:00:03 2020 Cross-referenced by PHPXref 0.7.1