Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Feb 27, 2024. It is now read-only.

ACF repeater example in block #552

Unanswered
lolitsyou asked this question in Q&A
Jul 1, 2021 · 3 comments · 6 replies
Discussion options

Does anyone have a good example of a block using an ACF repeater? Im trying to build an accordion but dont know how to Map through the block repeater inside a block component.

My set up is this.

Repeater ACF field named accordion (blockAccordion in Graphql)
A text field named 'title'
A Content field name 'body'

You must be logged in to vote

Replies: 3 comments 6 replies

Comment options

Hi there, is this still open? I have the same question...

Best

You must be logged in to vote
0 replies
Comment options

I'll third that, an example of this or documentation would be great!

You must be logged in to vote
0 replies
Comment options

This is pretty easy to achieve.

This would be your ACF BLOCK

import BrandRepeater from '@/components/organisms/BrandRepeater'
import PropTypes from 'prop-types'
/**
 * Handle the brandRepeaterBlock block.
 *
 * @author WebDevStudios
 * @param {object} props The props.
 * @param {object} props.attributes The attributes object.
 * @return {Element} The component.
 */
export default function BrandepeaterBlock({attributes}) {
 const {data} = attributes
 let images = []
 // Prepare repeater data for mapping
 for (let z = 0; z < attributes.data.brand; z++) {
 images.push({
 image: data[`brand_${z}_image`],
 title: data[`brand_${z}_title`],
 caption: data[`brand_${z}_image_caption`],
 content: data[`brand_${z}_content`],
 buttonText: data[`brand_${z}_button_text`],
 buttonURL: data[`brand_${z}_button_url`]
 })
 }
 return (
 <>
 {attributes ? (
 <BrandRepeater {...attributes.data} images={images} />
 ) : (
 'There was a problem with attributes in BrandRepeater.js.'
 )}
 </>
 )
}
BrandepeaterBlock.propTypes = {
 attributes: PropTypes.object
}

Then this would be your component

import DisplayImage from '@/components/atoms/Image'
import cn from 'classnames'
import PropTypes from 'prop-types'
import React from 'react'
import styles from './BrandRepeater.module.css'
import InnerHTML from 'dangerously-set-html-content'
/**
 * Render the LogoRepeater component.
 *
 * @param {object} props LogoRepeater component props.
 * @param {Array} props.images The images from LogoRepeaterBlock
 * @param {Array} props.imageMetas The images metadata
 * @param props.caption
 * @param props.color
 * @return {Element} The LogoRepeater component.
 */
export default function BrandRepeater({images, imageMetas, color}) {
 return (
 <section className={cn(styles.container)}>
 {images.map((image, i) => {
 let currMeta = imageMetas[i]
 return (
 <div key={i} className={styles.BrandRepeater} style={{color}}>
 <div className={cn(styles.media)}>
 <DisplayImage
 className={styles.imageWrap}
 id={image}
 alt={currMeta?.altText}
 imageMeta={currMeta}
 nextImageFill={true}
 />
 <div className={styles.caption}>
 <p>{image.caption}</p>
 </div>
 </div>
 <div className={styles.content}>
 <h3>{image.title}</h3>
 <InnerHTML html={image.content} />
 {!image.buttonURL ? null : (
 <a className={styles.link} href={image.buttonURL}>
 {image.buttonText}
 </a>
 )}
 </div>
 </div>
 )
 })}
 </section>
 )
}
BrandRepeater.propTypes = {
 images: PropTypes.array,
 imageMetas: PropTypes.array
}
You must be logged in to vote
6 replies
Comment options

Here you go

 case 'acf/acf-media-text':
 // Retrieve additional image meta.
 attributes.data.imageMeta = await getMediaByID(
 attributes?.data?.image
 )
 break
Comment options

Hi, thanks, but this snippet only works for a single image? When you have images in a repeater i'm guessing it needs some sort of iteration. I have tried a bunch of things but haven't managed to get it working yet.

It just displays the last image for all of the items in the repeater

Comment options

I think you should be able to get this to work

 case 'acf/highlight-block':
 // Prepare slider data for mapping
 attributes.highlights = []
 for (let z = 0; z < attributes.data.highlights; z++) {
 attributes.highlights.push({
 imageMeta: await getMediaByID(attributes?.data[`highlights_${z}_image`]),
 title: attributes?.data[`highlights_${z}_title`],
 description: attributes?.data[`highlights_${z}_description`]
 })
 }
 break
 }
Comment options

So this snippet is from a different block from the original example, is the code the same for both examples? It doesn't seem to be working for me, i'm getting a "currMeta is undefined" message in console.

I could put the code I have here if you like? I wouldn't want to take up too much of your time though if you're busy, not sure why this code isn't working for me though, i'm pretty sure it's something simple i'm missing.

Comment options

Also the ACF BLOCK code throws an error "TypeError: attributes.data is undefined" I changed the code a bit for that file. Do you have a working example of this with all three relevant snippets per chance?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /