@wordpress/block-library
Version:
Block library for the WordPress editor.
294 lines (287 loc) • 9.7 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = PostTemplateEdit;
var _clsx = _interopRequireDefault(require("clsx"));
var _element = require("@wordpress/element");
var _data = require("@wordpress/data");
var _i18n = require("@wordpress/i18n");
var _blockEditor = require("@wordpress/block-editor");
var _components = require("@wordpress/components");
var _coreData = require("@wordpress/core-data");
var _icons = require("@wordpress/icons");
var _jsxRuntime = require("react/jsx-runtime");
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
const TEMPLATE = [['core/post-title'], ['core/post-date'], ['core/post-excerpt']];
function PostTemplateInnerBlocks({
classList
}) {
const innerBlocksProps = (0, _blockEditor.useInnerBlocksProps)({
className: (0, _clsx.default)('wp-block-post', classList)
}, {
template: TEMPLATE,
__unstableDisableLayoutClassNames: true
});
return /*#__PURE__*/(0, _jsxRuntime.jsx)("li", {
...innerBlocksProps
});
}
function PostTemplateBlockPreview({
blocks,
blockContextId,
classList,
isHidden,
setActiveBlockContextId
}) {
const blockPreviewProps = (0, _blockEditor.__experimentalUseBlockPreview)({
blocks,
props: {
className: (0, _clsx.default)('wp-block-post', classList)
}
});
const handleOnClick = () => {
setActiveBlockContextId(blockContextId);
};
const style = {
display: isHidden ? 'none' : undefined
};
return /*#__PURE__*/(0, _jsxRuntime.jsx)("li", {
...blockPreviewProps,
tabIndex: 0
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
,
role: "button",
onClick: handleOnClick,
onKeyPress: handleOnClick,
style: style
});
}
const MemoizedPostTemplateBlockPreview = (0, _element.memo)(PostTemplateBlockPreview);
function PostTemplateEdit({
setAttributes,
clientId,
context: {
query: {
perPage,
offset = 0,
postType,
order,
orderBy,
author,
search,
exclude,
sticky,
inherit,
taxQuery,
parents,
pages,
format,
// We gather extra query args to pass to the REST API call.
// This way extenders of Query Loop can add their own query args,
// and have accurate previews in the editor.
// Noting though that these args should either be supported by the
// REST API or be handled by custom REST filters like `rest_{$this->post_type}_query`.
...restQueryArgs
} = {},
templateSlug,
previewPostType
},
attributes: {
layout
},
__unstableLayoutClassNames
}) {
const {
type: layoutType,
columnCount = 3
} = layout || {};
const [activeBlockContextId, setActiveBlockContextId] = (0, _element.useState)();
const {
posts,
blocks
} = (0, _data.useSelect)(select => {
const {
getEntityRecords,
getTaxonomies
} = select(_coreData.store);
const {
getBlocks
} = select(_blockEditor.store);
const templateCategory = inherit && templateSlug?.startsWith('category-') && getEntityRecords('taxonomy', 'category', {
context: 'view',
per_page: 1,
_fields: ['id'],
slug: templateSlug.replace('category-', '')
});
const templateTag = inherit && templateSlug?.startsWith('tag-') && getEntityRecords('taxonomy', 'post_tag', {
context: 'view',
per_page: 1,
_fields: ['id'],
slug: templateSlug.replace('tag-', '')
});
const query = {
offset: offset || 0,
order,
orderby: orderBy
};
// There is no need to build the taxQuery if we inherit.
if (taxQuery && !inherit) {
const taxonomies = getTaxonomies({
type: postType,
per_page: -1,
context: 'view'
});
// We have to build the tax query for the REST API and use as
// keys the taxonomies `rest_base` with the `term ids` as values.
const builtTaxQuery = Object.entries(taxQuery).reduce((accumulator, [taxonomySlug, terms]) => {
const taxonomy = taxonomies?.find(({
slug
}) => slug === taxonomySlug);
if (taxonomy?.rest_base) {
accumulator[taxonomy?.rest_base] = terms;
}
return accumulator;
}, {});
if (!!Object.keys(builtTaxQuery).length) {
Object.assign(query, builtTaxQuery);
}
}
if (perPage) {
query.per_page = perPage;
}
if (author) {
query.author = author;
}
if (search) {
query.search = search;
}
if (exclude?.length) {
query.exclude = exclude;
}
if (parents?.length) {
query.parent = parents;
}
if (format?.length) {
query.format = format;
}
/*
* Handle cases where sticky is set to `exclude` or `only`.
* Which works as a `post__in/post__not_in` query for sticky posts.
*/
if (['exclude', 'only'].includes(sticky)) {
query.sticky = sticky === 'only';
}
// Empty string represents the default behavior of including sticky posts.
if (['', 'ignore'].includes(sticky)) {
// Remove any leftover sticky query parameter.
delete query.sticky;
query.ignore_sticky = sticky === 'ignore';
}
// If `inherit` is truthy, adjust conditionally the query to create a better preview.
let currentPostType = postType;
if (inherit) {
// Change the post-type if needed.
if (templateSlug?.startsWith('archive-')) {
query.postType = templateSlug.replace('archive-', '');
currentPostType = query.postType;
} else if (templateCategory) {
query.categories = templateCategory[0]?.id;
} else if (templateTag) {
query.tags = templateTag[0]?.id;
} else if (templateSlug?.startsWith('taxonomy-post_format')) {
// Get the post format slug from the template slug by removing the prefix.
query.format = templateSlug.replace('taxonomy-post_format-post-format-', '');
}
}
// When we preview Query Loop blocks we should prefer the current
// block's postType, which is passed through block context.
const usedPostType = previewPostType || currentPostType;
return {
posts: getEntityRecords('postType', usedPostType, {
...query,
...restQueryArgs
}),
blocks: getBlocks(clientId)
};
}, [perPage, offset, order, orderBy, clientId, author, search, postType, exclude, sticky, inherit, templateSlug, taxQuery, parents, format, restQueryArgs, previewPostType]);
const blockContexts = (0, _element.useMemo)(() => posts?.map(post => {
var _post$class_list;
return {
postType: post.type,
postId: post.id,
classList: (_post$class_list = post.class_list) !== null && _post$class_list !== void 0 ? _post$class_list : ''
};
}), [posts]);
const blockProps = (0, _blockEditor.useBlockProps)({
className: (0, _clsx.default)(__unstableLayoutClassNames, {
[`columns-${columnCount}`]: layoutType === 'grid' && columnCount // Ensure column count is flagged via classname for backwards compatibility.
})
});
if (!posts) {
return /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
...blockProps,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Spinner, {})
});
}
if (!posts.length) {
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("p", {
...blockProps,
children: [" ", (0, _i18n.__)('No results found.')]
});
}
const setDisplayLayout = newDisplayLayout => setAttributes({
layout: {
...layout,
...newDisplayLayout
}
});
const displayLayoutControls = [{
icon: _icons.list,
title: (0, _i18n._x)('List view', 'Post template block display setting'),
onClick: () => setDisplayLayout({
type: 'default'
}),
isActive: layoutType === 'default' || layoutType === 'constrained'
}, {
icon: _icons.grid,
title: (0, _i18n._x)('Grid view', 'Post template block display setting'),
onClick: () => setDisplayLayout({
type: 'grid',
columnCount
}),
isActive: layoutType === 'grid'
}];
// To avoid flicker when switching active block contexts, a preview is rendered
// for each block context, but the preview for the active block context is hidden.
// This ensures that when it is displayed again, the cached rendering of the
// block preview is used, instead of having to re-render the preview from scratch.
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.BlockControls, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarGroup, {
controls: displayLayoutControls
})
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("ul", {
...blockProps,
children: blockContexts && blockContexts.map(blockContext => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_blockEditor.BlockContextProvider, {
value: blockContext,
children: [blockContext.postId === (activeBlockContextId || blockContexts[0]?.postId) ? /*#__PURE__*/(0, _jsxRuntime.jsx)(PostTemplateInnerBlocks, {
classList: blockContext.classList
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(MemoizedPostTemplateBlockPreview, {
blocks: blocks,
blockContextId: blockContext.postId,
classList: blockContext.classList,
setActiveBlockContextId: setActiveBlockContextId,
isHidden: blockContext.postId === (activeBlockContextId || blockContexts[0]?.postId)
})]
}, blockContext.postId))
})]
});
}
//# sourceMappingURL=edit.js.map