Im Frontend stehen Entwickler jedoch regelmäßig vor der Herausforderung, diese dynamischen Zeilen gestalterisch zu variieren. Häufig verlangt das Screendesign ein sogenanntes Zick-Zack-Muster (Bild links, Text rechts im ersten Block; Bild rechts, Text links im zweiten Block) oder wechselnde Hintergrundfarben zur visuellen Rhythmisierung.
In dieser technischen Anleitung zeigen wir Ihnen, wie Sie die have_rows()-Schleife sauber strukturieren, wie Sie den Modulo-Operator in PHP und moderne CSS-Pseudoklassen :nth-child() gezielt einsetzen und wie Sie teure Performance-Fallen in der WordPress-Datenbank vermeiden.
Das Datenmodell hinter dem ACF Repeater
Um sauberen und performanten Code zu schreiben, müssen Entwickler verstehen, wie WordPress und ACF die Werte auf Datenbankebene ablegen. WordPress speichert Beitragsmetadaten in der relationalen Tabelle wp_postmeta als einfache Schlüssel-Wert-Paare.
Wenn Sie ein Repeater-Feld mit dem Bezeichner leistungs_merkmale anlegen, das zwei Unterfelder (titel und beschreibung) enthält, und der Redakteur 4 Zeilen speichert, erzeugt ACF folgende Einträge:
- Einen Zähler-Datensatz:
leistungs_merkmalemit dem Wert4. - Einträge für Zeile 0:
leistungs_merkmale_0_titelundleistungs_merkmale_0_beschreibung. - Einträge für Zeile 1:
leistungs_merkmale_1_titelundleistungs_merkmale_1_beschreibung. - …sowie interne Referenzschlüssel für die Felddefinitionen (
_leistungs_merkmale_0_titel).
Für 10 Zeilen mit jeweils 3 Unterfeldern entstehen somit über 60 Zeilen in der Tabelle wp_postmeta. Bei unbedachter Nutzung in Schleifen kann dies zu spürbaren Verzögerungen führen, wenn WordPress viele Datenbankabfragen nacheinander absetzt.
Die Standard-Schleife: have_rows() und the_row()
Die empfohlene Methode zur Ausgabe eines Repeater-Felds nutzt die Funktionen have_rows() und the_row():
<?php if ( have_rows('leistungs_merkmale') ) : ?>
<section class="features-repeater-section">
<div class="container">
<div class="features-grid">
<?php while ( have_rows('leistungs_merkmale') ) : the_row();
$titel = get_sub_field('titel');
$text = get_sub_field('beschreibung');
$icon = get_sub_field('symbol');
?>
<div class="feature-card">
<?php if ( ! empty( $icon ) ) : ?>
<div class="feature-icon">
<?php echo wp_get_attachment_image( $icon['id'], 'thumbnail' ); ?>
</div>
<?php endif; ?>
<h3><?php echo esc_html( $titel ); ?></h3>
<div class="feature-body">
<?php echo wp_kses_post( $text ); ?>
</div>
</div>
<?php endwhile; ?>
</div>
</div>
</section>
<?php endif; ?>Wichtig: Verwenden Sie innerhalb der Repeater-Schleife niemals get_field(), sondern immer get_sub_field(). Nur get_sub_field() greift auf den internen Zeiger zu, der durch the_row() für die aktuelle Iteration gesetzt wurde.
Dynamisches Styling in PHP: Zähler und Modulo-Operator
Wenn Sie Zeilen basierend auf ihrer Position mit unterschiedlichen CSS-Klassen versehen oder HTML-Elemente umstellen möchten, liefert PHP präzise Kontrollmöglichkeiten.
Nutzung der integrierten Funktion get_row_index()
Anstatt vor der Schleife manuell eine Variable wie $i = 0; zu deklarieren und hochzuzählen, stellt ACF die Hilfsfunktion get_row_index() bereit. Sie liefert die Nummer der aktuellen Zeile zurück, beginnend bei 1:
<?php if ( have_rows('prozess_schritte') ) : ?>
<div class="timeline-container">
<?php while ( have_rows('prozess_schritte') ) : the_row();
$index = get_row_index();
$ist_gerade = ( $index % 2 === 0 );
$layout_klasse = $ist_gerade ? 'layout-reversed' : 'layout-standard';
?>
<article class="timeline-item <?php echo esc_attr( $layout_klasse ); ?>">
<div class="step-badge">Schritt 0<?php echo (int) $index; ?></div>
<div class="step-content">
<h3><?php echo esc_html( get_sub_field('schritt_titel') ); ?></h3>
<p><?php echo esc_html( get_sub_field('schritt_text') ); ?></p>
</div>
</article>
<?php endwhile; ?>
</div>
<?php endif; ?>Modulo-Muster im Praxiseinsatz
Der Modulo-Operator (%) ermittelt den mathematischen Rest einer Ganzzahldivision:
- Abwechselnde Zeilen (A/B-Muster):
$index % 2 === 0(jede gerade Zeile). - Hervorhebung jedes dritten Elements in einem Grid:
$index % 3 === 0(z.B. Premium-Karten). - Sonderbehandlung des ersten Elements:
$index === 1für einen dominanten Hero-Eintrag.
Styling im Stylesheet: Moderne CSS-Selektoren
Gute Webarchitektur trennt Struktur von Präsentation. Wann immer eine Designänderung rein visueller Natur ist (z.B. Hintergrundfarben, Ausrichtungen oder Abstände), sollte dies direkt im Stylesheet über CSS abgebildet werden. Dadurch bleibt das PHP-Markup schlank und wartungsfreundlich.
Pseudoklasse :nth-child()
Moderne CSS-Spezifikationen bieten extrem flexible Pseudoklassen:
/* Abwechselnde Hintergrundfarben für Zebra-Tabellen oder Zeilen */
.timeline-container .timeline-item:nth-child(even) {
background-color: #f1f5f9;
}
/* Flexbox-Richtung bei geraden Zeilen umkehren (Zick-Zack-Layout) */
.timeline-container .timeline-item:nth-child(even) {
flex-direction: row-reverse;
}
/* Jedes dritte Element im CSS Grid farblich hervorheben */
.features-grid .feature-card:nth-child(3n) {
border: 2px solid #0284c7;
box-shadow: 0 10px 25px -5px rgba(2, 132, 199, 0.1);
}
/* Das letzte Element der Liste gezielt ansprechen */
.timeline-container .timeline-item:last-child .divider-line {
display: none;
}Wann PHP unverzichtbar bleibt
Trotz der Stärke von CSS gibt es Fälle, in denen die PHP-Logik zwingend erforderlich ist:
- Unterschiedliche HTML-Elemente: Wenn ungerade Elemente ein
<section>-Tag und gerade Zeilen ein<aside>-Tag nutzen. - Dynamisches Einbinden von Sub-Templates: Wenn abhängig von der Position separate Template-Parts über
get_template_part()geladen werden. - Strukturierte Daten (Schema.org): Wenn für SEO-Zwecke numerische Positionsangaben in JSON-LD-Scripts ausgegeben werden müssen.
Performance-Optimierung bei großen Datenmengen
Wächst ein Repeater-Feld auf mehr als 30 bis 50 Zeilen an, kann die Ladezeit der Seite leiden. Da jedes get_sub_field() im Hintergrund Metadaten abfragt, steigen die CPU- und Speicherauslastung des PHP-Prozesses.
1. Alle Daten auf einmal mit get_field() laden
Statt der iterativen while(have_rows())-Schleife kann es bei sehr großen Datenmengen effizienter sein, das gesamte Repeater-Feld als verschachteltes PHP-Array einzulesen:
$alle_schritte = get_field('prozess_schritte');
if ( ! empty( $alle_schritte ) && is_array( $alle_schritte ) ) {
foreach ( $alle_schritte as $position => $schritt ) {
$titel = $schritt['schritt_titel'] ?? '';
$text = $schritt['schritt_text'] ?? '';
$nummer = $position + 1;
// Verarbeitung ohne wiederholte get_sub_field()-Funktionsaufrufe
}
}2. HTML-Ausgabe im Transients-Cache sichern
Wenn sich der Inhalt des Repeaters selten ändert, empfiehlt sich das Zwischenspeichern des fertig gerenderten HTML-Blocks mithilfe der WordPress Transients API:
function wppoland_render_prozess_cached( int $post_id ): void {
$cache_key = 'wppoland_prozess_html_' . $post_id;
$output = get_transient( $cache_key );
if ( false === $output ) {
ob_start();
if ( have_rows('prozess_schritte', $post_id) ) {
echo '<div class="timeline-container">';
while ( have_rows('prozess_schritte', $post_id) ) {
the_row();
// HTML-Ausgabe...
}
echo '</div>';
}
$output = ob_get_clean();
// 24 Stunden im Cache vorhalten
set_transient( $cache_key, $output, DAY_IN_SECONDS );
}
echo $output;
}
// Cache bei Beitragsaktualisierung invalidieren
add_action('save_post', function (int $post_id): void {
delete_transient('wppoland_prozess_html_' . $post_id);
});Mit dieser Architektur wird die Datenbankabfrage nur ein einziges Mal pro Tag ausgeführt; alle folgenden Besucher erhalten die fertige HTML-Struktur verzögerungsfrei aus dem Cache.
Häufig gestellte Fragen (FAQ)
Worin liegt der Unterschied zwischen get_row_index() und einem manuellen Zähler?
Sollte man für Farbwechsel eher PHP oder CSS verwenden?
Wie werden Bilder im Repeater-Feld performant ausgegeben?
Warum reagiert meine Seite bei vielen Repeater-Zeilen träge?
Fazit
Das ACF Repeater Field bietet Entwicklern die perfekte Balance zwischen redaktionellem Komfort und technischer Gestaltungsfreiheit. Durch die Kombination von have_rows(), der Indizierungsfunktion get_row_index() und modernen CSS-Selektoren lassen sich anspruchsvolle Layouts sauber und wartbar umsetzen.
Benötigen Sie Unterstützung bei der Entwicklung maßgeschneiderter WordPress-Themes mit Advanced Custom Fields oder möchten Sie Ihre bestehende Architektur auf maximale Geschwindigkeit optimieren? Entdecken Sie unsere Leistungen für professionelle WordPress-Entwicklung oder buchen Sie eine gezielte WordPress-Wartung.







