diff --git a/assets/css/abstracts/_mixins.scss b/assets/css/abstracts/_mixins.scss
index 96e1735c2f8..906e72a2bce 100644
--- a/assets/css/abstracts/_mixins.scss
+++ b/assets/css/abstracts/_mixins.scss
@@ -217,7 +217,7 @@ $fontSizes: (
left: 0;
bottom: 0;
right: 0;
- background-color: inherit;
+ background: inherit;
border-radius: inherit;
opacity: $opacity;
z-index: 1;
diff --git a/assets/js/blocks/featured-items/featured-category/block.json b/assets/js/blocks/featured-items/featured-category/block.json
index 5cca01685d9..da1da21ae70 100644
--- a/assets/js/blocks/featured-items/featured-category/block.json
+++ b/assets/js/blocks/featured-items/featured-category/block.json
@@ -57,6 +57,14 @@
"type": "string",
"default": "none"
},
+ "hasParallax": {
+ "type": "boolean",
+ "default": false
+ },
+ "isRepeated": {
+ "type": "boolean",
+ "default": false
+ },
"mediaId": {
"type": "number",
"default": 0
diff --git a/src/BlockTypes/FeaturedCategory.php b/src/BlockTypes/FeaturedCategory.php
index 00e7d7b0393..52d2bcbd04f 100644
--- a/src/BlockTypes/FeaturedCategory.php
+++ b/src/BlockTypes/FeaturedCategory.php
@@ -14,6 +14,14 @@ class FeaturedCategory extends AbstractDynamicBlock {
*/
protected $block_name = 'featured-category';
+ /**
+ * Default attribute values, should match what's set in JS `registerBlockType`.
+ *
+ * @var array
+ */
+ protected $defaults = array(
+ 'align' => 'none',
+ );
/**
* Global style enabled for this block.
@@ -45,15 +53,6 @@ protected function get_block_type_supports() {
);
}
- /**
- * Default attribute values, should match what's set in JS `registerBlockType`.
- *
- * @var array
- */
- protected $defaults = array(
- 'align' => 'none',
- );
-
/**
* Get block attributes.
*
@@ -79,17 +78,16 @@ protected function get_block_type_attributes() {
* @return string Rendered block type output.
*/
protected function render( $attributes, $content ) {
+ $id = absint( $attributes['categoryId'] ?? 0 );
- $id = absint( isset( $attributes['categoryId'] ) ? $attributes['categoryId'] : 0 );
$category = get_term( $id, 'product_cat' );
-
if ( ! $category || is_wp_error( $category ) ) {
return '';
}
$attributes = wp_parse_args( $attributes, $this->defaults );
- $attributes['height'] = isset( $attributes['height'] ) ? $attributes['height'] : wc_get_theme_support( 'featured_block::default_height', 500 );
+ $attributes['height'] = $attributes['height'] ?? wc_get_theme_support( 'featured_block::default_height', 500 );
$title = sprintf(
'
', esc_attr( trim( $classes ) ), esc_attr( $styles ) );
$output .= '
';
$output .= $this->render_overlay( $attributes );
- $output .= $this->render_image( $attributes, $category );
+
+ if ( ! $attributes['isRepeated'] && ! $attributes['hasParallax'] ) {
+ $output .= $this->render_image( $attributes, $category, $image_url );
+ } else {
+ $output .= $this->render_bg_image( $attributes, $image_url );
+ }
+
$output .= $title;
if ( $attributes['showDesc'] ) {
$output .= $desc_str;
@@ -119,29 +125,39 @@ protected function render( $attributes, $content ) {
}
/**
- * Renders the featured image
+ * Returns the url of a category image
*
- * @param array $attributes Block attributes. Default empty array.
- * @param \WC_Product $category Product object.
+ * @param array $attributes Block attributes. Default empty array.
+ * @param \WP_Term $category Category object.
*
* @return string
*/
- private function render_image( $attributes, $category ) {
- $style = '';
+ private function get_image_url( $attributes, $category ) {
$image_size = 'large';
if ( 'none' !== $attributes['align'] || $attributes['height'] > 800 ) {
$image_size = 'full';
}
- $style .= sprintf( 'object-fit: %s;', $attributes['imageFit'] );
-
if ( $attributes['mediaId'] ) {
- $image = wp_get_attachment_image_url( $attributes['mediaId'], $image_size );
- } else {
- $image = $this->get_image( $category, $image_size );
+ return wp_get_attachment_image_url( $attributes['mediaId'], $image_size );
}
- if ( is_array( $attributes['focalPoint'] ) && 2 === count( $attributes['focalPoint'] ) ) {
+ return $this->get_image( $category, $image_size );
+ }
+
+ /**
+ * Renders the featured image
+ *
+ * @param array $attributes Block attributes. Default empty array.
+ * @param \WC_Product $category Product object.
+ * @param string $image_url Product image url.
+ *
+ * @return string
+ */
+ private function render_image( $attributes, $category, string $image_url ) {
+ $style = sprintf( 'object-fit: %s;', $attributes['imageFit'] );
+
+ if ( $this->hasFocalPoint( $attributes ) ) {
$style .= sprintf(
'object-position: %s%% %s%%;',
$attributes['focalPoint']['x'] * 100,
@@ -149,11 +165,11 @@ private function render_image( $attributes, $category ) {
);
}
- if ( ! empty( $image ) ) {
+ if ( ! empty( $image_url ) ) {
return sprintf(
'
',
wp_kses_post( $attributes['alt'] ?: $category->name ),
- esc_url( $image ),
+ $image_url,
$style
);
}
@@ -162,24 +178,57 @@ private function render_image( $attributes, $category ) {
}
/**
- * Renders the block overlay
+ * Renders the featured image as a div background.
*
- * @param array $attributes Block attributes. Default empty array.
+ * @param array $attributes Block attributes. Default empty array.
+ * @param string $image_url Product image url.
*
* @return string
*/
- private function render_overlay( $attributes ) {
- $overlay_styles = '';
+ private function render_bg_image( $attributes, $image_url ) {
+ $styles = $this->get_bg_styles( $attributes, $image_url );
- if ( isset( $attributes['overlayColor'] ) ) {
- $overlay_styles = sprintf( 'background-color: %s', $attributes['overlayColor'] );
- } elseif ( isset( $attributes['overlayGradient'] ) ) {
- $overlay_styles = sprintf( 'background-image: %s', $attributes['overlayGradient'] );
- } else {
- $overlay_styles = 'background-color: #000000';
+ $classes = [ 'wc-block-featured-category__background-image' ];
+
+ if ( $attributes['hasParallax'] ) {
+ $classes[] = ' has-parallax';
}
- return sprintf( '
', esc_attr( $overlay_styles ) );
+ return sprintf( '
', implode( ' ', $classes ), $styles );
+ }
+
+ /**
+ * Get the styles for the wrapper element (background image, color).
+ *
+ * @param array $attributes Block attributes. Default empty array.
+ * @param string $image_url Product image url.
+ *
+ * @return string
+ */
+ public function get_bg_styles( $attributes, $image_url ) {
+ $style = '';
+
+ if ( $attributes['isRepeated'] || $attributes['hasParallax'] ) {
+ $style .= "background-image: url($image_url);";
+ }
+
+ if ( ! $attributes['isRepeated'] ) {
+ $style .= 'background-repeat: no-repeat;';
+ $style .= 'background-size: ' . ( 'cover' === $attributes['imageFit'] ? $attributes['imageFit'] : 'auto' ) . ';';
+ }
+
+ if ( $this->hasFocalPoint( $attributes ) ) {
+ $style .= sprintf(
+ 'background-position: %s%% %s%%;',
+ $attributes['focalPoint']['x'] * 100,
+ $attributes['focalPoint']['y'] * 100
+ );
+ }
+
+ $global_style_style = StyleAttributesUtils::get_styles_by_attributes( $attributes, $this->global_style_wrapper );
+ $style .= $global_style_style;
+
+ return $style;
}
/**
@@ -191,7 +240,7 @@ private function render_overlay( $attributes ) {
public function get_styles( $attributes ) {
$style = '';
- $min_height = isset( $attributes['minHeight'] ) ? $attributes['minHeight'] : wc_get_theme_support( 'featured_block::default_height', 500 );
+ $min_height = $attributes['minHeight'] ?? wc_get_theme_support( 'featured_block::default_height', 500 );
if ( isset( $attributes['minHeight'] ) ) {
$style .= sprintf( 'min-height:%dpx;', intval( $min_height ) );
@@ -203,6 +252,25 @@ public function get_styles( $attributes ) {
return $style;
}
+ /**
+ * Renders the block overlay
+ *
+ * @param array $attributes Block attributes. Default empty array.
+ *
+ * @return string
+ */
+ private function render_overlay( $attributes ) {
+ if ( isset( $attributes['overlayGradient'] ) ) {
+ $overlay_styles = sprintf( 'background-image: %s', $attributes['overlayGradient'] );
+ } elseif ( isset( $attributes['overlayColor'] ) ) {
+ $overlay_styles = sprintf( 'background-color: %s', $attributes['overlayColor'] );
+ } else {
+ $overlay_styles = 'background-color: #000000';
+ }
+
+ return sprintf( '
', esc_attr( $overlay_styles ) );
+ }
+
/**
* Get class names for the block container.
*
@@ -257,6 +325,17 @@ public function get_image( $category, $size = 'full' ) {
return $image;
}
+ /**
+ * Returns whether the focal point is defined for the block.
+ *
+ * @param array $attributes Block attributes. Default empty array.
+ *
+ * @return bool
+ */
+ private function hasFocalPoint( $attributes ): bool {
+ return is_array( $attributes['focalPoint'] ) && 2 === count( $attributes['focalPoint'] );
+ }
+
/**
* Extra data passed through from server to client for block.
*
diff --git a/src/BlockTypes/FeaturedProduct.php b/src/BlockTypes/FeaturedProduct.php
index c62db2fd4db..b32021196c8 100644
--- a/src/BlockTypes/FeaturedProduct.php
+++ b/src/BlockTypes/FeaturedProduct.php
@@ -61,16 +61,16 @@ protected function get_block_type_supports() {
* @return string Rendered block type output.
*/
protected function render( $attributes, $content ) {
- $id = absint( isset( $attributes['productId'] ) ? $attributes['productId'] : 0 );
+ $id = absint( $attributes['productId'] ?? 0 );
+
$product = wc_get_product( $id );
if ( ! $product ) {
return '';
}
+
$attributes = wp_parse_args( $attributes, $this->defaults );
- $default_height = wc_get_theme_support( 'featured_block::default_height', 500 );
- $min_height = $attributes['minHeight'] ?? $default_height;
- $attributes['height'] = $attributes['height'] ?? $default_height;
+ $attributes['height'] = $attributes['height'] ?? wc_get_theme_support( 'featured_block::default_height', 500 );
$title = sprintf(
'
%s
',
@@ -96,10 +96,11 @@ protected function render( $attributes, $content ) {
$image_url = esc_url( $this->get_image_url( $attributes, $product ) );
+ $styles = $this->get_styles( $attributes );
$classes = $this->get_classes( $attributes );
- $output = sprintf( '
', esc_attr( trim( $classes ) ) );
- $output .= $this->render_wrapper( $attributes );
+ $output = sprintf( '
', esc_attr( trim( $classes ) ), esc_attr( $styles ) );
+ $output .= '
';
$output .= $this->render_overlay( $attributes );
if ( ! $attributes['isRepeated'] && ! $attributes['hasParallax'] ) {
@@ -195,48 +196,6 @@ private function render_bg_image( $attributes, $image_url ) {
return sprintf( '
', implode( ' ', $classes ), $styles );
}
- /**
- * Renders the image wrapper.
- *
- * @param array $attributes Block attributes. Default empty array.
- *
- * @return string
- */
- private function render_wrapper( $attributes ) {
- $min_height = $attributes['minHeight'] ?? wc_get_theme_support( 'featured_block::default_height', 500 );
-
- $style = '';
- if ( isset( $attributes['minHeight'] ) ) {
- $style = sprintf( 'min-height:%dpx;', intval( $min_height ) );
- }
-
- $global_style_style = StyleAttributesUtils::get_styles_by_attributes( $attributes, $this->global_style_wrapper );
- $style .= $global_style_style;
-
- return sprintf( '
', esc_attr( $style ) );
- }
-
- /**
- * Renders the block overlay
- *
- * @param array $attributes Block attributes. Default empty array.
- *
- * @return string
- */
- private function render_overlay( $attributes ) {
- $overlay_styles = '';
-
- if ( isset( $attributes['overlayColor'] ) ) {
- $overlay_styles = sprintf( 'background-color: %s', $attributes['overlayColor'] );
- } elseif ( isset( $attributes['overlayGradient'] ) ) {
- $overlay_styles = sprintf( 'background-image: %s', $attributes['overlayGradient'] );
- } else {
- $overlay_styles = 'background-color: #000000';
- }
-
- return sprintf( '
', esc_attr( $overlay_styles ) );
- }
-
/**
* Get the styles for the wrapper element (background image, color).
*
@@ -271,6 +230,46 @@ public function get_bg_styles( $attributes, $image_url ) {
return $style;
}
+ /**
+ * Get the styles for the wrapper element (background image, color).
+ *
+ * @param array $attributes Block attributes. Default empty array.
+ * @return string
+ */
+ public function get_styles( $attributes ) {
+ $style = '';
+
+ $min_height = $attributes['minHeight'] ?? wc_get_theme_support( 'featured_block::default_height', 500 );
+
+ if ( isset( $attributes['minHeight'] ) ) {
+ $style .= sprintf( 'min-height:%dpx;', intval( $min_height ) );
+ }
+
+ $global_style_style = StyleAttributesUtils::get_styles_by_attributes( $attributes, $this->global_style_wrapper );
+ $style .= $global_style_style;
+
+ return $style;
+ }
+
+ /**
+ * Renders the block overlay
+ *
+ * @param array $attributes Block attributes. Default empty array.
+ *
+ * @return string
+ */
+ private function render_overlay( $attributes ) {
+ if ( isset( $attributes['overlayGradient'] ) ) {
+ $overlay_styles = sprintf( 'background-image: %s', $attributes['overlayGradient'] );
+ } elseif ( isset( $attributes['overlayColor'] ) ) {
+ $overlay_styles = sprintf( 'background-color: %s', $attributes['overlayColor'] );
+ } else {
+ $overlay_styles = 'background-color: #000000';
+ }
+
+ return sprintf( '
', esc_attr( $overlay_styles ) );
+ }
+
/**
* Get class names for the block container.
*