Skip to content
This repository has been archived by the owner on Oct 16, 2024. It is now read-only.

Allow adding new categories in Editor UI #123

Merged
merged 64 commits into from
Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
a59ecdc
Register new meta; hydrate editor with patternCategories
mike-day Mar 23, 2023
867881f
Adjust types for new customCategories, global
mike-day Mar 23, 2023
477d3f3
Update usePatternData to use global, create combinedCategories
mike-day Mar 23, 2023
a1e7af1
Add customCategories to pattern-data-handlers, parse in header, add r…
mike-day Mar 23, 2023
ebaa2c6
Use customCategories in CategoriesPanel
mike-day Mar 23, 2023
b562add
Move registration creation to it's own function; add conditional chec…
mike-day Mar 23, 2023
65b77cb
Add registry check before registering a category; move string buildin…
mike-day Mar 23, 2023
8771720
Conditionally add/remove `Custom Category` header
mike-day Mar 23, 2023
6b47385
Add missing doc for `maybe_add_custom_category_header`
mike-day Mar 23, 2023
c9f0ad3
Use prepended string to find custom categories instead of pm_meta; us…
mike-day Mar 24, 2023
2dce936
Try to make the registration string easier to read in pattern-data-ha…
mike-day Mar 24, 2023
731932f
Linting
mike-day Mar 24, 2023
88f460d
Remove unneeded $registered_categories, make registration block more …
mike-day Mar 27, 2023
109d9ad
Try to resolve CCI PHP linting error by removing inline function
mike-day Mar 27, 2023
601b302
Remove unused function maybe_display_formatted_category_registrations
mike-day Mar 27, 2023
19c42fb
Remove conditional checks, comments; use individual register calls in…
mike-day Mar 28, 2023
0e29eff
Getter for custom category prefix; hydrate editor with value
mike-day Mar 29, 2023
c027f73
Create parseCustomCategories util (with tests)
mike-day Mar 29, 2023
458ad38
Use parseCustomCategories in CategoriesPanel
mike-day Mar 29, 2023
a9c4d47
Create getSelectedOptions utility (with tests)
mike-day Mar 29, 2023
f653edd
Use getSelectedOptions in CategoriesPanel
mike-day Mar 29, 2023
5a69677
Import get_pattern_names at top of editor.php
mike-day Mar 29, 2023
c4cd4e6
Update util name to getCustomCategories
mike-day Mar 30, 2023
9e9e5cd
Add getSelectedOptions test case for duplicates
mike-day Mar 30, 2023
250891b
Maybe add text-domain to category registration
mike-day Mar 30, 2023
d2aef84
Editor: npm i --save-dev @types/jest
mike-day Mar 31, 2023
3ebb259
Fix type errors in a few editor util tests
mike-day Mar 31, 2023
8c580eb
App: npm i --save-dev @types/jest
mike-day Mar 31, 2023
e464100
Fix type errors in a few App js tests
mike-day Mar 31, 2023
ab2c646
Try adding `pm_custom` property for custom categories
mike-day Apr 6, 2023
a594057
Merge branch 'main' of https://github.com/studiopress/pattern-manager…
mike-day May 9, 2023
2648d8b
Linting
mike-day May 9, 2023
c3c9c5d
Remove extra newline in test pattern fixture
mike-day May 9, 2023
aec32b9
Merge branch 'main' of https://github.com/studiopress/pattern-manager…
mike-day May 16, 2023
55cd726
Remove duplicate global patternCategories
mike-day May 16, 2023
878c0be
Remove unused customCategoryPrefix
mike-day May 16, 2023
91d9a07
Add test for `maybe_add_custom_category_header`
mike-day May 19, 2023
5d3f2e8
Use a mock value for testing custom categories
mike-day May 19, 2023
fb8b87a
Add test for custom category registration; tweak mocks/tests for header
mike-day May 19, 2023
c233972
Remove newline chars from mock registrations
mike-day May 19, 2023
12e45b0
Tweak the mock again
mike-day May 19, 2023
58b2c05
Update the mock again to fix a typo
mike-day May 19, 2023
9c23184
Try using normalize for the new tests
mike-day May 19, 2023
20fb8e6
Lint PHP
mike-day May 19, 2023
82beb35
Merge branch 'main' of https://github.com/studiopress/pattern-manager…
mike-day May 22, 2023
bdcce92
Create `addNewCategory` util
mike-day May 24, 2023
6d5f2f5
Use the new util in `usePatternData`
mike-day May 24, 2023
64216ad
Condense the category header, registration functions (suggestion from…
mike-day May 24, 2023
f2f180c
Merge branch 'main' of https://github.com/studiopress/pattern-manager…
mike-day Jun 1, 2023
4a57894
Use toKebabCase instead of convertToSlug
mike-day Jun 1, 2023
9dc9099
Merge branch 'main' of https://github.com/studiopress/pattern-manager…
mike-day Jun 14, 2023
45d4f26
Create validateInput utility
mike-day Jun 15, 2023
ca0e239
Use the new util; style the input for illegal chars
mike-day Jun 15, 2023
6f9e726
Format the creation text to also strip illegal chars
mike-day Jun 15, 2023
f5fcdcf
See if slashing pattern categories helps
kienstra Jun 15, 2023
48ae649
Fix linting errors
kienstra Jun 15, 2023
99a2bde
Revert "Fix linting errors"
kienstra Jun 15, 2023
6f707e1
Revert "See if slashing pattern categories helps"
kienstra Jun 15, 2023
0e133b2
Use Ryan's suggestion and return a bool from util; update name to has…
mike-day Jun 16, 2023
2dbe129
Make sure categories array also gets the validated title
mike-day Jun 16, 2023
00bee10
Fix a typo in text case decription
mike-day Jun 16, 2023
bf3d3e8
Merge pull request #198 from studiopress/bugfix/validate-new-category…
mike-day Jun 16, 2023
fa190d8
Prevent the adding of an empty category name
mike-day Jun 16, 2023
31908ec
Merge branch 'main' of https://github.com/studiopress/pattern-manager…
mike-day Jun 16, 2023
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
29 changes: 24 additions & 5 deletions wp-modules/editor/editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,24 @@ function register_pattern_post_type() {
'default' => get_pattern_defaults()['keywords'],
)
);

