@wordpress/block-library 9.30.0 → 9.30.1-next.6f42e1382.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/build/accordion-content/edit.js +8 -8
- package/build/accordion-content/edit.js.map +1 -1
- package/build/accordion-content/index.js +2 -1
- package/build/accordion-content/index.js.map +1 -1
- package/build/accordion-panel/index.js +2 -1
- package/build/accordion-panel/index.js.map +1 -1
- package/build/buttons/index.js +2 -1
- package/build/buttons/index.js.map +1 -1
- package/build/categories/edit.js +3 -1
- package/build/categories/edit.js.map +1 -1
- package/build/index.js +4 -0
- package/build/index.js.map +1 -1
- package/build/navigation/constants.js +5 -1
- package/build/navigation/constants.js.map +1 -1
- package/build/navigation/edit/index.js +45 -1
- package/build/navigation/edit/index.js.map +1 -1
- package/build/navigation/edit/leaf-more-menu.js +0 -1
- package/build/navigation/edit/leaf-more-menu.js.map +1 -1
- package/build/navigation/edit/menu-inspector-controls.js +40 -5
- package/build/navigation/edit/menu-inspector-controls.js.map +1 -1
- package/build/navigation-link/block-inserter.js +69 -0
- package/build/navigation-link/block-inserter.js.map +1 -0
- package/build/navigation-link/dialog-wrapper.js +80 -0
- package/build/navigation-link/dialog-wrapper.js.map +1 -0
- package/build/navigation-link/link-ui.js +80 -120
- package/build/navigation-link/link-ui.js.map +1 -1
- package/build/navigation-link/page-creator.js +137 -0
- package/build/navigation-link/page-creator.js.map +1 -0
- package/build/search/edit.js +22 -14
- package/build/search/edit.js.map +1 -1
- package/build/social-links/index.js +2 -1
- package/build/social-links/index.js.map +1 -1
- package/build/table-of-contents/edit.js +33 -9
- package/build/table-of-contents/edit.js.map +1 -1
- package/build/table-of-contents/index.js +4 -0
- package/build/table-of-contents/index.js.map +1 -1
- package/build/table-of-contents/list.js +6 -3
- package/build/table-of-contents/list.js.map +1 -1
- package/build/table-of-contents/save.js +6 -3
- package/build/table-of-contents/save.js.map +1 -1
- package/build/term-template/edit.js +318 -0
- package/build/term-template/edit.js.map +1 -0
- package/build/term-template/index.js +109 -0
- package/build/term-template/index.js.map +1 -0
- package/build/term-template/save.js +16 -0
- package/build/term-template/save.js.map +1 -0
- package/build/term-template/variations.js +83 -0
- package/build/term-template/variations.js.map +1 -0
- package/build/terms-query/edit.js +20 -0
- package/build/terms-query/edit.js.map +1 -0
- package/build/terms-query/index.js +83 -0
- package/build/terms-query/index.js.map +1 -0
- package/build/terms-query/inspector-controls.js +246 -0
- package/build/terms-query/inspector-controls.js.map +1 -0
- package/build/terms-query/save.js +24 -0
- package/build/terms-query/save.js.map +1 -0
- package/build/terms-query/terms-query-content.js +71 -0
- package/build/terms-query/terms-query-content.js.map +1 -0
- package/build-module/accordion-content/edit.js +8 -8
- package/build-module/accordion-content/edit.js.map +1 -1
- package/build-module/accordion-content/index.js +2 -1
- package/build-module/accordion-content/index.js.map +1 -1
- package/build-module/accordion-panel/index.js +2 -1
- package/build-module/accordion-panel/index.js.map +1 -1
- package/build-module/buttons/index.js +2 -1
- package/build-module/buttons/index.js.map +1 -1
- package/build-module/categories/edit.js +3 -1
- package/build-module/categories/edit.js.map +1 -1
- package/build-module/index.js +4 -0
- package/build-module/index.js.map +1 -1
- package/build-module/navigation/constants.js +5 -1
- package/build-module/navigation/constants.js.map +1 -1
- package/build-module/navigation/edit/index.js +50 -4
- package/build-module/navigation/edit/index.js.map +1 -1
- package/build-module/navigation/edit/leaf-more-menu.js +0 -1
- package/build-module/navigation/edit/leaf-more-menu.js.map +1 -1
- package/build-module/navigation/edit/menu-inspector-controls.js +40 -5
- package/build-module/navigation/edit/menu-inspector-controls.js.map +1 -1
- package/build-module/navigation-link/block-inserter.js +61 -0
- package/build-module/navigation-link/block-inserter.js.map +1 -0
- package/build-module/navigation-link/dialog-wrapper.js +75 -0
- package/build-module/navigation-link/dialog-wrapper.js.map +1 -0
- package/build-module/navigation-link/link-ui.js +85 -125
- package/build-module/navigation-link/link-ui.js.map +1 -1
- package/build-module/navigation-link/page-creator.js +130 -0
- package/build-module/navigation-link/page-creator.js.map +1 -0
- package/build-module/search/edit.js +22 -14
- package/build-module/search/edit.js.map +1 -1
- package/build-module/social-links/index.js +2 -1
- package/build-module/social-links/index.js.map +1 -1
- package/build-module/table-of-contents/edit.js +35 -11
- package/build-module/table-of-contents/edit.js.map +1 -1
- package/build-module/table-of-contents/index.js +4 -0
- package/build-module/table-of-contents/index.js.map +1 -1
- package/build-module/table-of-contents/list.js +6 -3
- package/build-module/table-of-contents/list.js.map +1 -1
- package/build-module/table-of-contents/save.js +6 -3
- package/build-module/table-of-contents/save.js.map +1 -1
- package/build-module/term-template/edit.js +310 -0
- package/build-module/term-template/edit.js.map +1 -0
- package/build-module/term-template/index.js +102 -0
- package/build-module/term-template/index.js.map +1 -0
- package/build-module/term-template/save.js +9 -0
- package/build-module/term-template/save.js.map +1 -0
- package/build-module/term-template/variations.js +76 -0
- package/build-module/term-template/variations.js.map +1 -0
- package/build-module/terms-query/edit.js +12 -0
- package/build-module/terms-query/edit.js.map +1 -0
- package/build-module/terms-query/index.js +76 -0
- package/build-module/terms-query/index.js.map +1 -0
- package/build-module/terms-query/inspector-controls.js +239 -0
- package/build-module/terms-query/inspector-controls.js.map +1 -0
- package/build-module/terms-query/save.js +17 -0
- package/build-module/terms-query/save.js.map +1 -0
- package/build-module/terms-query/terms-query-content.js +63 -0
- package/build-module/terms-query/terms-query-content.js.map +1 -0
- package/build-style/accordion/style-rtl.css +5 -6
- package/build-style/accordion/style.css +5 -6
- package/build-style/editor-rtl.css +38 -0
- package/build-style/editor.css +38 -0
- package/build-style/form-input/style-rtl.css +4 -3
- package/build-style/form-input/style.css +4 -3
- package/build-style/navigation-link/editor-rtl.css +14 -0
- package/build-style/navigation-link/editor.css +14 -0
- package/build-style/navigation-link/style-rtl.css +1 -1
- package/build-style/navigation-link/style.css +1 -1
- package/build-style/post-comments-form/style-rtl.css +8 -5
- package/build-style/post-comments-form/style.css +8 -5
- package/build-style/search/style-rtl.css +11 -12
- package/build-style/search/style.css +11 -12
- package/build-style/style-rtl.css +45 -27
- package/build-style/style.css +45 -27
- package/build-style/term-template/editor-rtl.css +160 -0
- package/build-style/term-template/editor.css +160 -0
- package/build-style/term-template/style-rtl.css +146 -0
- package/build-style/term-template/style.css +146 -0
- package/build-style/terms-query/style-rtl.css +140 -0
- package/build-style/terms-query/style.css +140 -0
- package/build-types/table-of-contents/list.d.ts +2 -1
- package/build-types/table-of-contents/list.d.ts.map +1 -1
- package/package.json +35 -35
- package/src/accordion/style.scss +6 -6
- package/src/accordion-content/block.json +2 -1
- package/src/accordion-content/edit.js +21 -27
- package/src/accordion-panel/block.json +2 -1
- package/src/buttons/block.json +2 -1
- package/src/categories/edit.js +2 -1
- package/src/cover/test/edit.js +1 -5
- package/src/editor.scss +1 -0
- package/src/form-input/style.scss +3 -2
- package/src/index.js +4 -0
- package/src/navigation/constants.js +4 -0
- package/src/navigation/edit/index.js +50 -1
- package/src/navigation/edit/leaf-more-menu.js +0 -1
- package/src/navigation/edit/menu-inspector-controls.js +40 -5
- package/src/navigation-link/block-inserter.js +65 -0
- package/src/navigation-link/dialog-wrapper.js +74 -0
- package/src/navigation-link/editor.scss +17 -0
- package/src/navigation-link/link-ui.js +108 -164
- package/src/navigation-link/page-creator.js +157 -0
- package/src/navigation-link/style.scss +1 -1
- package/src/post-comments-form/style.scss +11 -11
- package/src/post-date/index.php +18 -13
- package/src/search/edit.js +44 -13
- package/src/search/index.php +16 -2
- package/src/search/style.scss +15 -16
- package/src/social-links/block.json +2 -1
- package/src/style.scss +2 -0
- package/src/table-of-contents/block.json +4 -0
- package/src/table-of-contents/edit.js +58 -21
- package/src/table-of-contents/list.tsx +7 -2
- package/src/table-of-contents/save.js +7 -3
- package/src/term-template/block.json +73 -0
- package/src/term-template/edit.js +391 -0
- package/src/term-template/editor.scss +26 -0
- package/src/term-template/index.js +26 -0
- package/src/term-template/index.php +224 -0
- package/src/term-template/save.js +8 -0
- package/src/term-template/style.scss +12 -0
- package/src/term-template/variations.js +87 -0
- package/src/terms-query/block.json +49 -0
- package/src/terms-query/edit.js +10 -0
- package/src/terms-query/index.js +24 -0
- package/src/terms-query/index.php +44 -0
- package/src/terms-query/inspector-controls.js +233 -0
- package/src/terms-query/save.js +10 -0
- package/src/terms-query/style.scss +6 -0
- package/src/terms-query/terms-query-content.js +74 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { memo, useMemo, useState } from '@wordpress/element';
|
|
10
|
+
import { useSelect, useDispatch } from '@wordpress/data';
|
|
11
|
+
import { layout } from '@wordpress/icons';
|
|
12
|
+
import { __ } from '@wordpress/i18n';
|
|
13
|
+
import {
|
|
14
|
+
BlockContextProvider,
|
|
15
|
+
__experimentalUseBlockPreview as useBlockPreview,
|
|
16
|
+
__experimentalBlockVariationPicker as BlockVariationPicker,
|
|
17
|
+
useBlockProps,
|
|
18
|
+
useInnerBlocksProps,
|
|
19
|
+
store as blockEditorStore,
|
|
20
|
+
} from '@wordpress/block-editor';
|
|
21
|
+
import { useEntityRecords } from '@wordpress/core-data';
|
|
22
|
+
import {
|
|
23
|
+
createBlocksFromInnerBlocksTemplate,
|
|
24
|
+
store as blocksStore,
|
|
25
|
+
} from '@wordpress/blocks';
|
|
26
|
+
|
|
27
|
+
const TEMPLATE = [
|
|
28
|
+
[
|
|
29
|
+
'core/group',
|
|
30
|
+
{
|
|
31
|
+
layout: {
|
|
32
|
+
type: 'flex',
|
|
33
|
+
orientation: 'horizontal',
|
|
34
|
+
},
|
|
35
|
+
style: {
|
|
36
|
+
spacing: {
|
|
37
|
+
blockGap: '0.5rem',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
metadata: {
|
|
41
|
+
name: __( 'Term Name with Count' ),
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
[
|
|
45
|
+
[
|
|
46
|
+
'core/paragraph',
|
|
47
|
+
{
|
|
48
|
+
metadata: {
|
|
49
|
+
name: __( 'Term Name' ),
|
|
50
|
+
bindings: {
|
|
51
|
+
content: {
|
|
52
|
+
source: 'core/term-data',
|
|
53
|
+
args: {
|
|
54
|
+
key: 'name',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
[
|
|
62
|
+
'core/paragraph',
|
|
63
|
+
{
|
|
64
|
+
placeholder: __( '(count)' ),
|
|
65
|
+
metadata: {
|
|
66
|
+
name: __( 'Term Count' ),
|
|
67
|
+
bindings: {
|
|
68
|
+
content: {
|
|
69
|
+
source: 'core/term-data',
|
|
70
|
+
args: {
|
|
71
|
+
key: 'count',
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
],
|
|
79
|
+
],
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
function TermTemplateInnerBlocks( { classList } ) {
|
|
83
|
+
const innerBlocksProps = useInnerBlocksProps(
|
|
84
|
+
{ className: clsx( 'wp-block-term', classList ) },
|
|
85
|
+
{ template: TEMPLATE, __unstableDisableLayoutClassNames: true }
|
|
86
|
+
);
|
|
87
|
+
return <li { ...innerBlocksProps } />;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function TermTemplateBlockPreview( {
|
|
91
|
+
blocks,
|
|
92
|
+
blockContextId,
|
|
93
|
+
classList,
|
|
94
|
+
isHidden,
|
|
95
|
+
setActiveBlockContextId,
|
|
96
|
+
} ) {
|
|
97
|
+
const blockPreviewProps = useBlockPreview( {
|
|
98
|
+
blocks,
|
|
99
|
+
props: {
|
|
100
|
+
className: clsx( 'wp-block-term', classList ),
|
|
101
|
+
},
|
|
102
|
+
} );
|
|
103
|
+
|
|
104
|
+
const handleOnClick = () => {
|
|
105
|
+
setActiveBlockContextId( blockContextId );
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const style = {
|
|
109
|
+
display: isHidden ? 'none' : undefined,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<li
|
|
114
|
+
{ ...blockPreviewProps }
|
|
115
|
+
tabIndex={ 0 }
|
|
116
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
|
|
117
|
+
role="button"
|
|
118
|
+
onClick={ handleOnClick }
|
|
119
|
+
onKeyPress={ handleOnClick }
|
|
120
|
+
style={ style }
|
|
121
|
+
/>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Prevent re-rendering of the block preview when the terms data changes.
|
|
126
|
+
const MemoizedTermTemplateBlockPreview = memo( TermTemplateBlockPreview );
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Builds a hierarchical tree structure from flat terms array.
|
|
130
|
+
*
|
|
131
|
+
* @param {Array} terms Array of term objects.
|
|
132
|
+
* @return {Array} Tree structure with parent/child relationships.
|
|
133
|
+
*/
|
|
134
|
+
function buildTermsTree( terms ) {
|
|
135
|
+
const termsById = {};
|
|
136
|
+
const rootTerms = [];
|
|
137
|
+
|
|
138
|
+
terms.forEach( ( term ) => {
|
|
139
|
+
termsById[ term.id ] = {
|
|
140
|
+
term,
|
|
141
|
+
children: [],
|
|
142
|
+
};
|
|
143
|
+
} );
|
|
144
|
+
|
|
145
|
+
terms.forEach( ( term ) => {
|
|
146
|
+
if ( term.parent && termsById[ term.parent ] ) {
|
|
147
|
+
termsById[ term.parent ].children.push( termsById[ term.id ] );
|
|
148
|
+
} else {
|
|
149
|
+
rootTerms.push( termsById[ term.id ] );
|
|
150
|
+
}
|
|
151
|
+
} );
|
|
152
|
+
|
|
153
|
+
return rootTerms;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Renders a single term node and its children recursively.
|
|
158
|
+
*
|
|
159
|
+
* @param {Object} termNode Term node with term object and children.
|
|
160
|
+
* @param {Function} renderTerm Function to render individual terms.
|
|
161
|
+
* @return {JSX.Element} Rendered term node with children.
|
|
162
|
+
*/
|
|
163
|
+
function renderTermNode( termNode, renderTerm ) {
|
|
164
|
+
return (
|
|
165
|
+
<li className="wp-block-term">
|
|
166
|
+
{ renderTerm( termNode.term ) }
|
|
167
|
+
{ termNode.children.length > 0 && (
|
|
168
|
+
<ul>
|
|
169
|
+
{ termNode.children.map( ( child ) =>
|
|
170
|
+
renderTermNode( child, renderTerm )
|
|
171
|
+
) }
|
|
172
|
+
</ul>
|
|
173
|
+
) }
|
|
174
|
+
</li>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Checks if a term is the currently active term.
|
|
180
|
+
*
|
|
181
|
+
* @param {number} termId The term ID to check.
|
|
182
|
+
* @param {number} activeBlockContextId The currently active block context ID.
|
|
183
|
+
* @param {Array} blockContexts Array of block contexts.
|
|
184
|
+
* @return {boolean} True if the term is active, false otherwise.
|
|
185
|
+
*/
|
|
186
|
+
function isActiveTerm( termId, activeBlockContextId, blockContexts ) {
|
|
187
|
+
return termId === ( activeBlockContextId || blockContexts[ 0 ]?.termId );
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export default function TermTemplateEdit( {
|
|
191
|
+
clientId,
|
|
192
|
+
setAttributes,
|
|
193
|
+
context: {
|
|
194
|
+
termQuery: {
|
|
195
|
+
taxonomy,
|
|
196
|
+
order,
|
|
197
|
+
orderBy,
|
|
198
|
+
hideEmpty,
|
|
199
|
+
hierarchical,
|
|
200
|
+
parent,
|
|
201
|
+
perPage = 10,
|
|
202
|
+
} = {},
|
|
203
|
+
},
|
|
204
|
+
__unstableLayoutClassNames,
|
|
205
|
+
} ) {
|
|
206
|
+
const [ activeBlockContextId, setActiveBlockContextId ] = useState();
|
|
207
|
+
const { replaceInnerBlocks } = useDispatch( blockEditorStore );
|
|
208
|
+
|
|
209
|
+
const queryArgs = {
|
|
210
|
+
order,
|
|
211
|
+
orderby: orderBy,
|
|
212
|
+
hide_empty: hideEmpty,
|
|
213
|
+
// To preview the data the closest to the frontend, we fetch the largest number of terms
|
|
214
|
+
// and limit them during rendering. This is because WP_Term_Query fetches data in hierarchical manner,
|
|
215
|
+
// while in editor we build the hierarchy manually. It also allows us to avoid re-fetching data when max terms changes.
|
|
216
|
+
per_page: 100,
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const { records: terms, isResolving } = useEntityRecords(
|
|
220
|
+
'taxonomy',
|
|
221
|
+
taxonomy,
|
|
222
|
+
queryArgs
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// Filter to show only top-level terms if "Show only top-level terms" is enabled.
|
|
226
|
+
const filteredTerms = useMemo( () => {
|
|
227
|
+
if ( ! terms || parent !== 0 ) {
|
|
228
|
+
return terms;
|
|
229
|
+
}
|
|
230
|
+
return terms.filter( ( term ) => ! term.parent );
|
|
231
|
+
}, [ terms, parent ] );
|
|
232
|
+
|
|
233
|
+
const { blocks, variations, defaultVariation } = useSelect(
|
|
234
|
+
( select ) => {
|
|
235
|
+
const { getBlocks } = select( blockEditorStore );
|
|
236
|
+
const { getBlockVariations, getDefaultBlockVariation } =
|
|
237
|
+
select( blocksStore );
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
blocks: getBlocks( clientId ),
|
|
241
|
+
variations: getBlockVariations( 'core/term-template', 'block' ),
|
|
242
|
+
defaultVariation: getDefaultBlockVariation(
|
|
243
|
+
'core/term-template',
|
|
244
|
+
'block'
|
|
245
|
+
),
|
|
246
|
+
};
|
|
247
|
+
},
|
|
248
|
+
[ clientId ]
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
const blockProps = useBlockProps( {
|
|
252
|
+
className: __unstableLayoutClassNames,
|
|
253
|
+
} );
|
|
254
|
+
|
|
255
|
+
const blockContexts = useMemo(
|
|
256
|
+
() =>
|
|
257
|
+
filteredTerms?.map( ( term ) => ( {
|
|
258
|
+
taxonomy,
|
|
259
|
+
termId: term.id,
|
|
260
|
+
classList: `term-${ term.id }`,
|
|
261
|
+
termData: term,
|
|
262
|
+
} ) ),
|
|
263
|
+
[ filteredTerms, taxonomy ]
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
// Show variation picker if no blocks exist.
|
|
267
|
+
if ( ! blocks?.length ) {
|
|
268
|
+
return (
|
|
269
|
+
<div { ...blockProps }>
|
|
270
|
+
<BlockVariationPicker
|
|
271
|
+
icon={ layout }
|
|
272
|
+
label={ __( 'Term Template' ) }
|
|
273
|
+
variations={ variations }
|
|
274
|
+
instructions={ __(
|
|
275
|
+
'Choose a layout for displaying terms:'
|
|
276
|
+
) }
|
|
277
|
+
onSelect={ ( nextVariation = defaultVariation ) => {
|
|
278
|
+
if ( nextVariation.attributes ) {
|
|
279
|
+
setAttributes( nextVariation.attributes );
|
|
280
|
+
}
|
|
281
|
+
if ( nextVariation.innerBlocks ) {
|
|
282
|
+
replaceInnerBlocks(
|
|
283
|
+
clientId,
|
|
284
|
+
createBlocksFromInnerBlocksTemplate(
|
|
285
|
+
nextVariation.innerBlocks
|
|
286
|
+
),
|
|
287
|
+
true
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
} }
|
|
291
|
+
allowSkip
|
|
292
|
+
/>
|
|
293
|
+
</div>
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if ( isResolving ) {
|
|
298
|
+
return (
|
|
299
|
+
<ul { ...blockProps }>
|
|
300
|
+
<li className="wp-block-term term-loading">
|
|
301
|
+
<div className="term-loading-placeholder" />
|
|
302
|
+
</li>
|
|
303
|
+
<li className="wp-block-term term-loading">
|
|
304
|
+
<div className="term-loading-placeholder" />
|
|
305
|
+
</li>
|
|
306
|
+
<li className="wp-block-term term-loading">
|
|
307
|
+
<div className="term-loading-placeholder" />
|
|
308
|
+
</li>
|
|
309
|
+
</ul>
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if ( ! filteredTerms?.length ) {
|
|
314
|
+
return <p { ...blockProps }> { __( 'No terms found.' ) }</p>;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const renderTerm = ( term ) => {
|
|
318
|
+
const blockContext = {
|
|
319
|
+
taxonomy,
|
|
320
|
+
termId: term.id,
|
|
321
|
+
classList: `term-${ term.id }`,
|
|
322
|
+
termData: term,
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
return (
|
|
326
|
+
<BlockContextProvider key={ term.id } value={ blockContext }>
|
|
327
|
+
{ isActiveTerm(
|
|
328
|
+
term.id,
|
|
329
|
+
activeBlockContextId,
|
|
330
|
+
blockContexts
|
|
331
|
+
) ? (
|
|
332
|
+
<TermTemplateInnerBlocks
|
|
333
|
+
classList={ blockContext.classList }
|
|
334
|
+
/>
|
|
335
|
+
) : null }
|
|
336
|
+
<MemoizedTermTemplateBlockPreview
|
|
337
|
+
blocks={ blocks }
|
|
338
|
+
blockContextId={ term.id }
|
|
339
|
+
classList={ blockContext.classList }
|
|
340
|
+
setActiveBlockContextId={ setActiveBlockContextId }
|
|
341
|
+
isHidden={ isActiveTerm(
|
|
342
|
+
term.id,
|
|
343
|
+
activeBlockContextId,
|
|
344
|
+
blockContexts
|
|
345
|
+
) }
|
|
346
|
+
/>
|
|
347
|
+
</BlockContextProvider>
|
|
348
|
+
);
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
return (
|
|
352
|
+
<>
|
|
353
|
+
<ul { ...blockProps }>
|
|
354
|
+
{ hierarchical
|
|
355
|
+
? buildTermsTree( filteredTerms ).map( ( termNode ) =>
|
|
356
|
+
renderTermNode( termNode, renderTerm )
|
|
357
|
+
)
|
|
358
|
+
: blockContexts &&
|
|
359
|
+
blockContexts
|
|
360
|
+
.slice( 0, perPage )
|
|
361
|
+
.map( ( blockContext ) => (
|
|
362
|
+
<BlockContextProvider
|
|
363
|
+
key={ blockContext.termId }
|
|
364
|
+
value={ blockContext }
|
|
365
|
+
>
|
|
366
|
+
{ blockContext.termId ===
|
|
367
|
+
( activeBlockContextId ||
|
|
368
|
+
blockContexts[ 0 ]?.termId ) ? (
|
|
369
|
+
<TermTemplateInnerBlocks
|
|
370
|
+
classList={ blockContext.classList }
|
|
371
|
+
/>
|
|
372
|
+
) : null }
|
|
373
|
+
<MemoizedTermTemplateBlockPreview
|
|
374
|
+
blocks={ blocks }
|
|
375
|
+
blockContextId={ blockContext.termId }
|
|
376
|
+
classList={ blockContext.classList }
|
|
377
|
+
setActiveBlockContextId={
|
|
378
|
+
setActiveBlockContextId
|
|
379
|
+
}
|
|
380
|
+
isHidden={
|
|
381
|
+
blockContext.termId ===
|
|
382
|
+
( activeBlockContextId ||
|
|
383
|
+
blockContexts[ 0 ]?.termId )
|
|
384
|
+
}
|
|
385
|
+
/>
|
|
386
|
+
</BlockContextProvider>
|
|
387
|
+
) ) }
|
|
388
|
+
</ul>
|
|
389
|
+
</>
|
|
390
|
+
);
|
|
391
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.wp-block-term-template {
|
|
2
|
+
.term-loading {
|
|
3
|
+
.term-loading-placeholder {
|
|
4
|
+
width: 100%;
|
|
5
|
+
height: 1.5em;
|
|
6
|
+
margin-bottom: 0.25em;
|
|
7
|
+
background-color: $gray-100;
|
|
8
|
+
border-radius: 2px;
|
|
9
|
+
@media not ( prefers-reduced-motion ) {
|
|
10
|
+
animation: loadingpulse 1.5s ease-in-out infinite;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@keyframes loadingpulse {
|
|
17
|
+
0% {
|
|
18
|
+
opacity: 1;
|
|
19
|
+
}
|
|
20
|
+
50% {
|
|
21
|
+
opacity: 0.5;
|
|
22
|
+
}
|
|
23
|
+
100% {
|
|
24
|
+
opacity: 1;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { layout as icon } from '@wordpress/icons';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import initBlock from '../utils/init-block';
|
|
10
|
+
import metadata from './block.json';
|
|
11
|
+
import edit from './edit';
|
|
12
|
+
import save from './save';
|
|
13
|
+
import variations from './variations';
|
|
14
|
+
|
|
15
|
+
const { name } = metadata;
|
|
16
|
+
export { metadata, name };
|
|
17
|
+
|
|
18
|
+
export const settings = {
|
|
19
|
+
icon,
|
|
20
|
+
variations,
|
|
21
|
+
edit,
|
|
22
|
+
save,
|
|
23
|
+
example: {},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const init = () => initBlock( { name, metadata, settings } );
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* Server-side rendering of the `core/term-template` block.
|
|
4
|
+
*
|
|
5
|
+
* @package WordPress
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Renders the `core/term-template` block on the server.
|
|
10
|
+
*
|
|
11
|
+
* @since 6.9.0
|
|
12
|
+
*
|
|
13
|
+
* @param array $attributes Block attributes.
|
|
14
|
+
* @param string $content Block default content.
|
|
15
|
+
* @param WP_Block $block Block instance.
|
|
16
|
+
*
|
|
17
|
+
* @return string Returns the output of the term template.
|
|
18
|
+
*/
|
|
19
|
+
function render_block_core_term_template( $attributes, $content, $block ) {
|
|
20
|
+
if ( ! isset( $block->context ) || ! isset( $attributes ) ) {
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
$query_block_context = $block->context;
|
|
25
|
+
|
|
26
|
+
if ( empty( $query_block_context['termQuery'] ) ) {
|
|
27
|
+
return '';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
$query = $query_block_context['termQuery'];
|
|
31
|
+
|
|
32
|
+
$query_args = array(
|
|
33
|
+
'taxonomy' => $query['taxonomy'] ?? 'category',
|
|
34
|
+
'number' => $query['perPage'] ?? 10,
|
|
35
|
+
'order' => $query['order'] ?? 'asc',
|
|
36
|
+
'orderby' => $query['orderBy'] ?? 'name',
|
|
37
|
+
'hide_empty' => $query['hideEmpty'] ?? true,
|
|
38
|
+
'include' => $query['include'] ?? array(),
|
|
39
|
+
'exclude' => $query['exclude'] ?? array(),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// Handle parent.
|
|
43
|
+
if ( ! empty( $query['hierarchical'] ) && isset( $query['parent'] ) ) {
|
|
44
|
+
$query_args['parent'] = $query['parent'];
|
|
45
|
+
} elseif ( ! empty( $query['hierarchical'] ) ) {
|
|
46
|
+
$query_args['parent'] = 0;
|
|
47
|
+
} elseif ( isset( $query['parent'] ) ) {
|
|
48
|
+
$query_args['parent'] = $query['parent'];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
$terms_query = new WP_Term_Query( $query_args );
|
|
52
|
+
$terms = $terms_query->get_terms();
|
|
53
|
+
|
|
54
|
+
if ( ! $terms || is_wp_error( $terms ) ) {
|
|
55
|
+
return '';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Handle hierarchical list.
|
|
59
|
+
$is_hierarchical = ! empty( $query['hierarchical'] );
|
|
60
|
+
|
|
61
|
+
if ( $is_hierarchical ) {
|
|
62
|
+
$content = render_block_core_term_template_hierarchical( $terms, $block, $query_args );
|
|
63
|
+
} else {
|
|
64
|
+
$content = render_block_core_term_template_flat( $terms, $block );
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
$classnames = 'wp-block-term-template';
|
|
68
|
+
|
|
69
|
+
if ( isset( $attributes['style']['elements']['link']['color']['text'] ) ) {
|
|
70
|
+
$classnames .= ' has-link-color';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => trim( $classnames ) ) );
|
|
74
|
+
|
|
75
|
+
// Default list layout.
|
|
76
|
+
return sprintf(
|
|
77
|
+
'<ul %s>%s</ul>',
|
|
78
|
+
$wrapper_attributes,
|
|
79
|
+
$content
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Renders terms in a flat list structure.
|
|
85
|
+
*
|
|
86
|
+
* @since 6.9.0
|
|
87
|
+
*
|
|
88
|
+
* @param array $terms Array of WP_Term objects.
|
|
89
|
+
* @param WP_Block $block Block instance.
|
|
90
|
+
*
|
|
91
|
+
* @return string HTML content for flat terms list.
|
|
92
|
+
*/
|
|
93
|
+
function render_block_core_term_template_flat( $terms, $block ) {
|
|
94
|
+
$content = '';
|
|
95
|
+
foreach ( $terms as $term ) {
|
|
96
|
+
$content .= render_block_core_term_template_single( $term, $block );
|
|
97
|
+
}
|
|
98
|
+
return $content;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Renders terms in a hierarchical structure.
|
|
103
|
+
*
|
|
104
|
+
* @since 6.9.0
|
|
105
|
+
*
|
|
106
|
+
* @param array $terms Array of WP_Term objects.
|
|
107
|
+
* @param WP_Block $block Block instance.
|
|
108
|
+
* @param array $base_query_args Base query arguments.
|
|
109
|
+
*
|
|
110
|
+
* @return string HTML content for hierarchical terms list.
|
|
111
|
+
*/
|
|
112
|
+
function render_block_core_term_template_hierarchical( $terms, $block, $base_query_args ) {
|
|
113
|
+
$content = '';
|
|
114
|
+
|
|
115
|
+
foreach ( $terms as $term ) {
|
|
116
|
+
$term_content = render_block_core_term_template_single( $term, $block );
|
|
117
|
+
$children_content = render_block_core_term_template_get_children( $term->term_id, $block, $base_query_args );
|
|
118
|
+
|
|
119
|
+
if ( ! empty( $children_content ) ) {
|
|
120
|
+
$term_content = str_replace( '</li>', '<ul>' . $children_content . '</ul></li>', $term_content );
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
$content .= $term_content;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return $content;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Gets and renders children of a specific term.
|
|
131
|
+
*
|
|
132
|
+
* @since 6.9.0
|
|
133
|
+
*
|
|
134
|
+
* @param int $parent_term_id Parent term ID.
|
|
135
|
+
* @param WP_Block $block Block instance.
|
|
136
|
+
* @param array $base_query_args Base query arguments.
|
|
137
|
+
*
|
|
138
|
+
* @return string HTML content for children terms.
|
|
139
|
+
*/
|
|
140
|
+
function render_block_core_term_template_get_children( $parent_term_id, $block, $base_query_args ) {
|
|
141
|
+
$child_query_args = $base_query_args;
|
|
142
|
+
$child_query_args['parent'] = $parent_term_id;
|
|
143
|
+
|
|
144
|
+
$child_terms_query = new WP_Term_Query( $child_query_args );
|
|
145
|
+
$child_terms = $child_terms_query->get_terms();
|
|
146
|
+
|
|
147
|
+
if ( ! $child_terms || is_wp_error( $child_terms ) ) {
|
|
148
|
+
return '';
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
$content = '';
|
|
152
|
+
|
|
153
|
+
foreach ( $child_terms as $child_term ) {
|
|
154
|
+
$term_content = render_block_core_term_template_single( $child_term, $block );
|
|
155
|
+
$children_content = render_block_core_term_template_get_children( $child_term->term_id, $block, $base_query_args );
|
|
156
|
+
|
|
157
|
+
if ( ! empty( $children_content ) ) {
|
|
158
|
+
$term_content = str_replace( '</li>', '<ul>' . $children_content . '</ul></li>', $term_content );
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
$content .= $term_content;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return $content;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Renders a single term with its inner blocks.
|
|
169
|
+
*
|
|
170
|
+
* @since 6.9.0
|
|
171
|
+
*
|
|
172
|
+
* @param WP_Term $term Term object.
|
|
173
|
+
* @param WP_Block $block Block instance.
|
|
174
|
+
*
|
|
175
|
+
* @return string HTML content for a single term.
|
|
176
|
+
*/
|
|
177
|
+
function render_block_core_term_template_single( $term, $block ) {
|
|
178
|
+
$inner_blocks = $block->inner_blocks;
|
|
179
|
+
$block_content = '';
|
|
180
|
+
|
|
181
|
+
if ( ! empty( $inner_blocks ) ) {
|
|
182
|
+
$term_id = $term->term_id;
|
|
183
|
+
$taxonomy = $term->taxonomy;
|
|
184
|
+
|
|
185
|
+
$filter_block_context = static function ( $context ) use ( $term_id, $taxonomy ) {
|
|
186
|
+
$context['termId'] = $term_id;
|
|
187
|
+
$context['taxonomy'] = $taxonomy;
|
|
188
|
+
return $context;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
add_filter( 'render_block_context', $filter_block_context, 1 );
|
|
192
|
+
|
|
193
|
+
foreach ( $inner_blocks as $inner_block ) {
|
|
194
|
+
if ( method_exists( $inner_block, 'refresh_context_dependents' ) ) {
|
|
195
|
+
// WP_Block::refresh_context_dependents() was introduced in WordPress 6.8.
|
|
196
|
+
$inner_block->refresh_context_dependents();
|
|
197
|
+
$block_content .= $inner_block->render( array( 'dynamic' => true ) );
|
|
198
|
+
} else {
|
|
199
|
+
$block_content = ( new WP_Block( $inner_block->parsed_block ) )->render( array( 'dynamic' => false ) );
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
remove_filter( 'render_block_context', $filter_block_context, 1 );
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
$term_classes = implode( ' ', array( 'wp-block-term', 'term-' . $term->term_id ) );
|
|
206
|
+
|
|
207
|
+
// Default list layout
|
|
208
|
+
return '<li class="' . esc_attr( $term_classes ) . '">' . $block_content . '</li>';
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Registers the `core/term-template` block on the server.
|
|
213
|
+
*
|
|
214
|
+
* @since 6.9.0
|
|
215
|
+
*/
|
|
216
|
+
function register_block_core_term_template() {
|
|
217
|
+
register_block_type_from_metadata(
|
|
218
|
+
__DIR__ . '/term-template',
|
|
219
|
+
array(
|
|
220
|
+
'render_callback' => 'render_block_core_term_template',
|
|
221
|
+
)
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
add_action( 'init', 'register_block_core_term_template' );
|