Skip to content

Commit

Permalink
Add has_archive checks
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgefilipecosta authored and ntsekouras committed Aug 18, 2022
1 parent 29d6801 commit 639f0be
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 20 deletions.
33 changes: 33 additions & 0 deletions lib/compat/wordpress-6.1/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,36 @@ function gutenberg_add_site_icon_url_to_index( WP_REST_Response $response ) {
return $response;
}
add_action( 'rest_index', 'gutenberg_add_site_icon_url_to_index' );

/**
* Returns the has_archive post type field.
*
* @param array $type The response data.
* @param string $field_name $field_name The field name. The function handles field has_archive.
* @param WP_REST_Request $request The wp rest request object.
*/
function gutenberg_get_post_type_has_archive_field( $type, $field_name, $request ) {
if ( ! empty( $type ) && ! empty( $type['slug'] ) && 'has_archive' === $field_name ) {
$post_type_object = get_post_type_object( $type['slug'] );
return $post_type_object->has_archive;
}
}

/**
* Registers the has_archive post type REST API field.
*/
function gutenberg_register_has_archive_on_post_types_endpoint() {
register_rest_field(
'type',
'has_archive',
array(
'get_callback' => 'gutenberg_get_post_type_has_archive_field',
'schema' => array(
'description' => __( 'If the value is a string, the value will be used as the archive slug. If the value is false the post type has no archive.', 'gutenberg' ),
'type' => array( 'string', 'boolean' ),
'context' => array( 'view', 'edit' ),
),
)
);
}
add_action( 'rest_api_init', 'gutenberg_register_has_archive_on_post_types_endpoint' );
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
useTaxonomiesMenuItems,
usePostTypeMenuItems,
useAuthorMenuItem,
usePostTypeArchiveMenuItems,
} from './utils';
import AddCustomGenericTemplateModal from './add-custom-generic-template-modal';
import { useHistory } from '../routes';
Expand Down Expand Up @@ -292,6 +293,7 @@ function useMissingTemplates(
} );
const missingTemplates = [
...enhancedMissingDefaultTemplateTypes,
...usePostTypeArchiveMenuItems(),
...postTypesMenuItems,
...taxonomiesMenuItems,
];
Expand Down
101 changes: 81 additions & 20 deletions packages/edit-site/src/components/add-new-template/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { store as editorStore } from '@wordpress/editor';
import { decodeEntities } from '@wordpress/html-entities';
import { useMemo, useCallback } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { blockMeta, post } from '@wordpress/icons';
import { blockMeta, post, archive } from '@wordpress/icons';

/**
* @typedef IHasNameAndId
Expand Down Expand Up @@ -86,10 +86,89 @@ const usePublicTaxonomies = () => {
}, [ taxonomies ] );
};

function usePostTypeNeedsUniqueIdentifier( publicPostTypes ) {
const postTypeLabels = useMemo( () =>
publicPostTypes?.reduce( ( accumulator, { labels } ) => {
const singularName = labels.singular_name.toLowerCase();
accumulator[ singularName ] =
( accumulator[ singularName ] || 0 ) + 1;
return accumulator;
}, {} )
);
return useCallback(
( { labels, slug } ) => {
const singularName = labels.singular_name.toLowerCase();
return postTypeLabels[ singularName ] > 1 && singularName !== slug;
},
[ postTypeLabels ]
);
}

export function usePostTypeArchiveMenuItems() {
const publicPostTypes = usePublicPostTypes();
const postTypesWithArchives = useMemo(
() => publicPostTypes?.filter( ( postType ) => postType.has_archive ),
[ publicPostTypes ]
);
const existingTemplates = useExistingTemplates();
const needsUniqueIdentifier = usePostTypeNeedsUniqueIdentifier(
postTypesWithArchives
);
return useMemo(
() =>
postTypesWithArchives
?.filter(
( postType ) =>
! existingTemplates.some(
( existingTemplate ) =>
existingTemplate.slug ===
'archive-' + postType.slug
)
)
.map( ( postType ) => {
let title;
if ( needsUniqueIdentifier( postType ) ) {
title = sprintf(
// translators: %1s: Name of the post type e.g: "Post"; %2s: Slug of the post type e.g: "book".
__( 'Archive: %1$s (%2$s)' ),
postType.labels.singular_name,
postType.slug
);
} else {
title = sprintf(
// translators: %s: Name of the post type e.g: "Post".
__( 'Archive: %s' ),
postType.labels.singular_name
);
}
return {
slug: 'archive-' + postType.slug,
description: sprintf(
// translators: %s: Name of the post type e.g: "Post".
__(
'Displays an archive with the latests posts of type: %s.'
),
postType.labels.singular_name
),
title,
// `icon` is the `menu_icon` property of a post type. We
// only handle `dashicons` for now, even if the `menu_icon`
// also supports urls and svg as values.
icon: postType.icon?.startsWith( 'dashicons-' )
? postType.icon.slice( 10 )
: archive,
};
} ) || [],
[ postTypesWithArchives, existingTemplates, needsUniqueIdentifier ]
);
}

export const usePostTypeMenuItems = ( onClickMenuItem ) => {
const publicPostTypes = usePublicPostTypes();
const existingTemplates = useExistingTemplates();
const defaultTemplateTypes = useDefaultTemplateTypes();
const needsUniqueIdentifier =
usePostTypeNeedsUniqueIdentifier( publicPostTypes );
// `page`is a special case in template hierarchy.
const templatePrefixes = useMemo(
() =>
Expand All @@ -103,21 +182,6 @@ export const usePostTypeMenuItems = ( onClickMenuItem ) => {
}, {} ),
[ publicPostTypes ]
);
// We need to keep track of naming conflicts. If a conflict
// occurs, we need to add slug.
const postTypeLabels = publicPostTypes?.reduce(
( accumulator, { labels } ) => {
const singularName = labels.singular_name.toLowerCase();
accumulator[ singularName ] =
( accumulator[ singularName ] || 0 ) + 1;
return accumulator;
},
{}
);
const needsUniqueIdentifier = ( labels, slug ) => {
const singularName = labels.singular_name.toLowerCase();
return postTypeLabels[ singularName ] > 1 && singularName !== slug;
};
const postTypesInfo = useEntitiesInfo( 'postType', templatePrefixes );
const existingTemplateSlugs = ( existingTemplates || [] ).map(
( { slug } ) => slug
Expand All @@ -134,10 +198,7 @@ export const usePostTypeMenuItems = ( onClickMenuItem ) => {
);
const hasGeneralTemplate =
existingTemplateSlugs?.includes( generalTemplateSlug );
const _needsUniqueIdentifier = needsUniqueIdentifier(
labels,
slug
);
const _needsUniqueIdentifier = needsUniqueIdentifier( postType );
let menuItemTitle = sprintf(
// translators: %s: Name of the post type e.g: "Post".
__( 'Single item: %s' ),
Expand Down

0 comments on commit 639f0be

Please sign in to comment.