[ 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 a
  16   *                                   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. Any arguments may be defined, however the
  20   *     ones described below are supported by default. Default empty array.
  21   *
  22   *     @type callable $render_callback Callback used to render blocks of this block type.
  23   * }
  24   * @return WP_Block_Type|false The registered block type on success, or false on failure.
  25   */
  26  function register_block_type( $name, $args = array() ) {
  27      return WP_Block_Type_Registry::get_instance()->register( $name, $args );
  28  }
  29  
  30  /**
  31   * Unregisters a block type.
  32   *
  33   * @since 5.0.0
  34   *
  35   * @param string|WP_Block_Type $name Block type name including namespace, or alternatively a
  36   *                                   complete WP_Block_Type instance.
  37   * @return WP_Block_Type|false The unregistered block type on success, or false on failure.
  38   */
  39  function unregister_block_type( $name ) {
  40      return WP_Block_Type_Registry::get_instance()->unregister( $name );
  41  }
  42  
  43  /**
  44   * Determine whether a post or content string has blocks.
  45   *
  46   * This test optimizes for performance rather than strict accuracy, detecting
  47   * the pattern of a block but not validating its structure. For strict accuracy,
  48   * you should use the block parser on post content.
  49   *
  50   * @since 5.0.0
  51   * @see parse_blocks()
  52   *
  53   * @param int|string|WP_Post|null $post Optional. Post content, post ID, or post object. Defaults to global $post.
  54   * @return bool Whether the post has blocks.
  55   */
  56  function has_blocks( $post = null ) {
  57      if ( ! is_string( $post ) ) {
  58          $wp_post = get_post( $post );
  59          if ( $wp_post instanceof WP_Post ) {
  60              $post = $wp_post->post_content;
  61          }
  62      }
  63  
  64      return false !== strpos( (string) $post, '<!-- wp:' );
  65  }
  66  
  67  /**
  68   * Determine whether a $post or a string contains a specific block type.
  69   *
  70   * This test optimizes for performance rather than strict accuracy, detecting
  71   * the block type exists but not validating its structure. For strict accuracy,
  72   * you should use the block parser on post content.
  73   *
  74   * @since 5.0.0
  75   * @see parse_blocks()
  76   *
  77   * @param string                  $block_type Full Block type to look for.
  78   * @param int|string|WP_Post|null $post Optional. Post content, post ID, or post object. Defaults to global $post.
  79   * @return bool Whether the post content contains the specified block.
  80   */
  81  function has_block( $block_type, $post = null ) {
  82      if ( ! has_blocks( $post ) ) {
  83          return false;
  84      }
  85  
  86      if ( ! is_string( $post ) ) {
  87          $wp_post = get_post( $post );
  88          if ( $wp_post instanceof WP_Post ) {
  89              $post = $wp_post->post_content;
  90          }
  91      }
  92  
  93      return false !== strpos( $post, '<!-- wp:' . $block_type . ' ' );
  94  }
  95  
  96  /**
  97   * Returns an array of the names of all registered dynamic block types.
  98   *
  99   * @since 5.0.0
 100   *
 101   * @return array Array of dynamic block names.
 102   */
 103  function get_dynamic_block_names() {
 104      $dynamic_block_names = array();
 105  
 106      $block_types = WP_Block_Type_Registry::get_instance()->get_all_registered();
 107      foreach ( $block_types as $block_type ) {
 108          if ( $block_type->is_dynamic() ) {
 109              $dynamic_block_names[] = $block_type->name;
 110          }
 111      }
 112  
 113      return $dynamic_block_names;
 114  }
 115  
 116  /**
 117   * Parses blocks out of a content string, and renders those appropriate for the excerpt.
 118   *
 119   * As the excerpt should be a small string of text relevant to the full post content,
 120   * this function renders the blocks that are most likely to contain such text.
 121   *
 122   * @since 5.0.0
 123   *
 124   * @param string $content The content to parse.
 125   * @return string The parsed and filtered content.
 126   */
 127  function excerpt_remove_blocks( $content ) {
 128      $allowed_inner_blocks = array(
 129          // Classic blocks have their blockName set to null.
 130          null,
 131          'core/freeform',
 132          'core/heading',
 133          'core/html',
 134          'core/list',
 135          'core/media-text',
 136          'core/paragraph',
 137          'core/preformatted',
 138          'core/pullquote',
 139          'core/quote',
 140          'core/table',
 141          'core/verse',
 142      );
 143  
 144      $allowed_blocks = array_merge( $allowed_inner_blocks, array( 'core/columns' ) );
 145  
 146      /**
 147       * Filters the list of blocks that can contribute to the excerpt.
 148       *
 149       * If a dynamic block is added to this list, it must not generate another
 150       * excerpt, as this will cause an infinite loop to occur.
 151       *
 152       * @since 5.0.0
 153       *
 154       * @param array $allowed_blocks The list of allowed blocks.
 155       */
 156      $allowed_blocks = apply_filters( 'excerpt_allowed_blocks', $allowed_blocks );
 157      $blocks         = parse_blocks( $content );
 158      $output         = '';
 159  
 160      foreach ( $blocks as $block ) {
 161          if ( in_array( $block['blockName'], $allowed_blocks, true ) ) {
 162              if ( ! empty( $block['innerBlocks'] ) ) {
 163                  if ( 'core/columns' === $block['blockName'] ) {
 164                      $output .= _excerpt_render_inner_columns_blocks( $block, $allowed_inner_blocks );
 165                      continue;
 166                  }
 167  
 168                  // Skip the block if it has disallowed or nested inner blocks.
 169                  foreach ( $block['innerBlocks'] as $inner_block ) {
 170                      if (
 171                          ! in_array( $inner_block['blockName'], $allowed_inner_blocks, true ) ||
 172                          ! empty( $inner_block['innerBlocks'] )
 173                      ) {
 174                          continue 2;
 175                      }
 176                  }
 177              }
 178  
 179              $output .= render_block( $block );
 180          }
 181      }
 182  
 183      return $output;
 184  }
 185  
 186  /**
 187   * Render inner blocks from the `core/columns` block for generating an excerpt.
 188   *
 189   * @since 5.2.0
 190   * @access private
 191   *
 192   * @param array $columns        The parsed columns block.
 193   * @param array $allowed_blocks The list of allowed inner blocks.
 194   * @return string The rendered inner blocks.
 195   */
 196  function _excerpt_render_inner_columns_blocks( $columns, $allowed_blocks ) {
 197      $output = '';
 198  
 199      foreach ( $columns['innerBlocks'] as $column ) {
 200          foreach ( $column['innerBlocks'] as $inner_block ) {
 201              if ( in_array( $inner_block['blockName'], $allowed_blocks, true ) && empty( $inner_block['innerBlocks'] ) ) {
 202                  $output .= render_block( $inner_block );
 203              }
 204          }
 205      }
 206  
 207      return $output;
 208  }
 209  
 210  /**
 211   * Renders a single block into a HTML string.
 212   *
 213   * @since 5.0.0
 214   *
 215   * @global WP_Post $post The post to edit.
 216   *
 217   * @param array $block A single parsed block object.
 218   * @return string String of rendered HTML.
 219   */
 220  function render_block( $block ) {
 221      global $post;
 222  
 223      /**
 224       * Allows render_block() to be shortcircuited, by returning a non-null value.
 225       *
 226       * @since 5.1.0
 227       *
 228       * @param string $pre_render The pre-rendered content. Default null.
 229       * @param array  $block      The block being rendered.
 230       */
 231      $pre_render = apply_filters( 'pre_render_block', null, $block );
 232      if ( ! is_null( $pre_render ) ) {
 233          return $pre_render;
 234      }
 235  
 236      $source_block = $block;
 237  
 238      /**
 239       * Filters the block being rendered in render_block(), before it's processed.
 240       *
 241       * @since 5.1.0
 242       *
 243       * @param array $block        The block being rendered.
 244       * @param array $source_block An un-modified copy of $block, as it appeared in the source content.
 245       */
 246      $block = apply_filters( 'render_block_data', $block, $source_block );
 247  
 248      $block_type    = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
 249      $is_dynamic    = $block['blockName'] && null !== $block_type && $block_type->is_dynamic();
 250      $block_content = '';
 251      $index         = 0;
 252  
 253      foreach ( $block['innerContent'] as $chunk ) {
 254          $block_content .= is_string( $chunk ) ? $chunk : render_block( $block['innerBlocks'][ $index++ ] );
 255      }
 256  
 257      if ( ! is_array( $block['attrs'] ) ) {
 258          $block['attrs'] = array();
 259      }
 260  
 261      if ( $is_dynamic ) {
 262          $global_post   = $post;
 263          $block_content = $block_type->render( $block['attrs'], $block_content );
 264          $post          = $global_post;
 265      }
 266  
 267      /**
 268       * Filters the content of a single block.
 269       *
 270       * @since 5.0.0
 271       *
 272       * @param string $block_content The block content about to be appended.
 273       * @param array  $block         The full block, including name and attributes.
 274       */
 275      return apply_filters( 'render_block', $block_content, $block );
 276  }
 277  
 278  /**
 279   * Parses blocks out of a content string.
 280   *
 281   * @since 5.0.0
 282   *
 283   * @param string $content Post content.
 284   * @return array Array of parsed block objects.
 285   */
 286  function parse_blocks( $content ) {
 287      /**
 288       * Filter to allow plugins to replace the server-side block parser
 289       *
 290       * @since 5.0.0
 291       *
 292       * @param string $parser_class Name of block parser class.
 293       */
 294      $parser_class = apply_filters( 'block_parser_class', 'WP_Block_Parser' );
 295  
 296      $parser = new $parser_class();
 297      return $parser->parse( $content );
 298  }
 299  
 300  /**
 301   * Parses dynamic blocks out of `post_content` and re-renders them.
 302   *
 303   * @since 5.0.0
 304   *
 305   * @param string $content Post content.
 306   * @return string Updated post content.
 307   */
 308  function do_blocks( $content ) {
 309      $blocks = parse_blocks( $content );
 310      $output = '';
 311  
 312      foreach ( $blocks as $block ) {
 313          $output .= render_block( $block );
 314      }
 315  
 316      // If there are blocks in this content, we shouldn't run wpautop() on it later.
 317      $priority = has_filter( 'the_content', 'wpautop' );
 318      if ( false !== $priority && doing_filter( 'the_content' ) && has_blocks( $content ) ) {
 319          remove_filter( 'the_content', 'wpautop', $priority );
 320          add_filter( 'the_content', '_restore_wpautop_hook', $priority + 1 );
 321      }
 322  
 323      return $output;
 324  }
 325  
 326  /**
 327   * If do_blocks() needs to remove wpautop() from the `the_content` filter, this re-adds it afterwards,
 328   * for subsequent `the_content` usage.
 329   *
 330   * @access private
 331   *
 332   * @since 5.0.0
 333   *
 334   * @param string $content The post content running through this filter.
 335   * @return string The unmodified content.
 336   */
 337  function _restore_wpautop_hook( $content ) {
 338      $current_priority = has_filter( 'the_content', '_restore_wpautop_hook' );
 339  
 340      add_filter( 'the_content', 'wpautop', $current_priority - 1 );
 341      remove_filter( 'the_content', '_restore_wpautop_hook', $current_priority );
 342  
 343      return $content;
 344  }
 345  
 346  /**
 347   * Returns the current version of the block format that the content string is using.
 348   *
 349   * If the string doesn't contain blocks, it returns 0.
 350   *
 351   * @since 5.0.0
 352   *
 353   * @param string $content Content to test.
 354   * @return int The block format version is 1 if the content contains one or more blocks, 0 otherwise.
 355   */
 356  function block_version( $content ) {
 357      return has_blocks( $content ) ? 1 : 0;
 358  }
 359  
 360  /**
 361   * Registers a new block style.
 362   *
 363   * @since 5.3.0
 364   *
 365   * @param string $block_name       Block type name including namespace.
 366   * @param array  $style_properties Array containing the properties of the style name, label, style (name of the stylesheet to be enqueued), inline_style (string containing the CSS to be added).
 367   *
 368   * @return boolean True if the block style was registered with success and false otherwise.
 369   */
 370  function register_block_style( $block_name, $style_properties ) {
 371      return WP_Block_Styles_Registry::get_instance()->register( $block_name, $style_properties );
 372  }
 373  
 374  /**
 375   * Unregisters a block style.
 376   *
 377   * @since 5.3.0
 378   *
 379   * @param string $block_name       Block type name including namespace.
 380   * @param array  $block_style_name Block style name.
 381   *
 382   * @return boolean True if the block style was unregistered with success and false otherwise.
 383   */
 384  function unregister_block_style( $block_name, $block_style_name ) {
 385      return WP_Block_Styles_Registry::get_instance()->unregister( $block_name, $block_style_name );
 386  }


Generated: Thu Sep 19 01:00:03 2019 Cross-referenced by PHPXref 0.7.1