Pro guides Pro

Recipes for the repeatable and relational fields. The loop functions mirror the pattern most WordPress developers already know.

The row loop

Repeater, Group and Flexible Content are read with four functions:

FunctionUse
fstn_have_rows( $name, $context )True while there are rows left; advances the internal pointer.
fstn_the_row()Loads the current row so fstn_get_sub_field() reads from it.
fstn_get_sub_field( $name )A sub-field value in the current row.
fstn_get_row_layout()The current row's layout name (Flexible Content).
<?php if ( fstn_have_rows( 'team' ) ) : ?>
  <?php while ( fstn_have_rows( 'team' ) ) : fstn_the_row(); ?>
    <div class="member">
      <h3><?php echo esc_html( fstn_get_sub_field( 'name' ) ); ?></h3>
      <p><?php echo esc_html( fstn_get_sub_field( 'role' ) ); ?></p>
    </div>
  <?php endwhile; ?>
<?php endif; ?>

Nested repeaters

A repeater can contain another repeater. Loop the inner one inside the outer row — the functions are context-aware:

<?php while ( fstn_have_rows( 'sections' ) ) : fstn_the_row(); ?>
  <h2><?php echo esc_html( fstn_get_sub_field( 'title' ) ); ?></h2>
  <?php while ( fstn_have_rows( 'links' ) ) : fstn_the_row(); ?>
    <a href="<?php echo esc_url( fstn_get_sub_field( 'url' ) ); ?>"><?php echo esc_html( fstn_get_sub_field( 'label' ) ); ?></a>
  <?php endwhile; ?>
<?php endwhile; ?>

Flexible Content: one partial per layout

Switch on fstn_get_row_layout() and keep each layout's markup tidy:

<?php while ( fstn_have_rows( 'content' ) ) : fstn_the_row();
  $layout = fstn_get_row_layout();
  if ( $layout === 'hero' ) : ?>
    <section class="hero">
      <h1><?php echo esc_html( fstn_get_sub_field( 'heading' ) ); ?></h1>
    </section>
  <?php elseif ( $layout === 'gallery' ) : ?>
    <?php foreach ( fstn_get_sub_field( 'images' ) as $img ) : ?>
      <img src="<?php echo esc_url( $img['url'] ); ?>" alt="<?php echo esc_attr( $img['alt'] ); ?>">
    <?php endforeach; ?>
  <?php endif; ?>
<?php endwhile; ?>

Two-way (bidirectional) relationships

On a Relationship or Post Object field, turn on the two-way option and pick the field on the other post type to keep in sync. When an editor links Post A to Post B, Fieldstone automatically adds A to B's field — no code needed. Read either end the normal way:

<?php foreach ( (array) fstn_get_field( 'related_products' ) as $post ) : ?>
  <a href="<?php echo esc_url( get_permalink( $post ) ); ?>"><?php echo esc_html( get_the_title( $post ) ); ?></a>
<?php endforeach; ?>

Options pages (site-wide fields)

Options pages hold values that aren't tied to a single post — a logo, social links, a footer notice.

  1. Go to Fieldstone → Options Pages and create a page (give it a title and menu slug).
  2. Create a field group and, in its Location Rules, target that options page.
  3. Edit the options page and fill in the fields.

Read the values anywhere with the 'option' context:

<?php echo esc_html( fstn_get_field( 'company_tagline', 'option' ) ); ?>
<img src="<?php echo esc_url( fstn_get_field( 'logo', 'option' )['url'] ); ?>">

Bind blocks to fields

In the block editor (WordPress 6.5+), a core block's text or attribute can be bound to a Fieldstone field using the binding source fieldstone/field — so a Paragraph or Heading shows a field's value with no theme code. Select a supported block, open Attributes / Bindings, and choose the Fieldstone field. The block then renders that field for whichever post it appears on.

Clone tip: build a reusable set of fields once, then drop a Clone field into any group to include them — great for shared "SEO" or "Call to action" field sets.