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

Post fields: extract title from edit-site to fields package #66940

Merged
merged 5 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions packages/core-data/src/entity-types/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ declare module './base-entity-records' {
* The ID of the page that should be displayed on the front page
*/
page_on_front: number;
/**
* The ID of the page that should display the latest posts
*/
page_for_posts: number;
/**
* Site title.
*/
Expand Down
59 changes: 3 additions & 56 deletions packages/edit-site/src/components/post-fields/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import clsx from 'clsx';
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import { decodeEntities } from '@wordpress/html-entities';
import {
featuredImageField,
slugField,
parentField,
passwordField,
statusField,
commentStatusField,
titleField,
} from '@wordpress/fields';
import {
createInterpolateElement,
Expand Down Expand Up @@ -75,63 +75,10 @@ function usePostFields() {
const { records: authors, isResolving: isLoadingAuthors } =
useEntityRecords( 'root', 'user', { per_page: -1 } );

const { frontPageId, postsPageId } = useSelect( ( select ) => {
const { getEntityRecord } = select( coreStore );
const siteSettings = getEntityRecord( 'root', 'site' );
return {
frontPageId: siteSettings?.page_on_front,
postsPageId: siteSettings?.page_for_posts,
};
}, [] );

const fields = useMemo(
() => [
featuredImageField,
{
label: __( 'Title' ),
id: 'title',
type: 'text',
getValue: ( { item } ) =>
typeof item.title === 'string'
? item.title
: item.title?.raw,
render: ( { item } ) => {
const renderedTitle =
typeof item.title === 'string'
? item.title
: item.title?.rendered;

let suffix = '';
if ( item.id === frontPageId ) {
suffix = (
<span className="edit-site-post-list__title-badge">
{ __( 'Homepage' ) }
</span>
);
} else if ( item.id === postsPageId ) {
suffix = (
<span className="edit-site-post-list__title-badge">
{ __( 'Posts Page' ) }
</span>
);
}

return (
<HStack
className="edit-site-post-list__title"
alignment="center"
justify="flex-start"
>
<span>
{ decodeEntities( renderedTitle ) ||
__( '(no title)' ) }
</span>
{ suffix }
</HStack>
);
},
enableHiding: false,
},
titleField,
{
label: __( 'Author' ),
id: 'author',
Expand Down Expand Up @@ -234,7 +181,7 @@ function usePostFields() {
commentStatusField,
passwordField,
],
[ authors, frontPageId, postsPageId ]
[ authors ]
);

return {
Expand Down
4 changes: 2 additions & 2 deletions packages/fields/src/actions/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ export function getItemTitle( item: Post ) {
if ( typeof item.title === 'string' ) {
return decodeEntities( item.title );
}
if ( 'rendered' in item.title ) {
if ( item.title && 'rendered' in item.title ) {
return decodeEntities( item.title.rendered );
}
if ( 'raw' in item.title ) {
if ( item.title && 'raw' in item.title ) {
return decodeEntities( item.title.raw );
}
return '';
Expand Down
3 changes: 3 additions & 0 deletions packages/fields/src/fields/title/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import { __ } from '@wordpress/i18n';
*/
import type { BasePost } from '../../types';
import { getItemTitle } from '../../actions/utils';
import TitleView from './title-view';

const titleField: Field< BasePost > = {
type: 'text',
id: 'title',
label: __( 'Title' ),
placeholder: __( 'No title' ),
getValue: ( { item } ) => getItemTitle( item ),
Copy link
Contributor

Choose a reason for hiding this comment

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

It's nice that this basically means we're reusing the same field for DataForm and DataViews.

Copy link
Member Author

Choose a reason for hiding this comment

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

And actions! For the record, I tested the "Duplicate" action in DataViews, DataForm, and Document Inspector.

render: TitleView,
enableHiding: false,
};

export default titleField;
62 changes: 62 additions & 0 deletions packages/fields/src/fields/title/title-view.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* WordPress dependencies
*/
import { __experimentalHStack as HStack } from '@wordpress/components';
import { decodeEntities } from '@wordpress/html-entities';
import { __ } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import type { Settings } from '@wordpress/core-data';

/**
* Internal dependencies
*/
import type { BasePost } from '../../types';
import { getItemTitle } from '../../actions/utils';

const TitleView = ( { item }: { item: BasePost } ) => {
const { frontPageId, postsPageId } = useSelect( ( select ) => {
const { getEntityRecord } = select( coreStore );
const siteSettings: Settings | undefined = getEntityRecord(
'root',
'site',
''
Copy link
Member

Choose a reason for hiding this comment

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

It looks like siteSettings is undefined here, I think it's because of this empty key. If I remove the key parameter altogether, then siteSettings works (i.e. calling getEntityRecord with just root and site).

(Found because I'm working on #65426 😄)

Copy link
Member

Choose a reason for hiding this comment

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

I just realised this works because the above PR makes key optional in getEntityRecord. Maybe this isn't ideal, although I'm not sure the best way around it.

Copy link
Member Author

@oandregal oandregal Nov 18, 2024

Choose a reason for hiding this comment

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

Oh, I see. I had to add the empty string for TypeScript not to protest, it wasn't there before. Thanks for providing a fix :)

);
return {
frontPageId: siteSettings?.page_on_front,
postsPageId: siteSettings?.page_for_posts,
};
}, [] );

const renderedTitle = getItemTitle( item );

let suffix;
if ( item.id === frontPageId ) {
suffix = (
<span className="edit-site-post-list__title-badge">
{ __( 'Homepage' ) }
</span>
);
} else if ( item.id === postsPageId ) {
suffix = (
<span className="edit-site-post-list__title-badge">
{ __( 'Posts Page' ) }
</span>
);
}

return (
<HStack
className="edit-site-post-list__title"
alignment="center"
justify="flex-start"
>
<span>
{ decodeEntities( renderedTitle ) || __( '(no title)' ) }
</span>
{ suffix }
</HStack>
);
};

export default TitleView;
Loading