diff --git a/includes/class-newspack-blocks-api.php b/includes/class-newspack-blocks-api.php index 7bd2add71..4093c4c9c 100644 --- a/includes/class-newspack-blocks-api.php +++ b/includes/class-newspack-blocks-api.php @@ -9,130 +9,6 @@ * `Newspack_Blocks_API` is a wrapper for `register_rest_fields()` */ class Newspack_Blocks_API { - - /** - * Register Newspack REST fields. - */ - public static function register_rest_fields() { - register_rest_field( - [ 'post', 'page' ], - 'newspack_featured_image_src', - [ - 'get_callback' => [ 'Newspack_Blocks_API', 'newspack_blocks_get_image_src' ], - 'schema' => [ - 'context' => [ - 'edit', - ], - 'type' => 'array', - ], - ] - ); - - register_rest_field( - [ 'post', 'page' ], - 'newspack_featured_image_caption', - [ - 'get_callback' => [ 'Newspack_Blocks_API', 'newspack_blocks_get_image_caption' ], - 'schema' => [ - 'context' => [ - 'edit', - ], - 'type' => 'string', - ], - ] - ); - - /* Add author info source */ - register_rest_field( - 'post', - 'newspack_author_info', - [ - 'get_callback' => [ 'Newspack_Blocks_API', 'newspack_blocks_get_author_info' ], - 'schema' => [ - 'context' => [ - 'edit', - ], - 'type' => 'array', - ], - ] - ); - - /* Add first category source */ - register_rest_field( - 'post', - 'newspack_category_info', - [ - 'get_callback' => [ 'Newspack_Blocks_API', 'newspack_blocks_get_primary_category' ], - 'schema' => [ - 'context' => [ - 'edit', - ], - 'type' => 'string', - ], - ] - ); - - /* Add list of categories for CSS classes */ - register_rest_field( - 'post', - 'newspack_article_classes', - [ - 'get_callback' => [ 'Newspack_Blocks_API', 'newspack_blocks_get_cat_tag_classes' ], - 'schema' => [ - 'context' => [ - 'edit', - ], - 'type' => 'string', - ], - ] - ); - - /* Sponsors */ - register_rest_field( - 'post', - 'newspack_post_sponsors', - [ - 'get_callback' => [ 'Newspack_Blocks_API', 'newspack_blocks_sponsor_info' ], - 'schema' => [ - 'context' => [ - 'edit', - ], - 'type' => 'array', - ], - ] - ); - - /* Post format */ - register_rest_field( - 'post', - 'newspack_post_format', - [ - 'get_callback' => [ 'Newspack_Blocks_API', 'newspack_blocks_post_format' ], - 'schema' => [ - 'context' => [ - 'edit', - ], - 'type' => 'string', - ], - ] - ); - - /* Has custom excerpt */ - register_rest_field( - 'post', - 'newspack_has_custom_excerpt', - [ - 'get_callback' => [ 'Newspack_Blocks_API', 'newspack_blocks_has_custom_excerpt' ], - 'schema' => [ - 'context' => [ - 'edit', - ], - 'type' => 'boolean', - ], - ] - ); - } - /** * Get thumbnail featured image source for the rest field. * @@ -438,11 +314,13 @@ public static function posts_endpoint( $request ) { $args['post_type'] = $params['post_type']; } - $block_attributes = [ - 'showExcerpt' => $params['show_excerpt'], - 'excerptLength' => $params['excerpt_length'], - ]; - Newspack_Blocks::filter_excerpt_length( $block_attributes ); + if ( isset( $params['show_excerpt'], $params['excerpt_length'] ) ) { + $block_attributes = [ + 'showExcerpt' => $params['show_excerpt'], + 'excerptLength' => $params['excerpt_length'], + ]; + Newspack_Blocks::filter_excerpt_length( $block_attributes ); + } $query = new WP_Query(); $query_result = $query->query( $args ); @@ -550,39 +428,6 @@ public static function add_post_title_wildcard_search( $where, $query ) { $where .= ' AND post_title LIKE "%' . $search . '%" '; return $where; } - - /** - * Adds meta query support to API rest endpoint. - * - * @param array $args Key value array of query var to query value. - * @param WP_REST_Request $request The request used. - * @return array $args Filtered request parameters. - */ - public static function post_meta_request_params( $args, $request ) { - $params = $request->get_params(); - - if ( - isset( $params['meta_key'], $params['meta_value_num'], $params['meta_compare'] ) && - '_thumbnail_id' === $params['meta_key'] && - '0' === $params['meta_value_num'] && - '>' === $params['meta_compare'] - ) { - // phpcs:disable WordPress.DB.SlowDBQuery - $args['meta_key'] = $params['meta_key']; - $args['meta_value_num'] = $params['meta_value_num']; - $args['meta_compare'] = $params['meta_compare']; - // phpcs:enable WordPress.DB.SlowDBQuery - } - - if ( $request->get_param( 'suppress_password_protected_posts' ) ) { - $args['has_password'] = false; - } - - return $args; - } - } -add_action( 'rest_api_init', array( 'Newspack_Blocks_API', 'register_rest_fields' ) ); add_action( 'rest_api_init', array( 'Newspack_Blocks_API', 'register_video_playlist_endpoint' ) ); -add_filter( 'rest_post_query', array( 'Newspack_Blocks_API', 'post_meta_request_params' ), 10, 2 ); diff --git a/includes/class-newspack-blocks.php b/includes/class-newspack-blocks.php index 6a8c93cfe..a95883558 100644 --- a/includes/class-newspack-blocks.php +++ b/includes/class-newspack-blocks.php @@ -66,6 +66,8 @@ public static function enqueue_block_editor_assets() { 'patterns' => self::get_patterns_for_post_type( get_post_type() ), 'posts_rest_url' => rest_url( 'newspack-blocks/v1/newspack-blocks-posts' ), 'specific_posts_rest_url' => rest_url( 'newspack-blocks/v1/newspack-blocks-specific-posts' ), + 'assets_path' => plugins_url( '/src/assets', NEWSPACK_BLOCKS__PLUGIN_FILE ), + 'post_subtitle' => get_theme_support( 'post-subtitle' ), ] ); @@ -317,20 +319,20 @@ public static function add_image_sizes() { * Builds and returns query args based on block attributes. * * @param array $attributes An array of block attributes. + * @param array $block_name Name of the block requesting the query. * * @return array */ - public static function build_articles_query( $attributes ) { + public static function build_articles_query( $attributes, $block_name ) { global $newspack_blocks_post_id; if ( ! $newspack_blocks_post_id ) { $newspack_blocks_post_id = array(); } - // Get all blocks and gather specificPosts ids of all Homepage Articles blocks. + // Get all blocks and gather specificPosts ids of all eligible blocks. global $newspack_blocks_all_specific_posts_ids; if ( ! is_array( $newspack_blocks_all_specific_posts_ids ) ) { $blocks = parse_blocks( get_the_content() ); - $block_name = apply_filters( 'newspack_blocks_block_name', 'newspack-blocks/homepage-articles' ); $newspack_blocks_all_specific_posts_ids = array_reduce( $blocks, function ( $acc, $block ) use ( $block_name ) { @@ -357,7 +359,7 @@ function ( $acc, $block ) use ( $block_name ) { $tag_exclusions = isset( $attributes['tagExclusions'] ) ? $attributes['tagExclusions'] : array(); $specific_posts = isset( $attributes['specificPosts'] ) ? $attributes['specificPosts'] : array(); $posts_to_show = intval( $attributes['postsToShow'] ); - $specific_mode = intval( $attributes['specificMode'] ); + $specific_mode = isset( $attributes['specificMode'] ) ? intval( $attributes['specificMode'] ) : false; $args = array( 'post_type' => $post_type, 'post_status' => 'publish', @@ -674,7 +676,7 @@ public static function remove_wc_memberships_excerpt_limit() { */ public static function filter_excerpt_length( $attributes ) { // If showing excerpt, filter the length using the block attribute. - if ( $attributes['showExcerpt'] ) { + if ( isset( $attributes['excerptLength'] ) && $attributes['showExcerpt'] ) { self::$newspack_blocks_excerpt_length_closure = add_filter( 'excerpt_length', function() use ( $attributes ) { diff --git a/newspack-blocks.php b/newspack-blocks.php index b8546330a..86365f9a8 100755 --- a/newspack-blocks.php +++ b/newspack-blocks.php @@ -46,20 +46,3 @@ function newspack_blocks_plugin_textdomain() { load_plugin_textdomain( 'newspack-blocks', false, dirname( plugin_basename( NEWSPACK_BLOCKS__PLUGIN_FILE ) ) . '/languages' ); } add_action( 'plugins_loaded', 'newspack_blocks_plugin_textdomain' ); - - -/** - * Add global variable for theme supports detection. - * - * @action enqueue_block_editor_assets - */ -function newspack_blocks_post_subtitle_detection() { - wp_localize_script( - 'newspack-blocks-editor', - 'newspackIsPostSubtitleSupported', - array( - 'post_subtitle' => get_theme_support( 'post-subtitle' ), - ) - ); -} -add_action( 'enqueue_block_editor_assets', 'newspack_blocks_post_subtitle_detection' ); diff --git a/src/assets/newspack-1024x536.jpg b/src/assets/newspack-1024x536.jpg new file mode 100644 index 000000000..1c3f929a4 Binary files /dev/null and b/src/assets/newspack-1024x536.jpg differ diff --git a/src/assets/newspack-600x800.jpg b/src/assets/newspack-600x800.jpg new file mode 100644 index 000000000..81006d2fd Binary files /dev/null and b/src/assets/newspack-600x800.jpg differ diff --git a/src/assets/newspack-800x600.jpeg b/src/assets/newspack-800x600.jpeg new file mode 100644 index 000000000..ec0959f71 Binary files /dev/null and b/src/assets/newspack-800x600.jpeg differ diff --git a/src/assets/newspack-800x600.jpg b/src/assets/newspack-800x600.jpg new file mode 100644 index 000000000..ec0959f71 Binary files /dev/null and b/src/assets/newspack-800x600.jpg differ diff --git a/src/assets/newspack-800x800.jpg b/src/assets/newspack-800x800.jpg new file mode 100644 index 000000000..06d2379d7 Binary files /dev/null and b/src/assets/newspack-800x800.jpg differ diff --git a/src/blocks/carousel/edit.js b/src/blocks/carousel/edit.js index 45602fd10..170b7ad3b 100644 --- a/src/blocks/carousel/edit.js +++ b/src/blocks/carousel/edit.js @@ -3,7 +3,7 @@ /** * External dependencies */ -import { isEqual, isUndefined, pickBy } from 'lodash'; +import { isEqual } from 'lodash'; import classnames from 'classnames'; /** @@ -21,7 +21,7 @@ import { Spinner, ToggleControl, } from '@wordpress/components'; -import { withSelect } from '@wordpress/data'; +import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { decodeEntities } from '@wordpress/html-entities'; @@ -36,6 +36,8 @@ import { formatSponsorLogos, formatSponsorByline, } from '../../shared/js/utils'; +// Use same posts store as Homepage Posts block. +import { postsBlockSelector, postsBlockDispatch, shouldReflow } from '../homepage-articles/utils'; class Edit extends Component { constructor( props ) { @@ -51,9 +53,14 @@ class Edit extends Component { componentDidMount() { this.initializeSwiper( 0 ); + this.props.triggerReflow(); } componentDidUpdate( prevProps ) { + if ( shouldReflow( prevProps, this.props ) ) { + this.props.triggerReflow(); + } + const { attributes, latestPosts } = this.props; if ( @@ -76,6 +83,10 @@ class Edit extends Component { } } + componentWillUnmount() { + this.props.triggerReflow(); + } + initializeSwiper( initialSlide ) { const { latestPosts } = this.props; @@ -102,7 +113,7 @@ class Edit extends Component { } render() { - const { attributes, className, setAttributes, latestPosts } = this.props; + const { attributes, className, setAttributes, latestPosts, isUIDisabled } = this.props; const { authors, autoplay, @@ -119,7 +130,10 @@ class Edit extends Component { className, 'wp-block-newspack-blocks-carousel', // Default to make styles work for third-party consumers. 'swiper-container', - autoplay && 'wp-block-newspack-blocks-carousel__autoplay-playing' + { + 'wp-block-newspack-blocks-carousel__autoplay-playing': autoplay, + 'newspack-block--disabled': isUIDisabled, + } ); const dateFormat = __experimentalGetSettings().formats.date; return ( @@ -290,24 +304,6 @@ class Edit extends Component { } } -export default compose( [ - withSelect( ( select, props ) => { - const { postsToShow, authors, categories, tags } = props.attributes; - const { getEntityRecords } = select( 'core' ); - const latestPostsQuery = pickBy( - { - per_page: postsToShow, - categories, - author: authors, - tags, - meta_key: '_thumbnail_id', - meta_value_num: 0, - meta_compare: '>', - }, - value => ! isUndefined( value ) - ); - return { - latestPosts: getEntityRecords( 'postType', 'post', latestPostsQuery ), - }; - } ), -] )( Edit ); +export default compose( [ withSelect( postsBlockSelector ), withDispatch( postsBlockDispatch ) ] )( + Edit +); diff --git a/src/blocks/carousel/view.php b/src/blocks/carousel/view.php index 5d32cdf34..78289d4f8 100644 --- a/src/blocks/carousel/view.php +++ b/src/blocks/carousel/view.php @@ -14,18 +14,16 @@ */ function newspack_blocks_render_block_carousel( $attributes ) { static $newspack_blocks_carousel_id = 0; + global $newspack_blocks_post_id; // This will let the FSE plugin know we need CSS/JS now. do_action( 'newspack_blocks_render_post_carousel' ); $newspack_blocks_carousel_id++; - $autoplay = isset( $attributes['autoplay'] ) ? $attributes['autoplay'] : false; - $delay = isset( $attributes['delay'] ) ? absint( $attributes['delay'] ) : 3; - $posts_to_show = intval( $attributes['postsToShow'] ); - $authors = isset( $attributes['authors'] ) ? $attributes['authors'] : array(); - $categories = isset( $attributes['categories'] ) ? $attributes['categories'] : array(); - $tags = isset( $attributes['tags'] ) ? $attributes['tags'] : array(); - $is_amp = function_exists( 'is_amp_endpoint' ) && is_amp_endpoint(); + $autoplay = isset( $attributes['autoplay'] ) ? $attributes['autoplay'] : false; + $delay = isset( $attributes['delay'] ) ? absint( $attributes['delay'] ) : 3; + $authors = isset( $attributes['authors'] ) ? $attributes['authors'] : array(); + $is_amp = function_exists( 'is_amp_endpoint' ) && is_amp_endpoint(); $other = array(); if ( $autoplay ) { @@ -33,27 +31,7 @@ function newspack_blocks_render_block_carousel( $attributes ) { } $classes = Newspack_Blocks::block_classes( 'carousel', $attributes, $other ); - $args = array( - 'posts_per_page' => $posts_to_show, - 'post_status' => 'publish', - 'suppress_filters' => false, - 'ignore_sticky_posts' => true, - 'meta_key' => '_thumbnail_id', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key - 'meta_value_num' => 0, - 'meta_compare' => '>', - ); - - if ( $authors ) { - $args['author__in'] = $authors; - } - if ( $categories ) { - $args['category__in'] = $categories; - } - if ( $tags ) { - $args['tag__in'] = $tags; - } - - $article_query = new WP_Query( $args ); + $article_query = new WP_Query( Newspack_Blocks::build_articles_query( $attributes, apply_filters( 'newspack_blocks_block_name', 'newspack-blocks/carousel' ) ) ); $counter = 0; $article_classes = [ 'post-has-image', @@ -69,6 +47,7 @@ function newspack_blocks_render_block_carousel( $attributes ) { if ( ! has_post_thumbnail() ) { continue; } + $newspack_blocks_post_id[ get_the_ID() ] = true; // Get sponsors for this post. $sponsors = Newspack_Blocks::get_all_sponsors( get_the_id() ); @@ -76,7 +55,7 @@ function newspack_blocks_render_block_carousel( $attributes ) { $counter++; ?> -
+
get_attribute_schema(), 'default' ) ); - $article_query_args = Newspack_Blocks::build_articles_query( $attributes ); + $article_query_args = Newspack_Blocks::build_articles_query( $attributes, apply_filters( 'newspack_blocks_block_name', 'newspack-blocks/homepage-articles' ) ); // If using exclude_ids, don't worry about pagination. Just get the next postsToShow number of results without the excluded posts. Otherwise, use standard WP pagination. $query = ! empty( $exclude_ids ) ? diff --git a/src/blocks/homepage-articles/edit.js b/src/blocks/homepage-articles/edit.js index ae97b5dfd..8ea1cecf4 100644 --- a/src/blocks/homepage-articles/edit.js +++ b/src/blocks/homepage-articles/edit.js @@ -4,8 +4,7 @@ * Internal dependencies */ import QueryControls from '../../components/query-controls'; -import { STORE_NAMESPACE } from './store'; -import { getEditorBlocksIds, isBlogPrivate, shouldReflow, getCoreStorePosts } from './utils'; +import { postsBlockSelector, postsBlockDispatch, isBlogPrivate, shouldReflow } from './utils'; import { formatAvatars, formatByline, @@ -54,8 +53,8 @@ import { decodeEntities } from '@wordpress/html-entities'; let IS_SUBTITLE_SUPPORTED_IN_THEME; if ( typeof window === 'object' && - window.newspackIsPostSubtitleSupported && - window.newspackIsPostSubtitleSupported.post_subtitle + window.newspack_blocks_data && + window.newspack_blocks_data.post_subtitle ) { IS_SUBTITLE_SUPPORTED_IN_THEME = true; } @@ -132,7 +131,7 @@ class Edit extends Component { const postClasses = classNames( { 'post-has-image': post.newspack_featured_image_src, - 'homepage-posts-block__post--disabled': isUIDisabled, + 'newspack-block--disabled': isUIDisabled, }, post.newspack_article_classes ); @@ -708,7 +707,7 @@ class Edit extends Component { } className="component-placeholder__align-center" /> ) } { ! latestPosts && error && ( - + { error } ) } @@ -749,38 +748,6 @@ class Edit extends Component { export default compose( [ withColors( { textColor: 'color' } ), - withSelect( ( select, { clientId, attributes } ) => { - const { getPostTypes } = select( 'core' ); - const { getEditorBlocks, getBlocks } = select( 'core/editor' ); - const editorBlocksIds = getEditorBlocksIds( getEditorBlocks() ); - // The block might be rendered in the block styles preview, not in the editor. - const isEditorBlock = editorBlocksIds.indexOf( clientId ) >= 0; - - const { getPosts, getError, isUIDisabled } = select( STORE_NAMESPACE ); - const props = { - isEditorBlock, - isUIDisabled: isUIDisabled(), - error: getError( { clientId } ), - topBlocksClientIdsInOrder: getBlocks().map( block => block.clientId ), - availablePostTypes: getPostTypes( { per_page: -1 } )?.filter( - ( { supports: { newspack_blocks: newspackBlocks } } ) => newspackBlocks - ), - }; - - if ( isEditorBlock ) { - props.latestPosts = getPosts( { clientId } ); - } else { - // For block preview, display without deduplication. If there would be a way to match the outside-editor's - // block clientId to the clientId of the block that's being previewed, the correct posts could be shown here. - props.latestPosts = getCoreStorePosts( attributes ); - } - - return props; - } ), - withDispatch( ( dispatch, { isEditorBlock } ) => { - return { - // Only editor blocks can trigger reflows. - triggerReflow: isEditorBlock ? dispatch( STORE_NAMESPACE ).reflow : () => {}, - }; - } ), + withSelect( postsBlockSelector ), + withDispatch( postsBlockDispatch ), ] )( Edit ); diff --git a/src/blocks/homepage-articles/editor.js b/src/blocks/homepage-articles/editor.js index aba9f7519..a0bcc6ba3 100644 --- a/src/blocks/homepage-articles/editor.js +++ b/src/blocks/homepage-articles/editor.js @@ -3,9 +3,11 @@ */ import { registerBlockType } from '@wordpress/blocks'; import { settings, name } from '.'; +import { name as carouselBlockName } from '../carousel'; + import { registerQueryStore } from './store'; const BLOCK_NAME = `newspack-blocks/${ name }`; registerBlockType( BLOCK_NAME, settings ); -registerQueryStore( BLOCK_NAME ); +registerQueryStore( [ BLOCK_NAME, `newspack-blocks/${ carouselBlockName }` ] ); diff --git a/src/blocks/homepage-articles/editor.scss b/src/blocks/homepage-articles/editor.scss index cdcad9c9b..4827516f1 100644 --- a/src/blocks/homepage-articles/editor.scss +++ b/src/blocks/homepage-articles/editor.scss @@ -50,24 +50,22 @@ background-color: transparent; } -.homepage-posts-block { +.newspack-block { &--error.components-placeholder { color: $color__error; } - &__post { - &--disabled { - position: relative; - &::after { - content: ''; - position: absolute; - z-index: 2; - width: 100%; - height: 100%; - top: 0; - left: 0; - background-color: #fff; - opacity: 0.6; - } + &--disabled { + position: relative; + &::after { + content: ''; + position: absolute; + z-index: 2; + width: 100%; + height: 100%; + top: 0; + left: 0; + background-color: #fff; + opacity: 0.6; } } } diff --git a/src/blocks/homepage-articles/store.js b/src/blocks/homepage-articles/store.js index b8a1e6c16..f9a503443 100644 --- a/src/blocks/homepage-articles/store.js +++ b/src/blocks/homepage-articles/store.js @@ -109,7 +109,7 @@ function* getPostsForBlock( block ) { return postsIds; } -const createFetchPostsSaga = blockName => { +const createFetchPostsSaga = blockNames => { /** * "worker" Saga: will be fired on REFLOW actions */ @@ -122,7 +122,7 @@ const createFetchPostsSaga = blockName => { yield put( { type: 'DISABLE_UI' } ); - const blockQueries = getBlockQueries( getBlocks(), blockName ); + const blockQueries = getBlockQueries( getBlocks(), blockNames ); // Use requested specific posts ids as the starting state of exclusion list. const specificPostsId = blockQueries.reduce( ( acc, { postsQuery } ) => { @@ -160,9 +160,9 @@ const createFetchPostsSaga = blockName => { }; }; -export const registerQueryStore = blockName => { +export const registerQueryStore = blockNames => { registerGenericStore( STORE_NAMESPACE, genericStore ); // Run the saga ✨ - sagaMiddleware.run( createFetchPostsSaga( blockName ) ); + sagaMiddleware.run( createFetchPostsSaga( blockNames ) ); }; diff --git a/src/blocks/homepage-articles/templates/articles-loop.php b/src/blocks/homepage-articles/templates/articles-loop.php index a5c0d2c0d..ab4e7e5e5 100644 --- a/src/blocks/homepage-articles/templates/articles-loop.php +++ b/src/blocks/homepage-articles/templates/articles-loop.php @@ -14,7 +14,6 @@ function( $data ) { $article_query = $data['article_query']; global $newspack_blocks_post_id; - $post_counter = 0; do_action( 'newspack_blocks_homepage_posts_before_render' ); Newspack_Blocks::filter_excerpt_length( $attributes ); @@ -23,7 +22,6 @@ function( $data ) { while ( $article_query->have_posts() ) { $article_query->the_post(); $newspack_blocks_post_id[ get_the_ID() ] = true; - $post_counter++; echo Newspack_Blocks::template_inc( __DIR__ . '/article.php', array( 'attributes' => $attributes ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } diff --git a/src/blocks/homepage-articles/utils.js b/src/blocks/homepage-articles/utils.js index 22f022775..e490d68a9 100644 --- a/src/blocks/homepage-articles/utils.js +++ b/src/blocks/homepage-articles/utils.js @@ -1,12 +1,14 @@ /** * External dependencies */ -import { debounce, isEqual, isUndefined, pick, pickBy } from 'lodash'; +import { uniqueId, times, isEqual, isUndefined, pick, pickBy } from 'lodash'; /** - * External dependencies + * WordPress dependencies */ -import { select as globalSelect } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; + +import { STORE_NAMESPACE } from './store'; /** * Based global WP.com blog_public option, checks whether current blog is @@ -66,7 +68,7 @@ export const queryCriteriaFromAttributes = attributes => { postType, showExcerpt, tags, - specificPosts, + specificPosts = [], specificMode, tagExclusions, } = pick( attributes, POST_QUERY_ATTRIBUTES ); @@ -90,7 +92,6 @@ export const queryCriteriaFromAttributes = attributes => { }, value => ! isUndefined( value ) ); - criteria.suppress_password_protected_posts = true; criteria.excerpt_length = excerptLength; criteria.show_excerpt = showExcerpt; return criteria; @@ -99,14 +100,14 @@ export const queryCriteriaFromAttributes = attributes => { export const sanitizePostList = postList => postList.map( id => parseInt( id ) ).filter( id => id > 0 ); -export const getBlockQueries = ( blocks, blockName ) => +export const getBlockQueries = ( blocks, blockNames ) => blocks.flatMap( block => { const homepageArticleBlocks = []; - if ( block.name === blockName ) { + if ( blockNames.indexOf( block.name ) >= 0 ) { const postsQuery = queryCriteriaFromAttributes( block.attributes ); homepageArticleBlocks.push( { postsQuery, clientId: block.clientId } ); } - return homepageArticleBlocks.concat( getBlockQueries( block.innerBlocks, blockName ) ); + return homepageArticleBlocks.concat( getBlockQueries( block.innerBlocks, blockNames ) ); } ); export const getEditorBlocksIds = blocks => @@ -116,12 +117,80 @@ export const getEditorBlocksIds = blocks => return homepageArticleBlocks.concat( getEditorBlocksIds( block.innerBlocks ) ); } ); -export const getCoreStorePosts = debounce( - attributes => - globalSelect( 'core' ).getEntityRecords( - 'postType', - 'post', - queryCriteriaFromAttributes( attributes ) +const PREVIEW_IMAGE_BASE = window.newspack_blocks_data.assets_path; +const generatePreviewPost = () => ( { + author: 1, + content: { + rendered: __( 'The post content.', 'newspack' ), + }, + date_gmt: new Date().toISOString(), + excerpt: { + rendered: __( 'The post excerpt.', 'newspack' ), + }, + featured_media: uniqueId(), + id: uniqueId(), + meta: { + newspack_post_subtitle: __( 'Post Subtitle', 'newspack' ), + }, + title: { + rendered: __( 'Post Title', 'newspack' ), + }, + newspack_article_classes: 'type-post', + newspack_author_info: [ + { + display_name: __( 'Author Name', 'newspack' ), + avatar: `
`, + id: 1, + author_link: '/', + }, + ], + newspack_category_info: __( 'Category', 'newspack' ), + newspack_featured_image_caption: __( 'Featured image caption', 'newspack' ), + newspack_featured_image_src: { + large: `${ PREVIEW_IMAGE_BASE }/newspack-1024x683.jpg`, + landscape: `${ PREVIEW_IMAGE_BASE }/newspack-800x600.jpg`, + portrait: `${ PREVIEW_IMAGE_BASE }/newspack-600x800.jpg`, + square: `${ PREVIEW_IMAGE_BASE }/newspack-800x800.jpg`, + uncropped: `${ PREVIEW_IMAGE_BASE }/newspack-1024x683.jpg`, + }, + newspack_has_custom_excerpt: false, + newspack_post_format: 'standard', + newspack_post_sponsors: false, +} ); + +const getPreviewPosts = attributes => times( attributes.postsToShow, generatePreviewPost ); + +export const postsBlockSelector = ( select, { clientId, attributes } ) => { + const { getPostTypes } = select( 'core' ); + const { getEditorBlocks, getBlocks } = select( 'core/editor' ); + const editorBlocksIds = getEditorBlocksIds( getEditorBlocks() ); + // The block might be rendered in the block styles preview, not in the editor. + const isEditorBlock = editorBlocksIds.indexOf( clientId ) >= 0; + + const { getPosts, getError, isUIDisabled } = select( STORE_NAMESPACE ); + const props = { + isEditorBlock, + isUIDisabled: isUIDisabled(), + error: getError( { clientId } ), + topBlocksClientIdsInOrder: getBlocks().map( block => block.clientId ), + availablePostTypes: getPostTypes( { per_page: -1 } )?.filter( + ( { supports: { newspack_blocks: newspackBlocks } } ) => newspackBlocks ), - 500 -); + }; + + if ( isEditorBlock ) { + props.latestPosts = getPosts( { clientId } ); + } else { + // For block preview, display static content. + props.latestPosts = getPreviewPosts( attributes ); + } + + return props; +}; + +export const postsBlockDispatch = ( dispatch, { isEditorBlock } ) => { + return { + // Only editor blocks can trigger reflows. + triggerReflow: isEditorBlock ? dispatch( STORE_NAMESPACE ).reflow : () => {}, + }; +}; diff --git a/src/blocks/homepage-articles/view.js b/src/blocks/homepage-articles/view.js index ca89189df..e85e681b6 100644 --- a/src/blocks/homepage-articles/view.js +++ b/src/blocks/homepage-articles/view.js @@ -103,15 +103,11 @@ function buildLoadMoreHandler( blockWrapperEl ) { * Returns unique IDs for posts that are currently in the DOM. */ function getRenderedPostsIds() { - const postEls = document.querySelectorAll( - '.wp-block-newspack-blocks-homepage-articles [data-post-id]' - ); + const postEls = document.querySelectorAll( "[class^='wp-block-newspack-blocks'] [data-post-id]" ); const postIds = Array.from( postEls ).map( el => el.getAttribute( 'data-post-id' ) ); postIds.push( - document - .querySelector( '.wp-block-newspack-blocks-homepage-articles > div[data-current-post-id]' ) - .getAttribute( 'data-current-post-id' ) + document.querySelector( 'div[data-current-post-id]' ).getAttribute( 'data-current-post-id' ) ); return [ ...new Set( postIds ) ]; // Make values unique with Set diff --git a/src/blocks/homepage-articles/view.php b/src/blocks/homepage-articles/view.php index 621198801..f2867215c 100644 --- a/src/blocks/homepage-articles/view.php +++ b/src/blocks/homepage-articles/view.php @@ -21,7 +21,7 @@ function newspack_blocks_render_block_homepage_articles( $attributes ) { // This will let the FSE plugin know we need CSS/JS now. do_action( 'newspack_blocks_render_homepage_articles' ); - $article_query = new WP_Query( Newspack_Blocks::build_articles_query( $attributes ) ); + $article_query = new WP_Query( Newspack_Blocks::build_articles_query( $attributes, apply_filters( 'newspack_blocks_block_name', 'newspack-blocks/homepage-articles' ) ) ); $classes = Newspack_Blocks::block_classes( 'homepage-articles', $attributes, [ 'wpnbha' ] );