Now that we have learnt on how to add a new variation to a teaser block. Sometimes its important to also have schemas of those variations merged into the main schema. So each variation can come up with its own set of schema. We can use schemaEnhancers for this purpose.
schemaEnhancers works on the concept of composition. They are just functions which take original schema, formdata and intl and return modified schema based on its arguments.
In our variation, let's add a schemaEnhancer to modify existing schema and add a CreationDate from catalog metadata brain.
data.href contains the catalog brain properties which are requested via selectedItemAttrs. CreationDate is one of them. Notice we are using formatDate from Volto helpers which is used to parse date into respective formats on the basis of locales.
Finally render it conditionally on the basis of data.creationDate
importReactfrom"react";importPropTypesfrom"prop-types";import{Message}from"semantic-ui-react";import{defineMessages,useIntl}from"react-intl";importimageBlockSVGfrom"@plone/volto/components/manage/Blocks/Image/block-image.svg";import{flattenToAppURL,isInternalURL}from"@plone/volto/helpers";import{MaybeWrap}from"@plone/volto/components";import{formatDate}from"@plone/volto/helpers/Utils/Date";import{UniversalLink}from"@plone/volto/components";importcxfrom"classnames";importconfigfrom"@plone/volto/registry";constmessages=defineMessages({PleaseChooseContent:{id:"Please choose an existing content as source for this element",defaultMessage:"Please choose an existing content as source for this element",},});constDefaultImage=(props)=><img{...props}alt={props.alt||""}/>;constTeaserBlockImageDefault=(props)=>{const{className,data,isEditMode}=props;constlocale=config.settings.dateLocale||"en";constintl=useIntl();consthref=data.href?.[0];constimage=data.preview_image?.[0];constalign=data?.styles?.align;constcreationDate=data.href?.[0]?.CreationDate;constformattedDate=formatDate({date:creationDate,format:{year:"numeric",month:"short",day:"2-digit",},locale:locale,});constImage=config.getComponent("Image").component||DefaultImage;const{openExternalLinkInNewTab}=config.settings;return(<divclassName={cx("block teaser",className)}><>{!href&&isEditMode&&(<Message><divclassName="teaser-item placeholder"><imgsrc={imageBlockSVG}alt=""/><p>{intl.formatMessage(messages.PleaseChooseContent)}</p></div></Message>)}{href&&(<MaybeWrapcondition={!isEditMode}as={UniversalLink}href={href["@id"]}target={data.openLinkInNewTab||(openExternalLinkInNewTab&&!isInternalURL(href["@id"]))?"_blank":null}><divclassName="teaser-item default"style={{display:"flex",flexDirection:"column",alignItems:"center",}}>{(href.hasPreviewImage||href.image_field||image)&&(<divclassName="image-wrapper"><Imageitem={props["@type"]==="listing"?null:image||href}src={props["@type"]==="listing"?addAppURL(`${href}/${image?.download}`):null}imageField={image?image.image_field:href.image_field}alt=""loading="lazy"responsive={true}/></div>)}<divclassName="content">{data?.head_title&&(<divclassName="headline">{data.head_title}</div>)}<h2>{data?.title}</h2>{data.creationDate&&<p>{formattedDate}</p>}{!data.hide_description&&<p>{data?.description}</p>}</div></div></MaybeWrap>)}</></div>);};TeaserBlockImageDefault.propTypes={data:PropTypes.objectOf(PropTypes.any).isRequired,isEditMode:PropTypes.bool,};exportdefaultTeaserBlockImageDefault;