Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let Gutenberg be default editor for posts with blocks; add links to classic editor #1797

Merged
merged 11 commits into from
Sep 8, 2017
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 184 additions & 21 deletions lib/register.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,62 @@ function gutenberg_menu() {
}
add_action( 'admin_menu', 'gutenberg_menu' );

/**
* Provide an edit link for posts and terms.
*
* @since 0.5.0
*
* @param WP_Admin_Bar $wp_admin_bar Admin bar.
*/
function gutenberg_add_admin_bar_edit_link( $wp_admin_bar ) {
$edit_node = $wp_admin_bar->get_node( 'edit' );
if ( ! $edit_node ) {
return;
}

$queried_object = get_queried_object();
if ( empty( $queried_object ) || empty( $queried_object->post_type ) || ! post_type_exists( $queried_object->post_type ) || ! gutenberg_can_edit_post( $queried_object->ID ) ) {
return;
}
$post = $queried_object;

if ( ! get_post_type_object( $post->post_type )->show_in_admin_bar ) {
return;
}

$classic_text = __( 'Edit in Classic Editor', 'gutenberg' );
remove_filter( 'get_edit_post_link', 'gutenberg_filter_edit_post_link', 10 );
$classic_url = get_edit_post_link( $post->ID, 'raw' );
add_filter( 'get_edit_post_link', 'gutenberg_filter_edit_post_link', 10, 3 );

if ( empty( $classic_url ) || ! post_type_supports( $post->post_type, 'editor' ) ) {
return;
}

$gutenberg_text = __( 'Edit in Gutenberg', 'gutenberg' );
$gutenberg_url = gutenberg_get_edit_post_url( $post->ID );

$is_gutenberg_default = gutenberg_post_has_blocks( $post->ID );

// Update title for edit link to indicate default editor.
$wp_admin_bar->add_node( array_merge(
(array) $edit_node,
array(
'title' => $is_gutenberg_default ? $gutenberg_text : $classic_text,
)
) );

// Add submenu item under link to go to Gutenberg editor or classic editor.
$wp_admin_bar->add_node( array(
'id' => 'edit_alt',
'parent' => 'edit',
'href' => $is_gutenberg_default ? $classic_url : $gutenberg_url,
'title' => $is_gutenberg_default ? $classic_text : $gutenberg_text,
) );

}
add_action( 'admin_bar_menu', 'gutenberg_add_admin_bar_edit_link', 81 );

/**
* Adds the filters to register additional links for the Gutenberg editor in
* the post/page screens.
Expand All @@ -82,39 +138,146 @@ function gutenberg_add_edit_links_filters() {
*
* @since 0.1.0
*
* @param array $actions Post actions.
* @param array $post Edited post.
* @param array $actions Post actions.
* @param WP_Post $post Edited post.
*
* @return array Updated post actions.
*/
function gutenberg_add_edit_links( $actions, $post ) {
$can_edit_post = current_user_can( 'edit_post', $post->ID );
$title = _draft_or_post_title( $post->ID );
$post_type = get_post_type( $post );
if ( ! gutenberg_can_edit_post( $post->ID ) ||
'trash' === $post->post_status ||
! post_type_supports( $post->post_type, 'editor' ) ||
! apply_filters( 'gutenberg_add_edit_link_for_post_type', true, $post->post_type, $post ) ) {
return $actions;
}

if ( $can_edit_post && 'trash' !== $post->post_status && apply_filters( 'gutenberg_add_edit_link_for_post_type', true, $post_type, $post ) ) {
// Build the Gutenberg edit action. See also: WP_Posts_List_Table::handle_row_actions().
$gutenberg_url = menu_page_url( 'gutenberg', false );
$gutenberg_action = sprintf(
if ( gutenberg_post_has_blocks( $post->ID ) ) {
remove_filter( 'get_edit_post_link', 'gutenberg_filter_edit_post_link', 10 );
add_filter( 'get_edit_post_link', 'gutenberg_filter_edit_post_link', 10, 3 );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@westonruter Should we just add a default filter handler for get_edit_post_link to always override with the preferred editor by content?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that what is already done here?

gutenberg/lib/register.php

Lines 210 to 231 in 547d038

/**
* Filters the post edit link to default to the Gutenberg editor when the post content contains a block.
*
* @since 0.5.0
*
* @param string $url The edit link URL.
* @param int $post_id Post ID.
* @param string $context The link context. If set to 'display' then ampersands are encoded.
* @return string Edit post link.
*/
function gutenberg_filter_edit_post_link( $url, $post_id, $context ) {
$post = get_post( $post_id );
if ( gutenberg_can_edit_post( $post_id ) && gutenberg_post_has_blocks( $post_id ) && post_type_supports( get_post_type( $post_id ), 'editor' ) ) {
$gutenberg_url = gutenberg_get_edit_post_url( $post->ID );
if ( 'display' === $context ) {
$gutenberg_url = esc_url( $gutenberg_url );
}
$url = $gutenberg_url;
}
return $url;
}
add_filter( 'get_edit_post_link', 'gutenberg_filter_edit_post_link', 10, 3 );

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why the remove_filter and add_filter are done above is to facilitate obtaining the classic post editor URL, even for a post that has blocks in it:

$classic_text = __( 'Edit in Classic Editor', 'gutenberg' );
remove_filter( 'get_edit_post_link', 'gutenberg_filter_edit_post_link', 10 );
$classic_url = get_edit_post_link( $post->ID, 'raw' );
add_filter( 'get_edit_post_link', 'gutenberg_filter_edit_post_link', 10, 3 );

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, seeing that now in the changes prior to 63ff18d. I guess this might not be working correctly for the "Classic Editor" link for Gutenberg posts currently then.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it stands right now, this if condition with add/remove of the get_edit_post_link filter is just removing and adding something right back, so it has no purpose right?

}

// Build the new edit actions. See also: WP_Posts_List_Table::handle_row_actions().
$title = _draft_or_post_title( $post->ID );
$edit_actions = array(
'classic hide-if-no-js' => sprintf(
'<a href="%s" aria-label="%s">%s</a>',
add_query_arg( 'post_id', $post->ID, $gutenberg_url ),
esc_url( get_edit_post_link( $post->ID, 'raw' ) ),
esc_attr( sprintf(
/* translators: %s: post title */
__( 'Edit &#8220;%s&#8221; in the classic editor', 'gutenberg' ),
$title
) ),
__( 'Classic Editor', 'gutenberg' )
),
'gutenberg hide-if-no-js' => sprintf(
'<a href="%s" aria-label="%s">%s</a>',
esc_url( gutenberg_get_edit_post_url( $post->ID ) ),
esc_attr( sprintf(
/* translators: %s: post title */
__( 'Edit &#8220;%s&#8221; in the Gutenberg editor', 'gutenberg' ),
$title
) ),
__( 'Gutenberg', 'gutenberg' )
);
// Insert the Gutenberg action immediately after the Edit action.
$edit_offset = array_search( 'edit', array_keys( $actions ), true );
$actions = array_merge(
array_slice( $actions, 0, $edit_offset + 1 ),
array(
'gutenberg hide-if-no-js' => $gutenberg_action,
),
array_slice( $actions, $edit_offset + 1 )
);
}
),
);

// Insert the new actions in place of the Edit action.
$edit_offset = array_search( 'edit', array_keys( $actions ), true );
$actions = array_merge(
array_slice( $actions, 0, $edit_offset ),
$edit_actions,
array_slice( $actions, $edit_offset + 1 )
);

return $actions;
}

