Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Site screenshot: Add responsive image support to the screenshot block #175

Merged
merged 7 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion source/wp-content/themes/wporg-showcase-2022/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ function setup_theme() {
add_image_size( 'screenshot-desktop', 2044, 1150, array( 'center', 'top' ) );
add_image_size( 'screenshot-mobile', 750, 1334, array( 'center', 'top' ) );

// More desktop sizes to support responsive images in the grid.
// In production these will be generated using Photon CDN, but we can set
// them up as real sizes for local support too.
// Images in the grid are display from 340-740px wide. This set of sizes
// should cover 1x and 2x resolution.
$desktop_ratio = 1150 / 2044;
add_image_size( 'screenshot-desktop-1400', 1400, 1400 * $desktop_ratio, array( 'center', 'top' ) );
add_image_size( 'screenshot-desktop-1100', 1100, 1100 * $desktop_ratio, array( 'center', 'top' ) );
add_image_size( 'screenshot-desktop-800', 800, 800 * $desktop_ratio, array( 'center', 'top' ) );
add_image_size( 'screenshot-desktop-500', 500, 500 * $desktop_ratio, array( 'center', 'top' ) );

// Add tonesque support so that Jetpack loads the class.
add_theme_support( 'tonesque' );

Expand Down Expand Up @@ -470,7 +481,7 @@ function jetpack_related_posts_display( $markup, $post_id, $related_posts, $bloc
<!-- wp:query {"queryId":2,"query":{"perPage":3,"include":<?php echo esc_attr( wp_json_encode( $ids ) ); ?>,"inherit":false},"align":"wide","layout":{"type":"constrained","wideSize":"1760px"}} -->
<div class="wp-block-query alignwide">
<!-- wp:post-template {"align":"wide","style":{"spacing":{"blockGap":"var:preset|spacing|40"}},"layout":{"type":"grid","columnCount":3},"className":"wporg-related-posts"} -->
<!-- wp:wporg/site-screenshot {"isLink":true,"lazyLoad":true} /-->
<!-- wp:wporg/site-screenshot {"isLink":true,"lazyLoad":true,"location":"row"} /-->

<!-- wp:group {"style":{"spacing":{"margin":{"top":"var:preset|spacing|10"}}},"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"space-between"}} -->
<div class="wp-block-group" style="margin-top:var(--wp--preset--spacing--10)">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
<!-- /wp:heading -->

<!-- wp:post-template {"align":"wide","style":{"spacing":{"blockGap":"var:preset|spacing|40"}},"layout":{"type":"grid","columnCount":3}} -->
<!-- wp:wporg/site-screenshot {"isLink":true,"lazyLoad":true} /-->
<!-- wp:wporg/site-screenshot {"isLink":true,"lazyLoad":true,"location":"grid"} /-->

<!-- wp:group {"style":{"spacing":{"margin":{"top":"var:preset|spacing|10"}}},"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"space-between"}} -->
<div class="wp-block-group" style="margin-top:var(--wp--preset--spacing--10)">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<!-- wp:query-title {"type":"archive","className":"screen-reader-text"} /-->

<!-- wp:post-template {"align":"wide","style":{"spacing":{"blockGap":"var:preset|spacing|40"}},"layout":{"type":"grid","columnCount":3}} -->
<!-- wp:wporg/site-screenshot {"isLink":true,"lazyLoad":true} /-->
<!-- wp:wporg/site-screenshot {"isLink":true,"lazyLoad":true,"location":"grid"} /-->

<!-- wp:group {"style":{"spacing":{"margin":{"top":"var:preset|spacing|10"}}},"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"space-between"}} -->
<div class="wp-block-group" style="margin-top:var(--wp--preset--spacing--10)">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<span aria-hidden="true" class="wp-block-cover__background has-background-dim-0 has-background-dim"></span>
<img class="wp-block-cover__image-background" alt="" src="<?php echo esc_url( get_theme_file_uri( 'images/dots-hero.svg' ) . '?v=' . time() ); ?>" style="object-position:0% 0%" data-object-fit="contain" data-object-position="0% 0%"/>
<div class="wp-block-cover__inner-container">
<!-- wp:wporg/site-screenshot {"isLink":true} /-->
<!-- wp:wporg/site-screenshot {"isLink":true,"location":"hero"} /-->
</div>
</div>
<!-- /wp:cover -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@
<h3 class="has-small-font-size"><?php esc_attr_e( 'Desktop', 'wporg' ); ?></h3>
<!-- /wp:heading -->

<!-- wp:wporg/site-screenshot {"isLink":true,"type":"desktop"} /--></div>
<!-- wp:wporg/site-screenshot {"isLink":true,"type":"desktop","location":"header"} /--></div>
<!-- /wp:column -->

<!-- wp:column {"width":"25%"} -->
<div class="wp-block-column" style="flex-basis:25%"><!-- wp:heading {"level":3,"fontSize":"small"} -->
<h3 class="has-small-font-size"><?php esc_attr_e( 'Mobile', 'wporg' ); ?></h3>
<!-- /wp:heading -->

<!-- wp:wporg/site-screenshot {"isLink":true,"type":"mobile"} /--></div>
<!-- wp:wporg/site-screenshot {"isLink":true,"type":"mobile","location":"header"} /--></div>
<!-- /wp:column --></div>
<!-- /wp:columns --></div>
<!-- /wp:group -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
"type": "string",
"default": "desktop",
"enum": [ "desktop", "mobile" ]
},
"location": {
"type": "string",
"default": "grid",
"enum": [ "grid", "hero", "header", "row" ]
}
},
"supports": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ function init() {
*
* @param WP_Post $post
* @param string $type
* @param string $size
* @return string
*/
function get_site_screenshot_src( $post, $type = 'desktop' ) {
function get_site_screenshot_src( $post, $type = 'desktop', $size = 'screenshot-desktop' ) {
$screenshot_url = false;
$media_id = get_post_meta( $post->ID, 'screenshot-' . $type, true );
$cache_key = '20230913'; // To break out of cached image.

$size = 'screenshot-' . $type;
$all_sizes = wp_get_registered_image_subsizes();
if ( ! isset( $all_sizes[ $size ] ) ) {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Site Screenshots

Display the screenshot for the current post (site). This uses the uploaded image if available, otherwise falls back to using the `domain` to take and load a screenshot from mshots.

The mshots behavior uses the [Interactivity API](https://github.com/WordPress/gutenberg/blob/trunk/packages/interactivity/docs/1-getting-started.md) to provide a CSS-controlled loading state.

When a local image is used, the block may use responsive images, depending on the location.

This block also controls loading the panel into the Document Settings sidebar for uploading the desktop & mobile images, and setting the custom background color.

## Attributes

### `isLink`: boolean

- Default: false

If true, will wrap the screenshot in a link to the current post.

### `lazyLoad`: boolean

- Default: false

Controls the `loading` attribute on the `img` tag. This is currently not used for mshots images.

### `type`: "desktop" | "mobile"

- Default: "desktop"

Controls which image to show/capture. When `desktop`, it uses the image saved as `screenshot-desktop` or captures from mshots at 1920x1080. When `mobile`, it uses the image saves as `screenshot-mobile` or captures from mshots at 375x667.

### `location`: "grid" | "hero" | "header" | "row"

- Default: "grid"

This indicates to the block where in the layout this will be rendered. This is used to control the responsive image hints.

- grid: the main site grid, on homepage or archives, which displays at 3, 2, or 1 column depending on screen size.
- hero: the homepage header, does not use responsive images.
- header: single site page header, does not use responsive images.
- row: the "related sites" section, which displays at 3 or 1 column depending on screen size.

Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,45 @@
$has_link = isset( $attributes['isLink'] ) && true == $attributes['isLink'];
$is_lazyload = isset( $attributes['lazyLoad'] ) && true === $attributes['lazyLoad'];

$screenshot = get_site_screenshot_src( $current_post, $attributes['type'] );
$img_size = ( 'desktop' === $attributes['type'] ) ? 'screenshot-desktop' : 'screenshot-mobile';
$screenshot = get_site_screenshot_src( $current_post, $attributes['type'], $img_size );
$is_mshots = str_contains( $screenshot, 'mshots' );

$classname = 'is-size-' . esc_attr( $attributes['type'] );
if ( $has_link ) {
$classname .= ' is-linked-image';
}

$has_responsive_images = ! $is_mshots && 'desktop' === $attributes['type'] && ( 'grid' === $attributes['location'] || 'row' === $attributes['location'] );

// If the block needs responsive images, set up more image URLs & sizes attribute.
if ( $has_responsive_images ) {
$screenshot = get_site_screenshot_src( $current_post, $attributes['type'], 'screenshot-desktop-1100' );
$screenshot_srcset = get_site_screenshot_src( $current_post, $attributes['type'], 'screenshot-desktop-500' ) . ' 500w, ';
$screenshot_srcset .= get_site_screenshot_src( $current_post, $attributes['type'], 'screenshot-desktop-800' ) . ' 800w, ';
$screenshot_srcset .= get_site_screenshot_src( $current_post, $attributes['type'], 'screenshot-desktop-1100' ) . ' 1100w, ';
$screenshot_srcset .= get_site_screenshot_src( $current_post, $attributes['type'], 'screenshot-desktop-1400' ) . ' 1400w';

// Set up the sizes attribute. The value here should reflect the width of
// the column, i.e., the displayed with of the image.
// On very large screens, columns are a fixed size.
$sizes = '(min-width: 1920px) 533px,';
// Handle dynamic column sizes. This math is not really reflective of the
// layout, but it works well. Real math would be tricky due to the scaling
// column gap value (--wp--preset--spacing--40).
// See https://css-tricks.com/a-guide-to-the-responsive-images-syntax-in-html/#aa-being-more-chill-about-sizes
if ( 'grid' === $attributes['location'] ) {
$sizes .= '(min-width: 1601px) calc(25vw + 30px),';
$sizes .= '(min-width: 801px) calc(50vw - 125px),';
} else {
// In "row", this stays 3-column until flipping to one-column.
$sizes .= '(min-width: 801px) calc(25vw + 30px),';
}
// One column—this one's actually accurate! At one column, we only need to
// account for site padding & border width.
$sizes .= 'calc(100vw - 60px)';
}

// Initial state to pass to Interactivity API.
// This handles the image data (used to load image from mshots) and current
// state information (like errors).
Expand Down Expand Up @@ -56,6 +87,10 @@ class="wporg-site-screenshot__mshot-container"
<?php else : ?>
<img
src="<?php echo esc_url( $screenshot ); ?>"
<?php if ( $has_responsive_images ) : ?>
srcset="<?php echo esc_attr( $screenshot_srcset ); ?>"
sizes="<?php echo esc_attr( $sizes ); ?>"
<?php endif; ?>
alt="<?php echo the_title_attribute( array( 'echo' => false ) ); ?>"
loading="<?php echo $is_lazyload ? 'lazy' : 'eager'; ?>"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ a:where(:not(.wp-element-button)):focus-visible {
}
}

@media (max-width: 1440px) {
@media (max-width: 1600px) {
.wp-block-post-template.is-layout-grid.columns-3:not(.wporg-related-posts) {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<div class="wp-block-group alignfull has-feature-color-background has-background" style="border-bottom-color:var(--wp--preset--color--light-grey-1);border-bottom-style:solid;border-bottom-width:1px;background-color:#f6f6f6;margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--60);padding-right:var(--wp--preset--spacing--edge-space);padding-left:var(--wp--preset--spacing--edge-space)">
<!-- wp:group {"style":{"spacing":{"blockGap":"var:preset|spacing|60"}},"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"center","verticalAlignment":"bottom"}} -->
<div class="wp-block-group">
<!-- wp:wporg/site-screenshot /-->
<!-- wp:wporg/site-screenshot {"location":"header"} /-->

<!-- wp:wporg/site-screenshot {"type":"mobile"} /-->
<!-- wp:wporg/site-screenshot {"type":"mobile","location":"header"} /-->
</div>
<!-- /wp:group -->
</div>
Expand Down
Loading