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

Try: Improve permalink editing #12009

Merged
merged 9 commits into from
Mar 18, 2020
14 changes: 14 additions & 0 deletions docs/designers-developers/developers/data/data-core-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,20 @@ _Returns_

- `?string`: Preview Link.

<a name="getEditedPostSlug" href="#getEditedPostSlug">#</a> **getEditedPostSlug**

Returns the slug for the post being edited, preferring a manually edited
value if one exists, then a sanitized version of the current post title, and
finally the post ID.

_Parameters_

- _state_ `Object`: Editor state.

_Returns_

- `string`: The current slug to be displayed in the editor

<a name="getEditedPostVisibility" href="#getEditedPostVisibility">#</a> **getEditedPostVisibility**

Returns the current visibility of the post being edited, preferring the
Expand Down
73 changes: 73 additions & 0 deletions lib/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,76 @@ function wp_api_nav_menus_taxonomy_args( $args, $taxonomy ) {
return $args;
}
add_filter( 'register_taxonomy_args', 'wp_api_nav_menus_taxonomy_args', 10, 2 );

/**
* Shim for get_sample_permalink() to add support for auto-draft status.
*
* This function filters the return from get_sample_permalink() and essentially
* re-runs the same logic minus the filters, but pretends a status of auto-save
* is actually publish in order to return the future permalink format.
*
* This is a temporary fix until we can patch get_sample_permalink()
*
* @see https://core.trac.wordpress.org/ticket/46266
*
* @param array $permalink Array containing the sample permalink with placeholder for the post name, and the post name.
* @param int $id ID of the post.
* @param string $title Title of the post.
* @param string $name Slug of the post.
* @param object $post WP_Post object.
*
* @return array Array containing the sample permalink with placeholder for the post name, and the post name.
*/
function gutenberg_auto_draft_get_sample_permalink( $permalink, $id, $title, $name, $post ) {
if ( 'auto-draft' !== $post->post_status ) {
return $permalink;
}
$ptype = get_post_type_object( $post->post_type );

$original_status = $post->post_status;
$original_date = $post->post_date;
$original_name = $post->post_name;

// Hack: get_permalink() would return ugly permalink for drafts, so we will fake that our post is published.
$post->post_status = 'publish';
$post->post_name = sanitize_title( $post->post_name ? $post->post_name : $post->post_title, $post->ID );

// If the user wants to set a new name -- override the current one.
// Note: if empty name is supplied -- use the title instead, see #6072.
if ( ! is_null( $name ) ) {
$post->post_name = sanitize_title( $name ? $name : $title, $post->ID );
}

$post->post_name = wp_unique_post_slug( $post->post_name, $post->ID, $post->post_status, $post->post_type, $post->post_parent );

$post->filter = 'sample';

$permalink = get_permalink( $post, true );

// Replace custom post_type Token with generic pagename token for ease of use.
$permalink = str_replace( "%$post->post_type%", '%pagename%', $permalink );

// Handle page hierarchy.
if ( $ptype->hierarchical ) {
$uri = get_page_uri( $post );
if ( $uri ) {
$uri = untrailingslashit( $uri );
$uri = strrev( stristr( strrev( $uri ), '/' ) );
$uri = untrailingslashit( $uri );
}

if ( ! empty( $uri ) ) {
$uri .= '/';
}
$permalink = str_replace( '%pagename%', "{$uri}%pagename%", $permalink );
}

$permalink = array( $permalink, $post->post_name );
$post->post_status = $original_status;
$post->post_date = $original_date;
$post->post_name = $original_name;
unset( $post->filter );

return $permalink;
}
add_filter( 'get_sample_permalink', 'gutenberg_auto_draft_get_sample_permalink', 10, 5 );
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
createNewPost,
deactivatePlugin,
findSidebarPanelWithTitle,
openDocumentSettingsSidebar,
publishPost,
} from '@wordpress/e2e-test-utils';

Expand All @@ -23,21 +22,8 @@ describe( 'Sidebar Permalink Panel', () => {
await deactivatePlugin( 'gutenberg-test-custom-post-types' );
} );