/**
* Get the edit post URL for Gutenberg.
*
* @since 0.5.0
*
* @param int $post_id Post ID.
* @return string|false URL or false if not available.
*/
function gutenberg_get_edit_post_url( $post_id ) {
// Note that menu_page_url() cannot be used because it does not work on the frontend.
$gutenberg_url = admin_url( 'admin.php?page=gutenberg' );
$gutenberg_url = add_query_arg( 'post_id', $post_id, $gutenberg_url );
return $gutenberg_url;
}

/**
* Filters the post edit link to default to the Gutenberg editor when the post content contains a block.
*
* @since 0.5.0
*
* @param string $url The edit link URL.
* @param int $post_id Post ID.
* @param string $context The link context. If set to 'display' then ampersands are encoded.
* @return string Edit post link.
*/
function gutenberg_filter_edit_post_link( $url, $post_id, $context ) {
$post = get_post( $post_id );
if ( gutenberg_can_edit_post( $post_id ) && gutenberg_post_has_blocks( $post_id ) && post_type_supports( get_post_type( $post_id ), 'editor' ) ) {
$gutenberg_url = gutenberg_get_edit_post_url( $post->ID );
if ( 'display' === $context ) {
$gutenberg_url = esc_url( $gutenberg_url );
}
$url = $gutenberg_url;
}
return $url;
}
add_filter( 'get_edit_post_link', 'gutenberg_filter_edit_post_link', 10, 3 );

/**
* Return whether the post can be edited in Gutenberg and by the current user.
*
* Gutenberg depends on the REST API, and if the post type is not shown in the
* REST API, then the post cannot be edited in Gutenberg.
*
* @since 0.5.0
*
* @param int $post_id Post.
* @return bool Whether the post can be edited with Gutenberg.
*/
function gutenberg_can_edit_post( $post_id ) {
$post = get_post( $post_id );
if ( ! $post || ! post_type_exists( $post->post_type ) ) {
return false;
}
$post_type_object = get_post_type_object( $post->post_type );
if ( ! $post_type_object->show_in_rest ) {
return false;
}
return current_user_can( 'edit_post', $post_id );
}

/**
* Determine whether a post has blocks.
*
* @since 0.5.0
*
* @param int $post_id Post ID.
* @return bool Whether the post has blocks.
*/
function gutenberg_post_has_blocks( $post_id ) {
$post = get_post( $post_id );
return $post && strpos( $post->post_content, '<!-- wp:' ) !== false;
}

/**
* Adds a "Gutenberg" post state for post tables, if the post contains blocks.
*
* @param array $post_states An array of post display states.
* @param WP_Post $post The current post object.
* @return array A filtered array of post display states.
*/
function gutenberg_add_gutenberg_post_state( $post_states, $post ) {
if ( gutenberg_post_has_blocks( $post->ID ) ) {
$post_states[] = 'Gutenberg';
}

return $post_states;
}
add_filter( 'display_post_states', 'gutenberg_add_gutenberg_post_state', 10, 2 );
Loading