Skip to content

Commit

Permalink
Merge pull request #219 from alleyinteractive/feature/issue-218/cache…
Browse files Browse the repository at this point in the history
…-initial-query-api-calls

Feature: Issue-218: Cache Initial Post API Calls
  • Loading branch information
efuller authored Aug 21, 2024
2 parents f45ba0f + 32e1e4c commit cfc19e7
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 58 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to `WP Curate` will be documented in this file.

## 2.2.2 - 2024-08-21

- Enhancement: Introduce `SWR` for caching API requests in the Query block.

## 2.2.1 - 2024-08-15

- Bug Fix: Handle cases where a pinned post has been deleted or unpublished.
Expand Down
85 changes: 33 additions & 52 deletions blocks/query/edit.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-disable camelcase */
import useSWRImmutable from 'swr/immutable';
import { PostPicker, TermSelector, Checkboxes } from '@alleyinteractive/block-editor-tools';
import classnames from 'classnames';
import { useDebounce } from '@uidotdev/usehooks';
Expand All @@ -21,7 +22,6 @@ import {
useState,
} from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { addQueryArgs } from '@wordpress/url';

import { Template } from '@wordpress/blocks';
import type {
Expand All @@ -32,11 +32,10 @@ import type {
Types,
} from './types';

import {
mainDedupe,
} from '../../services/deduplicate';

import { mainDedupe } from '../../services/deduplicate';
import buildPostsApiPath from '../../services/buildPostsApiPath';
import buildTermQueryArgs from '../../services/buildTermQueryArgs';
import queryBlockPostFetcher from '../../services/queryBlockPostFetcher';

import './index.scss';

Expand Down Expand Up @@ -134,9 +133,28 @@ export default function Edit({
);

const manualPostIds = manualPosts.map((post) => (post ?? null)).join(',');
const currentPostId = useSelect((select: any) => select('core/editor').getCurrentPostId(), []);
const currentPostId = Number(useSelect((select: any) => select('core/editor').getCurrentPostId(), []));
const postTypeString = postTypes.join(',');

// Construct the API path using query args.
const path = Object.keys(availableTaxonomies).length > 0
? `${buildPostsApiPath({
search: debouncedSearchTerm,
offset,
postType: postTypeString,
status: 'publish',
perPage: 20,
orderBy: orderby,
currentPostId,
})}&${termQueryArgs}`
: undefined;

// Use SWR to fetch data.
const { data, error } = useSWRImmutable(
[path, currentPostId],
queryBlockPostFetcher,
);

// Fetch available taxonomies.
useEffect(() => {
const fetchTaxonomies = async () => {
Expand All @@ -157,58 +175,19 @@ export default function Edit({
fetchTypes();
}, []);

// Fetch "backfill" posts when categories, tags, or search term change.
// Handle the fetched data.
useEffect(() => {
if (Object.keys(availableTaxonomies).length <= 0) {
return;
if (data && !error) {
setAttributes({ backfillPosts: data });
}
const fetchPosts = async () => {
let path = addQueryArgs(
'/wp-curate/v1/posts',
{
search: debouncedSearchTerm,
offset,
post_type: postTypeString,
status: 'publish',
per_page: 20,
orderby,
current_post_id: Number.isInteger(currentPostId) ? currentPostId : 0,
},
);
path += `&${termQueryArgs}`;

apiFetch({ path }).then((response:any) => {
let revisedResponse;
// If the response is an array, filter out the current post.
if (Array.isArray(response)) {
revisedResponse = response.filter((item) => item !== currentPostId);
} else if (response.id === currentPostId) {
// Response is an object, if id is the current post, nullify it.
revisedResponse = null;
} else {
revisedResponse = response;
}
if (revisedResponse !== null) {
setAttributes({ backfillPosts: revisedResponse as Array<number> });
}
});
};
fetchPosts();
}, [
availableTaxonomies,
currentPostId,
debouncedSearchTerm,
offset,
orderby,
postTypeString,
setAttributes,
termQueryArgs,
]);
}, [data, error, setAttributes]);

// Update the query when the backfillPosts change.
// The query is passed via context to the core/post-template block.
useEffect(() => {
mainDedupe();
if (data && !error) {
mainDedupe();
}
}, [
manualPostIds,
backfillPosts,
Expand All @@ -218,6 +197,8 @@ export default function Edit({
isPostDeduplicating,
deduplication,
uniquePinnedPosts,
data,
error,
]);

const setManualPost = (id: number, index: number) => {
Expand Down
5 changes: 2 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,12 @@
"php": "^8.1",
"alleyinteractive/composer-wordpress-autoloader": "^1.0",
"alleyinteractive/traverse-reshape": "^2.0",
"alleyinteractive/wp-type-extensions": "^2.0",
"nunomaduro/collision": "^7.10"
"alleyinteractive/wp-type-extensions": "^2.0"
},
"require-dev": {
"alleyinteractive/alley-coding-standards": "^2.0",
"mantle-framework/testkit": "^1.1",
"nunomaduro/collision": "^6.0",
"nunomaduro/collision": "^7.10",
"szepeviktor/phpstan-wordpress": "^1.1"
},
"config": {
Expand Down
20 changes: 19 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@
"dompurify": "^3.1.6",
"prop-types": "^15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1"
"react-dom": "18.3.1",
"swr": "^2.2.5"
},
"devDependencies": {
"@alleyinteractive/build-tool": "^0.1.4",
Expand Down
23 changes: 23 additions & 0 deletions services/buildPostsApiPath/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { addQueryArgs } from '@wordpress/url';

interface PostsApiPathProps {
search: string,
offset: number,
postType: string,
status: 'publish',
perPage: 20,
orderBy: string,
currentPostId: number
}

export default function buildPostsApiPath(pathProps: PostsApiPathProps) {
return addQueryArgs('/wp-curate/v1/posts', {
search: pathProps.search,
offset: pathProps.offset,
post_type: pathProps.postType,
status: pathProps.status,
per_page: pathProps.perPage,
orderby: pathProps.orderBy,
current_post_id: pathProps.currentPostId,
});
}
28 changes: 28 additions & 0 deletions services/queryBlockPostFetcher/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import apiFetch from '@wordpress/api-fetch';

type FetcherProps = [string | undefined, number];
type PostResponse = number[] | { id: number };

/**
* Fetches the post data from the API.
* @param url The API url.
* @param currentPostId The current post ID.
*/
const queryBlockPostFetcher = (
[url, currentPostId]: FetcherProps,
) => apiFetch<PostResponse>({ path: url })
.then((response) => {
let revisedResponse;
// If the response is an array, filter out the current post.
if (Array.isArray(response)) {
revisedResponse = response.filter((item) => item !== currentPostId);
} else if (response.id === currentPostId) {
// Response is an object, if id is the current post, nullify it.
revisedResponse = null;
} else {
revisedResponse = response;
}
return revisedResponse;
});

export default queryBlockPostFetcher;
2 changes: 1 addition & 1 deletion wp-curate.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: WP Curate
* Plugin URI: https://github.com/alleyinteractive/wp-curate
* Description: Plugin to curate homepages and other landing pages
* Version: 2.2.1
* Version: 2.2.2
* Author: Alley Interactive
* Author URI: https://github.com/alleyinteractive/wp-curate
* Requires at least: 6.4
Expand Down

0 comments on commit cfc19e7

Please sign in to comment.