Have you noticed the new User Interface (UI) in the Site Editor for entities such as Pages, Templates, or Patterns? This new UI provides a more unified experience for managing and navigating data. With this new interface, users can filter information, customize views, and select specific fields—all in one, consistent environment.
As WordPress transitions into Phase 3: Collaboration, an ongoing effort is underway to enhance the admin experience and incorporate a new visual language across the platform.
But what’s the magic behind this new interface? It’s no magic at all—just the powerful and versatile DataViews component.
The DataViews
component (check the original proposal) provides a powerful API to render datasets using different layouts such as tables, grids, or lists. Additionally, users can customize the data in many ways: filtering, searching, pagination, grouping, sorting, field management, performing actions, and more.
Pretty impressive for just one component, right?
Now that you know WordPress Core is using Data Views to improve and consolidate the admin UI, you might be wondering: Could I also use Data Views in my projects? How about in my plugins? Yes, you can! Even though the component is still being refined, you can start using it in your own plugins.
In this article, you’ll learn how to do just that.
DataViews
is still considered an experimental component, and breaking changes are expected at its current stage. Any breaking changes to this component will be communicated through its Changelog.
Table of Contents
Let’s build a plugin!
Since the DataViews
component is all about managing datasets, let’s use it in a plugin to display some data.
First, let’s take a list of images from a JSON file and display them on several layouts. Next, using only the component’s built-in features, let’s provide the tools so users can decide how to display the list of images and perform actions on them.
But the project won’t stop there. In an article to come, I’ll guide you through adding functionality to let users add these images to the Media Library.
Throughout this whole process, you’ll learn how to:
- Add a custom React app to the admin screens.
- Leverage the DataViews component to display datasets.
- Add actions that enable users to upload selected images to the Media Library.
- Build a user-friendly UI that shows your users what they’re doing, as they do it.
This article will show you how to use DataViews component from a plugin. But the project started in this article will be expanded in a second article that will show you how to integrate the images displayed in the Media Library.
Here’s a video showing what the app you’ll create in this article will look like:
Before you start
To build this plugin, you’ll need a proper Block Development Environment on your machine, including the installation of Node.js and a Local WordPress environment.
You should also have a good grasp of JavaScript and React and be familiar with the @wordpress/scripts
package, especially how to run the start
and build
commands to process JavaScript and create bundled assets.
The final code of the project explained in this article is available at https://github.com/wptrainingteam/devblog-dataviews-plugin.
Throughout the article, you’ll find links to specific commits corresponding to the changes being explained, to help you track the project’s progress.
Loading a React app in an admin screen
Let’s start by building a plugin that loads a minimal React app on a page in the WordPress admin.
The How to use WordPress React components for plugin pages blog post covers how to create a plugin that loads a React app on an admin page, so please refer to that post for additional explanations. The Create your First App with Gutenberg Data guide in the Block Editor Handbook is another great example of a React app in the admin.
To create a basic plugin:
- Go to the
plugins
directory. - Create a new folder named
devblog-dataviews-plugin
. - Inside this folder, create a file named
plugin.php
. - Add the plugin header to the
plugin.php
file.
<?php
/**
* Plugin Name: Dataviews Images Media
* Description: Displays a dataset of images for upload to the Media Library.
* Version: 0.1.0
* Requires at least: 6.6
* Text Domain: dataviews-images-media
*/
defined( 'ABSPATH' ) || exit;
Next, activate the plugin DevBlog Data Views Plugin from the WordPress admin dashboard.
After activation:
- Inside the main plugin folder, create a
src
directory. - Within the
src
folder, create an emptyindex.js
file. - In the main plugin folder, create a
package.json
file with the following content.
{
"name": "devblog-dataviews-plugin",
"version": "0.1.0",
"author": "The WordPress Contributors",
"description": "Plugin with Admin menu option and dataviews",
"license": "GPL-2.0-or-later",
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
},
"devDependencies": {
"@wordpress/scripts": "^28.3.0"
}
}
Open your terminal and run npm install
to install the project’s dependencies.
With the plugin’s groundwork laid out, now add the necessary code to plugin.php
file to create a new Media subpage called Add Media from third-party service.
add_action( 'admin_menu', 'devblog_dataviews_admin_menu' );
/**
* Creates a new Media subpage and set the HTML for it.
*/
function devblog_dataviews_admin_menu() {
add_media_page(
__( 'Add Media from third party service', 'devblog-dataviews-plugin' ),
__( 'Add Media from third party service', 'devblog-dataviews-plugin' ),
'manage_options',
'add-media-from-third-party-service',
function () {
printf(
'<h1>%s</h1><div id="add-media-from-third-party-service"></div>',
esc_html__( 'Add Media from third party service', 'devblog-dataviews-plugin' )
);
}
);
}
Next, add the necessary code to the plugin.php
file to load the build/index.js
on the Add Media from third-party service page (this will attach the React app to this page).
add_action( 'admin_enqueue_scripts', 'devblog_dataviews_admin_enqueue_assets' );
/**
* Enqueues JS and CSS files for our custom Media subsection page.
*
* @param string $hook_suffix The current admin page.
*/
function devblog_dataviews_admin_enqueue_assets( $hook_suffix ) {
// Load only on ?page=add-media-from-third-party-service.
if ( 'media_page_add-media-from-third-party-service' !== $hook_suffix ) {
return;
}
$dir = plugin_dir_path( __FILE__ );
$url = plugin_dir_url( __FILE__ );
$asset_file = $dir . 'build/index.asset.php';
if ( ! file_exists( $asset_file ) ) {
return;
}
$asset = include $asset_file;
wp_enqueue_script(
'devblog-dataviews-script',
$url . 'build/index.js',
$asset['dependencies'],
$asset['version'],
array(
'in_footer' => true,
)
);
}
Last, create the Javascript code to attach a minimal React app to a specific ID on the HTML of the Add Media from third-party service page.
You can do that by adding the following code to src/index.js
:
import domReady from '@wordpress/dom-ready';
import { createRoot } from '@wordpress/element';
const App = () => {
return (
<div>
<p>Our React app</p>
</div>
);
};
domReady( () => {
const root = createRoot(
document.getElementById( 'add-media-from-third-party-service' )
);
root.render( <App /> );
} );
Run npm start
to start the build process with the wp-scripts
package and watch for changes in the code. You should see an index.js
generated in the build/
folder.
At this point, you should have a boilerplate code in your project to display a React app in the WordPress admin and see a new page under Media called Add Media from third party service and the output of a minimal React app in that subsection.
The project is ready to use the DataViews
component in the React app.
Displaying a dataset with Data Views
To use the DataViews
component in the React app, you must install the @wordpress/dataviews
package and import it into your app.
You can install this package and add it as a dependency of the project with the following command from the root of the project:
npm i @wordpress/dataviews --save
Now create an App.js
file under src
folder with a new version of the main App
component:
import { DataViews } from '@wordpress/dataviews' ;
// source "data" definition
// "defaultLayouts" definition
// "fields" definition
const App = () => {
// "view" and "setView" definition
// "processedData" and "paginationInfo" definition
// "actions" definition
return (
<DataViews
data={ processedData }
fields={ fields }
view={ view }
onChangeView={ setView }
defaultLayouts={ defaultLayouts }
actions={ actions }
paginationInfo={ paginationInfo }
/>
);
};
export default App;
This new file defines an App
component and exports it to be used elsewhere.
For now, this App
component just imports the DataViews
component and uses it with some yet-to-be-defined values passed to its props:
data
– A one-dimensional array of objects representing the dataset to work with. This data must be processed and updated to reflect the applied filtering, sorting, and pagination options.fields
– The display settings and capabilities for each record in the dataset.view
– The configuration of how the dataset is displayed to the user.onChangeView
– The callback that will be called every time the view config changes.defaultLayouts
– The view types that are available for the user.actions
– Collection of operations that can be performed upon each record.paginationInfo
– Total number of items in the dataset and total number of pages.
Before you can see something meaningful on the screen, you need to define all these values required by the DataViews
component. But before defining these values, there are a few things you must take care of.
First, import the new App
component from this file instead of the temporary one you created earlier. Do that from src/index.js
:
import domReady from '@wordpress/dom-ready';
import { createRoot } from '@wordpress/element';
import App from './App';
domReady( () => {
const root = createRoot(
document.getElementById( 'add-media-from-third-party-service' )
);
root.render( <App /> );
} );
Now, there’s an important thing that needs to be provided to the DataViews
component: its styles.
The styles
The DataViews
component uses several components of the @wordpress/components
package, so styles from both @wordpress/dataviews
and @wordpress/components
packages must be loaded wherever you use theDataViews
component.
You can use the wp-components
handle to load the styles for all the @wordpress/component
package components. But for the @wordpress/dataviews
styles, at this component’s stage, you must import them directly from the node_modules
folder.
Create a src/style.scss
file in your plugin and add the following code:
@import "@wordpress/dataviews/build-style/style.css";
#add-media-from-third-party-service {
background: white;
.topic_photos {
display: flex;
flex-wrap: wrap;
span {
background-color: rgb(166, 165, 165);
color: white;
padding: 2px 4px;
margin: 2px;
}
}
}
This code imports the @wordpress/dataviews
styles and adds some extra styles for your project.
You need to generate the final CSS file from this CSS file, which will be loaded on the same page the React app lives on and contain the styles of @wordpress/dataviews
.
To generate the final CSS file, import src/style.scss
from the src/index.js
file:
import "./style.scss";
With npm start
running , you’ll see a new style-index.css
file generated under the build
folder.
This generated file is the one you can enqueue in WordPress. Add the following code at the end of the devblog_dataviews_admin_enqueue_assets
function in plugin.php
:
wp_enqueue_style(
'devblog-dataviews-styles',
$url . 'build/style-index.css',
array( 'wp-components' ),
$asset['version'],
);
This code enqueues the generated build/style-index.css
, which contains the DataViews
component styles, in the page where the React app is located. Additionally, it loads the @wordpress/components
styles for that page by adding wp-components
as a dependency.
Now it’s time to define the values needed for the DataViews
component’s props. Let’s start with the data
prop!
The DataViews component is a very powerful and versatile component that requires a lot of input data through its props to work properly. You won’t be able to see the Data Views in action until you define the values for its props in the following section. Have some patience until then. It’ll be worth it.
The DataViews props
The data
The most important piece that the DataViews
component needs is data to display.
For this project, you’ll work with a local JSON file that contains a data list of photos. Each item from the list contains information about a photo, such as a description, an author, several URLs, and related topics.
For the sake of simplicity this project uses a local JSON file to get the dataset to work with, but a great use case for the DataViews component is connecting it to a third-party REST API, allowing for dynamic data integration within WordPress.
This is an example of an item contained in the data list used for this project:
dataPhotos = [
{
id: "nwPxPBWY5JI",
slug: "a-blue-bird-sitting-on--nwPxPBWY5JI",
width: 2818,
color: "#c0c0d9",
height: 4235,
alt_description: "a blue bird sitting on top of a plant",
urls: {
raw: "https://images.unsplash.com/photo-raw-...",
full: "https://images.unsplash.com/photo-full-...",
regular: "https://images.unsplash.com/photo-regular-...",
small: "https://images.unsplash.com/photo-small-...",
thumb: "https://images.unsplash.com/photo-thumb-...",
small_s3: "https://images.unsplash.com/photo-small_s3-...",
},
topics: ["health", "travel"],
user: {
first_name: "Clayton",
last_name: "Chase",
url: "https://chasemade.com",
},
},
{...},
...
]
Copy and paste the content of the file located here into a src/data.js
file and import the content of that file into a dataPhotos
constant in src/App.js
.
import { dataPhotos } from './data';
The data is ready for the project to be displayed with Data Views.
The fields
Next, you must define how the fields will be displayed in the DataViews
component and the specific features you want to enable for each field.
To do that, the fields
prop of the DataViews component expects an array of objects, where each object contains the configuration settings for each field. Some of the properties you can use to define a field’s configuration are:
id
: identifier for the field.label
: the field’s name to be shown in the UI.getValue
: a function that returns the field’s value.render
: a custom React component to render the field.elements
: the set of valid values to filter by this value. Setting this value enables the filters by this value.type
: the type of the field.enableSorting
: whether the data can be sorted by the given field.enableHiding
: whether the field can be hidden.enableGlobalSearch
: whether the field is searchable.filterBy
: configuration for the filters.operators
: the list of operators supported by the field.isPrimary
: whether it is a primary filter.
Check the official documentation on the fields
prop of the DataViews component for full info on each one of these properties
You must first decide which capabilities to provide to the data inside the DataViews component. This means you need to decide which fields can be sorted, filtered, hidden, and searched.
- Sorting: By default, all fields are sortable. To exclude specific fields from sorting, set
enableSorting
tofalse
for those fields. This project enables sorting for theImage
andTopics
fields. - Searching: By default, no fields are searchable. To enable search functionality for specific fields, set
enableGlobalSearch
totrue
. This project enables search on theID
,Author
, andDescription
fields. - Hidable: By default, all fields are hideable. To exclude specific fields from being hidden, set
enableHiding
tofalse
for those fields. This project disables hiding for theImage
field. - Filter by: To enable filtering by a field, you have to pass a value to the
elements
property of the field. The expected value is an array of objects with propertieslabel
andvalue
. With thefilterBy
property, you can fine-tune this filtering behavior by definingoperators
andisPrimary
properties. This project enables filters by theTopics
field.
To enable filters by the topics fields, we have a challenge to solve with the current project’s raw data. The topic values for each photo item come in the following format:
[
{ topics: ["nature", "water"] },
{ topics: ["nature", "mountain"] }
]
But the elements
prop expects something like the following:
[
{ label: "Nature", value: "nature" },
{ label: "Water", value: "water" },
{ label: "Mountain", value: "mountain" }
]
The elements
prop expects an array of unique topics, each described by a label
and a value
property.
The need to adapt your data when setting filters for the DataViews component may come up a lot. So, let’s write a Javascript function that does the following:
- Gets a list of unique topics from a list of arrays with repeated topics.
- Converts the topics to the right format expected by the
elements
property for thefields
prop.
Create a src/utils.js
file and add the following exportable getTopicsElementsFormat
function.
/**
* Retrieves the unique topics from an array of photos.
*/
export const getTopicsElementsFormat = ( photos ) => {
const topics = photos.reduce( ( acc, photo ) => {
return acc.concat( photo.topics );
}, [] );
return [ ...new Set( topics ) ].map( ( topic ) => {
return {
label: topic
.replace( /-/g, ' ' )
.replace( /\b\w/g, ( l ) => l.toUpperCase() ),
value: topic,
};
} );
};
This function leverages the reduce
method of Array, built-in Set objects (to get collections of unique values) and regular expressions for the replace
method of strings to shape the data to the desired format.
Last, you need to define how the final value for each field will be displayed and used by the DataViews
component:
- With the
getValue
property you can specify a function that determines the value for a field. This value will be used for searching, sorting, and displaying the field. For example:- To sort the field by its numeric value, you can convert a string to a number using this function.
- You can create a composite value by combining multiple properties from the original data. This combined value will be the field’s default display value and will also be used by the search functionality.
- With the
render
property, you can define a custom React component that controls how the field’s value is displayed. This is useful if you want to format the value in a specific way or include additional elements (like icons or buttons) in the display.
Now that you understand better the field settings that can be configured through the fields
prop, let’s define the array of field items that will be passed on to the Dataviews
component.
Add the following code to the src/App.js
file:
import { getTopicsElementsFormat } from "./utils";
import { __ } from '@wordpress/i18n';
...
// "fields" definition
const fields = [
{
id: 'img_src',
label: __( 'Image' ),
render: ( { item } ) => (
<img alt={ item.alt_description } src={ item.urls.thumb } />
),
enableSorting: false,
},
{
id: 'id',
label: __( 'ID' ),
enableGlobalSearch: true,
},
{
id: 'author',
label: __( 'Author' ),
getValue: ( { item } ) =>
`${ item.user.first_name } ${ item.user.last_name }`,
render: ( { item } ) => (
<a target="_blank" href={ item.user.url } rel="noreferrer">
{ item.user.first_name } { item.user.last_name }
</a>
),
enableGlobalSearch: true,
},
{
id: 'alt_description',
label: __( 'Description' ),
enableGlobalSearch: true,
},
{
id: 'topics',
label: __( 'Topics' ),
elements: getTopicsElementsFormat( dataPhotos ),
render: ( { item } ) => {
return (
<div className="topic_photos">
{ item.topics.map( ( topic ) => (
<span key={ topic } className="topic_photo_item">
{ topic.toUpperCase() }
</span>
) ) }
</div>
);
},
filterBy: {
operators: [ 'isAny', 'isNone', 'isAll', 'isNotAll' ],
},
enableSorting: false,
},
{
id: 'width',
label: __( 'Width' ),
getValue: ( { item } ) => parseInt( item.width ),
enableSorting: true,
},
{
id: 'height',
label: __( 'Height' ),
getValue: ( { item } ) => parseInt( item.height ),
enableSorting: true,
},
];
It’s a best practice to pass every string intended for display to the end user through an i18n function to ensure proper translation. The code above uses the Javascript i18n method:__
The layouts
The DataViews
component needs to know the layouts what will be available for the user. This is set in the defaultLayouts
prop.
The three current possible layouts to be displayed with DataViews are:
table
.grid
.list
.
If defaultLayouts
is empty, Data Views will enable all layout types with empty layout data.
Add the following code to define the defaultLayouts
const that we’ll pass to the defaultLayouts
prop of the DataViews
component to enable the table and grid views:
// "defaultLayouts" definition
const primaryField = 'id';
const mediaField = 'img_src';
const defaultLayouts = {
table: {
layout: {
primaryField,
},
},
grid: {
layout: {
primaryField,
mediaField,
},
},
};
List view (a.k.a. “side by side” view) is actually meant to be used as a sidebar view for when there’s a detailed view for each item. You can see an example of this view at Pages view of the Site Editor.
The defaultLayouts
prop should be an object that includes properties named table
, grid
, or list
, depending on the layouts you want to enable. Each of these properties should contain a layout
property, which holds the configuration for that specific layout type.
The properties used in this project to configure the layouts are:
primaryField
: The id of the field to be highlighted in each row/card/item. Used by the table, grid and list layouts.mediaField
: The id of the field to be used for rendering each card’s media. Used by the grid and list layouts.
There are other properties available for the grid layout, such as badgeFields
and columnFields
.
The view
The view
object represents the state of the Data Views configuration (how the dataset is rendered, which fields are visible…, etc.). It should be initialized with an object and updated whenever the view setting changes. It is the developer’s responsibility to ensure the view value is consistently updated whenever the user modifies view options through the UI. The onChangeView
callback is called every time the view settings are changed via the UI, making it the ideal place to update the view state.
The view
settings are defined in the form of a serializable object with the following properties:
type
: view type, one oftable
,grid
,list
.search
: the text search applied to the dataset.filters
: the filters applied to the dataset in the form of an array of objects with the following properties:field
: which field this filter is bound to.operator
: which type of filter operator it is.value
: the value selected by the user from the ones passed to the ‘elements’ property for that field’s definition.
perPage
: number of records to show per page.page
: the current page that is visible.sort
: sort settings for a field:field
: the field used for sorting the dataset.direction
: the direction to use for sorting, one of ‘asc’ or ‘desc’.
fields
: the id`s of the fields that are visible in the UI and the specific order in which they are displayed.layout
: config that is specific to a particular layout type. Same properties that are used to defined the defaultLayouts can be used here to update the layout config.
Set the following code inside the React app component in src/App.js
before the return
of the component:
import { useState } from "@wordpress/element";
...
// "view" and "setView" definition
const [ view, setView ] = useState( {
type: 'table',
perPage: 10,
layout: defaultLayouts.table.layout,
fields: [
'img_src',
'id',
'alt_description',
'author',
'topics',
'width',
'height',
],
} );
The view
object needs a default list of fields that will be displayed and the order in which they should appear. If you don’t provide this default value for the fields
property of view
, features like movings columns to the right or left won’t work.
With the useState
React Hook, a view
state variable and a setView
method to update it, are defined. The setView
method can be passed directly as the onChangeView
callback so that every time the UI changes, altering the Dataview settings, the view
object is directly updated, and the React component is refreshed.
But the data also needs to be updated to reflect the filters, orderings and other settings selected by the user. Uff! This sounds like a lot to handle, right?
I have good news for you. The @wordpress/dataviews
package has us covered for this operation with the filterSortAndPaginate
function. This function will apply the filtering, sorting, and pagination to the raw data based on the view configuration, returning the filtered data and the pagination info.
The filterSortAndPaginate
takes three arguments:
- Raw data.
- View config object.
- Fields config.
And returns an object with the following properties:
data
: Filtered data.-
paginationInfo
: Object with the pagination info in the format expected by thepaginationInfo
prop of DataViews.
Let’s import this function from the @wordpress/dataviews
package and add the following code to the App
React component:
import { ..., filterSortAndPaginate } from "@wordpress/dataviews";
import { ..., useMemo } from "@wordpress/element";
...
// "processedData" and "paginationInfo" definition
const { data: processedData, paginationInfo } = useMemo( () => {
return filterSortAndPaginate( dataPhotos, view, fields );
}, [ view ] );
In this code, the useMemo
React hook is used to cache the results of filterSortAndPaginate
and optimize the computing resources. Every result returned by useMemo
is associated with its input values and internally saved, so the second time useMemo
is called with the same input values, the returned values will be delivered from the cached results (optimizing calls to filterSortAndPaginate
).
Every time the view state variable changes, the useMemo
function is called, and it will return the processedData
and paginationInfo
values, either from its internal cache or from the result of calling filterSortAndPaginate
.
With the code above, we’ve established the necessary logic and variables for Data Views to manage the data, taking into account the view settings that the user can modify.
The actions
To finish the part of the project covered in this article, let’s add a simple action that can be launched over each item of the Data Views. The action will open a new window with the original URL of each photo item.
The DataViews
component’s actions
prop accepts a collection of operations that can be performed on each item.
Add the following code to src/App.js
:
// "actions" definition
const actions = [
{
id: 'see-original',
label: __( 'See Original' ),
callback: ( [ item ] ) => {
const urlImage = item.urls.raw;
window.open( urlImage, '_blank' );
},
},
];
];
The action has been defined with the following properties:
id
– Unique identifier of the action.label
– User-facing description of the action to be displayed in the UI.callback
– Callback function that takes the record as input and performs the required action.
Check here the complete list of properties that can be used to define actions for the Data Views items and enable additional behaviors.
At this point, your src/App.js
should look like this:
import { DataViews, filterSortAndPaginate } from '@wordpress/dataviews';
import { getTopicsElementsFormat } from './utils';
import { useState, useMemo } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import './style.scss';
// source "data" definition
import { dataPhotos } from './data';
// "defaultLayouts" definition
const primaryField = 'id';
const mediaField = 'img_src';
const defaultLayouts = {
table: {
layout: {
primaryField,
},
},
grid: {
layout: {
primaryField,
mediaField,
},
},
};
// "fields" definition
const fields = [
{
id: 'img_src',
label: __( 'Image' ),
render: ( { item } ) => (
<img alt={ item.alt_description } src={ item.urls.thumb } />
),
enableSorting: false,
},
{
id: 'id',
label: __( 'ID' ),
enableGlobalSearch: true,
},
{
id: 'author',
label: __( 'Author' ),
getValue: ( { item } ) =>
`${ item.user.first_name } ${ item.user.last_name }`,
render: ( { item } ) => (
<a target="_blank" href={ item.user.url } rel="noreferrer">
{ item.user.first_name } { item.user.last_name }
</a>
),
enableGlobalSearch: true,
},
{
id: 'alt_description',
label: __( 'Description' ),
enableGlobalSearch: true,
},
{
id: 'topics',
label: __( 'Topics' ),
elements: getTopicsElementsFormat( dataPhotos ),
render: ( { item } ) => {
return (
<div className="topic_photos">
{ item.topics.map( ( topic ) => (
<span key={ topic } className="topic_photo_item">
{ topic.toUpperCase() }
</span>
) ) }
</div>
);
},
filterBy: {
operators: [ 'isAny', 'isNone', 'isAll', 'isNotAll' ],
},
enableSorting: false,
},
{
id: 'width',
label: __( 'Width' ),
getValue: ( { item } ) => parseInt( item.width ),
enableSorting: true,
},
{
id: 'height',
label: __( 'Height' ),
getValue: ( { item } ) => parseInt( item.height ),
enableSorting: true,
},
];
const App = () => {
// "view" and "setView" definition
const [ view, setView ] = useState( {
type: 'table',
perPage: 10,
layout: defaultLayouts.table.layout,
fields: [
'img_src',
'id',
'alt_description',
'author',
'topics',
'width',
'height',
],
} );
// "processedData" and "paginationInfo" definition
const { data: processedData, paginationInfo } = useMemo( () => {
return filterSortAndPaginate( dataPhotos, view, fields );
}, [ view ] );
// "actions" definition
const actions = [
{
id: 'see-original',
label: __( 'See Original' ),
callback: ( [ item ] ) => {
const urlImage = item.urls.raw;
window.open( urlImage, '_blank' );
},
},
];
return (
<DataViews
data={ processedData }
fields={ fields }
view={ view }
onChangeView={ setView }
defaultLayouts={ defaultLayouts }
actions={ actions }
paginationInfo={ paginationInfo }
/>
);
};
export default App;
The DataViews
component is now ready to be displayed!
Go to your Admin panel and the Add Media from third party service subpage of the “Media” Settings. You should see something like this:
This layout should reflect all the settings and processes the DataViews
component has been called with:
- A table and grid layout to choose from.
- Filter by Topic.
- Some columns to be sorted by.
- An action to trigger per item.
- Hide and show columns.
- Change the position of columns.
- Data to display and pages are updated according to the settings chosen by the user.
With one component (the DataViews
component), you have built an advanced UI from a plugin to display custom data, including several layout types, search, filters, ordering, pagination, and custom actions over the items.
Wrapping up
The @wordpress/dataviews
package is playing a significant role in the WP Admin redesign. The @wordpress/dataviews
package also has a Dataforms
component that aims to simplify and standardize UI creation for the admin by using a declarative approach (you define what you want, and the system creates it) and sharing the same API as the Dataviews component.
Plans for the future to leverage these components to enhance and unify the Admin UI include Quick editing and the Media Library.
Built with extensibility in mind, the @wordpress/dataviews
package opens up exciting new opportunities for plugins and third-party developers. To learn more about the planned work on Data Views extensibility, be sure to check out this tracking issue.
Stay tuned for the second part of this article, where you’ll learn how to take this project further and add images to the Media Library from the Data Views UI.
Resources
- Data Views documentation at Block Editor Handbook
- Data Views example in the StoryBook (check the code to use the
DataViews
component and the data used for this example) Dataforms
component example in the StoryBook
Props to @greenshady, @ndiego, @welcher, @bph, @marybaum, @oandregal and @eidolonnight for providing feedback and reviewing this post.
Leave a Reply