@wordpress/block-library 8.3.2 → 8.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/build/button/edit.js +3 -1
- package/build/button/edit.js.map +1 -1
- package/build/button/index.js +17 -6
- package/build/button/index.js.map +1 -1
- package/build/cover/edit/index.js +3 -2
- package/build/cover/edit/index.js.map +1 -1
- package/build/file/index.js +10 -1
- package/build/file/index.js.map +1 -1
- package/build/image/image.js +21 -15
- package/build/image/image.js.map +1 -1
- package/build/latest-comments/edit.js +6 -2
- package/build/latest-comments/edit.js.map +1 -1
- package/build/latest-comments/index.js +13 -0
- package/build/latest-comments/index.js.map +1 -1
- package/build/navigation/edit/index.js +2 -28
- package/build/navigation/edit/index.js.map +1 -1
- package/build/navigation/edit/menu-inspector-controls.js +5 -6
- package/build/navigation/edit/menu-inspector-controls.js.map +1 -1
- package/build/navigation/edit/navigation-menu-selector.js +14 -11
- package/build/navigation/edit/navigation-menu-selector.js.map +1 -1
- package/build/navigation/edit/unsaved-inner-blocks.js +4 -5
- package/build/navigation/edit/unsaved-inner-blocks.js.map +1 -1
- package/build/navigation/edit/use-create-navigation-menu.js +11 -2
- package/build/navigation/edit/use-create-navigation-menu.js.map +1 -1
- package/build/navigation/use-navigation-menu.js +1 -1
- package/build/navigation/use-navigation-menu.js.map +1 -1
- package/build/navigation-link/edit.js +4 -0
- package/build/navigation-link/edit.js.map +1 -1
- package/build/navigation-link/link-ui.js +1 -0
- package/build/navigation-link/link-ui.js.map +1 -1
- package/build/navigation-submenu/edit.js +4 -0
- package/build/navigation-submenu/edit.js.map +1 -1
- package/build/page-list/edit.js +5 -4
- package/build/page-list/edit.js.map +1 -1
- package/build/page-list/use-convert-to-navigation-links.js +61 -5
- package/build/page-list/use-convert-to-navigation-links.js.map +1 -1
- package/build/post-excerpt/edit.js +49 -3
- package/build/post-excerpt/edit.js.map +1 -1
- package/build/post-excerpt/index.js +4 -0
- package/build/post-excerpt/index.js.map +1 -1
- package/build/post-featured-image/dimension-controls.js +52 -1
- package/build/post-featured-image/dimension-controls.js.map +1 -1
- package/build/post-featured-image/edit.js +9 -4
- package/build/post-featured-image/edit.js.map +1 -1
- package/build/post-featured-image/index.js +3 -0
- package/build/post-featured-image/index.js.map +1 -1
- package/build/{experiments.js → private-apis.js} +3 -3
- package/build/private-apis.js.map +1 -0
- package/build/site-logo/edit.js +7 -11
- package/build/site-logo/edit.js.map +1 -1
- package/build/table/edit.js +3 -3
- package/build/table/edit.js.map +1 -1
- package/build/table-of-contents/utils.js +1 -1
- package/build/table-of-contents/utils.js.map +1 -1
- package/build/verse/index.js +6 -0
- package/build/verse/index.js.map +1 -1
- package/build-module/button/edit.js +2 -1
- package/build-module/button/edit.js.map +1 -1
- package/build-module/button/index.js +17 -6
- package/build-module/button/index.js.map +1 -1
- package/build-module/cover/edit/index.js +3 -2
- package/build-module/cover/edit/index.js.map +1 -1
- package/build-module/file/index.js +10 -1
- package/build-module/file/index.js.map +1 -1
- package/build-module/image/image.js +21 -15
- package/build-module/image/image.js.map +1 -1
- package/build-module/latest-comments/edit.js +6 -2
- package/build-module/latest-comments/edit.js.map +1 -1
- package/build-module/latest-comments/index.js +13 -0
- package/build-module/latest-comments/index.js.map +1 -1
- package/build-module/navigation/edit/index.js +3 -29
- package/build-module/navigation/edit/index.js.map +1 -1
- package/build-module/navigation/edit/menu-inspector-controls.js +5 -5
- package/build-module/navigation/edit/menu-inspector-controls.js.map +1 -1
- package/build-module/navigation/edit/navigation-menu-selector.js +14 -10
- package/build-module/navigation/edit/navigation-menu-selector.js.map +1 -1
- package/build-module/navigation/edit/unsaved-inner-blocks.js +4 -5
- package/build-module/navigation/edit/unsaved-inner-blocks.js.map +1 -1
- package/build-module/navigation/edit/use-create-navigation-menu.js +11 -2
- package/build-module/navigation/edit/use-create-navigation-menu.js.map +1 -1
- package/build-module/navigation/use-navigation-menu.js +1 -1
- package/build-module/navigation/use-navigation-menu.js.map +1 -1
- package/build-module/navigation-link/edit.js +4 -0
- package/build-module/navigation-link/edit.js.map +1 -1
- package/build-module/navigation-link/link-ui.js +1 -0
- package/build-module/navigation-link/link-ui.js.map +1 -1
- package/build-module/navigation-submenu/edit.js +4 -0
- package/build-module/navigation-submenu/edit.js.map +1 -1
- package/build-module/page-list/edit.js +5 -4
- package/build-module/page-list/edit.js.map +1 -1
- package/build-module/page-list/use-convert-to-navigation-links.js +61 -5
- package/build-module/page-list/use-convert-to-navigation-links.js.map +1 -1
- package/build-module/post-excerpt/edit.js +52 -5
- package/build-module/post-excerpt/edit.js.map +1 -1
- package/build-module/post-excerpt/index.js +4 -0
- package/build-module/post-excerpt/index.js.map +1 -1
- package/build-module/post-featured-image/dimension-controls.js +52 -1
- package/build-module/post-featured-image/dimension-controls.js.map +1 -1
- package/build-module/post-featured-image/edit.js +9 -4
- package/build-module/post-featured-image/edit.js.map +1 -1
- package/build-module/post-featured-image/index.js +3 -0
- package/build-module/post-featured-image/index.js.map +1 -1
- package/build-module/{experiments.js → private-apis.js} +2 -2
- package/build-module/private-apis.js.map +1 -0
- package/build-module/site-logo/edit.js +7 -11
- package/build-module/site-logo/edit.js.map +1 -1
- package/build-module/table/edit.js +3 -3
- package/build-module/table/edit.js.map +1 -1
- package/build-module/table-of-contents/utils.js +1 -1
- package/build-module/table-of-contents/utils.js.map +1 -1
- package/build-module/verse/index.js +6 -0
- package/build-module/verse/index.js.map +1 -1
- package/build-style/avatar/style-rtl.css +3 -0
- package/build-style/avatar/style.css +3 -0
- package/build-style/button/editor-rtl.css +31 -0
- package/build-style/button/editor.css +31 -0
- package/build-style/button/style-rtl.css +31 -0
- package/build-style/button/style.css +31 -0
- package/build-style/classic-rtl.css +5 -0
- package/build-style/classic.css +5 -0
- package/build-style/editor-rtl.css +36 -1
- package/build-style/editor.css +36 -1
- package/build-style/file/style-rtl.css +1 -0
- package/build-style/file/style.css +1 -0
- package/build-style/image/editor-rtl.css +1 -0
- package/build-style/image/editor.css +1 -0
- package/build-style/image/style-rtl.css +6 -2
- package/build-style/image/style.css +6 -0
- package/build-style/latest-comments/style-rtl.css +18 -5
- package/build-style/latest-comments/style.css +18 -5
- package/build-style/quote/style-rtl.css +5 -5
- package/build-style/quote/style.css +5 -5
- package/build-style/style-rtl.css +64 -12
- package/build-style/style.css +64 -10
- package/build-types/table-of-contents/utils.d.ts +1 -1
- package/package.json +30 -30
- package/src/avatar/index.php +67 -63
- package/src/avatar/style.scss +3 -0
- package/src/button/block.json +17 -6
- package/src/button/edit.js +2 -1
- package/src/button/editor.scss +36 -0
- package/src/button/style.scss +37 -1
- package/src/classic.scss +5 -0
- package/src/cover/edit/index.js +4 -1
- package/src/editor.scss +5 -0
- package/src/file/block.json +10 -1
- package/src/file/style.scss +1 -0
- package/src/image/editor.scss +1 -0
- package/src/image/image.js +32 -27
- package/src/image/style.scss +13 -0
- package/src/latest-comments/block.json +13 -0
- package/src/latest-comments/edit.js +9 -2
- package/src/latest-comments/style.scss +25 -7
- package/src/navigation/edit/index.js +1 -30
- package/src/navigation/edit/menu-inspector-controls.js +3 -4
- package/src/navigation/edit/navigation-menu-selector.js +12 -26
- package/src/navigation/edit/test/navigation-menu-selector.js +638 -0
- package/src/navigation/edit/unsaved-inner-blocks.js +29 -36
- package/src/navigation/edit/use-create-navigation-menu.js +13 -1
- package/src/navigation/index.php +8 -6
- package/src/navigation/use-navigation-menu.js +1 -1
- package/src/navigation-link/edit.js +3 -0
- package/src/navigation-link/link-ui.js +1 -0
- package/src/navigation-submenu/edit.js +3 -0
- package/src/page-list/edit.js +6 -5
- package/src/page-list/index.php +4 -4
- package/src/page-list/test/convert-to-links-modal.js +134 -0
- package/src/page-list/use-convert-to-navigation-links.js +64 -4
- package/src/post-excerpt/block.json +4 -0
- package/src/post-excerpt/edit.js +72 -7
- package/src/post-excerpt/index.php +29 -5
- package/src/post-featured-image/block.json +3 -0
- package/src/post-featured-image/dimension-controls.js +64 -2
- package/src/post-featured-image/edit.js +18 -6
- package/src/post-featured-image/index.php +25 -9
- package/src/post-title/index.php +3 -3
- package/src/{experiments.js → private-apis.js} +1 -1
- package/src/quote/style.scss +2 -2
- package/src/site-logo/edit.js +3 -6
- package/src/table/edit.js +3 -3
- package/src/table-of-contents/utils.ts +1 -1
- package/src/template-part/index.php +1 -1
- package/src/verse/block.json +6 -0
- package/tsconfig.json +24 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/build/experiments.js.map +0 -1
- package/build/navigation/leaf-more-menu.js +0 -95
- package/build/navigation/leaf-more-menu.js.map +0 -1
- package/build-module/experiments.js.map +0 -1
- package/build-module/navigation/leaf-more-menu.js +0 -76
- package/build-module/navigation/leaf-more-menu.js.map +0 -1
- package/src/navigation/leaf-more-menu.js +0 -93
|
@@ -39,7 +39,6 @@ const ALLOWED_BLOCKS = [
|
|
|
39
39
|
export default function UnsavedInnerBlocks( {
|
|
40
40
|
blocks,
|
|
41
41
|
createNavigationMenu,
|
|
42
|
-
|
|
43
42
|
hasSelection,
|
|
44
43
|
} ) {
|
|
45
44
|
const originalBlocks = useRef();
|
|
@@ -91,37 +90,34 @@ export default function UnsavedInnerBlocks( {
|
|
|
91
90
|
}
|
|
92
91
|
);
|
|
93
92
|
|
|
94
|
-
const { isSaving,
|
|
95
|
-
|
|
96
|
-
(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
const { hasResolvedNavigationMenus, navigationMenus } = useNavigationMenu();
|
|
93
|
+
const { isSaving, hasResolvedDraftNavigationMenus } = useSelect(
|
|
94
|
+
( select ) => {
|
|
95
|
+
if ( isDisabled ) {
|
|
96
|
+
return EMPTY_OBJECT;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const {
|
|
100
|
+
getEntityRecords,
|
|
101
|
+
hasFinishedResolution,
|
|
102
|
+
isSavingEntityRecord,
|
|
103
|
+
} = select( coreStore );
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
isSaving: isSavingEntityRecord( 'postType', 'wp_navigation' ),
|
|
107
|
+
draftNavigationMenus: getEntityRecords(
|
|
108
|
+
// This is needed so that hasResolvedDraftNavigationMenus gives the correct status.
|
|
109
|
+
...DRAFT_MENU_PARAMS
|
|
110
|
+
),
|
|
111
|
+
hasResolvedDraftNavigationMenus: hasFinishedResolution(
|
|
112
|
+
'getEntityRecords',
|
|
113
|
+
DRAFT_MENU_PARAMS
|
|
114
|
+
),
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
[ isDisabled ]
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
const { hasResolvedNavigationMenus } = useNavigationMenu();
|
|
125
121
|
|
|
126
122
|
// Automatically save the uncontrolled blocks.
|
|
127
123
|
useEffect( () => {
|
|
@@ -154,11 +150,8 @@ export default function UnsavedInnerBlocks( {
|
|
|
154
150
|
isSaving,
|
|
155
151
|
hasResolvedDraftNavigationMenus,
|
|
156
152
|
hasResolvedNavigationMenus,
|
|
157
|
-
|
|
158
|
-
navigationMenus,
|
|
153
|
+
innerBlocksAreDirty,
|
|
159
154
|
hasSelection,
|
|
160
|
-
createNavigationMenu,
|
|
161
|
-
blocks,
|
|
162
155
|
] );
|
|
163
156
|
|
|
164
157
|
const Wrapper = isSaving ? Disabled : 'div';
|
|
@@ -21,7 +21,7 @@ export default function useCreateNavigationMenu( clientId ) {
|
|
|
21
21
|
const [ value, setValue ] = useState( null );
|
|
22
22
|
const [ error, setError ] = useState( null );
|
|
23
23
|
|
|
24
|
-
const { saveEntityRecord } = useDispatch( coreStore );
|
|
24
|
+
const { saveEntityRecord, editEntityRecord } = useDispatch( coreStore );
|
|
25
25
|
const generateDefaultTitle = useGenerateDefaultNavigationTitle( clientId );
|
|
26
26
|
|
|
27
27
|
// This callback uses data from the two placeholder steps and only creates
|
|
@@ -68,6 +68,18 @@ export default function useCreateNavigationMenu( clientId ) {
|
|
|
68
68
|
.then( ( response ) => {
|
|
69
69
|
setValue( response );
|
|
70
70
|
setStatus( CREATE_NAVIGATION_MENU_SUCCESS );
|
|
71
|
+
|
|
72
|
+
// Set the status to publish so that the Navigation block
|
|
73
|
+
// shows up in the multi entity save flow.
|
|
74
|
+
if ( postStatus !== 'publish' ) {
|
|
75
|
+
editEntityRecord(
|
|
76
|
+
'postType',
|
|
77
|
+
'wp_navigation',
|
|
78
|
+
response.id,
|
|
79
|
+
{ status: 'publish' }
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
71
83
|
return response;
|
|
72
84
|
} )
|
|
73
85
|
.catch( ( err ) => {
|
package/src/navigation/index.php
CHANGED
|
@@ -373,12 +373,14 @@ function block_core_navigation_get_most_recently_published_navigation() {
|
|
|
373
373
|
|
|
374
374
|
// Default to the most recently created menu.
|
|
375
375
|
$parsed_args = array(
|
|
376
|
-
'post_type'
|
|
377
|
-
'no_found_rows'
|
|
378
|
-
'
|
|
379
|
-
'
|
|
380
|
-
'
|
|
381
|
-
'
|
|
376
|
+
'post_type' => 'wp_navigation',
|
|
377
|
+
'no_found_rows' => true,
|
|
378
|
+
'update_post_meta_cache' => false,
|
|
379
|
+
'update_post_term_cache' => false,
|
|
380
|
+
'order' => 'DESC',
|
|
381
|
+
'orderby' => 'date',
|
|
382
|
+
'post_status' => 'publish',
|
|
383
|
+
'posts_per_page' => 1, // get only the most recent.
|
|
382
384
|
);
|
|
383
385
|
|
|
384
386
|
$navigation_post = new WP_Query( $parsed_args );
|
|
@@ -261,6 +261,9 @@ export default function NavigationLinkEdit( {
|
|
|
261
261
|
useEffect( () => {
|
|
262
262
|
// If block has inner blocks, transform to Submenu.
|
|
263
263
|
if ( hasChildren ) {
|
|
264
|
+
// This side-effect should not create an undo level as those should
|
|
265
|
+
// only be created via user interactions.
|
|
266
|
+
__unstableMarkNextChangeAsNotPersistent();
|
|
264
267
|
transformToSubmenu();
|
|
265
268
|
}
|
|
266
269
|
}, [ hasChildren ] );
|
|
@@ -358,6 +358,9 @@ export default function NavigationSubmenuEdit( {
|
|
|
358
358
|
useEffect( () => {
|
|
359
359
|
// If block becomes empty, transform to Navigation Link.
|
|
360
360
|
if ( ! hasChildren && prevHasChildren ) {
|
|
361
|
+
// This side-effect should not create an undo level as those should
|
|
362
|
+
// only be created via user interactions.
|
|
363
|
+
__unstableMarkNextChangeAsNotPersistent();
|
|
361
364
|
transformToLink();
|
|
362
365
|
}
|
|
363
366
|
}, [ hasChildren, prevHasChildren ] );
|
package/src/page-list/edit.js
CHANGED
|
@@ -182,11 +182,6 @@ export default function PageListEdit( {
|
|
|
182
182
|
pages?.length > 0 &&
|
|
183
183
|
pages?.length <= MAX_PAGE_COUNT;
|
|
184
184
|
|
|
185
|
-
const convertToNavigationLinks = useConvertToNavigationLinks( {
|
|
186
|
-
clientId,
|
|
187
|
-
pages,
|
|
188
|
-
} );
|
|
189
|
-
|
|
190
185
|
const pagesByParentId = useMemo( () => {
|
|
191
186
|
if ( pages === null ) {
|
|
192
187
|
return new Map();
|
|
@@ -213,6 +208,12 @@ export default function PageListEdit( {
|
|
|
213
208
|
}, new Map() );
|
|
214
209
|
}, [ pages ] );
|
|
215
210
|
|
|
211
|
+
const convertToNavigationLinks = useConvertToNavigationLinks( {
|
|
212
|
+
clientId,
|
|
213
|
+
pages,
|
|
214
|
+
parentPageID,
|
|
215
|
+
} );
|
|
216
|
+
|
|
216
217
|
const blockProps = useBlockProps( {
|
|
217
218
|
className: classnames( 'wp-block-page-list', {
|
|
218
219
|
'has-text-color': !! context.textColor,
|
package/src/page-list/index.php
CHANGED
|
@@ -150,7 +150,8 @@ function block_core_page_list_render_nested_page_list( $open_submenus_on_click,
|
|
|
150
150
|
if ( empty( $nested_pages ) ) {
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
153
|
-
$
|
|
153
|
+
$front_page_id = (int) get_option( 'page_on_front' );
|
|
154
|
+
$markup = '';
|
|
154
155
|
foreach ( (array) $nested_pages as $page ) {
|
|
155
156
|
$css_class = $page['is_active'] ? ' current-menu-item' : '';
|
|
156
157
|
$aria_current = $page['is_active'] ? ' aria-current="page"' : '';
|
|
@@ -181,7 +182,6 @@ function block_core_page_list_render_nested_page_list( $open_submenus_on_click,
|
|
|
181
182
|
}
|
|
182
183
|
}
|
|
183
184
|
|
|
184
|
-
$front_page_id = (int) get_option( 'page_on_front' );
|
|
185
185
|
if ( (int) $page['page_id'] === $front_page_id ) {
|
|
186
186
|
$css_class .= ' menu-item-home';
|
|
187
187
|
}
|
|
@@ -282,14 +282,14 @@ function render_block_core_page_list( $attributes, $content, $block ) {
|
|
|
282
282
|
$pages_with_children[ $page->post_parent ][ $page->ID ] = array(
|
|
283
283
|
'page_id' => $page->ID,
|
|
284
284
|
'title' => $page->post_title,
|
|
285
|
-
'link' => get_permalink( $page
|
|
285
|
+
'link' => get_permalink( $page ),
|
|
286
286
|
'is_active' => $is_active,
|
|
287
287
|
);
|
|
288
288
|
} else {
|
|
289
289
|
$top_level_pages[ $page->ID ] = array(
|
|
290
290
|
'page_id' => $page->ID,
|
|
291
291
|
'title' => $page->post_title,
|
|
292
|
-
'link' => get_permalink( $page
|
|
292
|
+
'link' => get_permalink( $page ),
|
|
293
293
|
'is_active' => $is_active,
|
|
294
294
|
);
|
|
295
295
|
|
|
@@ -383,5 +383,139 @@ describe( 'page list convert to links', () => {
|
|
|
383
383
|
},
|
|
384
384
|
] );
|
|
385
385
|
} );
|
|
386
|
+
|
|
387
|
+
it( 'Can use a different parent page', () => {
|
|
388
|
+
const pages = [
|
|
389
|
+
{
|
|
390
|
+
title: {
|
|
391
|
+
raw: 'Sample Page',
|
|
392
|
+
rendered: 'Sample Page',
|
|
393
|
+
},
|
|
394
|
+
id: 2,
|
|
395
|
+
parent: 0,
|
|
396
|
+
link: 'http://wordpress.local/sample-page/',
|
|
397
|
+
type: 'page',
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
title: {
|
|
401
|
+
raw: 'About',
|
|
402
|
+
rendered: 'About',
|
|
403
|
+
},
|
|
404
|
+
id: 34,
|
|
405
|
+
parent: 0,
|
|
406
|
+
link: 'http://wordpress.local/about/',
|
|
407
|
+
type: 'page',
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
title: {
|
|
411
|
+
raw: 'Contact Page',
|
|
412
|
+
rendered: 'Contact Page',
|
|
413
|
+
},
|
|
414
|
+
id: 37,
|
|
415
|
+
parent: 0,
|
|
416
|
+
link: 'http://wordpress.local/contact-page/',
|
|
417
|
+
type: 'page',
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
title: {
|
|
421
|
+
raw: 'Test',
|
|
422
|
+
rendered: 'Test',
|
|
423
|
+
},
|
|
424
|
+
id: 229,
|
|
425
|
+
parent: 0,
|
|
426
|
+
link: 'http://wordpress.local/test/',
|
|
427
|
+
type: 'page',
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
title: {
|
|
431
|
+
raw: 'About Sub 1',
|
|
432
|
+
rendered: 'About Sub 1',
|
|
433
|
+
},
|
|
434
|
+
id: 738,
|
|
435
|
+
parent: 34,
|
|
436
|
+
link: 'http://wordpress.local/about/about-sub-1/',
|
|
437
|
+
type: 'page',
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
title: {
|
|
441
|
+
raw: 'About Sub 2',
|
|
442
|
+
rendered: 'About Sub 2',
|
|
443
|
+
},
|
|
444
|
+
id: 740,
|
|
445
|
+
parent: 34,
|
|
446
|
+
link: 'http://wordpress.local/about/about-sub-2/',
|
|
447
|
+
type: 'page',
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
title: {
|
|
451
|
+
raw: 'Test Sub',
|
|
452
|
+
rendered: 'Test Sub',
|
|
453
|
+
},
|
|
454
|
+
id: 742,
|
|
455
|
+
parent: 229,
|
|
456
|
+
link: 'http://wordpress.local/test/test-sub/',
|
|
457
|
+
type: 'page',
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
title: {
|
|
461
|
+
raw: 'Test Sub Sub',
|
|
462
|
+
rendered: 'Test Sub Sub',
|
|
463
|
+
},
|
|
464
|
+
id: 744,
|
|
465
|
+
parent: 742,
|
|
466
|
+
link: 'http://wordpress.local/test/test-sub/test-sub-sub/',
|
|
467
|
+
type: 'page',
|
|
468
|
+
},
|
|
469
|
+
];
|
|
470
|
+
|
|
471
|
+
const convertLinksWithParentOneLevel = convertToNavigationLinks(
|
|
472
|
+
pages,
|
|
473
|
+
34
|
|
474
|
+
);
|
|
475
|
+
|
|
476
|
+
expect( convertLinksWithParentOneLevel ).toEqual( [
|
|
477
|
+
{
|
|
478
|
+
attributes: {
|
|
479
|
+
id: 738,
|
|
480
|
+
kind: 'post-type',
|
|
481
|
+
label: 'About Sub 1',
|
|
482
|
+
type: 'page',
|
|
483
|
+
url: 'http://wordpress.local/about/about-sub-1/',
|
|
484
|
+
},
|
|
485
|
+
innerBlocks: [],
|
|
486
|
+
name: 'core/navigation-link',
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
attributes: {
|
|
490
|
+
id: 740,
|
|
491
|
+
kind: 'post-type',
|
|
492
|
+
label: 'About Sub 2',
|
|
493
|
+
type: 'page',
|
|
494
|
+
url: 'http://wordpress.local/about/about-sub-2/',
|
|
495
|
+
},
|
|
496
|
+
innerBlocks: [],
|
|
497
|
+
name: 'core/navigation-link',
|
|
498
|
+
},
|
|
499
|
+
] );
|
|
500
|
+
|
|
501
|
+
const convertLinksWithParentTwoLevels = convertToNavigationLinks(
|
|
502
|
+
pages,
|
|
503
|
+
742
|
|
504
|
+
);
|
|
505
|
+
|
|
506
|
+
expect( convertLinksWithParentTwoLevels ).toEqual( [
|
|
507
|
+
{
|
|
508
|
+
attributes: {
|
|
509
|
+
id: 744,
|
|
510
|
+
kind: 'post-type',
|
|
511
|
+
label: 'Test Sub Sub',
|
|
512
|
+
type: 'page',
|
|
513
|
+
url: 'http://wordpress.local/test/test-sub/test-sub-sub/',
|
|
514
|
+
},
|
|
515
|
+
innerBlocks: [],
|
|
516
|
+
name: 'core/navigation-link',
|
|
517
|
+
},
|
|
518
|
+
] );
|
|
519
|
+
} );
|
|
386
520
|
} );
|
|
387
521
|
} );
|
|
@@ -5,7 +5,14 @@ import { createBlock } from '@wordpress/blocks';
|
|
|
5
5
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
6
6
|
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Converts an array of pages into a nested array of navigation link blocks.
|
|
10
|
+
*
|
|
11
|
+
* @param {Array} pages An array of pages.
|
|
12
|
+
*
|
|
13
|
+
* @return {Array} A nested array of navigation link blocks.
|
|
14
|
+
*/
|
|
15
|
+
function createNavigationLinks( pages = [] ) {
|
|
9
16
|
const linkMap = {};
|
|
10
17
|
const navigationLinks = [];
|
|
11
18
|
pages.forEach( ( { id, title, link: url, type, parent } ) => {
|
|
@@ -30,11 +37,61 @@ export function convertToNavigationLinks( pages = [] ) {
|
|
|
30
37
|
// Use a placeholder if the child appears before parent in list.
|
|
31
38
|
linkMap[ parent ] = { innerBlocks: [] };
|
|
32
39
|
}
|
|
40
|
+
// Although these variables are not referenced, they are needed to store the innerBlocks in memory.
|
|
33
41
|
const parentLinkInnerBlocks = linkMap[ parent ].innerBlocks;
|
|
34
42
|
parentLinkInnerBlocks.push( linkMap[ id ] );
|
|
35
43
|
}
|
|
36
44
|
} );
|
|
37
45
|
|
|
46
|
+
return navigationLinks;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Finds a navigation link block by id, recursively.
|
|
51
|
+
* It might be possible to make this a more generic helper function.
|
|
52
|
+
*
|
|
53
|
+
* @param {Array} navigationLinks An array of navigation link blocks.
|
|
54
|
+
* @param {number} id The id of the navigation link to find.
|
|
55
|
+
*
|
|
56
|
+
* @return {Object|null} The navigation link block with the given id.
|
|
57
|
+
*/
|
|
58
|
+
function findNavigationLinkById( navigationLinks, id ) {
|
|
59
|
+
for ( const navigationLink of navigationLinks ) {
|
|
60
|
+
// Is this the link we're looking for?
|
|
61
|
+
if ( navigationLink.attributes.id === id ) {
|
|
62
|
+
return navigationLink;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// If not does it have innerBlocks?
|
|
66
|
+
if ( navigationLink.innerBlocks && navigationLink.innerBlocks.length ) {
|
|
67
|
+
const foundNavigationLink = findNavigationLinkById(
|
|
68
|
+
navigationLink.innerBlocks,
|
|
69
|
+
id
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
if ( foundNavigationLink ) {
|
|
73
|
+
return foundNavigationLink;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function convertToNavigationLinks( pages = [], parentPageID = null ) {
|
|
82
|
+
let navigationLinks = createNavigationLinks( pages );
|
|
83
|
+
|
|
84
|
+
// If a parent page ID is provided, only return the children of that page.
|
|
85
|
+
if ( parentPageID ) {
|
|
86
|
+
const parentPage = findNavigationLinkById(
|
|
87
|
+
navigationLinks,
|
|
88
|
+
parentPageID
|
|
89
|
+
);
|
|
90
|
+
if ( parentPage && parentPage.innerBlocks ) {
|
|
91
|
+
navigationLinks = parentPage.innerBlocks;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
38
95
|
// Transform all links with innerBlocks into Submenus. This can't be done
|
|
39
96
|
// sooner because page objects have no information on their children.
|
|
40
97
|
const transformSubmenus = ( listOfLinks ) => {
|
|
@@ -53,11 +110,14 @@ export function convertToNavigationLinks( pages = [] ) {
|
|
|
53
110
|
};
|
|
54
111
|
|
|
55
112
|
transformSubmenus( navigationLinks );
|
|
56
|
-
|
|
57
113
|
return navigationLinks;
|
|
58
114
|
}
|
|
59
115
|
|
|
60
|
-
export function useConvertToNavigationLinks( {
|
|
116
|
+
export function useConvertToNavigationLinks( {
|
|
117
|
+
clientId,
|
|
118
|
+
pages,
|
|
119
|
+
parentPageID,
|
|
120
|
+
} ) {
|
|
61
121
|
const { replaceBlock, selectBlock } = useDispatch( blockEditorStore );
|
|
62
122
|
|
|
63
123
|
const { parentNavBlockClientId } = useSelect(
|
|
@@ -79,7 +139,7 @@ export function useConvertToNavigationLinks( { clientId, pages } ) {
|
|
|
79
139
|
);
|
|
80
140
|
|
|
81
141
|
return () => {
|
|
82
|
-
const navigationLinks = convertToNavigationLinks( pages );
|
|
142
|
+
const navigationLinks = convertToNavigationLinks( pages, parentPageID );
|
|
83
143
|
|
|
84
144
|
// Replace the Page List block with the Navigation Links.
|
|
85
145
|
replaceBlock( clientId, navigationLinks );
|
package/src/post-excerpt/edit.js
CHANGED
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
Warning,
|
|
17
17
|
useBlockProps,
|
|
18
18
|
} from '@wordpress/block-editor';
|
|
19
|
-
import { PanelBody, ToggleControl } from '@wordpress/components';
|
|
20
|
-
import { __ } from '@wordpress/i18n';
|
|
19
|
+
import { PanelBody, ToggleControl, RangeControl } from '@wordpress/components';
|
|
20
|
+
import { __, _x } from '@wordpress/i18n';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Internal dependencies
|
|
@@ -25,7 +25,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
25
25
|
import { useCanEditEntity } from '../utils/hooks';
|
|
26
26
|
|
|
27
27
|
export default function PostExcerptEditor( {
|
|
28
|
-
attributes: { textAlign, moreText, showMoreOnNewLine },
|
|
28
|
+
attributes: { textAlign, moreText, showMoreOnNewLine, excerptLength },
|
|
29
29
|
setAttributes,
|
|
30
30
|
isSelected,
|
|
31
31
|
context: { postId, postType, queryId },
|
|
@@ -33,6 +33,7 @@ export default function PostExcerptEditor( {
|
|
|
33
33
|
const isDescendentOfQueryLoop = Number.isFinite( queryId );
|
|
34
34
|
const userCanEdit = useCanEditEntity( 'postType', postType, postId );
|
|
35
35
|
const isEditable = userCanEdit && ! isDescendentOfQueryLoop;
|
|
36
|
+
|
|
36
37
|
const [
|
|
37
38
|
rawExcerpt,
|
|
38
39
|
setExcerpt,
|
|
@@ -43,6 +44,14 @@ export default function PostExcerptEditor( {
|
|
|
43
44
|
[ `has-text-align-${ textAlign }` ]: textAlign,
|
|
44
45
|
} ),
|
|
45
46
|
} );
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* translators: If your word count is based on single characters (e.g. East Asian characters),
|
|
50
|
+
* enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
|
|
51
|
+
* Do not translate into your own language.
|
|
52
|
+
*/
|
|
53
|
+
const wordCountType = _x( 'words', 'Word count type. Do not translate!' );
|
|
54
|
+
|
|
46
55
|
/**
|
|
47
56
|
* When excerpt is editable, strip the html tags from
|
|
48
57
|
* rendered excerpt. This will be used if the entity's
|
|
@@ -109,21 +118,67 @@ export default function PostExcerptEditor( {
|
|
|
109
118
|
const excerptClassName = classnames( 'wp-block-post-excerpt__excerpt', {
|
|
110
119
|
'is-inline': ! showMoreOnNewLine,
|
|
111
120
|
} );
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The excerpt length setting needs to be applied to both
|
|
124
|
+
* the raw and the rendered excerpt depending on which is being used.
|
|
125
|
+
*/
|
|
126
|
+
const rawOrRenderedExcerpt = !! renderedExcerpt
|
|
127
|
+
? strippedRenderedExcerpt
|
|
128
|
+
: rawExcerpt;
|
|
129
|
+
|
|
130
|
+
let trimmedExcerpt = '';
|
|
131
|
+
if ( wordCountType === 'words' ) {
|
|
132
|
+
trimmedExcerpt = rawOrRenderedExcerpt
|
|
133
|
+
.trim()
|
|
134
|
+
.split( ' ', excerptLength )
|
|
135
|
+
.join( ' ' );
|
|
136
|
+
} else if ( wordCountType === 'characters_excluding_spaces' ) {
|
|
137
|
+
/*
|
|
138
|
+
* 1. Split the excerpt at the character limit,
|
|
139
|
+
* then join the substrings back into one string.
|
|
140
|
+
* 2. Count the number of spaces in the excerpt
|
|
141
|
+
* by comparing the lengths of the string with and without spaces.
|
|
142
|
+
* 3. Add the number to the length of the visible excerpt,
|
|
143
|
+
* so that the spaces are excluded from the word count.
|
|
144
|
+
*/
|
|
145
|
+
const excerptWithSpaces = rawOrRenderedExcerpt
|
|
146
|
+
.trim()
|
|
147
|
+
.split( '', excerptLength )
|
|
148
|
+
.join( '' );
|
|
149
|
+
|
|
150
|
+
const numberOfSpaces =
|
|
151
|
+
excerptWithSpaces.length -
|
|
152
|
+
excerptWithSpaces.replaceAll( ' ', '' ).length;
|
|
153
|
+
|
|
154
|
+
trimmedExcerpt = rawOrRenderedExcerpt
|
|
155
|
+
.trim()
|
|
156
|
+
.split( '', excerptLength + numberOfSpaces )
|
|
157
|
+
.join( '' );
|
|
158
|
+
} else if ( wordCountType === 'characters_including_spaces' ) {
|
|
159
|
+
trimmedExcerpt = rawOrRenderedExcerpt.trim().split( '', excerptLength );
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
trimmedExcerpt = trimmedExcerpt + '...';
|
|
163
|
+
|
|
112
164
|
const excerptContent = isEditable ? (
|
|
113
165
|
<RichText
|
|
114
166
|
className={ excerptClassName }
|
|
115
167
|
aria-label={ __( 'Post excerpt text' ) }
|
|
116
168
|
value={
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
169
|
+
isSelected
|
|
170
|
+
? rawOrRenderedExcerpt
|
|
171
|
+
: ( trimmedExcerpt !== '...' ? trimmedExcerpt : '' ) ||
|
|
172
|
+
__( 'No post excerpt found' )
|
|
120
173
|
}
|
|
121
174
|
onChange={ setExcerpt }
|
|
122
175
|
tagName="p"
|
|
123
176
|
/>
|
|
124
177
|
) : (
|
|
125
178
|
<p className={ excerptClassName }>
|
|
126
|
-
{
|
|
179
|
+
{ trimmedExcerpt !== '...'
|
|
180
|
+
? trimmedExcerpt
|
|
181
|
+
: __( 'No post excerpt found' ) }
|
|
127
182
|
</p>
|
|
128
183
|
);
|
|
129
184
|
return (
|
|
@@ -147,6 +202,16 @@ export default function PostExcerptEditor( {
|
|
|
147
202
|
} )
|
|
148
203
|
}
|
|
149
204
|
/>
|
|
205
|
+
<RangeControl
|
|
206
|
+
label={ __( 'Max number of words' ) }
|
|
207
|
+
value={ excerptLength }
|
|
208
|
+
onChange={ ( value ) => {
|
|
209
|
+
setAttributes( { excerptLength: value } );
|
|
210
|
+
setExcerpt();
|
|
211
|
+
} }
|
|
212
|
+
min="10"
|
|
213
|
+
max="100"
|
|
214
|
+
/>
|
|
150
215
|
</PanelBody>
|
|
151
216
|
</InspectorControls>
|
|
152
217
|
<div { ...blockProps }>
|
|
@@ -18,12 +18,18 @@ function render_block_core_post_excerpt( $attributes, $content, $block ) {
|
|
|
18
18
|
return '';
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
/*
|
|
22
|
+
* The purpose of the excerpt length setting is to limit the length of both
|
|
23
|
+
* automatically generated and user-created excerpts.
|
|
24
|
+
* Because the excerpt_length filter only applies to auto generated excerpts,
|
|
25
|
+
* wp_trim_words is used instead.
|
|
26
|
+
*/
|
|
27
|
+
$excerpt_length = $attributes['excerptLength'];
|
|
28
|
+
if ( isset( $excerpt_length ) ) {
|
|
29
|
+
$excerpt = wp_trim_words( get_the_excerpt(), $excerpt_length );
|
|
30
|
+
} else {
|
|
31
|
+
$excerpt = get_the_excerpt();
|
|
25
32
|
}
|
|
26
|
-
|
|
27
33
|
$more_text = ! empty( $attributes['moreText'] ) ? '<a class="wp-block-post-excerpt__more-link" href="' . esc_url( get_the_permalink( $block->context['postId'] ) ) . '">' . wp_kses_post( $attributes['moreText'] ) . '</a>' : '';
|
|
28
34
|
$filter_excerpt_more = function( $more ) use ( $more_text ) {
|
|
29
35
|
return empty( $more_text ) ? $more : '';
|
|
@@ -70,3 +76,21 @@ function register_block_core_post_excerpt() {
|
|
|
70
76
|
);
|
|
71
77
|
}
|
|
72
78
|
add_action( 'init', 'register_block_core_post_excerpt' );
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* If themes or plugins filter the excerpt_length, we need to
|
|
82
|
+
* override the filter in the editor, otherwise
|
|
83
|
+
* the excerpt length block setting has no effect.
|
|
84
|
+
* Returns 100 because 100 is the max length in the setting.
|
|
85
|
+
*/
|
|
86
|
+
if ( is_admin() ||
|
|
87
|
+
defined( 'REST_REQUEST' ) ||
|
|
88
|
+
'REST_REQUEST' ) {
|
|
89
|
+
add_filter(
|
|
90
|
+
'excerpt_length',
|
|
91
|
+
function() {
|
|
92
|
+
return 100;
|
|
93
|
+
},
|
|
94
|
+
PHP_INT_MAX
|
|
95
|
+
);
|
|
96
|
+
}
|