@wordpress/edit-site 4.10.0 → 4.11.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/components/add-new-template/add-custom-template-modal.js +22 -42
- package/build/components/add-new-template/add-custom-template-modal.js.map +1 -1
- package/build/components/add-new-template/new-template.js +17 -20
- package/build/components/add-new-template/new-template.js.map +1 -1
- package/build/components/add-new-template/utils.js +366 -239
- package/build/components/add-new-template/utils.js.map +1 -1
- package/build/components/block-editor/index.js +1 -3
- package/build/components/block-editor/index.js.map +1 -1
- package/build/components/global-styles/dimensions-panel.js +183 -13
- package/build/components/global-styles/dimensions-panel.js.map +1 -1
- package/build/components/global-styles/hooks.js +1 -1
- package/build/components/global-styles/hooks.js.map +1 -1
- package/build/components/global-styles/use-global-styles-output.js +95 -17
- package/build/components/global-styles/use-global-styles-output.js.map +1 -1
- package/build/components/global-styles/utils.js +31 -0
- package/build/components/global-styles/utils.js.map +1 -1
- package/build/components/header/index.js +7 -6
- package/build/components/header/index.js.map +1 -1
- package/build/hooks/index.js +2 -0
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/template-part-edit.js +86 -0
- package/build/hooks/template-part-edit.js.map +1 -0
- package/build-module/components/add-new-template/add-custom-template-modal.js +23 -43
- package/build-module/components/add-new-template/add-custom-template-modal.js.map +1 -1
- package/build-module/components/add-new-template/new-template.js +18 -21
- package/build-module/components/add-new-template/new-template.js.map +1 -1
- package/build-module/components/add-new-template/utils.js +365 -227
- package/build-module/components/add-new-template/utils.js.map +1 -1
- package/build-module/components/block-editor/index.js +1 -2
- package/build-module/components/block-editor/index.js.map +1 -1
- package/build-module/components/global-styles/dimensions-panel.js +183 -14
- package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
- package/build-module/components/global-styles/hooks.js +1 -1
- package/build-module/components/global-styles/hooks.js.map +1 -1
- package/build-module/components/global-styles/use-global-styles-output.js +94 -22
- package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
- package/build-module/components/global-styles/utils.js +29 -0
- package/build-module/components/global-styles/utils.js.map +1 -1
- package/build-module/components/header/index.js +8 -6
- package/build-module/components/header/index.js.map +1 -1
- package/build-module/hooks/index.js +1 -0
- package/build-module/hooks/index.js.map +1 -1
- package/build-module/hooks/template-part-edit.js +67 -0
- package/build-module/hooks/template-part-edit.js.map +1 -0
- package/build-style/style-rtl.css +25 -25
- package/build-style/style.css +25 -25
- package/package.json +29 -29
- package/src/components/add-new-template/add-custom-template-modal.js +27 -45
- package/src/components/add-new-template/new-template.js +27 -64
- package/src/components/add-new-template/style.scss +20 -8
- package/src/components/add-new-template/utils.js +398 -229
- package/src/components/block-editor/index.js +0 -2
- package/src/components/global-styles/dimensions-panel.js +207 -14
- package/src/components/global-styles/hooks.js +2 -0
- package/src/components/global-styles/test/use-global-styles-output.js +64 -1
- package/src/components/global-styles/use-global-styles-output.js +100 -8
- package/src/components/global-styles/utils.js +31 -0
- package/src/components/header/index.js +9 -10
- package/src/components/header/style.scss +5 -3
- package/src/components/sidebar/style.scss +4 -0
- package/src/hooks/index.js +1 -0
- package/src/hooks/template-part-edit.js +82 -0
- package/src/style.scss +0 -1
- package/build/components/edit-template-part-menu-button/index.js +0 -90
- package/build/components/edit-template-part-menu-button/index.js.map +0 -1
- package/build-module/components/edit-template-part-menu-button/index.js +0 -72
- package/build-module/components/edit-template-part-menu-button/index.js.map +0 -1
- package/src/components/edit-template-part-menu-button/index.js +0 -82
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.useTaxonomiesMenuItems = exports.usePostTypeMenuItems = exports.useExistingTemplates = exports.useDefaultTemplateTypes = exports.mapToIHasNameAndId = void 0;
|
|
7
7
|
|
|
8
8
|
var _lodash = require("lodash");
|
|
9
9
|
|
|
@@ -55,76 +55,8 @@ const mapToIHasNameAndId = (entities, path) => {
|
|
|
55
55
|
* @property {number[]} existingEntitiesIds An array of the existing entities ids.
|
|
56
56
|
*/
|
|
57
57
|
|
|
58
|
-
/**
|
|
59
|
-
* @typedef {Object} EntityConfig
|
|
60
|
-
* @property {string} entityName The entity's name.
|
|
61
|
-
* @property {Function} getOrderBy Getter for an entity's `orderBy` query parameter, given the object
|
|
62
|
-
* {search} as argument.
|
|
63
|
-
* @property {Function} getIcon Getter function for returning an entity's icon for the menu item.
|
|
64
|
-
* @property {Function} getTitle Getter function for returning an entity's title for the menu item.
|
|
65
|
-
* @property {Function} getDescription Getter function for returning an entity's description for the menu item.
|
|
66
|
-
* @property {string} recordNamePath The path to an entity's properties to use as a `name`. If not provided
|
|
67
|
-
* is assumed that `name` property exists.
|
|
68
|
-
* @property {string} templatePrefix The template prefix to create new templates and check against existing
|
|
69
|
-
* templates. For example custom post types need a `single-` prefix to all
|
|
70
|
-
* templates(`single-post-hello`), whereas `pages` don't (`page-hello`).
|
|
71
|
-
* @property {string} templateSlug If this property is provided, it is going to be used for the creation of
|
|
72
|
-
* new templates and the check against existing templates in the place
|
|
73
|
-
* of the actual entity's `slug`. An example is `Tag` templates where the
|
|
74
|
-
* the Tag's taxonomy slug is `post_tag`, but template hierarchy is based
|
|
75
|
-
* on `tag` alias.
|
|
76
|
-
*/
|
|
77
|
-
|
|
78
58
|
|
|
79
59
|
exports.mapToIHasNameAndId = mapToIHasNameAndId;
|
|
80
|
-
const taxonomyBaseConfig = {
|
|
81
|
-
entityName: 'taxonomy',
|
|
82
|
-
getOrderBy: _ref => {
|
|
83
|
-
let {
|
|
84
|
-
search
|
|
85
|
-
} = _ref;
|
|
86
|
-
return search ? 'name' : 'count';
|
|
87
|
-
},
|
|
88
|
-
getIcon: () => _icons.blockMeta,
|
|
89
|
-
getTitle: labels => (0, _i18n.sprintf)( // translators: %s: Name of the taxonomy e.g: "Cagegory".
|
|
90
|
-
(0, _i18n.__)('Single taxonomy: %s'), labels.singular_name),
|
|
91
|
-
getDescription: labels => (0, _i18n.sprintf)( // translators: %s: Name of the taxonomy e.g: "Product Categories".
|
|
92
|
-
(0, _i18n.__)('Displays a single taxonomy: %s.'), labels.singular_name)
|
|
93
|
-
};
|
|
94
|
-
const postTypeBaseConfig = {
|
|
95
|
-
entityName: 'postType',
|
|
96
|
-
getOrderBy: _ref2 => {
|
|
97
|
-
let {
|
|
98
|
-
search
|
|
99
|
-
} = _ref2;
|
|
100
|
-
return search ? 'relevance' : 'modified';
|
|
101
|
-
},
|
|
102
|
-
recordNamePath: 'title.rendered',
|
|
103
|
-
// `icon` is the `menu_icon` property of a post type. We
|
|
104
|
-
// only handle `dashicons` for now, even if the `menu_icon`
|
|
105
|
-
// also supports urls and svg as values.
|
|
106
|
-
getIcon: _icon => _icon !== null && _icon !== void 0 && _icon.startsWith('dashicons-') ? _icon.slice(10) : _icons.post,
|
|
107
|
-
getTitle: labels => (0, _i18n.sprintf)( // translators: %s: Name of the post type e.g: "Post".
|
|
108
|
-
(0, _i18n.__)('Single item: %s'), labels.singular_name),
|
|
109
|
-
getDescription: labels => (0, _i18n.sprintf)( // translators: %s: Name of the post type e.g: "Post".
|
|
110
|
-
(0, _i18n.__)('Displays a single item: %s.'), labels.singular_name)
|
|
111
|
-
};
|
|
112
|
-
const entitiesConfig = {
|
|
113
|
-
postType: { ...postTypeBaseConfig,
|
|
114
|
-
templatePrefix: 'single-'
|
|
115
|
-
},
|
|
116
|
-
page: { ...postTypeBaseConfig
|
|
117
|
-
},
|
|
118
|
-
taxonomy: { ...taxonomyBaseConfig,
|
|
119
|
-
templatePrefix: 'taxonomy-'
|
|
120
|
-
},
|
|
121
|
-
category: { ...taxonomyBaseConfig
|
|
122
|
-
},
|
|
123
|
-
tag: { ...taxonomyBaseConfig,
|
|
124
|
-
templateSlug: 'tag'
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
exports.entitiesConfig = entitiesConfig;
|
|
128
60
|
|
|
129
61
|
const useExistingTemplates = () => {
|
|
130
62
|
return (0, _data.useSelect)(select => select(_coreData.store).getEntityRecords('postType', 'wp_template', {
|
|
@@ -146,135 +78,369 @@ const usePublicPostTypes = () => {
|
|
|
146
78
|
}), []);
|
|
147
79
|
return (0, _element.useMemo)(() => {
|
|
148
80
|
const excludedPostTypes = ['attachment'];
|
|
149
|
-
return postTypes === null || postTypes === void 0 ? void 0 : postTypes.filter(
|
|
81
|
+
return postTypes === null || postTypes === void 0 ? void 0 : postTypes.filter(_ref => {
|
|
150
82
|
let {
|
|
151
83
|
viewable,
|
|
152
84
|
slug
|
|
153
|
-
} =
|
|
85
|
+
} = _ref;
|
|
154
86
|
return viewable && !excludedPostTypes.includes(slug);
|
|
155
87
|
});
|
|
156
88
|
}, [postTypes]);
|
|
157
|
-
}; // `page` post type is a special case in the template hierarchy,
|
|
158
|
-
// so we exclude it from the list of post types and we handle it
|
|
159
|
-
// separately.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const usePostTypes = () => {
|
|
163
|
-
const postTypes = usePublicPostTypes();
|
|
164
|
-
return (0, _element.useMemo)(() => {
|
|
165
|
-
return postTypes === null || postTypes === void 0 ? void 0 : postTypes.filter(_ref4 => {
|
|
166
|
-
let {
|
|
167
|
-
slug
|
|
168
|
-
} = _ref4;
|
|
169
|
-
return slug !== 'page';
|
|
170
|
-
});
|
|
171
|
-
}, [postTypes]);
|
|
172
89
|
};
|
|
173
90
|
|
|
174
|
-
exports.usePostTypes = usePostTypes;
|
|
175
|
-
|
|
176
|
-
const usePostTypePage = () => {
|
|
177
|
-
const postTypes = usePublicPostTypes();
|
|
178
|
-
return (0, _element.useMemo)(() => {
|
|
179
|
-
return postTypes === null || postTypes === void 0 ? void 0 : postTypes.filter(_ref5 => {
|
|
180
|
-
let {
|
|
181
|
-
slug
|
|
182
|
-
} = _ref5;
|
|
183
|
-
return slug === 'page';
|
|
184
|
-
});
|
|
185
|
-
}, [postTypes]);
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
exports.usePostTypePage = usePostTypePage;
|
|
189
|
-
|
|
190
91
|
const usePublicTaxonomies = () => {
|
|
191
92
|
const taxonomies = (0, _data.useSelect)(select => select(_coreData.store).getTaxonomies({
|
|
192
93
|
per_page: -1
|
|
193
94
|
}), []);
|
|
194
95
|
return (0, _element.useMemo)(() => {
|
|
195
|
-
return taxonomies === null || taxonomies === void 0 ? void 0 : taxonomies.filter(
|
|
96
|
+
return taxonomies === null || taxonomies === void 0 ? void 0 : taxonomies.filter(_ref2 => {
|
|
196
97
|
let {
|
|
197
98
|
visibility
|
|
198
|
-
} =
|
|
99
|
+
} = _ref2;
|
|
199
100
|
return visibility === null || visibility === void 0 ? void 0 : visibility.publicly_queryable;
|
|
200
101
|
});
|
|
201
102
|
}, [taxonomies]);
|
|
202
103
|
};
|
|
203
|
-
/**
|
|
204
|
-
* `category` and `post_tag` are handled specifically in template
|
|
205
|
-
* hierarchy so we need to differentiate them and return the rest,
|
|
206
|
-
* e.g. `category-$slug` and `taxonomy-$taxonomy-$term`.
|
|
207
|
-
*/
|
|
208
104
|
|
|
105
|
+
const usePostTypeMenuItems = onClickMenuItem => {
|
|
106
|
+
const publicPostTypes = usePublicPostTypes();
|
|
107
|
+
const existingTemplates = useExistingTemplates();
|
|
108
|
+
const defaultTemplateTypes = useDefaultTemplateTypes(); // `page`is a special case in template hierarchy.
|
|
209
109
|
|
|
210
|
-
const
|
|
211
|
-
const taxonomies = usePublicTaxonomies();
|
|
212
|
-
const specialTaxonomies = ['category', 'post_tag'];
|
|
213
|
-
return (0, _element.useMemo)(() => taxonomies === null || taxonomies === void 0 ? void 0 : taxonomies.filter(_ref7 => {
|
|
110
|
+
const templatePrefixes = (0, _element.useMemo)(() => publicPostTypes === null || publicPostTypes === void 0 ? void 0 : publicPostTypes.reduce((accumulator, _ref3) => {
|
|
214
111
|
let {
|
|
215
112
|
slug
|
|
216
|
-
} =
|
|
217
|
-
|
|
218
|
-
}), [taxonomies]);
|
|
219
|
-
};
|
|
113
|
+
} = _ref3;
|
|
114
|
+
let suffix = slug;
|
|
220
115
|
|
|
221
|
-
|
|
116
|
+
if (slug !== 'page') {
|
|
117
|
+
suffix = `single-${suffix}`;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
accumulator[slug] = suffix;
|
|
121
|
+
return accumulator;
|
|
122
|
+
}, {}), [publicPostTypes]); // We need to keep track of naming conflicts. If a conflict
|
|
123
|
+
// occurs, we need to add slug.
|
|
124
|
+
|
|
125
|
+
const postTypeLabels = publicPostTypes === null || publicPostTypes === void 0 ? void 0 : publicPostTypes.reduce((accumulator, _ref4) => {
|
|
126
|
+
let {
|
|
127
|
+
labels
|
|
128
|
+
} = _ref4;
|
|
129
|
+
const singularName = labels.singular_name.toLowerCase();
|
|
130
|
+
accumulator[singularName] = (accumulator[singularName] || 0) + 1;
|
|
131
|
+
return accumulator;
|
|
132
|
+
}, {});
|
|
133
|
+
|
|
134
|
+
const needsUniqueIdentifier = (labels, slug) => {
|
|
135
|
+
const singularName = labels.singular_name.toLowerCase();
|
|
136
|
+
return postTypeLabels[singularName] > 1 && singularName !== slug;
|
|
137
|
+
};
|
|
222
138
|
|
|
223
|
-
const
|
|
224
|
-
const
|
|
225
|
-
return (0, _element.useMemo)(() => taxonomies === null || taxonomies === void 0 ? void 0 : taxonomies.filter(_ref8 => {
|
|
139
|
+
const postTypesInfo = useEntitiesInfo('postType', templatePrefixes);
|
|
140
|
+
const existingTemplateSlugs = (existingTemplates || []).map(_ref5 => {
|
|
226
141
|
let {
|
|
227
142
|
slug
|
|
228
|
-
} =
|
|
229
|
-
return slug
|
|
230
|
-
})
|
|
143
|
+
} = _ref5;
|
|
144
|
+
return slug;
|
|
145
|
+
});
|
|
146
|
+
const menuItems = (publicPostTypes || []).reduce((accumulator, postType) => {
|
|
147
|
+
var _postTypesInfo$slug;
|
|
148
|
+
|
|
149
|
+
const {
|
|
150
|
+
slug,
|
|
151
|
+
labels,
|
|
152
|
+
icon
|
|
153
|
+
} = postType; // We need to check if the general template is part of the
|
|
154
|
+
// defaultTemplateTypes. If it is, just use that info and
|
|
155
|
+
// augment it with the specific template functionality.
|
|
156
|
+
|
|
157
|
+
const generalTemplateSlug = templatePrefixes[slug];
|
|
158
|
+
const defaultTemplateType = defaultTemplateTypes === null || defaultTemplateTypes === void 0 ? void 0 : defaultTemplateTypes.find(_ref6 => {
|
|
159
|
+
let {
|
|
160
|
+
slug: _slug
|
|
161
|
+
} = _ref6;
|
|
162
|
+
return _slug === generalTemplateSlug;
|
|
163
|
+
});
|
|
164
|
+
const hasGeneralTemplate = existingTemplateSlugs === null || existingTemplateSlugs === void 0 ? void 0 : existingTemplateSlugs.includes(generalTemplateSlug);
|
|
165
|
+
|
|
166
|
+
const _needsUniqueIdentifier = needsUniqueIdentifier(labels, slug);
|
|
167
|
+
|
|
168
|
+
let menuItemTitle = (0, _i18n.sprintf)( // translators: %s: Name of the post type e.g: "Post".
|
|
169
|
+
(0, _i18n.__)('Single item: %s'), labels.singular_name);
|
|
170
|
+
|
|
171
|
+
if (_needsUniqueIdentifier) {
|
|
172
|
+
menuItemTitle = (0, _i18n.sprintf)( // translators: %1s: Name of the post type e.g: "Post"; %2s: Slug of the post type e.g: "book".
|
|
173
|
+
(0, _i18n.__)('Single item: %1$s (%2$s)'), labels.singular_name, slug);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const menuItem = defaultTemplateType ? { ...defaultTemplateType
|
|
177
|
+
} : {
|
|
178
|
+
slug: generalTemplateSlug,
|
|
179
|
+
title: menuItemTitle,
|
|
180
|
+
description: (0, _i18n.sprintf)( // translators: %s: Name of the post type e.g: "Post".
|
|
181
|
+
(0, _i18n.__)('Displays a single item: %s.'), labels.singular_name),
|
|
182
|
+
// `icon` is the `menu_icon` property of a post type. We
|
|
183
|
+
// only handle `dashicons` for now, even if the `menu_icon`
|
|
184
|
+
// also supports urls and svg as values.
|
|
185
|
+
icon: icon !== null && icon !== void 0 && icon.startsWith('dashicons-') ? icon.slice(10) : _icons.post
|
|
186
|
+
};
|
|
187
|
+
const hasEntities = postTypesInfo === null || postTypesInfo === void 0 ? void 0 : (_postTypesInfo$slug = postTypesInfo[slug]) === null || _postTypesInfo$slug === void 0 ? void 0 : _postTypesInfo$slug.hasEntities; // We have a different template creation flow only if they have entities.
|
|
188
|
+
|
|
189
|
+
if (hasEntities) {
|
|
190
|
+
menuItem.onClick = template => {
|
|
191
|
+
onClickMenuItem({
|
|
192
|
+
type: 'postType',
|
|
193
|
+
slug,
|
|
194
|
+
config: {
|
|
195
|
+
recordNamePath: 'title.rendered',
|
|
196
|
+
queryArgs: _ref7 => {
|
|
197
|
+
let {
|
|
198
|
+
search
|
|
199
|
+
} = _ref7;
|
|
200
|
+
return {
|
|
201
|
+
_fields: 'id,title,slug,link',
|
|
202
|
+
orderBy: search ? 'relevance' : 'modified',
|
|
203
|
+
exclude: postTypesInfo[slug].existingEntitiesIds
|
|
204
|
+
};
|
|
205
|
+
},
|
|
206
|
+
getSpecificTemplate: suggestion => {
|
|
207
|
+
let title = (0, _i18n.sprintf)( // translators: Represents the title of a user's custom template in the Site Editor, where %1$s is the singular name of a post type and %2$s is the name of the post, e.g. "Page: Hello".
|
|
208
|
+
(0, _i18n.__)('%1$s: %2$s'), labels.singular_name, suggestion.name);
|
|
209
|
+
const description = (0, _i18n.sprintf)( // translators: Represents the description of a user's custom template in the Site Editor, e.g. "Template for Page: Hello"
|
|
210
|
+
(0, _i18n.__)('Template for %1$s'), title);
|
|
211
|
+
|
|
212
|
+
if (_needsUniqueIdentifier) {
|
|
213
|
+
title = (0, _i18n.sprintf)( // translators: Represents the title of a user's custom template in the Site Editor, where %1$s is the template title and %2$s is the slug of the post type, e.g. "Project: Hello (project_type)"
|
|
214
|
+
(0, _i18n.__)('%1$s %2$s'), title, `(${slug})`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
title,
|
|
219
|
+
description,
|
|
220
|
+
slug: `${templatePrefixes[slug]}-${suggestion.slug}`
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
labels,
|
|
225
|
+
hasGeneralTemplate,
|
|
226
|
+
template
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
} // We don't need to add the menu item if there are no
|
|
230
|
+
// entities and the general template exists.
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
if (!hasGeneralTemplate || hasEntities) {
|
|
234
|
+
accumulator.push(menuItem);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return accumulator;
|
|
238
|
+
}, []); // Split menu items into two groups: one for the default post types
|
|
239
|
+
// and one for the rest.
|
|
240
|
+
|
|
241
|
+
const postTypesMenuItems = (0, _element.useMemo)(() => menuItems.reduce((accumulator, postType) => {
|
|
242
|
+
const {
|
|
243
|
+
slug
|
|
244
|
+
} = postType;
|
|
245
|
+
let key = 'postTypesMenuItems';
|
|
246
|
+
|
|
247
|
+
if (slug === 'page') {
|
|
248
|
+
key = 'defaultPostTypesMenuItems';
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
accumulator[key].push(postType);
|
|
252
|
+
return accumulator;
|
|
253
|
+
}, {
|
|
254
|
+
defaultPostTypesMenuItems: [],
|
|
255
|
+
postTypesMenuItems: []
|
|
256
|
+
}), [menuItems]);
|
|
257
|
+
return postTypesMenuItems;
|
|
231
258
|
};
|
|
232
259
|
|
|
233
|
-
exports.
|
|
260
|
+
exports.usePostTypeMenuItems = usePostTypeMenuItems;
|
|
261
|
+
|
|
262
|
+
const useTaxonomiesMenuItems = onClickMenuItem => {
|
|
263
|
+
const publicTaxonomies = usePublicTaxonomies();
|
|
264
|
+
const existingTemplates = useExistingTemplates();
|
|
265
|
+
const defaultTemplateTypes = useDefaultTemplateTypes(); // `category` and `post_tag` are special cases in template hierarchy.
|
|
234
266
|
|
|
235
|
-
const
|
|
236
|
-
const taxonomies = usePublicTaxonomies();
|
|
237
|
-
return (0, _element.useMemo)(() => taxonomies === null || taxonomies === void 0 ? void 0 : taxonomies.filter(_ref9 => {
|
|
267
|
+
const templatePrefixes = (0, _element.useMemo)(() => publicTaxonomies === null || publicTaxonomies === void 0 ? void 0 : publicTaxonomies.reduce((accumulator, _ref8) => {
|
|
238
268
|
let {
|
|
239
269
|
slug
|
|
270
|
+
} = _ref8;
|
|
271
|
+
let suffix = slug;
|
|
272
|
+
|
|
273
|
+
if (!['category', 'post_tag'].includes(slug)) {
|
|
274
|
+
suffix = `taxonomy-${suffix}`;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (slug === 'post_tag') {
|
|
278
|
+
suffix = `tag`;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
accumulator[slug] = suffix;
|
|
282
|
+
return accumulator;
|
|
283
|
+
}, {}), [publicTaxonomies]); // We need to keep track of naming conflicts. If a conflict
|
|
284
|
+
// occurs, we need to add slug.
|
|
285
|
+
|
|
286
|
+
const taxonomyLabels = publicTaxonomies === null || publicTaxonomies === void 0 ? void 0 : publicTaxonomies.reduce((accumulator, _ref9) => {
|
|
287
|
+
let {
|
|
288
|
+
labels
|
|
240
289
|
} = _ref9;
|
|
241
|
-
|
|
242
|
-
|
|
290
|
+
const singularName = labels.singular_name.toLowerCase();
|
|
291
|
+
accumulator[singularName] = (accumulator[singularName] || 0) + 1;
|
|
292
|
+
return accumulator;
|
|
293
|
+
}, {});
|
|
294
|
+
|
|
295
|
+
const needsUniqueIdentifier = (labels, slug) => {
|
|
296
|
+
if (['category', 'post_tag'].includes(slug)) {
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const singularName = labels.singular_name.toLowerCase();
|
|
301
|
+
return taxonomyLabels[singularName] > 1 && singularName !== slug;
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
const taxonomiesInfo = useEntitiesInfo('taxonomy', templatePrefixes);
|
|
305
|
+
const existingTemplateSlugs = (existingTemplates || []).map(_ref10 => {
|
|
306
|
+
let {
|
|
307
|
+
slug
|
|
308
|
+
} = _ref10;
|
|
309
|
+
return slug;
|
|
310
|
+
});
|
|
311
|
+
const menuItems = (publicTaxonomies || []).reduce((accumulator, taxonomy) => {
|
|
312
|
+
var _taxonomiesInfo$slug;
|
|
313
|
+
|
|
314
|
+
const {
|
|
315
|
+
slug,
|
|
316
|
+
labels
|
|
317
|
+
} = taxonomy; // We need to check if the general template is part of the
|
|
318
|
+
// defaultTemplateTypes. If it is, just use that info and
|
|
319
|
+
// augment it with the specific template functionality.
|
|
320
|
+
|
|
321
|
+
const generalTemplateSlug = templatePrefixes[slug];
|
|
322
|
+
const defaultTemplateType = defaultTemplateTypes === null || defaultTemplateTypes === void 0 ? void 0 : defaultTemplateTypes.find(_ref11 => {
|
|
323
|
+
let {
|
|
324
|
+
slug: _slug
|
|
325
|
+
} = _ref11;
|
|
326
|
+
return _slug === generalTemplateSlug;
|
|
327
|
+
});
|
|
328
|
+
const hasGeneralTemplate = existingTemplateSlugs === null || existingTemplateSlugs === void 0 ? void 0 : existingTemplateSlugs.includes(generalTemplateSlug);
|
|
329
|
+
|
|
330
|
+
const _needsUniqueIdentifier = needsUniqueIdentifier(labels, slug);
|
|
331
|
+
|
|
332
|
+
let menuItemTitle = labels.singular_name;
|
|
333
|
+
|
|
334
|
+
if (_needsUniqueIdentifier) {
|
|
335
|
+
menuItemTitle = (0, _i18n.sprintf)( // translators: %1s: Name of the taxonomy e.g: "Category"; %2s: Slug of the taxonomy e.g: "product_cat".
|
|
336
|
+
(0, _i18n.__)('%1$s (%2$s)'), labels.singular_name, slug);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const menuItem = defaultTemplateType ? { ...defaultTemplateType
|
|
340
|
+
} : {
|
|
341
|
+
slug: generalTemplateSlug,
|
|
342
|
+
title: menuItemTitle,
|
|
343
|
+
description: (0, _i18n.sprintf)( // translators: %s: Name of the taxonomy e.g: "Product Categories".
|
|
344
|
+
(0, _i18n.__)('Displays taxonomy: %s.'), labels.singular_name),
|
|
345
|
+
icon: _icons.blockMeta
|
|
346
|
+
};
|
|
347
|
+
const hasEntities = taxonomiesInfo === null || taxonomiesInfo === void 0 ? void 0 : (_taxonomiesInfo$slug = taxonomiesInfo[slug]) === null || _taxonomiesInfo$slug === void 0 ? void 0 : _taxonomiesInfo$slug.hasEntities; // We have a different template creation flow only if they have entities.
|
|
348
|
+
|
|
349
|
+
if (hasEntities) {
|
|
350
|
+
menuItem.onClick = template => {
|
|
351
|
+
onClickMenuItem({
|
|
352
|
+
type: 'taxonomy',
|
|
353
|
+
slug,
|
|
354
|
+
config: {
|
|
355
|
+
queryArgs: _ref12 => {
|
|
356
|
+
let {
|
|
357
|
+
search
|
|
358
|
+
} = _ref12;
|
|
359
|
+
return {
|
|
360
|
+
_fields: 'id,name,slug,link',
|
|
361
|
+
orderBy: search ? 'name' : 'count',
|
|
362
|
+
exclude: taxonomiesInfo[slug].existingEntitiesIds
|
|
363
|
+
};
|
|
364
|
+
},
|
|
365
|
+
getSpecificTemplate: suggestion => {
|
|
366
|
+
let title = (0, _i18n.sprintf)( // translators: Represents the title of a user's custom template in the Site Editor, where %1$s is the singular name of a taxonomy and %2$s is the name of the term, e.g. "Category: shoes".
|
|
367
|
+
(0, _i18n.__)('%1$s: %2$s'), labels.singular_name, suggestion.name);
|
|
368
|
+
const description = (0, _i18n.sprintf)( // translators: Represents the description of a user's custom template in the Site Editor, e.g. "Template for Category: shoes"
|
|
369
|
+
(0, _i18n.__)('Template for %1$s'), title);
|
|
370
|
+
|
|
371
|
+
if (_needsUniqueIdentifier) {
|
|
372
|
+
title = (0, _i18n.sprintf)( // translators: Represents the title of a user's custom template in the Site Editor, where %1$s is the template title and %2$s is the slug of the taxonomy, e.g. "Category: shoes (product_tag)"
|
|
373
|
+
(0, _i18n.__)('%1$s %2$s'), title, `(${slug})`);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return {
|
|
377
|
+
title,
|
|
378
|
+
description,
|
|
379
|
+
slug: `${templatePrefixes[slug]}-${suggestion.slug}`
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
labels,
|
|
384
|
+
hasGeneralTemplate,
|
|
385
|
+
template
|
|
386
|
+
});
|
|
387
|
+
};
|
|
388
|
+
} // We don't need to add the menu item if there are no
|
|
389
|
+
// entities and the general template exists.
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
if (!hasGeneralTemplate || hasEntities) {
|
|
393
|
+
accumulator.push(menuItem);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return accumulator;
|
|
397
|
+
}, []); // Split menu items into two groups: one for the default taxonomies
|
|
398
|
+
// and one for the rest.
|
|
399
|
+
|
|
400
|
+
const taxonomiesMenuItems = (0, _element.useMemo)(() => menuItems.reduce((accumulator, taxonomy) => {
|
|
401
|
+
const {
|
|
402
|
+
slug
|
|
403
|
+
} = taxonomy;
|
|
404
|
+
let key = 'taxonomiesMenuItems';
|
|
405
|
+
|
|
406
|
+
if (['category', 'tag'].includes(slug)) {
|
|
407
|
+
key = 'defaultTaxonomiesMenuItems';
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
accumulator[key].push(taxonomy);
|
|
411
|
+
return accumulator;
|
|
412
|
+
}, {
|
|
413
|
+
defaultTaxonomiesMenuItems: [],
|
|
414
|
+
taxonomiesMenuItems: []
|
|
415
|
+
}), [menuItems]);
|
|
416
|
+
return taxonomiesMenuItems;
|
|
243
417
|
};
|
|
244
418
|
/**
|
|
245
|
-
* Helper hook that
|
|
246
|
-
*
|
|
419
|
+
* Helper hook that filters all the existing templates by the given
|
|
420
|
+
* object with the entity's slug as key and the template prefix as value.
|
|
247
421
|
*
|
|
248
|
-
*
|
|
249
|
-
* `
|
|
422
|
+
* Example:
|
|
423
|
+
* `existingTemplates` is: [ { slug: tag-apple }, { slug: page-about }, { slug: tag } ]
|
|
424
|
+
* `templatePrefixes` is: { post_tag: 'tag' }
|
|
425
|
+
* It will return: { post_tag: [apple] }
|
|
250
426
|
*
|
|
251
|
-
*
|
|
252
|
-
* to query afterwards for any remaing record, by excluding them.
|
|
427
|
+
* Note: We append the `-` to the given template prefix in this function for our checks.
|
|
253
428
|
*
|
|
254
|
-
* @param {string
|
|
255
|
-
* @
|
|
256
|
-
* @param {EntityConfig} entityConfig The entity config.
|
|
257
|
-
* @return {Record<string,EntitiesInfo>} An object with the `entities.slug` as `keys` and EntitiesInfo as values.
|
|
429
|
+
* @param {Record<string,string>} templatePrefixes An object with the entity's slug as key and the template prefix as value.
|
|
430
|
+
* @return {Record<string,string[]>} An object with the entity's slug as key and an array with the existing template slugs as value.
|
|
258
431
|
*/
|
|
259
432
|
|
|
260
433
|
|
|
261
|
-
exports.
|
|
262
|
-
|
|
263
|
-
const useEntitiesInfo = (existingTemplates, entities, _ref10) => {
|
|
264
|
-
let {
|
|
265
|
-
entityName,
|
|
266
|
-
templatePrefix,
|
|
267
|
-
templateSlug
|
|
268
|
-
} = _ref10;
|
|
269
|
-
const slugsToExcludePerEntity = (0, _element.useMemo)(() => {
|
|
270
|
-
return entities === null || entities === void 0 ? void 0 : entities.reduce((accumulator, entity) => {
|
|
271
|
-
let _prefix = `${templateSlug || entity.slug}-`;
|
|
272
|
-
|
|
273
|
-
if (templatePrefix) {
|
|
274
|
-
_prefix = templatePrefix + _prefix;
|
|
275
|
-
}
|
|
434
|
+
exports.useTaxonomiesMenuItems = useTaxonomiesMenuItems;
|
|
276
435
|
|
|
436
|
+
const useExistingTemplateSlugs = templatePrefixes => {
|
|
437
|
+
const existingTemplates = useExistingTemplates();
|
|
438
|
+
const existingSlugs = (0, _element.useMemo)(() => {
|
|
439
|
+
return Object.entries(templatePrefixes || {}).reduce((accumulator, _ref13) => {
|
|
440
|
+
let [slug, prefix] = _ref13;
|
|
277
441
|
const slugsWithTemplates = (existingTemplates || []).reduce((_accumulator, existingTemplate) => {
|
|
442
|
+
const _prefix = `${prefix}-`;
|
|
443
|
+
|
|
278
444
|
if (existingTemplate.slug.startsWith(_prefix)) {
|
|
279
445
|
_accumulator.push(existingTemplate.slug.substring(_prefix.length));
|
|
280
446
|
}
|
|
@@ -283,43 +449,70 @@ const useEntitiesInfo = (existingTemplates, entities, _ref10) => {
|
|
|
283
449
|
}, []);
|
|
284
450
|
|
|
285
451
|
if (slugsWithTemplates.length) {
|
|
286
|
-
accumulator[
|
|
452
|
+
accumulator[slug] = slugsWithTemplates;
|
|
287
453
|
}
|
|
288
454
|
|
|
289
455
|
return accumulator;
|
|
290
456
|
}, {});
|
|
291
|
-
}, [
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
457
|
+
}, [templatePrefixes, existingTemplates]);
|
|
458
|
+
return existingSlugs;
|
|
459
|
+
};
|
|
460
|
+
/**
|
|
461
|
+
* Helper hook that finds the existing records with an associated template,
|
|
462
|
+
* as they need to be excluded from the template suggestions.
|
|
463
|
+
*
|
|
464
|
+
* @param {string} entityName The entity's name.
|
|
465
|
+
* @param {Record<string,string>} templatePrefixes An object with the entity's slug as key and the template prefix as value.
|
|
466
|
+
* @return {Record<string,EntitiesInfo>} An object with the entity's slug as key and the existing records as value.
|
|
467
|
+
*/
|
|
296
468
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
469
|
+
|
|
470
|
+
const useTemplatesToExclude = (entityName, templatePrefixes) => {
|
|
471
|
+
const slugsToExcludePerEntity = useExistingTemplateSlugs(templatePrefixes);
|
|
472
|
+
const recordsToExcludePerEntity = (0, _data.useSelect)(select => {
|
|
473
|
+
return Object.entries(slugsToExcludePerEntity || {}).reduce((accumulator, _ref14) => {
|
|
474
|
+
let [slug, slugsWithTemplates] = _ref14;
|
|
475
|
+
const entitiesWithTemplates = select(_coreData.store).getEntityRecords(entityName, slug, {
|
|
300
476
|
_fields: 'id',
|
|
301
477
|
context: 'view',
|
|
302
478
|
slug: slugsWithTemplates
|
|
303
479
|
});
|
|
304
480
|
|
|
305
|
-
if (
|
|
306
|
-
accumulator[slug] =
|
|
481
|
+
if (entitiesWithTemplates !== null && entitiesWithTemplates !== void 0 && entitiesWithTemplates.length) {
|
|
482
|
+
accumulator[slug] = entitiesWithTemplates;
|
|
307
483
|
}
|
|
308
484
|
|
|
309
485
|
return accumulator;
|
|
310
486
|
}, {});
|
|
311
487
|
}, [slugsToExcludePerEntity]);
|
|
488
|
+
return recordsToExcludePerEntity;
|
|
489
|
+
};
|
|
490
|
+
/**
|
|
491
|
+
* Helper hook that returns information about an entity having
|
|
492
|
+
* records that we can create a specific template for.
|
|
493
|
+
*
|
|
494
|
+
* For example we can search for `terms` in `taxonomy` entity or
|
|
495
|
+
* `posts` in `postType` entity.
|
|
496
|
+
*
|
|
497
|
+
* First we need to find the existing records with an associated template,
|
|
498
|
+
* to query afterwards for any remaining record, by excluding them.
|
|
499
|
+
*
|
|
500
|
+
* @param {string} entityName The entity's name.
|
|
501
|
+
* @param {Record<string,string>} templatePrefixes An object with the entity's slug as key and the template prefix as value.
|
|
502
|
+
* @return {Record<string,EntitiesInfo>} An object with the entity's slug as key and the EntitiesInfo as value.
|
|
503
|
+
*/
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
const useEntitiesInfo = (entityName, templatePrefixes) => {
|
|
507
|
+
const recordsToExcludePerEntity = useTemplatesToExclude(entityName, templatePrefixes);
|
|
312
508
|
const entitiesInfo = (0, _data.useSelect)(select => {
|
|
313
|
-
return
|
|
509
|
+
return Object.keys(templatePrefixes || {}).reduce((accumulator, slug) => {
|
|
314
510
|
var _recordsToExcludePerE, _select$getEntityReco;
|
|
315
511
|
|
|
316
|
-
|
|
317
|
-
slug
|
|
318
|
-
} = _ref12;
|
|
319
|
-
const existingEntitiesIds = (recordsToExcludePerEntity === null || recordsToExcludePerEntity === void 0 ? void 0 : (_recordsToExcludePerE = recordsToExcludePerEntity[slug]) === null || _recordsToExcludePerE === void 0 ? void 0 : _recordsToExcludePerE.map(_ref13 => {
|
|
512
|
+
const existingEntitiesIds = (recordsToExcludePerEntity === null || recordsToExcludePerEntity === void 0 ? void 0 : (_recordsToExcludePerE = recordsToExcludePerEntity[slug]) === null || _recordsToExcludePerE === void 0 ? void 0 : _recordsToExcludePerE.map(_ref15 => {
|
|
320
513
|
let {
|
|
321
514
|
id
|
|
322
|
-
} =
|
|
515
|
+
} = _ref15;
|
|
323
516
|
return id;
|
|
324
517
|
})) || [];
|
|
325
518
|
accumulator[slug] = {
|
|
@@ -333,73 +526,7 @@ const useEntitiesInfo = (existingTemplates, entities, _ref10) => {
|
|
|
333
526
|
};
|
|
334
527
|
return accumulator;
|
|
335
528
|
}, {});
|
|
336
|
-
}, [
|
|
529
|
+
}, [templatePrefixes, recordsToExcludePerEntity]);
|
|
337
530
|
return entitiesInfo;
|
|
338
531
|
};
|
|
339
|
-
|
|
340
|
-
const useExtraTemplates = (entities, entityConfig, onClickMenuItem) => {
|
|
341
|
-
const existingTemplates = useExistingTemplates();
|
|
342
|
-
const defaultTemplateTypes = useDefaultTemplateTypes();
|
|
343
|
-
const entitiesInfo = useEntitiesInfo(existingTemplates, entities, entityConfig);
|
|
344
|
-
const existingTemplateSlugs = (existingTemplates || []).map(_ref14 => {
|
|
345
|
-
let {
|
|
346
|
-
slug
|
|
347
|
-
} = _ref14;
|
|
348
|
-
return slug;
|
|
349
|
-
});
|
|
350
|
-
const extraTemplates = (entities || []).reduce((accumulator, entity) => {
|
|
351
|
-
var _entityConfig$getIcon, _entitiesInfo$slug;
|
|
352
|
-
|
|
353
|
-
const {
|
|
354
|
-
slug,
|
|
355
|
-
labels,
|
|
356
|
-
icon
|
|
357
|
-
} = entity;
|
|
358
|
-
const slugForGeneralTemplate = entityConfig.templateSlug || slug; // We need to check if the general template is part of the
|
|
359
|
-
// defaultTemplateTypes. If it is, just use that info and
|
|
360
|
-
// augment it with the specific template functionality.
|
|
361
|
-
|
|
362
|
-
const defaultTemplateType = defaultTemplateTypes === null || defaultTemplateTypes === void 0 ? void 0 : defaultTemplateTypes.find(_ref15 => {
|
|
363
|
-
let {
|
|
364
|
-
slug: _slug
|
|
365
|
-
} = _ref15;
|
|
366
|
-
return _slug === slugForGeneralTemplate;
|
|
367
|
-
});
|
|
368
|
-
const generalTemplateSlug = (defaultTemplateType === null || defaultTemplateType === void 0 ? void 0 : defaultTemplateType.slug) || `${entityConfig.templatePrefix}${slug}`;
|
|
369
|
-
const hasGeneralTemplate = existingTemplateSlugs === null || existingTemplateSlugs === void 0 ? void 0 : existingTemplateSlugs.includes(generalTemplateSlug);
|
|
370
|
-
const menuItem = defaultTemplateType ? { ...defaultTemplateType
|
|
371
|
-
} : {
|
|
372
|
-
slug: generalTemplateSlug,
|
|
373
|
-
title: entityConfig.getTitle(labels),
|
|
374
|
-
description: entityConfig.getDescription(labels),
|
|
375
|
-
icon: (_entityConfig$getIcon = entityConfig.getIcon) === null || _entityConfig$getIcon === void 0 ? void 0 : _entityConfig$getIcon.call(entityConfig, icon)
|
|
376
|
-
};
|
|
377
|
-
const hasEntities = entitiesInfo === null || entitiesInfo === void 0 ? void 0 : (_entitiesInfo$slug = entitiesInfo[slug]) === null || _entitiesInfo$slug === void 0 ? void 0 : _entitiesInfo$slug.hasEntities; // We have a different template creation flow only if they have entities.
|
|
378
|
-
|
|
379
|
-
if (hasEntities) {
|
|
380
|
-
menuItem.onClick = template => {
|
|
381
|
-
onClickMenuItem({
|
|
382
|
-
type: entityConfig.entityName,
|
|
383
|
-
slug,
|
|
384
|
-
config: entityConfig,
|
|
385
|
-
labels,
|
|
386
|
-
hasGeneralTemplate,
|
|
387
|
-
template,
|
|
388
|
-
postsToExclude: entitiesInfo[slug].existingEntitiesIds
|
|
389
|
-
});
|
|
390
|
-
};
|
|
391
|
-
} // We don't need to add the menu item if there are no
|
|
392
|
-
// entities and the general template exists.
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
if (!hasGeneralTemplate || hasEntities) {
|
|
396
|
-
accumulator.push(menuItem);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
return accumulator;
|
|
400
|
-
}, []);
|
|
401
|
-
return extraTemplates;
|
|
402
|
-
};
|
|
403
|
-
|
|
404
|
-
exports.useExtraTemplates = useExtraTemplates;
|
|
405
532
|
//# sourceMappingURL=utils.js.map
|