it( 'should not render permalink sidebar panel while the post is new', async () => {
it( 'should allow permalink sidebar panel to be removed', async () => {
await createNewPost();
await openDocumentSettingsSidebar();
expect(
await findSidebarPanelWithTitle( 'Permalink' )
).toBeUndefined();
} );

it( 'should render permalink sidebar panel after the post is published and allow its removal', async () => {
await createNewPost();
await page.keyboard.type( 'aaaaa' );
await publishPost();
// Start editing again.
await page.type( '.editor-post-title__input', ' (Updated)' );
expect( await findSidebarPanelWithTitle( 'Permalink' ) ).toBeDefined();
await page.evaluate( () => {
const { removeEditorPanel } = wp.data.dispatch( 'core/edit-post' );
removeEditorPanel( 'post-link' );
Expand Down
31 changes: 9 additions & 22 deletions packages/edit-post/src/components/sidebar/post-link/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,18 @@ function PostLink( {
editPermalink,
forceEmptyField,
setState,
postTitle,
postSlug,
postID,
postTypeLabel,
} ) {
const { prefix, suffix } = permalinkParts;
let prefixElement, postNameElement, suffixElement;
const currentSlug =
safeDecodeURIComponent( postSlug ) ||
cleanForSlug( postTitle ) ||
postID;
if ( isEditable ) {
prefixElement = prefix && (
<span className="edit-post-post-link__link-prefix">{ prefix }</span>
);
postNameElement = currentSlug && (
postNameElement = postSlug && (
<span className="edit-post-post-link__link-post-name">
{ currentSlug }
{ postSlug }
</span>
);
suffixElement = suffix && (
Expand All @@ -62,7 +56,7 @@ function PostLink( {
<div className="editor-post-link">
<TextControl
label={ __( 'URL Slug' ) }
value={ forceEmptyField ? '' : currentSlug }
value={ forceEmptyField ? '' : postSlug }
onChange={ ( newValue ) => {
editPermalink( newValue );
// When we delete the field the permalink gets
Expand Down Expand Up @@ -127,45 +121,38 @@ function PostLink( {
export default compose( [
withSelect( ( select ) => {
const {
isEditedPostNew,
isPermalinkEditable,
getCurrentPost,
isCurrentPostPublished,
getPermalinkParts,
getEditedPostAttribute,
getEditedPostSlug,
} = select( 'core/editor' );
const { isEditorPanelEnabled, isEditorPanelOpened } = select(
'core/edit-post'
);
const { getPostType } = select( 'core' );

const { link, id } = getCurrentPost();
const { link } = getCurrentPost();

const postTypeName = getEditedPostAttribute( 'type' );
const postType = getPostType( postTypeName );

return {
isNew: isEditedPostNew(),
postLink: link,
isEditable: isPermalinkEditable(),
isPublished: isCurrentPostPublished(),
isOpened: isEditorPanelOpened( PANEL_NAME ),
permalinkParts: getPermalinkParts(),
isEnabled: isEditorPanelEnabled( PANEL_NAME ),
isViewable: get( postType, [ 'viewable' ], false ),
postTitle: getEditedPostAttribute( 'title' ),
postSlug: getEditedPostAttribute( 'slug' ),
postID: id,
postSlug: safeDecodeURIComponent( getEditedPostSlug() ),
postTypeLabel: get( postType, [ 'labels', 'view_item' ] ),
};
} ),
ifCondition(
( { isEnabled, isNew, postLink, isViewable, permalinkParts } ) => {
return (
isEnabled && ! isNew && postLink && isViewable && permalinkParts
);
}
),
ifCondition( ( { isEnabled, postLink, isViewable, permalinkParts } ) => {
return isEnabled && postLink && isViewable && permalinkParts;
} ),
withDispatch( ( dispatch ) => {
const { toggleEditorPanelOpened } = dispatch( 'core/edit-post' );
const { editPost } = dispatch( 'core/editor' );
Expand Down
20 changes: 7 additions & 13 deletions packages/editor/src/components/post-permalink/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { link as linkIcon } from '@wordpress/icons';
* Internal dependencies
*/
import PostPermalinkEditor from './editor.js';
import { cleanForSlug } from '../../utils/url';

class PostPermalink extends Component {
constructor() {
Expand Down Expand Up @@ -70,8 +69,6 @@ class PostPermalink extends Component {
permalinkParts,
postLink,
postSlug,
postID,
postTitle,
} = this.props;

if ( isNew || ! isViewable || ! permalinkParts || ! postLink ) {
Expand All @@ -84,11 +81,9 @@ class PostPermalink extends Component {
: __( 'Copy the permalink' );

const { prefix, suffix } = permalinkParts;
const slug =
safeDecodeURIComponent( postSlug ) ||
cleanForSlug( postTitle ) ||
postID;
const samplePermalink = isEditable ? prefix + slug + suffix : prefix;
const samplePermalink = isEditable
? prefix + postSlug + suffix
: prefix;

return (
<div className="editor-post-permalink">
Expand Down Expand Up @@ -123,7 +118,7 @@ class PostPermalink extends Component {

{ isEditingPermalink && (
<PostPermalinkEditor
slug={ slug }
slug={ postSlug }
onSave={ () =>
this.setState( { isEditingPermalink: false } )
}
Expand Down Expand Up @@ -155,10 +150,11 @@ export default compose( [
getPermalinkParts,
getEditedPostAttribute,
isCurrentPostPublished,
getEditedPostSlug,
} = select( 'core/editor' );
const { getPostType } = select( 'core' );

const { id, link } = getCurrentPost();
const { link } = getCurrentPost();

const postTypeName = getEditedPostAttribute( 'type' );
const postType = getPostType( postTypeName );
Expand All @@ -167,11 +163,9 @@ export default compose( [
isNew: isEditedPostNew(),
postLink: link,
permalinkParts: getPermalinkParts(),
postSlug: getEditedPostAttribute( 'slug' ),
postSlug: safeDecodeURIComponent( getEditedPostSlug() ),
isEditable: isPermalinkEditable(),
isPublished: isCurrentPostPublished(),
postTitle: getEditedPostAttribute( 'title' ),
postID: id,
isViewable: get( postType, [ 'viewable' ], false ),
};
} ),
Expand Down
18 changes: 18 additions & 0 deletions packages/editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
} from './constants';
import { getPostRawValue } from './reducer';
import serializeBlocks from './utils/serialize-blocks';
import { cleanForSlug } from '../utils/url';

/**
* Shared reference to an empty object for cases where it is important to avoid
Expand Down Expand Up @@ -1149,6 +1150,23 @@ export function getPermalink( state ) {
return prefix;
}

/**
* Returns the slug for the post being edited, preferring a manually edited
* value if one exists, then a sanitized version of the current post title, and
* finally the post ID.
*
* @param {Object} state Editor state.
*
* @return {string} The current slug to be displayed in the editor
*/
export function getEditedPostSlug( state ) {
return (
getEditedPostAttribute( state, 'slug' ) ||
cleanForSlug( getEditedPostAttribute( state, 'title' ) ) ||
getCurrentPostId( state )
);
}

/**
* Returns the permalink for a post, split into it's three parts: the prefix,
* the postName, and the suffix.
Expand Down
Loading