Add sorting options to blog page and CMS clients

This update enables sorting of blog page entries based on 'publishedAt' date or custom order. This flexibility has been implemented across the marketing blog page, Keystatic, Wordpress, and Core CMS client services. This functionality allows more control over the presentation of entries.
This commit is contained in:
giancarlo
2024-04-15 16:02:14 +08:00
parent cb690ec317
commit 2927d9980b
4 changed files with 55 additions and 21 deletions

View File

@@ -36,6 +36,8 @@ export namespace Cms {
tags?: string[];
parentIds?: string[];
language?: string | undefined;
sortDirection?: 'asc' | 'desc';
sortBy?: 'publishedAt' | 'order';
}
export interface GetCategoriesOptions {

View File

@@ -22,33 +22,55 @@ export class KeystaticClient implements CmsClient {
const startOffset = options?.offset ?? 0;
const endOffset = startOffset + (options?.limit ?? 10);
const filtered = docs.filter((item) => {
const categoryMatch = options?.categories?.length
? options.categories.find((category) =>
item.entry.categories.includes(category),
)
: true;
const filtered = docs
.filter((item) => {
const categoryMatch = options?.categories?.length
? options.categories.find((category) =>
item.entry.categories.includes(category),
)
: true;
if (!categoryMatch) {
return false;
}
if (options.language) {
if (item.entry.language && item.entry.language !== options.language) {
if (!categoryMatch) {
return false;
}
}
const tagMatch = options?.tags?.length
? options.tags.find((tag) => item.entry.tags.includes(tag))
: true;
if (options.language) {
if (item.entry.language && item.entry.language !== options.language) {
return false;
}
}
if (!tagMatch) {
return false;
}
const tagMatch = options?.tags?.length
? options.tags.find((tag) => item.entry.tags.includes(tag))
: true;
return true;
});
if (!tagMatch) {
return false;
}
return true;
})
.sort((a, b) => {
const direction = options.sortDirection ?? 'asc';
const sortBy = options.sortBy ?? 'publishedAt';
const transform = (value: string | number | undefined | null) => {
if (typeof value === 'string') {
return new Date(value).getTime();
}
return value ?? 0;
};
const left = transform(a.entry[sortBy]);
const right = transform(b.entry[sortBy]);
if (direction === 'asc') {
return left - right;
}
return right - left;
});
const items = await Promise.all(
filtered.slice(startOffset, endOffset).map(async (item) => {

View File

@@ -38,6 +38,14 @@ export class WordpressClient implements CmsClient {
queryParams.append('offset', options.offset.toString());
}
if (options.sortBy) {
queryParams.append('orderby', options.sortBy);
}
if (options.sortDirection) {
queryParams.append('order', options.sortDirection);
}
if (options?.categories) {
const ids = await this.getCategories({
slugs: options.categories,