Skip to content

Commit 4a8e48e

Browse files
iRohitSinghdanalvrziFlameing
authored
Add missing placeholder image for person grid variation of a listing (#897)
Co-authored-by: Dante Álvarez <89805481+danalvrz@users.noreply.github.com> Co-authored-by: Alok Kumar <ialokkumarsingh0@gmail.com>
1 parent f6d67b7 commit 4a8e48e

6 files changed

Lines changed: 53 additions & 18 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add missing placeholder image for person grid variation of a listing @iRohitSingh

frontend/packages/volto-light-theme/src/components/Blocks/Listing/GridTemplate.jsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,19 @@ const GridTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
4242
if (item['@type'] === 'Person' && showProfileLinks !== undefined) {
4343
showLink = showProfileLinks && !isEditMode;
4444
}
45-
45+
const placeholderSrc =
46+
config.settings.placeholderImages?.[item['@type']];
4647
const ItemBodyTemplate = (props) =>
4748
CustomItemBodyTemplate ? (
4849
<CustomItemBodyTemplate item={item} />
4950
) : (
5051
<>
51-
{item.image_field !== '' && (
52+
{(item.image_field !== '' || placeholderSrc) && (
5253
<Card.Image
5354
className="item-image"
5455
item={item}
56+
showPlaceholderImage={true}
57+
placeholderSrc={placeholderSrc}
5558
imageComponent={PreviewImageComponent}
5659
sizes={`(max-width: ${config.settings.layout.tabletBreakpoint}px) 100vw, ${Math.trunc(config.settings.layout.defaultContainerWidth / 2)}px`}
5760
/>

frontend/packages/volto-light-theme/src/components/Blocks/Listing/SummaryTemplate.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ const SummaryTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
4141
if (item['@type'] === 'Person' && showProfileLinks !== undefined) {
4242
showLink = showProfileLinks && !isEditMode;
4343
}
44+
const placeholderSrc =
45+
config.settings.placeholderImages?.[item['@type']];
4446
const ItemBodyTemplate = (props) =>
4547
CustomItemBodyTemplate ? (
4648
<CustomItemBodyTemplate item={item} />
@@ -49,6 +51,7 @@ const SummaryTemplate = ({ items, linkTitle, linkHref, isEditMode }) => {
4951
<Card.Image
5052
item={item}
5153
showPlaceholderImage={true}
54+
placeholderSrc={placeholderSrc}
5255
imageComponent={PreviewImageComponent}
5356
sizes={`(max-width: ${config.settings.layout.tabletBreakpoint}px) 100vw, 220px`}
5457
/>

frontend/packages/volto-light-theme/src/components/Blocks/Teaser/DefaultBody.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,17 @@ const TeaserDefaultTemplate = (props) => {
5151
head_title: data.head_title || '',
5252
};
5353

54+
const placeholderSrc = config.settings.placeholderImages?.[href['@type']];
55+
5456
return (
5557
<Card item={showLink ? href : null} openLinkInNewTab={openLinkInNewTab}>
5658
<Card.Image
5759
src={url && !image?.image_field ? url : undefined}
5860
item={!data.overwrite ? href : { ...href, ...localOverrides }}
5961
image={data.overwrite ? image : undefined}
6062
imageComponent={Image}
63+
showPlaceholderImage={Boolean(placeholderSrc)}
64+
placeholderSrc={placeholderSrc}
6165
sizes={sizes}
6266
/>
6367
<Card.Summary>

frontend/packages/volto-light-theme/src/primitives/Card/Card.tsx

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as React from 'react';
22
import ConditionalLink from '@plone/volto/components/manage/ConditionalLink/ConditionalLink';
33
import cx from 'classnames';
44
import type { ObjectBrowserItem } from '@plone/types';
5+
import defaultPlaceholderSVG from '@plone/volto/components/manage/Blocks/Listing/default-image.svg';
56

67
type BaseCardProps = {
78
/** Optional additional CSS class names to apply to the card. */
@@ -93,33 +94,49 @@ type CardImageProps = {
9394
/** A custom React component to render the image. */
9495
imageComponent?: React.ComponentType<any>;
9596
children?: React.ReactNode;
97+
/** Show a placeholder image when the item has no image of its own. */
9698
showPlaceholderImage?: boolean;
99+
/**
100+
* Optional custom image configurable per content type at config.settings.placeholderImages.[type]. Falls back to the default placeholder image.
101+
*/
102+
placeholderSrc?: string;
97103
sizes?: string;
98104
};
99105

100106
const CardImage = (props: CardImageProps) => {
101-
const { src, item, image, imageComponent, showPlaceholderImage, sizes } =
102-
props;
107+
const {
108+
src,
109+
item,
110+
image,
111+
imageComponent,
112+
showPlaceholderImage,
113+
placeholderSrc,
114+
sizes,
115+
} = props;
103116
const Image = imageComponent || DefaultImage;
117+
const imageField = image ? image.image_field : item?.image_field;
118+
const hasItemImage = item?.hasPreviewImage || imageField || image;
104119

105120
return (
106121
<div className="image-wrapper">
107122
{src ? (
108123
<Image src={src} alt="" loading="lazy" responsive={true} />
109-
) : item || image ? (
110-
(item?.hasPreviewImage ||
111-
item?.image_field ||
112-
image ||
113-
showPlaceholderImage) && (
114-
<Image
115-
item={image || item}
116-
imageField={image ? image.image_field : item?.image_field}
117-
alt=""
118-
loading="lazy"
119-
responsive={true}
120-
sizes={sizes}
121-
/>
122-
)
124+
) : showPlaceholderImage && !hasItemImage ? (
125+
<DefaultImage
126+
src={placeholderSrc || defaultPlaceholderSVG}
127+
alt=""
128+
loading="lazy"
129+
responsive={true}
130+
/>
131+
) : hasItemImage ? (
132+
<Image
133+
item={image || item}
134+
imageField={imageField}
135+
alt=""
136+
loading="lazy"
137+
responsive={true}
138+
sizes={sizes}
139+
/>
123140
) : (
124141
props.children
125142
)}

frontend/packages/volto-light-theme/src/types.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,11 @@ declare module '@plone/types' {
116116
sticky_menu: Array<stickyMenu>;
117117
footer_links: Array<Link>;
118118
}
119+
export interface SettingsConfig {
120+
/**
121+
* Maps a content type to the placeholder image, shown in Cards when
122+
* an item has no image of its own. If undefined, it falls back to the default placeholder image.
123+
*/
124+
placeholderImages?: Record<string, string>;
125+
}
119126
}

0 commit comments

Comments
 (0)