register_post_meta(
$post_type_key,
'customCategories',
array(
'show_in_rest' => array(
'schema' => array(
'type' => 'array',
'items' => array(
'type' => 'string',
),
),
),
'single' => true,
'type' => 'array',
'default' => [],
)
);
}
add_action( 'init', __NAMESPACE__ . '\register_pattern_post_type' );

Expand Down Expand Up @@ -263,13 +281,14 @@ function enqueue_meta_fields_in_editor() {
'pattern_manager_post_meta',
'patternManager',
[
'activeTheme' => basename( get_stylesheet_directory() ),
'apiEndpoints' => array(
'activeTheme' => basename( get_stylesheet_directory() ),
'apiEndpoints' => array(
'getPatternNamesEndpoint' => get_rest_url( false, 'pattern-manager/v1/get-pattern-names/' ),
),
'apiNonce' => wp_create_nonce( 'wp_rest' ),
'patternNames' => \PatternManager\PatternDataHandlers\get_pattern_names(),
'siteUrl' => get_bloginfo( 'url' ),
'apiNonce' => wp_create_nonce( 'wp_rest' ),
'patternNames' => \PatternManager\PatternDataHandlers\get_pattern_names(),
'siteUrl' => get_bloginfo( 'url' ),
'patternCategories' => \WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(),
]
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export default function PatternManagerMetaControls() {
<CategoriesPanel
categories={ postMeta.categories }
categoryOptions={ queriedCategories }
customCategories={ postMeta.customCategories }
handleChange={ updatePostMeta }
/>
<KeywordsPanel
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { __ } from '@wordpress/i18n';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
import { Spinner } from '@wordpress/components';
import Select from 'react-select';
import Creatable from 'react-select/creatable';
import convertToSlug from '../../utils/convertToSlug';

import type { BaseSidebarProps, AdditionalSidebarProps } from './types';

Expand All @@ -12,36 +13,79 @@ import type { BaseSidebarProps, AdditionalSidebarProps } from './types';
export default function CategoriesPanel( {
categories,
categoryOptions,
customCategories,
handleChange,
}: BaseSidebarProps< 'categories' > &
}: BaseSidebarProps< 'categories' | 'customCategories' > &
AdditionalSidebarProps< 'categoryOptions' > ) {
const combinedSelectedCategories = [
...customCategories.filter( ( categoryTitle ) =>
categories.includes( convertToSlug( categoryTitle ) )
),
...categories,
];

return (
<PluginDocumentSettingPanel
name="patternmanager-pattern-editor-pattern-categories"
title={ __( 'Pattern Categories', 'pattern-manager' ) }
>
{ categoryOptions ? (
<Select
<Creatable
isMulti
isClearable
closeMenuOnSelect={ false }
aria-label={ __(
'Add Pattern Categories',
'pattern-manager'
) }
value={ categories?.map( ( category ) =>
categoryOptions.find(
( matchedCategory ) =>
matchedCategory.value === category
)
value={ combinedSelectedCategories.reduce(
( acc, categoryName ) =>
! acc.includes( categoryName )
? [
...acc,
categoryOptions.find(
( matchedCategory ) =>
matchedCategory.value ===
categoryName
),
]
: acc,
[]
) }
options={ categoryOptions }
onChange={ ( categorySelections ) => {
const selections = categorySelections.map(
( category ) => category.value
);

const customCategorySelections = categoryOptions.reduce(
( acc, category ) => {
const customCategoryFound =
selections.includes( category.value ) &&
category.pm_meta &&
category.pm_meta === 'pm_custom_category';

return customCategoryFound
? [ ...acc, category.label ]
: acc;
},
[]
);

handleChange( 'categories', selections, {
customCategories: customCategorySelections,
} );
} }
onCreateOption={ ( newCategoryTitle ) => {
handleChange(
'categories',
categorySelections.map(
( category ) => category.value
)
'customCategories',
[ ...customCategories, newCategoryTitle ],
{
categories: [
...categories,
convertToSlug( newCategoryTitle ),
],
}
);
} }
menuPlacement="auto"
Expand Down
52 changes: 40 additions & 12 deletions wp-modules/editor/js/src/hooks/usePatternData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import sortAlphabetically from '../utils/sortAlphabetically';
import { useSelect, useDispatch } from '@wordpress/data';
import { useEffect } from '@wordpress/element';
import { PostMeta, SelectQuery } from '../types';
import { patternManager } from '../globals';
import convertToSlug from '../utils/convertToSlug';

export default function usePatternData( postMeta: PostMeta ) {
const { editPost } = useDispatch( 'core/editor' );
Expand Down Expand Up @@ -57,18 +59,44 @@ export default function usePatternData( postMeta: PostMeta ) {

/**
* Alphabetized block pattern categories for the site editor, mapped for react-select.
*
* Using categories from app hydration instead of select( 'core' ).getBlockPatternCategories().
* Otherwise, custom fields (such as `pm_meta`) are not included in the result.
*/
const categories = useSelect( ( select: SelectQuery ) => {
return sortAlphabetically(
select( 'core' )
.getBlockPatternCategories()
.map( ( category ) => ( {
label: category.label,
value: category.name,
} ) ),
'label'
);
}, [] );
const categories = sortAlphabetically(
patternManager.patternCategories.map( ( category ) => ( {
label: category.label,
value: category.name,
...( category.pm_meta && {
pm_meta: category.pm_meta,
} ),
} ) ),
'label'
);

/**
* Registered and newly added custom categories, combined.
* Needed for including new categories before the post is saved.
*/
const combinedCategories: typeof categories = [
...postMeta.customCategories.reduce( ( acc, categoryLabel ) => {
const missingCategory = ! categories.some(
( queriedCategory ) => queriedCategory.label === categoryLabel
);

return missingCategory
? [
...acc,
{
label: categoryLabel,
value: convertToSlug( categoryLabel ),
pm_meta: 'pm_custom_category',
},
]
: acc;
}, [] ),
...categories,
mike-day marked this conversation as resolved.
Show resolved Hide resolved
];

/**
* The alphabetized list of transformable block types, mapped for react-select.
Expand Down Expand Up @@ -195,7 +223,7 @@ export default function usePatternData( postMeta: PostMeta ) {

return {
queriedBlockTypes: blockTypes,
queriedCategories: categories,
queriedCategories: combinedCategories,
queriedPostTypes: postTypes,
updatePostMeta,
updatePostMetaMulti,
Expand Down
14 changes: 13 additions & 1 deletion wp-modules/editor/js/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
export type PostMeta = {
blockTypes: string[];
categories: string[];
customCategories: string[];
description: string;
inserter: boolean;
keywords: string[];
Expand All @@ -16,7 +17,11 @@ export type PatternPostData = PostMeta & {
};

export type SelectQuery = ( dataStore: string ) => {
getBlockPatternCategories: () => { name: string; label: string }[];
getBlockPatternCategories: () => {
name: string;
label: string;
pm_meta?: string;
}[];
getBlockTypes: () => { name: string; transforms?: unknown }[];
getCurrentPostAttribute: ( attributeName: 'meta' ) => PostMeta;
getEditedPostAttribute: ( postAttribute: string ) => unknown;
Expand All @@ -34,6 +39,7 @@ export type SelectQuery = ( dataStore: string ) => {
export type Pattern = {
blockTypes: string[];
categories: string[];
customCategories: string[];
content: string;
description: string;
inserter: boolean;
Expand All @@ -55,6 +61,12 @@ export type InitialPatternManager = {
apiEndpoints: {
getPatternNamesEndpoint: string;
};
patternCategories: {
name: string;
label: string;
description?: string;
pm_meta?: string;
}[];
patternNames: Array< Pattern[ 'slug' ] >;
siteUrl: string;
};
Loading