diff --git a/blocks/api/categories.js b/blocks/api/categories.js index 05361f55ff39bc..493070492d0eac 100644 --- a/blocks/api/categories.js +++ b/blocks/api/categories.js @@ -16,6 +16,7 @@ const categories = [ { slug: 'formatting', title: __( 'Formatting' ) }, { slug: 'embed', title: __( 'Embed' ) }, { slug: 'layout', title: __( 'Layout Blocks' ) }, + { slug: 'rest-api', title: __( 'REST API Blocks' ) }, ]; /** diff --git a/blocks/library/index.js b/blocks/library/index.js index 59f625113cf564..5f1b28bcf894d2 100644 --- a/blocks/library/index.js +++ b/blocks/library/index.js @@ -11,3 +11,4 @@ import './pullquote'; import './table'; import './preformatted'; import './code'; +import './latest-posts'; diff --git a/blocks/library/latest-posts/data.js b/blocks/library/latest-posts/data.js new file mode 100644 index 00000000000000..e48dbd2544d48f --- /dev/null +++ b/blocks/library/latest-posts/data.js @@ -0,0 +1,19 @@ +/** + * Returns a Promise with the latest posts or an error on failure. + * + * @param {Number} postsToShow Number of posts to display. + * + * @returns {wp.api.collections.Posts} Returns a Promise with the latest posts. + */ +export function getLatestPosts( postsToShow = 5 ) { + const postsCollection = new wp.api.collections.Posts(); + + const posts = postsCollection.fetch( { + data: { + per_page: postsToShow, + }, + } ); + + return posts; +} + diff --git a/blocks/library/latest-posts/index.js b/blocks/library/latest-posts/index.js new file mode 100644 index 00000000000000..af82a1bad7988e --- /dev/null +++ b/blocks/library/latest-posts/index.js @@ -0,0 +1,74 @@ +/** + * WordPress dependencies + */ +import { Placeholder } from 'components'; +import { __ } from 'i18n'; + +/** + * Internal dependencies + */ +import { registerBlockType } from '../../api'; +import { getLatestPosts } from './data.js'; + +registerBlockType( 'core/latestposts', { + title: __( 'Latest Posts' ), + + icon: 'list-view', + + category: 'rest-api', + + defaultAttributes: { + poststoshow: 5, + }, + + edit: class extends wp.element.Component { + constructor() { + super( ...arguments ); + + const { poststoshow } = this.props.attributes; + + this.state = { + latestPosts: [], + }; + + this.latestPostsRequest = getLatestPosts( poststoshow ); + + this.latestPostsRequest + .then( latestPosts => this.setState( { latestPosts } ) ); + } + + render() { + const { latestPosts } = this.state; + + if ( ! latestPosts.length ) { + return ( + + + ); + } + + return ( +
+ +
+ ); + } + }, + + componentWillUnmount() { + if ( this.latestPostsRequest.state() === 'pending' ) { + this.latestPostsRequest.abort(); + } + }, + + save() { + return null; + }, +} ); diff --git a/blocks/library/latest-posts/index.php b/blocks/library/latest-posts/index.php new file mode 100644 index 00000000000000..e947a54f8aaa2e --- /dev/null +++ b/blocks/library/latest-posts/index.php @@ -0,0 +1,60 @@ + 0 && + $posts_to_show_attr < 100 + ) { + $posts_to_show = $attributes['poststoshow']; + } + } + + $recent_posts = wp_get_recent_posts( array( + 'numberposts' => $posts_to_show, + 'post_status' => 'publish', + ) ); + + $posts_content = ''; + + foreach ( $recent_posts as $post ) { + $post_id = $post['ID']; + $post_permalink = get_permalink( $post_id ); + $post_title = get_the_title( $post_id ); + + $posts_content .= "
  • {$post_title}
  • \n"; + } + + $block_content = << + + + +CONTENT; + + return $block_content; +} + +register_block_type( 'core/latestposts', array( + 'render' => 'gutenberg_block_core_latest_posts', +) ); diff --git a/blocks/test/fixtures/core-latestposts.html b/blocks/test/fixtures/core-latestposts.html new file mode 100644 index 00000000000000..cc09cb936f430a --- /dev/null +++ b/blocks/test/fixtures/core-latestposts.html @@ -0,0 +1,2 @@ + + diff --git a/blocks/test/fixtures/core-latestposts.json b/blocks/test/fixtures/core-latestposts.json new file mode 100644 index 00000000000000..619edde2c7b2c0 --- /dev/null +++ b/blocks/test/fixtures/core-latestposts.json @@ -0,0 +1,9 @@ +[ + { + "uid": "_uid_0", + "name": "core/latestposts", + "attributes": { + "poststoshow": 5 + } + } +] diff --git a/blocks/test/fixtures/core-latestposts.serialized.html b/blocks/test/fixtures/core-latestposts.serialized.html new file mode 100644 index 00000000000000..cc09cb936f430a --- /dev/null +++ b/blocks/test/fixtures/core-latestposts.serialized.html @@ -0,0 +1,2 @@ + + diff --git a/gutenberg.php b/gutenberg.php index 6dae588b0c734a..98fa84bc9c0519 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -9,6 +9,8 @@ * @package gutenberg */ +define( 'GUTENBERG__PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); + require_once dirname( __FILE__ ) . '/lib/blocks.php'; require_once dirname( __FILE__ ) . '/lib/client-assets.php'; require_once dirname( __FILE__ ) . '/lib/i18n.php'; diff --git a/lib/blocks.php b/lib/blocks.php index 58d23c7eb8a9d1..7864b5f9b31f7b 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -9,6 +9,8 @@ die( 'Silence is golden.' ); } +define( 'GUTENBERG__BLOCKS_LIBRARY_DIR', GUTENBERG__PLUGIN_DIR . 'blocks/library' ); + $wp_registered_blocks = array(); /** @@ -128,3 +130,12 @@ function do_blocks( $content ) { return $new_content; } add_filter( 'the_content', 'do_blocks', 10 ); // BEFORE do_shortcode(). + +/** + * Loads the server-side rendering of blocks. If your block supports + * server-side rendering, add it here. + */ +function gutenberg_load_blocks_server_side_rendering() { + require_once GUTENBERG__BLOCKS_LIBRARY_DIR . '/latest-posts/index.php'; +} +add_action( 'init', 'gutenberg_load_blocks_server_side_rendering' );