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

Fix dirty template and template parts on template creation. #26560

Merged
merged 10 commits into from
Oct 30, 2020
56 changes: 38 additions & 18 deletions packages/block-library/src/template-part/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { chevronUp, chevronDown } from '@wordpress/icons';

import { serialize } from '@wordpress/blocks';
/**
* Internal dependencies
*/
Expand All @@ -27,44 +27,64 @@ export default function TemplatePartEdit( {
setAttributes,
clientId,
} ) {
const initialPostId = useRef( _postId );
const initialSlug = useRef( slug );
const initialTheme = useRef( theme );
const initialContent = useRef();

// Resolve the post ID if not set, and load its post.
const postId = useTemplatePartPost( _postId, slug, theme );

// Set the post ID, once found, so that edits persist,
// but wait until the third inner blocks change,
// because the first 2 are just the template part
// content loading.
const { innerBlocks } = useSelect(
// Set the postId block attribute if it did not exist,
// but wait until the inner blocks have loaded to allow
// new edits to trigger this.
const { innerBlocks, expectedContent } = useSelect(
( select ) => {
const { getBlocks } = select( 'core/block-editor' );
const entityRecord = select( 'core' ).getEntityRecord(
'postType',
'wp_template_part',
postId
);

return {
innerBlocks: getBlocks( clientId ),
expectedContent: entityRecord?.content.raw,
};
},
[ clientId ]
[ clientId, postId ]
);
const { editEntityRecord } = useDispatch( 'core' );
const blockChanges = useRef( 0 );
useEffect( () => {
if ( blockChanges.current < 4 ) blockChanges.current++;
// If postId (entity) has not resolved or _postId (block attr) is set,
// then we have no need for this effect.
if ( ! postId || _postId ) {
return;
}

const innerContent = serialize( innerBlocks );

// If we havent set initialContent, check if innerBlocks are loaded.
if ( ! initialContent.current ) {
// If the content of innerBlocks and the content from entity match,
// then we can consider innerBlocks as loaded and set initialContent.
if ( innerContent === expectedContent ) {
initialContent.current = innerContent;
}
// Continue to return early until this effect is triggered
// with innerBlocks already loaded (as denoted by initialContent being set).
return;
}

if (
blockChanges.current === 3 &&
( initialPostId.current === undefined ||
initialPostId.current === null ) &&
postId !== undefined &&
postId !== null
) {
// After initialContent is set and the content is updated, we can set the
// postId block attribute and set the post status to 'publish'.
// After this is done the hook will no longer run due to the first return above.
if ( initialContent.current !== innerContent ) {
setAttributes( { postId } );
editEntityRecord( 'postType', 'wp_template_part', postId, {
status: 'publish',
} );
}
}, [ innerBlocks ] );
}, [ innerBlocks, expectedContent ] );
Addison-Stavlo marked this conversation as resolved.
Show resolved Hide resolved

const blockProps = useBlockProps();

Expand Down