Package Exports
- kasia
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (kasia) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
kasia
A React Redux toolset for the WordPress API
Made with ❤ at @outlandish
Features
- Declaratively connect React components to data from WordPress.
- Uses
node-wpapiinternally in order to facilitate complex queries. - Register and consume Custom Content Types with ease.
- Support for universal applications.
- Support for plugins, e.g.
wp-api-menus.
Check out the Kasia boilerplate WordPress theme.
Glossary
- Requirements
- Install
- Import
- Connect a Component
- API
- Exports
- The Shape of Things
- Plugins
- Universal Applications
- Author & License
Requirements
Kasia suits applications that are built using these technologies:
- React
- Redux
- Redux Sagas
- WordPress
- WP-API plugin
node-wpapi
Install
npm install kasia --save
Import
// ES6
import kasia from 'kasia'// non-ES6
var kasia = require('kasia')Configure
Initialise Kasia with an instance of
node-wpapi.Spread the Kasia reducer and sagas when creating your redux store.
import { combineReducers, createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'
import Kasia from 'kasia'
import wpapi from 'wpapi'
const WP = new wpapi({ endpoint: 'http://wordpress/' })
const { kasiaReducer, kasiaSagas } = Kasia({ WP })
const rootReducer = combineReducers({
...kasiaReducer
})
const sagaMiddleware = createSagaMiddleware(
...kasiaSagas
)
export default function configureStore (initialState) {
return createStore(
rootReducer,
initialState,
applyMiddleware(sagaMiddleware)
)
}Connect a Component
Things to keep in mind:
- A component will make a request for data 1) when it mounts and 2) if its props change.
- Content data should be parsed before being rendered as it may contain encoded HTML entities.
- In arbitrary queries with
connectWpQuery, we suggest that you always call theembedmethod on the query chain, otherwise embedded content data will be omitted from the response. - Paging data for the request made on behalf of the component is available at
this.props.kasia.query.paging. - The examples given assume the use of decorators. However decorator support is not necessary. See the end of each example for the alternative Higher Order Component approach.
@connectWpPost(contentType, identifier) : Component
Connect a component to a single entity in WordPress, e.g. Post, Page, or custom content type.
- contentType {String} The content type to fetch
- identifier {String|Number|Function} ID of the entity to fetch or function that derives it from
props
Returns a connected component.
Example, using identifier derived from route parameter on props:
import React, { Component } from 'react'
import { Route } from 'react-router'
import { connectWpPost } from 'kasia/connect'
import { Page } from 'kasia/types'
@connectWpPost(Page, (props) => props.params.slug)
export default class Page extends Component {
render () {
const { query, page } = this.props.kasia
if (!query.complete) {
return <span>Loading...</span>
}
return <h1>{page.title}</h1>
}
}
// Without decorator support
export default connectWpPost(Page, (props) => props.params.slug)(Post)@connectWpQuery(queryFn) : Component
Connect a component to the result of an arbitrary WP-API query.
- queryFn {Function} A function that accepts
wpapiand returns a WP-API query
Returns a connected component.
Entities returned from the query will be placed on this.props.kasia.entities under the same
normalised structure as described in The Shape of Things.
Example, fetching the most recent "News" entities:
import React, { Component } from 'react'
import { Route } from 'react-router'
import { connectWpPost } from 'kasia/connect'
// Note the invocation of `embed` in the query chain
@connectWpQuery((wpapi) => {
return wpapi.news().embed().get()
})
export default class RecentNews extends Component {
render () {
const {
query,
entities: { news }
} = this.props.kasia
if (!query.complete) {
return <span>Loading...</span>
}
return (
<div>
<h1>Recent News Headlines</h1>
{Object.keys(news).map((key) =>
<h2>{news[key].title}</h2>)}
</div>
)
}
}
// Without decorator support
export default connectWpQuery((wpapi) => {
return wpapi.news().embed().get()
})(Post)API
Kasia(options) : Object
Configure Kasia.
- options {Object} Options object
Returns an object containing the Kasia reducer and sagas.
const { kasiaReducer, kasiaSagas } = Kasia({
WP: new wpapi({ endpoint: 'http://wordpress/' })
})The options object accepts:
WP{wpapi}An instance of
node-wpapi.keyEntitiesBy{String} (optional) (default'id')Property of entities used to key them in the store
customContentTypes{Array} (optional)Array of custom content type definitions
// Example custom content type definition customContentTypes: [{ name: 'book', plural: 'books', slug: 'books', route, // optional, default="/{plural}/(?P<id>)" namespace, // optional, default="wp/v2" methodName // optional, default={plural} }]
plugins{Array} (optional)Array of Kasia plugins.
import KasiaWpApiMenusPlugin from 'kasia-plugin-wp-api-menus' // Example passing in plugin plugins: [ [KasiaWpApiMenusPlugin, { route: 'menus' }], // with configuration KasiaWpApiMenusPlugin, // without configuration ]
Exports
kasia/connect
The connect Higher Order Components.
import { connectWpPost, connectWpQuery } from 'kasia/connect'kasia/types
The built-in WordPress content types that can be passed to connectWpPost to define what content type
a request should be made for.
import {
Category, Comment, Media, Page,
Post, PostStatus, PostType,
PostRevision, Tag, Taxonomy, User
} from 'kasia/types'The Shape of Things
Kasia restructures the shape of things returned from the WP-API.
The changes made to the data are all effects available in the
wp-api-response-modify library.
Why?
The JSON returned from WP-API contains such things as objects with a single property (e.g. objects with rendered),
meta data property names prefixed with an underscore (e.g. _links), and
What changes should I be aware of?
Queries initiated by
connectWpPostwill always request embedded data.The primary reason for this is to reduce the number of requests made to the WP-API as it is very common to not only want content data, but also any metadata such as authors.
All property names are camel-cased.
"featured_media" => "featuredMedia"
Links are removed.
{ title: 'Wow what an amazing title!', _links: {}, ... } // becomes... { title: 'Wow what an amazing title!', ... }
Objects that have a single property
'rendered'are flattened.{ content: { rendered: '<h1>Hello, World!</h1>' }, ... } // becomes... { content: '<h1>Hello, World!</h1>', ... }
Content types are normalised using
normalizr. This means that any embedded content data is made available on the store within its respective content type collection.
Plugins
Kasia exposes a simple API for third-party plugins.
A plugin should:
be a function that accepts these arguments:
- WP {wpapi} An instance of
wpapi - pluginOptions {Object} The user's options for the plugin
- kasiaOptions {Object} The user's options for Kasia
- WP {wpapi} An instance of
return an object containing
reducers(Object) andsagas(Array).use the
'kasia/'action type prefix.
// Example definition returned by a plugin
{
reducer: {
'kasia/SET_DATA': function setDataReducer () {}
'kasia/REMOVE_DATA': function removeDataReducer () {}
},
sagas: [function * fetchDataSaga () {}]
}See kasia-plugin-wp-api-menus for an example implementation of a Kasia plugin.
Universal Applications
Connected components expose a static method makePreloader that produces an array of saga operations
to facilitate the request for entity data on the server. It is recommended that important
data is declared at the highest level as traversing the component tree to load data from children
is currently unsupported.
ConnectedComponent.makePreloader(renderProps) : Function
Create a preloader function.
- renderProps {Object} Component's render props
Returns a function that returns an array of saga operations in the form:
// Saga operations
[ [sagaGeneratorFn, actionObj] ]Elements:
sagaGenerator{Function} Must be called with theactionObjaction{Object} An action object containing information for the saga to fetch data
Consult the boilerplate for an example implementation of a universal Kasia application.
Contributing
All pull requests and issues welcome!
- When submitting an issue please provide adequate steps to reproduce the problem.
- PRs must be made using the
standardcode style.
If you're not sure how to contribute, check out Kent C. Dodds' great video tutorials on egghead.io!
Author & License
kasia was created by Outlandish and is released under the MIT license.