[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-admin/ -> edit-form-blocks.php (source)

   1  <?php
   2  /**
   3   * The block editor page.
   4   *
   5   * @since 5.0.0
   6   *
   7   * @package WordPress
   8   * @subpackage Administration
   9   */
  10  
  11  // Don't load directly.
  12  if ( ! defined( 'ABSPATH' ) ) {
  13      die( '-1' );
  14  }
  15  
  16  /**
  17   * @global string       $post_type        Global post type.
  18   * @global WP_Post_Type $post_type_object Global post type object.
  19   * @global WP_Post      $post             Global post object.
  20   * @global string       $title            The title of the current screen.
  21   * @global array        $wp_meta_boxes    Global meta box state.
  22   */
  23  global $post_type, $post_type_object, $post, $title, $wp_meta_boxes;
  24  
  25  $block_editor_context = new WP_Block_Editor_Context( array( 'post' => $post ) );
  26  
  27  // Flag that we're loading the block editor.
  28  $current_screen = get_current_screen();
  29  $current_screen->is_block_editor( true );
  30  
  31  // Default to is-fullscreen-mode to avoid jumps in the UI.
  32  add_filter(
  33      'admin_body_class',
  34      static function ( $classes ) {
  35          return "$classes is-fullscreen-mode";
  36      }
  37  );
  38  
  39  /*
  40   * Emoji replacement is disabled for now, until it plays nicely with React.
  41   */
  42  remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
  43  
  44  /*
  45   * Block editor implements its own Options menu for toggling Document Panels.
  46   */
  47  add_filter( 'screen_options_show_screen', '__return_false' );
  48  
  49  wp_enqueue_script( 'heartbeat' );
  50  wp_enqueue_script( 'wp-edit-post' );
  51  
  52  $rest_path = rest_get_route_for_post( $post );
  53  
  54  $active_theme                   = get_stylesheet();
  55  $global_styles_endpoint_context = current_user_can( 'edit_theme_options' ) ? 'edit' : 'view';
  56  // Preload common data.
  57  $preload_paths = array(
  58      '/wp/v2/types?context=view',
  59      '/wp/v2/taxonomies?context=view',
  60      add_query_arg( 'context', 'edit', $rest_path ),
  61      sprintf( '/wp/v2/types/%s?context=edit', $post_type ),
  62      '/wp/v2/users/me',
  63      array( rest_get_route_for_post_type_items( 'attachment' ), 'OPTIONS' ),
  64      array( rest_get_route_for_post_type_items( 'page' ), 'OPTIONS' ),
  65      array( rest_get_route_for_post_type_items( 'wp_block' ), 'OPTIONS' ),
  66      array( rest_get_route_for_post_type_items( 'wp_template' ), 'OPTIONS' ),
  67      sprintf( '%s/autosaves?context=edit', $rest_path ),
  68      '/wp/v2/settings',
  69      array( '/wp/v2/settings', 'OPTIONS' ),
  70      '/wp/v2/global-styles/themes/' . $active_theme . '?context=view',
  71      '/wp/v2/global-styles/themes/' . $active_theme . '/variations?context=view',
  72      '/wp/v2/themes?context=edit&status=active',
  73      array( '/wp/v2/global-styles/' . WP_Theme_JSON_Resolver::get_user_global_styles_post_id(), 'OPTIONS' ),
  74      /*
  75       * Preload the global styles path with the correct context based on user caps.
  76       * NOTE: There is an equivalent conditional check in the client-side code to fetch
  77       * the global styles entity using the appropriate context value.
  78       * See the call to `canUser()`, under `useGlobalStylesUserConfig()` in `packages/edit-site/src/components/use-global-styles-user-config/index.js`.
  79       * Please ensure that the equivalent check is kept in sync with this preload path.
  80       */
  81      '/wp/v2/global-styles/' . WP_Theme_JSON_Resolver::get_user_global_styles_post_id() . '?context=' . $global_styles_endpoint_context,
  82  );
  83  
  84  block_editor_rest_api_preload( $preload_paths, $block_editor_context );
  85  
  86  wp_add_inline_script(
  87      'wp-blocks',
  88      sprintf( 'wp.blocks.setCategories( %s );', wp_json_encode( get_block_categories( $post ) ) ),
  89      'after'
  90  );
  91  
  92  /*
  93   * Assign initial edits, if applicable. These are not initially assigned to the persisted post,
  94   * but should be included in its save payload.
  95   */
  96  $initial_edits = array();
  97  $is_new_post   = false;
  98  if ( 'auto-draft' === $post->post_status ) {
  99      $is_new_post = true;
 100      // Override "(Auto Draft)" new post default title with empty string, or filtered value.
 101      if ( post_type_supports( $post->post_type, 'title' ) ) {
 102          $initial_edits['title'] = $post->post_title;
 103      }
 104  
 105      if ( post_type_supports( $post->post_type, 'editor' ) ) {
 106          $initial_edits['content'] = $post->post_content;
 107      }
 108  
 109      if ( post_type_supports( $post->post_type, 'excerpt' ) ) {
 110          $initial_edits['excerpt'] = $post->post_excerpt;
 111      }
 112  }
 113  
 114  // Preload server-registered block schemas.
 115  wp_add_inline_script(
 116      'wp-blocks',
 117      'wp.blocks.unstable__bootstrapServerSideBlockDefinitions(' . wp_json_encode( get_block_editor_server_block_settings() ) . ');'
 118  );
 119  
 120  // Preload server-registered block bindings sources.
 121  $registered_sources = get_all_registered_block_bindings_sources();
 122  if ( ! empty( $registered_sources ) ) {
 123      $filtered_sources = array();
 124      foreach ( $registered_sources as $source ) {
 125          $filtered_sources[] = array(
 126              'name'        => $source->name,
 127              'label'       => $source->label,
 128              'usesContext' => $source->uses_context,
 129          );
 130      }
 131      $script = sprintf( 'for ( const source of %s ) { wp.blocks.registerBlockBindingsSource( source ); }', wp_json_encode( $filtered_sources ) );
 132      wp_add_inline_script(
 133          'wp-blocks',
 134          $script
 135      );
 136  }
 137  
 138  // Get admin url for handling meta boxes.
 139  $meta_box_url = admin_url( 'post.php' );
 140  $meta_box_url = add_query_arg(
 141      array(
 142          'post'                  => $post->ID,
 143          'action'                => 'edit',
 144          'meta-box-loader'       => true,
 145          'meta-box-loader-nonce' => wp_create_nonce( 'meta-box-loader' ),
 146      ),
 147      $meta_box_url
 148  );
 149  wp_add_inline_script(
 150      'wp-editor',
 151      sprintf( 'var _wpMetaBoxUrl = %s;', wp_json_encode( $meta_box_url ) ),
 152      'before'
 153  );
 154  
 155  // Set Heartbeat interval to 10 seconds, used to refresh post locks.
 156  wp_add_inline_script(
 157      'heartbeat',
 158      'jQuery( function() {
 159          wp.heartbeat.interval( 10 );
 160      } );',
 161      'after'
 162  );
 163  
 164  /*
 165   * Get all available templates for the post/page attributes meta-box.
 166   * The "Default template" array element should only be added if the array is
 167   * not empty so we do not trigger the template select element without any options
 168   * besides the default value.
 169   */
 170  $available_templates = wp_get_theme()->get_page_templates( get_post( $post->ID ) );
 171  $available_templates = ! empty( $available_templates ) ? array_replace(
 172      array(
 173          /** This filter is documented in wp-admin/includes/meta-boxes.php */
 174          '' => apply_filters( 'default_page_template_title', __( 'Default template' ), 'rest-api' ),
 175      ),
 176      $available_templates
 177  ) : $available_templates;
 178  
 179  // Lock settings.
 180  $user_id = wp_check_post_lock( $post->ID );
 181  if ( $user_id ) {
 182      $locked = false;
 183  
 184      /** This filter is documented in wp-admin/includes/post.php */
 185      if ( apply_filters( 'show_post_locked_dialog', true, $post, $user_id ) ) {
 186          $locked = true;
 187      }
 188  
 189      $user_details = null;
 190      if ( $locked ) {
 191          $user         = get_userdata( $user_id );
 192          $user_details = array(
 193              'name' => $user->display_name,
 194          );
 195  
 196          if ( get_option( 'show_avatars' ) ) {
 197              $user_details['avatar'] = get_avatar_url( $user_id, array( 'size' => 128 ) );
 198          }
 199      }
 200  
 201      $lock_details = array(
 202          'isLocked' => $locked,
 203          'user'     => $user_details,
 204      );
 205  } else {
 206      // Lock the post.
 207      $active_post_lock = wp_set_post_lock( $post->ID );
 208      if ( $active_post_lock ) {
 209          $active_post_lock = esc_attr( implode( ':', $active_post_lock ) );
 210      }
 211  
 212      $lock_details = array(
 213          'isLocked'       => false,
 214          'activePostLock' => $active_post_lock,
 215      );
 216  }
 217  
 218  /**
 219   * Filters the body placeholder text.
 220   *
 221   * @since 5.0.0
 222   * @since 5.8.0 Changed the default placeholder text.
 223   *
 224   * @param string  $text Placeholder text. Default 'Type / to choose a block'.
 225   * @param WP_Post $post Post object.
 226   */
 227  $body_placeholder = apply_filters( 'write_your_story', __( 'Type / to choose a block' ), $post );
 228  
 229  $editor_settings = array(
 230      'availableTemplates'   => $available_templates,
 231      'disablePostFormats'   => ! current_theme_supports( 'post-formats' ),
 232      /** This filter is documented in wp-admin/edit-form-advanced.php */
 233      'titlePlaceholder'     => apply_filters( 'enter_title_here', __( 'Add title' ), $post ),
 234      'bodyPlaceholder'      => $body_placeholder,
 235      'autosaveInterval'     => AUTOSAVE_INTERVAL,
 236      'richEditingEnabled'   => user_can_richedit(),
 237      'postLock'             => $lock_details,
 238      'postLockUtils'        => array(
 239          'nonce'       => wp_create_nonce( 'lock-post_' . $post->ID ),
 240          'unlockNonce' => wp_create_nonce( 'update-post_' . $post->ID ),
 241          'ajaxUrl'     => admin_url( 'admin-ajax.php' ),
 242      ),
 243      'supportsLayout'       => wp_theme_has_theme_json(),
 244      'supportsTemplateMode' => current_theme_supports( 'block-templates' ),
 245  
 246      // Whether or not to load the 'postcustom' meta box is stored as a user meta
 247      // field so that we're not always loading its assets.
 248      'enableCustomFields'   => (bool) get_user_meta( get_current_user_id(), 'enable_custom_fields', true ),
 249  );
 250  
 251  // Add additional back-compat patterns registered by `current_screen` et al.
 252  $editor_settings['__experimentalAdditionalBlockPatterns']          = WP_Block_Patterns_Registry::get_instance()->get_all_registered( true );
 253  $editor_settings['__experimentalAdditionalBlockPatternCategories'] = WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered( true );
 254  
 255  $autosave = wp_get_post_autosave( $post->ID );
 256  if ( $autosave ) {
 257      if ( mysql2date( 'U', $autosave->post_modified_gmt, false ) > mysql2date( 'U', $post->post_modified_gmt, false ) ) {
 258          $editor_settings['autosave'] = array(
 259              'editLink' => get_edit_post_link( $autosave->ID ),
 260          );
 261      } else {
 262          wp_delete_post_revision( $autosave->ID );
 263      }
 264  }
 265  
 266  if ( ! empty( $post_type_object->template ) ) {
 267      $editor_settings['template']     = $post_type_object->template;
 268      $editor_settings['templateLock'] = ! empty( $post_type_object->template_lock ) ? $post_type_object->template_lock : false;
 269  }
 270  
 271  // If there's no template set on a new post, use the post format, instead.
 272  if ( $is_new_post && ! isset( $editor_settings['template'] ) && 'post' === $post->post_type ) {
 273      $post_format = get_post_format( $post );
 274      if ( in_array( $post_format, array( 'audio', 'gallery', 'image', 'quote', 'video' ), true ) ) {
 275          $editor_settings['template'] = array( array( "core/$post_format" ) );
 276      }
 277  }
 278  
 279  if ( wp_is_block_theme() && $editor_settings['supportsTemplateMode'] ) {
 280      $editor_settings['defaultTemplatePartAreas'] = get_allowed_block_template_part_areas();
 281  }
 282  
 283  /**
 284   * Scripts
 285   */
 286  wp_enqueue_media(
 287      array(
 288          'post' => $post->ID,
 289      )
 290  );
 291  wp_tinymce_inline_scripts();
 292  wp_enqueue_editor();
 293  
 294  /**
 295   * Styles
 296   */
 297  wp_enqueue_style( 'wp-edit-post' );
 298  
 299  /**
 300   * Fires after block assets have been enqueued for the editing interface.
 301   *
 302   * Call `add_action` on any hook before 'admin_enqueue_scripts'.
 303   *
 304   * In the function call you supply, simply use `wp_enqueue_script` and
 305   * `wp_enqueue_style` to add your functionality to the block editor.
 306   *
 307   * @since 5.0.0
 308   */
 309  do_action( 'enqueue_block_editor_assets' );
 310  
 311  // In order to duplicate classic meta box behavior, we need to run the classic meta box actions.
 312  require_once  ABSPATH . 'wp-admin/includes/meta-boxes.php';
 313  register_and_do_post_meta_boxes( $post );
 314  
 315  // Check if the Custom Fields meta box has been removed at some point.
 316  $core_meta_boxes = $wp_meta_boxes[ $current_screen->id ]['normal']['core'];
 317  if ( ! isset( $core_meta_boxes['postcustom'] ) || ! $core_meta_boxes['postcustom'] ) {
 318      unset( $editor_settings['enableCustomFields'] );
 319  }
 320  
 321  $editor_settings = get_block_editor_settings( $editor_settings, $block_editor_context );
 322  
 323  $init_script = <<<JS
 324  ( function() {
 325      window._wpLoadBlockEditor = new Promise( function( resolve ) {
 326          wp.domReady( function() {
 327              resolve( wp.editPost.initializeEditor( 'editor', "%s", %d, %s, %s ) );
 328          } );
 329      } );
 330  } )();
 331  JS;
 332  
 333  $script = sprintf(
 334      $init_script,
 335      $post->post_type,
 336      $post->ID,
 337      wp_json_encode( $editor_settings ),
 338      wp_json_encode( $initial_edits )
 339  );
 340  wp_add_inline_script( 'wp-edit-post', $script );
 341  
 342  if ( (int) get_option( 'page_for_posts' ) === $post->ID ) {
 343      add_action( 'admin_enqueue_scripts', '_wp_block_editor_posts_page_notice' );
 344  }
 345  
 346  require_once  ABSPATH . 'wp-admin/admin-header.php';
 347  ?>
 348  
 349  <div class="block-editor">
 350      <h1 class="screen-reader-text hide-if-no-js"><?php echo esc_html( $title ); ?></h1>
 351      <div id="editor" class="block-editor__container hide-if-no-js"></div>
 352      <div id="metaboxes" class="hidden">
 353          <?php the_block_editor_meta_boxes(); ?>
 354      </div>
 355  
 356      <?php // JavaScript is disabled. ?>
 357      <div class="wrap hide-if-js block-editor-no-js">
 358          <h1 class="wp-heading-inline"><?php echo esc_html( $title ); ?></h1>
 359          <?php
 360          if ( file_exists( WP_PLUGIN_DIR . '/classic-editor/classic-editor.php' ) ) {
 361              // If Classic Editor is already installed, provide a link to activate the plugin.
 362              $installed           = true;
 363              $plugin_activate_url = wp_nonce_url( 'plugins.php?action=activate&amp;plugin=classic-editor/classic-editor.php', 'activate-plugin_classic-editor/classic-editor.php' );
 364              $message             = sprintf(
 365                  /* translators: %s: Link to activate the Classic Editor plugin. */
 366                  __( 'The block editor requires JavaScript. Please enable JavaScript in your browser settings, or activate the <a href="%s">Classic Editor plugin</a>.' ),
 367                  esc_url( $plugin_activate_url )
 368              );
 369          } else {
 370              // If Classic Editor is not installed, provide a link to install it.
 371              $installed          = false;
 372              $plugin_install_url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=classic-editor' ), 'install-plugin_classic-editor' );
 373              $message            = sprintf(
 374                  /* translators: %s: Link to install the Classic Editor plugin. */
 375                  __( 'The block editor requires JavaScript. Please enable JavaScript in your browser settings, or install the <a href="%s">Classic Editor plugin</a>.' ),
 376                  esc_url( $plugin_install_url )
 377              );
 378          }
 379  
 380          /**
 381           * Filters the message displayed in the block editor interface when JavaScript is
 382           * not enabled in the browser.
 383           *
 384           * @since 5.0.3
 385           * @since 6.4.0 Added `$installed` parameter.
 386           *
 387           * @param string  $message   The message being displayed.
 388           * @param WP_Post $post      The post being edited.
 389           * @param bool    $installed Whether the classic editor is installed.
 390           */
 391          $message = apply_filters( 'block_editor_no_javascript_message', $message, $post, $installed );
 392          wp_admin_notice(
 393              $message,
 394              array(
 395                  'type' => 'error',
 396              )
 397          );
 398          ?>
 399      </div>
 400  </div>


Generated : Fri Feb 21 08:20:01 2025 Cross-referenced by PHPXref