Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Post Type Archive in Link UI and Navigation Link via Types API endpoint #67793

Open
wants to merge 8 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions lib/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,23 @@ function gutenberg_register_edit_site_export_controller_endpoints() {
$edit_site_export_controller->register_routes();
}
add_action( 'rest_api_init', 'gutenberg_register_edit_site_export_controller_endpoints' );


function gutenberg_register_archive_link_field() {
register_rest_field(
'type',
'archive_link',
array(
'get_callback' => static function ( $post_object ) {
return (string) get_post_type_archive_link( $post_object['slug'] );
},
'update_callback' => null,
'schema' => array(
'description' => __( 'Link to the post type archive page', 'default' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
),
)
);
}
add_action( 'rest_api_init', 'gutenberg_register_archive_link_field' );
23 changes: 13 additions & 10 deletions packages/block-editor/src/components/link-control/search-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
file,
home,
verse,
customPostType,
} from '@wordpress/icons';
import { __unstableStripHTML as stripHTML } from '@wordpress/dom';
import { safeDecodeURI, filterURLForDisplay, getPath } from '@wordpress/url';
Expand Down Expand Up @@ -42,18 +43,16 @@ function SearchItemIcon( { isURL, suggestion } ) {
icon = verse;
}
}
} else {
icon = customPostType;
}

if ( icon ) {
return (
<Icon
className="block-editor-link-control__search-item-icon"
icon={ icon }
/>
);
}

return null;
return (
<Icon
className="block-editor-link-control__search-item-icon"
icon={ icon }
/>
);
}

/**
Expand Down Expand Up @@ -156,6 +155,10 @@ function getVisualTypeName( suggestion ) {
return 'blog home';
}

if ( suggestion.kind === 'post-type-archive' ) {
return 'archive';
}

// Rename 'post_tag' to 'tag'. Ideally, the API would return the localised CPT or taxonomy label.
return suggestion.type === 'post_tag' ? 'tag' : suggestion.type;
}
Expand Down
23 changes: 23 additions & 0 deletions packages/block-library/src/navigation-link/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ function block_core_navigation_link_filter_variations( $variations, $block_type
* @return array
*/
function block_core_navigation_link_build_variations() {

$post_types = get_post_types( array( 'show_in_nav_menus' => true ), 'objects' );
$taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'objects' );

Expand All @@ -407,6 +408,28 @@ function block_core_navigation_link_build_variations() {
$variations[] = $variation;
}
}

// If any of the post types have `has_archive` set to true then add a post-type-archive variation.
$has_archive = array();

foreach ( $post_types as $post_type ) {
if ( $post_type->has_archive ) {
$has_archive[] = $post_type;
}
}

if ( $has_archive ) {
$variation = array(
'name' => 'post-type-archive',
'title' => __( 'Post Type Archive Link' ),
'description' => __( 'A link to a post type archive' ),
'attributes' => array(
'type' => 'all',
'kind' => 'post-type-archive',
),
);
$variations[] = $variation;
}
}
if ( $taxonomies ) {
foreach ( $taxonomies as $taxonomy ) {
Expand Down
3 changes: 3 additions & 0 deletions packages/block-library/src/navigation-link/link-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ export function getSuggestionsQuery( type, kind ) {
if ( kind === 'taxonomy' ) {
return { type: 'term', subtype: type };
}
if ( kind === 'post-type-archive' ) {
return { type: 'post-type-archive' };
}
if ( kind === 'post-type' ) {
return { type: 'post', subtype: type };
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export type SearchOptions = {
/**
* Filters by search type.
*/
type?: 'attachment' | 'post' | 'term' | 'post-format';
type?: 'attachment' | 'post' | 'term' | 'post-format' | 'post-type-archive';
/**
* Slug of the post-type or taxonomy.
*/
Expand Down Expand Up @@ -58,6 +58,12 @@ type MediaAPIResult = {
type: string;
};

type PostTypesAPIResult = {
slug: string;
name: string;
archive_link: string;
};

export type SearchResult = {
/**
* Post or term id.
Expand Down Expand Up @@ -240,6 +246,31 @@ export default async function fetchLinkSuggestions(
);
}

if ( ! type || type === 'post-type-archive' ) {
queries.push(
apiFetch< PostTypesAPIResult[] >( {
path: addQueryArgs( '/wp/v2/types' ),
} )
.then( ( results ) => {
const resultValues = Object.values( results );
return resultValues
.filter( ( result ) => !! result.archive_link ) // Filter out results with falsy archive_link, including empty strings
.map( ( result, index ) => {
return {
id: index + 1, // avoid results being filtered due to falsy id
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having to use a manual id isn't ideal here.

url: result.archive_link,
title:
decodeEntities( result.name || '' ) ||
__( '(no title)' ),
type: result.slug,
kind: 'post-type-archive',
};
} );
} )
.catch( () => [] ) // Fail by returning no results.
);
}

const responses = await Promise.all( queries );

let results = responses.flat();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@
'http://localhost:8888/wp-content/uploads/2022/03/test-pdf.pdf',
},
] );
case '/wp/v2/search?search=&per_page=20&type=post-type-archive':
return Promise.resolve( [
{
id: 'books',
title: 'All Books',
url: 'http://wordpress.local/books/',
type: 'books-archive',
kind: 'post-type-archive',
},
] );
default:
return Promise.resolve( [
{
Expand Down Expand Up @@ -187,9 +197,9 @@
);
} );

it( 'returns suggestions from post, term, post-format and media', () => {
it( 'returns suggestions from post, term, post-format, media and post-type-archive', () => {
return fetchLinkSuggestions( '', {} ).then( ( suggestions ) =>
expect( suggestions ).toEqual( [

Check failure on line 202 in packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js

View workflow job for this annotation

GitHub Actions / JavaScript (Node.js 22) 4/4

Error: expect(received).toEqual(expected) // deep equality - Expected - 7 + Received + 0 @@ -39,13 +39,6 @@ "kind": "media", "title": "Some Test Media Title", "type": "attachment", "url": "http://localhost:8888/wp-content/uploads/2022/03/test-pdf.pdf", }, - Object { - "id": "books", - "kind": "post-type-archive", - "title": "All Books", - "type": "books-archive", - "url": "http://wordpress.local/books/", - }, ] at toEqual (/home/runner/work/gutenberg/gutenberg/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js:202:26) at processTicksAndRejections (node:internal/process/task_queues:105:5)

Check failure on line 202 in packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js

View workflow job for this annotation

GitHub Actions / JavaScript (Node.js 20) 4/4

Error: expect(received).toEqual(expected) // deep equality - Expected - 7 + Received + 0 @@ -39,13 +39,6 @@ "kind": "media", "title": "Some Test Media Title", "type": "attachment", "url": "http://localhost:8888/wp-content/uploads/2022/03/test-pdf.pdf", }, - Object { - "id": "books", - "kind": "post-type-archive", - "title": "All Books", - "type": "books-archive", - "url": "http://wordpress.local/books/", - }, ] at toEqual (/home/runner/work/gutenberg/gutenberg/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js:202:26) at processTicksAndRejections (node:internal/process/task_queues:95:5)
{
id: 37,
title: 'Contact Page',
Expand Down Expand Up @@ -232,6 +242,13 @@
type: 'attachment',
kind: 'media',
},
{
id: 'books',
title: 'All Books',
url: 'http://wordpress.local/books/',
type: 'books-archive',
kind: 'post-type-archive',
},
] )
);
} );
Expand Down
Loading