mirror of
https://github.com/WordPress/WordPress.git
synced 2024-11-19 09:05:22 +01:00
083134f694
These endpoints facilitate the Block Directory Inserter feature in Gutenberg. Users can now install, activate, deactivate, and delete plugins over the REST API. The block directoryendpoint allows searching for available blocks from the WordPress.org block directory. Props cklee, talldanwp, noisysocks, joen, soean, youknowriad, dufresnesteven, gziolo, dd32, tellyworth, ryelle, spacedmonkey, TimothyBlynJacobs. Fixes #50321. Built from https://develop.svn.wordpress.org/trunk@48242 git-svn-id: http://core.svn.wordpress.org/trunk@48011 1a063a9b-81f0-0310-95a4-ce76da25c4cd
461 lines
14 KiB
PHP
461 lines
14 KiB
PHP
<?php
|
|
/**
|
|
* The block editor page.
|
|
*
|
|
* @since 5.0.0
|
|
*
|
|
* @package WordPress
|
|
* @subpackage Administration
|
|
*/
|
|
|
|
// Don't load directly.
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
die( '-1' );
|
|
}
|
|
|
|
/**
|
|
* @global string $post_type
|
|
* @global WP_Post_Type $post_type_object
|
|
* @global WP_Post $post Global post object.
|
|
* @global string $title
|
|
* @global array $editor_styles
|
|
* @global array $wp_meta_boxes
|
|
*/
|
|
global $post_type, $post_type_object, $post, $title, $editor_styles, $wp_meta_boxes;
|
|
|
|
// Flag that we're loading the block editor.
|
|
$current_screen = get_current_screen();
|
|
$current_screen->is_block_editor( true );
|
|
|
|
/*
|
|
* Emoji replacement is disabled for now, until it plays nicely with React.
|
|
*/
|
|
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
|
|
|
|
wp_enqueue_script( 'heartbeat' );
|
|
wp_enqueue_script( 'wp-edit-post' );
|
|
wp_enqueue_script( 'wp-format-library' );
|
|
|
|
$rest_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
|
|
|
|
// Preload common data.
|
|
$preload_paths = array(
|
|
'/',
|
|
'/wp/v2/types?context=edit',
|
|
'/wp/v2/taxonomies?per_page=-1&context=edit',
|
|
'/wp/v2/themes?status=active',
|
|
sprintf( '/wp/v2/%s/%s?context=edit', $rest_base, $post->ID ),
|
|
sprintf( '/wp/v2/types/%s?context=edit', $post_type ),
|
|
sprintf( '/wp/v2/users/me?post_type=%s&context=edit', $post_type ),
|
|
array( '/wp/v2/media', 'OPTIONS' ),
|
|
array( '/wp/v2/blocks', 'OPTIONS' ),
|
|
sprintf( '/wp/v2/%s/%d/autosaves?context=edit', $rest_base, $post->ID ),
|
|
);
|
|
|
|
/**
|
|
* Preload common data by specifying an array of REST API paths that will be preloaded.
|
|
*
|
|
* Filters the array of paths that will be preloaded.
|
|
*
|
|
* @since 5.0.0
|
|
*
|
|
* @param string[] $preload_paths Array of paths to preload.
|
|
* @param WP_Post $post Post being edited.
|
|
*/
|
|
$preload_paths = apply_filters( 'block_editor_preload_paths', $preload_paths, $post );
|
|
|
|
/*
|
|
* Ensure the global $post remains the same after API data is preloaded.
|
|
* Because API preloading can call the_content and other filters, plugins
|
|
* can unexpectedly modify $post.
|
|
*/
|
|
$backup_global_post = $post;
|
|
|
|
$preload_data = array_reduce(
|
|
$preload_paths,
|
|
'rest_preload_api_request',
|
|
array()
|
|
);
|
|
|
|
// Restore the global $post as it was before API preloading.
|
|
$post = $backup_global_post;
|
|
|
|
wp_add_inline_script(
|
|
'wp-api-fetch',
|
|
sprintf( 'wp.apiFetch.use( wp.apiFetch.createPreloadingMiddleware( %s ) );', wp_json_encode( $preload_data ) ),
|
|
'after'
|
|
);
|
|
|
|
wp_add_inline_script(
|
|
'wp-blocks',
|
|
sprintf( 'wp.blocks.setCategories( %s );', wp_json_encode( get_block_categories( $post ) ) ),
|
|
'after'
|
|
);
|
|
|
|
/*
|
|
* Assign initial edits, if applicable. These are not initially assigned to the persisted post,
|
|
* but should be included in its save payload.
|
|
*/
|
|
$initial_edits = null;
|
|
$is_new_post = false;
|
|
if ( 'auto-draft' === $post->post_status ) {
|
|
$is_new_post = true;
|
|
// Override "(Auto Draft)" new post default title with empty string, or filtered value.
|
|
$initial_edits = array(
|
|
'title' => $post->post_title,
|
|
'content' => $post->post_content,
|
|
'excerpt' => $post->post_excerpt,
|
|
);
|
|
}
|
|
|
|
// Preload server-registered block schemas.
|
|
wp_add_inline_script(
|
|
'wp-blocks',
|
|
'wp.blocks.unstable__bootstrapServerSideBlockDefinitions(' . wp_json_encode( get_block_editor_server_block_settings() ) . ');'
|
|
);
|
|
|
|
// Get admin url for handling meta boxes.
|
|
$meta_box_url = admin_url( 'post.php' );
|
|
$meta_box_url = add_query_arg(
|
|
array(
|
|
'post' => $post->ID,
|
|
'action' => 'edit',
|
|
'meta-box-loader' => true,
|
|
'meta-box-loader-nonce' => wp_create_nonce( 'meta-box-loader' ),
|
|
),
|
|
$meta_box_url
|
|
);
|
|
wp_localize_script( 'wp-editor', '_wpMetaBoxUrl', $meta_box_url );
|
|
|
|
|
|
/*
|
|
* Initialize the editor.
|
|
*/
|
|
|
|
$align_wide = get_theme_support( 'align-wide' );
|
|
$color_palette = current( (array) get_theme_support( 'editor-color-palette' ) );
|
|
$font_sizes = current( (array) get_theme_support( 'editor-font-sizes' ) );
|
|
$gradient_presets = current( (array) get_theme_support( 'editor-gradient-presets' ) );
|
|
|
|
/**
|
|
* Filters the allowed block types for the editor, defaulting to true (all
|
|
* block types supported).
|
|
*
|
|
* @since 5.0.0
|
|
*
|
|
* @param bool|array $allowed_block_types Array of block type slugs, or
|
|
* boolean to enable/disable all.
|
|
* @param WP_Post $post The post resource data.
|
|
*/
|
|
$allowed_block_types = apply_filters( 'allowed_block_types', true, $post );
|
|
|
|
/*
|
|
* Get all available templates for the post/page attributes meta-box.
|
|
* The "Default template" array element should only be added if the array is
|
|
* not empty so we do not trigger the template select element without any options
|
|
* besides the default value.
|
|
*/
|
|
$available_templates = wp_get_theme()->get_page_templates( get_post( $post->ID ) );
|
|
$available_templates = ! empty( $available_templates ) ? array_merge(
|
|
array(
|
|
/** This filter is documented in wp-admin/includes/meta-boxes.php */
|
|
'' => apply_filters( 'default_page_template_title', __( 'Default template' ), 'rest-api' ),
|
|
),
|
|
$available_templates
|
|
) : $available_templates;
|
|
|
|
// Media settings.
|
|
$max_upload_size = wp_max_upload_size();
|
|
if ( ! $max_upload_size ) {
|
|
$max_upload_size = 0;
|
|
}
|
|
|
|
// Editor Styles.
|
|
$styles = array(
|
|
array(
|
|
'css' => file_get_contents(
|
|
ABSPATH . WPINC . '/css/dist/editor/editor-styles.css'
|
|
),
|
|
),
|
|
);
|
|
|
|
/* translators: Use this to specify the CSS font family for the default font. */
|
|
$locale_font_family = esc_html_x( 'Noto Serif', 'CSS Font Family for Editor Font' );
|
|
$styles[] = array(
|
|
'css' => "body { font-family: '$locale_font_family' }",
|
|
);
|
|
|
|
if ( $editor_styles && current_theme_supports( 'editor-styles' ) ) {
|
|
foreach ( $editor_styles as $style ) {
|
|
if ( preg_match( '~^(https?:)?//~', $style ) ) {
|
|
$response = wp_remote_get( $style );
|
|
if ( ! is_wp_error( $response ) ) {
|
|
$styles[] = array(
|
|
'css' => wp_remote_retrieve_body( $response ),
|
|
);
|
|
}
|
|
} else {
|
|
$file = get_theme_file_path( $style );
|
|
if ( is_file( $file ) ) {
|
|
$styles[] = array(
|
|
'css' => file_get_contents( $file ),
|
|
'baseURL' => get_theme_file_uri( $style ),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Image sizes.
|
|
|
|
/** This filter is documented in wp-admin/includes/media.php */
|
|
$image_size_names = apply_filters(
|
|
'image_size_names_choose',
|
|
array(
|
|
'thumbnail' => __( 'Thumbnail' ),
|
|
'medium' => __( 'Medium' ),
|
|
'large' => __( 'Large' ),
|
|
'full' => __( 'Full Size' ),
|
|
)
|
|
);
|
|
|
|
$available_image_sizes = array();
|
|
foreach ( $image_size_names as $image_size_slug => $image_size_name ) {
|
|
$available_image_sizes[] = array(
|
|
'slug' => $image_size_slug,
|
|
'name' => $image_size_name,
|
|
);
|
|
}
|
|
|
|
$image_dimensions = array();
|
|
$all_sizes = wp_get_registered_image_subsizes();
|
|
foreach ( $available_image_sizes as $size ) {
|
|
$key = $size['slug'];
|
|
if ( isset( $all_sizes[ $key ] ) ) {
|
|
$image_dimensions[ $key ] = $all_sizes[ $key ];
|
|
}
|
|
}
|
|
|
|
// Lock settings.
|
|
$user_id = wp_check_post_lock( $post->ID );
|
|
if ( $user_id ) {
|
|
$locked = false;
|
|
|
|
/** This filter is documented in wp-admin/includes/post.php */
|
|
if ( apply_filters( 'show_post_locked_dialog', true, $post, $user_id ) ) {
|
|
$locked = true;
|
|
}
|
|
|
|
$user_details = null;
|
|
if ( $locked ) {
|
|
$user = get_userdata( $user_id );
|
|
$user_details = array(
|
|
'name' => $user->display_name,
|
|
);
|
|
$avatar = get_avatar_url( $user_id, array( 'size' => 64 ) );
|
|
}
|
|
|
|
$lock_details = array(
|
|
'isLocked' => $locked,
|
|
'user' => $user_details,
|
|
);
|
|
} else {
|
|
// Lock the post.
|
|
$active_post_lock = wp_set_post_lock( $post->ID );
|
|
if ( $active_post_lock ) {
|
|
$active_post_lock = esc_attr( implode( ':', $active_post_lock ) );
|
|
}
|
|
|
|
$lock_details = array(
|
|
'isLocked' => false,
|
|
'activePostLock' => $active_post_lock,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Filters the body placeholder text.
|
|
*
|
|
* @since 5.0.0
|
|
*
|
|
* @param string $text Placeholder text. Default 'Start writing or type / to choose a block'.
|
|
* @param WP_Post $post Post object.
|
|
*/
|
|
$body_placeholder = apply_filters( 'write_your_story', __( 'Start writing or type / to choose a block' ), $post );
|
|
|
|
$editor_settings = array(
|
|
'alignWide' => $align_wide,
|
|
'availableTemplates' => $available_templates,
|
|
'allowedBlockTypes' => $allowed_block_types,
|
|
'disableCustomColors' => get_theme_support( 'disable-custom-colors' ),
|
|
'disableCustomFontSizes' => get_theme_support( 'disable-custom-font-sizes' ),
|
|
'disableCustomGradients' => get_theme_support( 'disable-custom-gradients' ),
|
|
'disablePostFormats' => ! current_theme_supports( 'post-formats' ),
|
|
/** This filter is documented in wp-admin/edit-form-advanced.php */
|
|
'titlePlaceholder' => apply_filters( 'enter_title_here', __( 'Add title' ), $post ),
|
|
'bodyPlaceholder' => $body_placeholder,
|
|
'isRTL' => is_rtl(),
|
|
'autosaveInterval' => AUTOSAVE_INTERVAL,
|
|
'maxUploadFileSize' => $max_upload_size,
|
|
'allowedMimeTypes' => get_allowed_mime_types(),
|
|
'styles' => $styles,
|
|
'imageSizes' => $available_image_sizes,
|
|
'imageDimensions' => $image_dimensions,
|
|
'richEditingEnabled' => user_can_richedit(),
|
|
'postLock' => $lock_details,
|
|
'postLockUtils' => array(
|
|
'nonce' => wp_create_nonce( 'lock-post_' . $post->ID ),
|
|
'unlockNonce' => wp_create_nonce( 'update-post_' . $post->ID ),
|
|
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
|
),
|
|
'__experimentalBlockPatterns' => WP_Block_Patterns_Registry::get_instance()->get_all_registered(),
|
|
'__experimentalBlockPatternCategories' => WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(),
|
|
|
|
// Whether or not to load the 'postcustom' meta box is stored as a user meta
|
|
// field so that we're not always loading its assets.
|
|
'enableCustomFields' => (bool) get_user_meta( get_current_user_id(), 'enable_custom_fields', true ),
|
|
);
|
|
|
|
$autosave = wp_get_post_autosave( $post_ID );
|
|
if ( $autosave ) {
|
|
if ( mysql2date( 'U', $autosave->post_modified_gmt, false ) > mysql2date( 'U', $post->post_modified_gmt, false ) ) {
|
|
$editor_settings['autosave'] = array(
|
|
'editLink' => get_edit_post_link( $autosave->ID ),
|
|
);
|
|
} else {
|
|
wp_delete_post_revision( $autosave->ID );
|
|
}
|
|
}
|
|
|
|
if ( false !== $color_palette ) {
|
|
$editor_settings['colors'] = $color_palette;
|
|
}
|
|
|
|
if ( false !== $font_sizes ) {
|
|
$editor_settings['fontSizes'] = $font_sizes;
|
|
}
|
|
|
|
if ( false !== $gradient_presets ) {
|
|
$editor_settings['gradients'] = $gradient_presets;
|
|
}
|
|
|
|
if ( ! empty( $post_type_object->template ) ) {
|
|
$editor_settings['template'] = $post_type_object->template;
|
|
$editor_settings['templateLock'] = ! empty( $post_type_object->template_lock ) ? $post_type_object->template_lock : false;
|
|
}
|
|
|
|
// If there's no template set on a new post, use the post format, instead.
|
|
if ( $is_new_post && ! isset( $editor_settings['template'] ) && 'post' === $post->post_type ) {
|
|
$post_format = get_post_format( $post );
|
|
if ( in_array( $post_format, array( 'audio', 'gallery', 'image', 'quote', 'video' ), true ) ) {
|
|
$editor_settings['template'] = array( array( "core/$post_format" ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Scripts
|
|
*/
|
|
wp_enqueue_media(
|
|
array(
|
|
'post' => $post->ID,
|
|
)
|
|
);
|
|
wp_tinymce_inline_scripts();
|
|
wp_enqueue_editor();
|
|
wp_enqueue_script( 'wp-block-directory' );
|
|
|
|
/**
|
|
* Styles
|
|
*/
|
|
wp_enqueue_style( 'wp-edit-post' );
|
|
wp_enqueue_style( 'wp-format-library' );
|
|
wp_enqueue_style( 'wp-block-directory' );
|
|
|
|
/**
|
|
* Fires after block assets have been enqueued for the editing interface.
|
|
*
|
|
* Call `add_action` on any hook before 'admin_enqueue_scripts'.
|
|
*
|
|
* In the function call you supply, simply use `wp_enqueue_script` and
|
|
* `wp_enqueue_style` to add your functionality to the block editor.
|
|
*
|
|
* @since 5.0.0
|
|
*/
|
|
do_action( 'enqueue_block_editor_assets' );
|
|
|
|
// In order to duplicate classic meta box behaviour, we need to run the classic meta box actions.
|
|
require_once ABSPATH . 'wp-admin/includes/meta-boxes.php';
|
|
register_and_do_post_meta_boxes( $post );
|
|
|
|
// Check if the Custom Fields meta box has been removed at some point.
|
|
$core_meta_boxes = $wp_meta_boxes[ $current_screen->id ]['normal']['core'];
|
|
if ( ! isset( $core_meta_boxes['postcustom'] ) || ! $core_meta_boxes['postcustom'] ) {
|
|
unset( $editor_settings['enableCustomFields'] );
|
|
}
|
|
|
|
/**
|
|
* Filters the settings to pass to the block editor.
|
|
*
|
|
* @since 5.0.0
|
|
*
|
|
* @param array $editor_settings Default editor settings.
|
|
* @param WP_Post $post Post being edited.
|
|
*/
|
|
$editor_settings = apply_filters( 'block_editor_settings', $editor_settings, $post );
|
|
|
|
$init_script = <<<JS
|
|
( function() {
|
|
window._wpLoadBlockEditor = new Promise( function( resolve ) {
|
|
wp.domReady( function() {
|
|
resolve( wp.editPost.initializeEditor( 'editor', "%s", %d, %s, %s ) );
|
|
} );
|
|
} );
|
|
} )();
|
|
JS;
|
|
|
|
$script = sprintf(
|
|
$init_script,
|
|
$post->post_type,
|
|
$post->ID,
|
|
wp_json_encode( $editor_settings ),
|
|
wp_json_encode( $initial_edits )
|
|
);
|
|
wp_add_inline_script( 'wp-edit-post', $script );
|
|
|
|
require_once ABSPATH . 'wp-admin/admin-header.php';
|
|
?>
|
|
|
|
<div class="block-editor">
|
|
<h1 class="screen-reader-text hide-if-no-js"><?php echo esc_html( $title ); ?></h1>
|
|
<div id="editor" class="block-editor__container hide-if-no-js"></div>
|
|
<div id="metaboxes" class="hidden">
|
|
<?php the_block_editor_meta_boxes(); ?>
|
|
</div>
|
|
|
|
<?php // JavaScript is disabled. ?>
|
|
<div class="wrap hide-if-js block-editor-no-js">
|
|
<h1 class="wp-heading-inline"><?php echo esc_html( $title ); ?></h1>
|
|
<div class="notice notice-error notice-alt">
|
|
<p>
|
|
<?php
|
|
$message = sprintf(
|
|
/* translators: %s: A link to install the Classic Editor plugin. */
|
|
__( 'The block editor requires JavaScript. Please enable JavaScript in your browser settings, or try the <a href="%s">Classic Editor plugin</a>.' ),
|
|
esc_url( wp_nonce_url( self_admin_url( 'plugin-install.php?tab=favorites&user=wordpressdotorg&save=0' ), 'save_wporg_username_' . get_current_user_id() ) )
|
|
);
|
|
|
|
/**
|
|
* Filters the message displayed in the block editor interface when JavaScript is
|
|
* not enabled in the browser.
|
|
*
|
|
* @since 5.0.3
|
|
*
|
|
* @param string $message The message being displayed.
|
|
* @param WP_Post $post The post being edited.
|
|
*/
|
|
echo apply_filters( 'block_editor_no_javascript_message', $message, $post );
|
|
?>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|