WP API data provider
Core logic for fetching data from WP API.
Includes
- components - shared components like Providers
- controllers - "smart" components containing business logic
- helpers
- hooks - collection of specific hooks
- services - includes services for backend communication
Usage
Installation
npm install @hmn/wp-dataprovider --save
Importing
import { DataProviderConfig, ListingController, SingleItemController } from '@hmn/wp-dataprovider'
Setting URL of a WP based page
Make sure to wrap root of your app with DataProviderConfig
.
const App = () => {
return (
<DataProviderConfig baseUrl="http://example.com/wp-json">
<div />
</DataProviderConfig>
)
}
Example of fetching data for a post
const SinglePost = () => {
return (
<SingleItemController resource="posts" id="5238">
{({ data, ...rest }) =>
<div item={data} {...rest}>
<h3> {item.title.rendered} </h3>
</div>
}
</SingleItemController>
)
}
Example of fetching data for a listing
const PostsListing = () => {
const [perPage, setPerPage] = useState('10')
return (
<ListingController args={{ perPage }} resource="posts">
{({ data, ...rest }) => (
<div>
{data.map(item => (
<div key={item.id}>
<h3> {item.title.rendered} </h3>
</div>
))}
</div>
)}
</ListingController>
)
}
Example of using with Next.js
const Components = ({ singlePost, ssrPosts }) => {
return (
<div>
<h3> {singlePost.title.rendered} </h3>
<ListingController resource="posts" args={{ order: 'asc' }}>
{({ data, ...rest }) => {
const posts = data.length ? data : ssrPosts
return posts.map(item => (
<div key={item.id}>
<h3> {item.title.rendered} </h3>
</div>
))
}}
</ListingController>
</div>
)
}
Components.getInitialProps = async () => {
const singlePost = await BackendService.fetch('posts', { id: 5215 })
const { items } = await BackendService.fetch('posts', {})
return {
singlePost,
ssrPosts: items || [],
namespacesRequired: ['common']
}
}
const About = ({ data }) => <h1>{item.title.rendered}</h1>
const ControlledComponent = ({ ssrData, ...props }) => {
<SingleItemController resource="posts" id="46">
{({ data = ssrData, ...controllerProps }) => (
<About data={data} {...props} {...controllerProps} />
)}
</SingleItemController>
}
ControlledComponent.getInitialProps = async () => {
const post = await BackendService.fetch('posts', {id: 5215} )
return {
ssrData: post,
namespacesRequired: [common, navigation]
}
}
Pagination support
Two ways of pagination are built in: numbered pagination and infinite scroll / load more type.
Using infinite scroll / load more (default)
<ListingController args={{ perPage }} resource="media">
{({ onLoadMore, ...rest }) => (
<>
<div>
{data.map(item => (
<div key={item.id}>
<h3> {item.title.rendered} </h3>
</div>
))}
</div>
<br />
<button type="button" onClick={onLoadMore}>
Load more
</button>
</>
)}
</ListingController>
Using numeric pagination (add .Pagination)
<ListingController.Pagination
args={{
perPage,
search
}}
resource="posts">
{({ onPrev, onNext, onPage, ...rest }) => (
<>
<div>
{data.map(item => (
<div key={item.id}>
<h3> {item.title.rendered} </h3>
</div>
))}
</div>
<br />
<button type="button" onClick={onPrev}>
Prev
</button>
<button type="button" onClick={() => onPage(2)}>
2
</button>
<button type="button" onClick={() => onPage(3)}>
3
</button>
<button type="button" onClick={onNext}>
Next
</button>
</>
)}
</ListingController.Pagination>
Example of refetching data manually
const PostsListing = () => {
const [perPage, setPerPage] = useState('10')
return (
<ListingController args={{ perPage }} resource="posts">
{({ data, refetch, ...rest }) => (
<div>
<button onClick={refetch}>Refresh</button>
{data.map(item => (
<div key={item.id}>
<h3> {item.title.rendered} </h3>
</div>
))}
</div>
)}
</ListingController>
)
}
Currently supported resources (endpoints):
For Custom Post Types set customs like this:
const customs = {
speakers: 'posts',
awards: 'posts',
news: 'posts'
}
BackendService.customTypes = customs
Each package is available from main export. Check index.js for structure.
Develop
For further development of package follow setup:
Clone package.
npm install
npm run watch
Auto builds on each change to /lib
folder.
Publishing
Increment version.
npm version <version>
npm run build
npm pack
npm publish