diff --git a/src/blocks/curated-list/edit.js b/src/blocks/curated-list/edit.js
index dd6a68bd..0cb1bf41 100644
--- a/src/blocks/curated-list/edit.js
+++ b/src/blocks/curated-list/edit.js
@@ -5,18 +5,24 @@ import { __ } from '@wordpress/i18n';
import { createBlock } from '@wordpress/blocks';
import { InnerBlocks, InspectorControls, PanelColorSettings } from '@wordpress/block-editor';
import {
+ BaseControl,
Button,
ButtonGroup,
PanelBody,
PanelRow,
RangeControl,
+ SelectControl,
ToggleControl,
- BaseControl,
} from '@wordpress/components';
import { compose } from '@wordpress/compose';
import { withDispatch, withSelect } from '@wordpress/data';
import { Fragment, useEffect, useState } from '@wordpress/element';
+/**
+ * Internal dependencies
+ */
+import { getCuratedListClasses } from '../../editor/utils';
+
const CuratedListEditorComponent = ( {
attributes,
canUseMapBlock,
@@ -50,10 +56,7 @@ const CuratedListEditorComponent = ( {
innerBlock => innerBlock.name === 'newspack-listings/list-container'
);
const hasMap = innerBlocks.find( innerBlock => innerBlock.name === 'jetpack/map' );
- const classes = [ className, 'newspack-listings__curated-list' ];
- if ( showNumbers ) classes.push( 'show-numbers' );
- if ( showMap ) classes.push( 'show-map' );
- if ( showSortByDate ) classes.push( 'has-sort-by-date-ui' );
+ const classes = getCuratedListClasses( className, attributes );
// Update locations in component state. This lets us keep the map block in sync with listing items.
useEffect(() => {
@@ -176,13 +179,26 @@ const CuratedListEditorComponent = ( {
{ showImage && (
-
- setAttributes( { showCaption: ! showCaption } ) }
+
+
+ setAttributes( { showCaption: ! showCaption } ) }
+ />
+
+ setAttributes( { mediaPosition: value } ) }
+ options={ [
+ { label: __( 'Top', 'newspack-listings' ), value: 'top' },
+ { label: __( 'Left', 'newspack-listings' ), value: 'left' },
+ { label: __( 'Right', 'newspack-listings' ), value: 'right' },
+ { label: __( 'Behind', 'newspack-listings' ), value: 'behind' },
+ ] }
/>
-
+
) }
{ showImage && mediaPosition !== 'top' && mediaPosition !== 'behind' && (
diff --git a/src/blocks/curated-list/save.js b/src/blocks/curated-list/save.js
index 691032ff..3794060b 100644
--- a/src/blocks/curated-list/save.js
+++ b/src/blocks/curated-list/save.js
@@ -3,28 +3,13 @@
*/
import { InnerBlocks } from '@wordpress/block-editor';
-export const CuratedList = ( { attributes, className } ) => {
- const {
- showNumbers,
- showMap,
- showSortByDate,
- // showExcerpt,
- // showImage,
- // showCaption,
- // minHeight,
- // showCategory,
- // mediaPosition,
- // typeScale,
- // imageScale,
- // mobileStack,
- // textColor,
- // showSubtitle,
- } = attributes;
+/**
+ * Internal dependencies
+ */
+import { getCuratedListClasses } from '../../editor/utils';
- const classes = [ className, 'newspack-listings__curated-list' ];
- if ( showNumbers ) classes.push( 'show-numbers' );
- if ( showMap ) classes.push( 'show-map' );
- if ( showSortByDate ) classes.push( 'has-sort-by-date-ui' );
+export const CuratedList = ( { attributes, className } ) => {
+ const classes = getCuratedListClasses( className, attributes );
return (
diff --git a/src/blocks/listing/edit.js b/src/blocks/listing/edit.js
index e6c22b41..8ac0e9a8 100644
--- a/src/blocks/listing/edit.js
+++ b/src/blocks/listing/edit.js
@@ -4,7 +4,7 @@
import { __ } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import { withSelect } from '@wordpress/data';
-import { RawHTML, useEffect, useState } from '@wordpress/element';
+import { Fragment, RawHTML, useEffect, useState } from '@wordpress/element';
import { Button, Notice, Spinner } from '@wordpress/components';
import { addQueryArgs } from '@wordpress/url';
@@ -27,8 +27,19 @@ const ListingEditorComponent = ( {
const [ isEditingPost, setIsEditingPost ] = useState( false );
const { listing } = attributes;
- // Get the parent Curated List block.
- const parent = getBlock( getBlockParents( clientId )[ 0 ] );
+ // Get the parent List Container block.
+ const parents = getBlockParents( clientId );
+ const parent = parents.reduce( ( acc, outerBlock ) => {
+ const blockInfo = getBlock( outerBlock );
+
+ if ( 'newspack-listings/list-container' === blockInfo.name ) {
+ acc.listContainer = blockInfo;
+ } else if ( 'newspack-listings/curated-list' === blockInfo.name ) {
+ acc.curatedList = blockInfo;
+ }
+
+ return acc;
+ }, {} );
// Parent Curated List block attributes.
const {
@@ -43,10 +54,10 @@ const ListingEditorComponent = ( {
// mobileStack,
// textColor,
// showSubtitle,
- } = parent.attributes;
+ } = parent.curatedList.attributes;
// Build an array of just the listing post IDs that exist in the parent Curated List block.
- const listItems = parent.innerBlocks.reduce( ( acc, innerBlock ) => {
+ const listItems = parent.listContainer.innerBlocks.reduce( ( acc, innerBlock ) => {
if ( innerBlock.attributes.listing ) {
acc.push( innerBlock.attributes.listing );
}
@@ -70,8 +81,8 @@ const ListingEditorComponent = ( {
// Sync parent attributes to listing attributes, so that we can use parent attributes in the PHP render callback.
useEffect(() => {
- setAttributes( { ...parent.attributes } );
- }, [ JSON.stringify( parent.attributes ) ]);
+ setAttributes( { ...parent.curatedList.attributes } );
+ }, [ JSON.stringify( parent.curatedList.attributes ) ]);
// Fetch listing post by listingId.
const fetchPost = async listingId => {
@@ -104,7 +115,7 @@ const ListingEditorComponent = ( {
// Renders the autocomplete search field to select listings. Will only show listings of the type that matches the block.
const renderSearch = () => {
return (
-
+
- { error && (
-
- { error }
-
- ) }
- { post && post.title && (
-
- { post.title }
-
- ) }
- { showImage && post && post.media && post.media.image && (
-
- ) }
- { showExcerpt && post && post.excerpt && { post.excerpt } }
+
+
+ { error && (
+
+ { error }
+
+ ) }
+ { showImage && post && post.media && post.media.image && (
+
+ ) }
+ { post && post.title && (
+
+
+ { post.title }
+
+ { showExcerpt && post.excerpt && { post.excerpt } }
+
+ ) }
+
@@ -185,7 +200,7 @@ const ListingEditorComponent = ( {
{ __( 'Edit this listing', 'newspack-listing' ) }
) }
-
+
);
};
diff --git a/src/blocks/listing/editor.scss b/src/blocks/listing/editor.scss
index 5c111491..8d857517 100644
--- a/src/blocks/listing/editor.scss
+++ b/src/blocks/listing/editor.scss
@@ -1,3 +1,5 @@
+@import '../../listing-styles/shared/listing';
+
.block-editor-block-list__layout {
counter-reset: list;
}
@@ -37,9 +39,4 @@
&__error {
margin: 1rem auto 2rem;
}
-
- &__listing-featured-media {
- margin: 1rem 0;
- padding: 0;
- }
}
diff --git a/src/blocks/listing/view.php b/src/blocks/listing/view.php
index d3dec5d1..734feb61 100644
--- a/src/blocks/listing/view.php
+++ b/src/blocks/listing/view.php
@@ -71,9 +71,7 @@ function render_block( $attributes ) {
?>
-
- post_title ); ?>
-
+
ID, 'large' );
@@ -90,11 +88,15 @@ function render_block( $attributes ) {
- ID ) ) );
- }
- ?>
+
+
post_title ); ?>
+
+ ID ) ) );
+ }
+ ?>
+
diff --git a/src/editor/utils.js b/src/editor/utils.js
index b38677cb..c6662fd6 100644
--- a/src/editor/utils.js
+++ b/src/editor/utils.js
@@ -5,7 +5,7 @@
/**
* Check if the current post in the editor is a listing CPT.
*
- * @return {bool}
+ * @return {boolean} Whether or not the current post is a listing CPT.
*/
export const isListing = () => {
if ( ! window.newspack_listings_data ) {
@@ -22,3 +22,39 @@ export const isListing = () => {
return false;
};
+
+/**
+ * Get array of class names for Curated List, based on attributes.
+ *
+ * @param {string} className The base class name for the block.
+ * @param {Object} attributes Block attributes.
+ *
+ * @return {Array} Array of class names for the block.
+ */
+export const getCuratedListClasses = ( className, attributes ) => {
+ const {
+ showNumbers,
+ showMap,
+ showSortByDate,
+ showImage,
+ mediaPosition,
+ // typeScale,
+ imageScale,
+ // mobileStack,
+ // textColor,
+ // showSubtitle,
+ } = attributes;
+
+ const classes = [ className, 'newspack-listings__curated-list' ];
+
+ if ( showNumbers ) classes.push( 'show-numbers' );
+ if ( showMap ) classes.push( 'show-map' );
+ if ( showSortByDate ) classes.push( 'has-sort-by-date-ui' );
+ if ( showImage ) {
+ classes.push( 'show-image' );
+ classes.push( `media-position-${ mediaPosition }` );
+ classes.push( `media-size-${ imageScale }` );
+ }
+
+ return classes;
+};
diff --git a/src/listing-styles/listings/curated-list.scss b/src/listing-styles/front-end/curated-list.scss
similarity index 100%
rename from src/listing-styles/listings/curated-list.scss
rename to src/listing-styles/front-end/curated-list.scss
diff --git a/src/listing-styles/listings/listing.scss b/src/listing-styles/front-end/listing.scss
similarity index 87%
rename from src/listing-styles/listings/listing.scss
rename to src/listing-styles/front-end/listing.scss
index 87a1379a..8ae99fa2 100644
--- a/src/listing-styles/listings/listing.scss
+++ b/src/listing-styles/front-end/listing.scss
@@ -1,3 +1,5 @@
+@import '../shared/listing';
+
.newspack-listings {
// Target only .newspack-listings* when it's an `a` element
@at-root a#{&} {
diff --git a/src/listing-styles/listings/view.scss b/src/listing-styles/front-end/view.scss
similarity index 100%
rename from src/listing-styles/listings/view.scss
rename to src/listing-styles/front-end/view.scss
diff --git a/src/listing-styles/index.js b/src/listing-styles/index.js
index ad5ef89c..b6d8f251 100644
--- a/src/listing-styles/index.js
+++ b/src/listing-styles/index.js
@@ -1,4 +1,4 @@
/**
* Custom styles for listings pages.
*/
-import './listings/view.scss';
+import './front-end/view.scss';
diff --git a/src/listing-styles/shared/listing.scss b/src/listing-styles/shared/listing.scss
new file mode 100644
index 00000000..19f785c0
--- /dev/null
+++ b/src/listing-styles/shared/listing.scss
@@ -0,0 +1,43 @@
+.newspack-listings {
+ &__listing-post {
+ .media-position-left &,
+ .media-position-right & {
+ display: flex;
+ }
+ }
+
+ &__listing-featured-media {
+ flex-basis: 100%;
+ margin: 1rem 0;
+ max-width: 100%;
+ padding: 0;
+
+ .media-position-right & {
+ order: 2;
+ }
+
+ .media-size-1 & {
+ flex-basis: 25%;
+ }
+
+ .media-size-2 & {
+ flex-basis: 50%;
+ }
+
+ .media-size-3 & {
+ flex-basis: 75%;
+ }
+ }
+
+ &__listing-meta {
+ flex-basis: 100%;
+
+ .media-position-left & {
+ margin-left: 1rem;
+ }
+
+ .media-position-right & {
+ margin-right: 1rem;
+ }
+ }
+}