🎉 USE O CUPOM FIM.DE.SEMANA.FULL | 20% OFF acima de R$ 100,00

Como corrigir o erro de loop em Repeater aninhado no ACF PRO

Time Full Services Time Full Services
Tipo Page Builders
Nome do erro Loop infinito em Repeater aninhado do ACF PRO EN: ACF PRO nested repeater infinite loop
Severidade Atenção
Descrição O erro de loop em Repeater aninhado no ACF PRO acontece quando um have_rows de um Repeater filho e percorrido sem chamar the_row, ou quando o nome do sub campo não casa, gerando loop infinito com tela branca ou nenhuma linha exibida.

O que é loop em Repeater aninhado no ACF PRO?

O loop em Repeater aninhado no ACF PRO e o padrão de código usado para exibir um Repeater colocado dentro de outro Repeater, como uma lista de serviços onde cada serviço tem vários itens. Para isso o ACF usa o par have_rows e the_row: o have_rows abre o loop e devolve verdadeiro enquanto houver linhas, e o the_row avanca para a próxima linha e move o ponteiro interno do ACF para aquela linha. Dentro de cada linha do Repeater pai você abre um novo have_rows com o nome do Repeater filho e repete o ciclo.

O problema surge quando esse ciclo e quebrado no nível aninhado. Segundo a documentação oficial do ACF, usar have_rows sem chamar the_row cria um loop infinito que resulta em tela branca, e o escopo de um loop have_rows e limitado a linha atual, ou seja, get_sub_field e the_sub_field so enxergam os dados da iteracao corrente. Quando o the_row do filho e esquecido, o nome do sub Repeater esta errado ou o have_rows do pai e do filho se confundem, o resultado e loop infinito, linhas duplicadas ou um Repeater filho que nunca aparece.

Como identificar

  • A página abre em branco (White Screen of Death) ou trava ao carregar um template que percorre um Repeater dentro de outro Repeater.
  • O log de erros registra esgotamento de memória, com mensagem ‘Fatal error: Allowed memory size of X bytes exhausted’, causado pelo loop que nunca termina.
  • O Repeater pai exibe as linhas, mas o Repeater filho aninhado não mostra nenhum item, mesmo havendo dados salvos no campo.
  • Os itens do Repeater filho aparecem repetidos ou misturados entre as linhas do pai, em vez de respeitar cada linha.
  • get_sub_field do campo aninhado retorna vazio ou nulo dentro do loop interno, apesar de o campo estar preenchido no editor.
Antes de começar: Antes de editar arquivos de template do tema ou ativar o WP_DEBUG em producao, faça backup completo do site (arquivos e banco) ou teste em staging. Um loop infinito de have_rows derruba a página inteira, entao garanta um caminho de reversao rápido.

Como prevenir

  • Sempre escreva o the_row() na mesma linha do while( have_rows(…) ) para nunca esquecer e evitar o loop infinito que a doc do ACF descreve.
  • Indente e comente cada nível do Repeater aninhado, deixando claro qual have_rows pertence ao pai e qual pertence ao filho, evitando trocar os nomes dos campos.
  • Mantenha get_sub_field e the_sub_field sempre dentro do while do nível correspondente, respeitando o escopo limitado a linha atual.
  • Teste o template com um post que tenha várias linhas no pai e no filho em staging antes de subir, para flagrar duplicacao ou linhas filhas ausentes.

Causa

  • O while( have_rows('repeater_filho') ) do Repeater aninhado não chama the_row() dentro do laco; a documentação oficial do ACF afirma que usar have_rows sem the_row cria um loop infinito com tela branca.
  • O have_rows do Repeater filho recebe o nome do Repeater pai (ou o nome do sub campo errado), entao o ACF reabre o loop do pai dentro do laco e o ponteiro nunca chega ao fim, repetindo as linhas indefinidamente.
  • O get_sub_field do campo aninhado e chamado fora do while do Repeater filho, fora do escopo da linha atual, e por isso retorna vazio, já que o escopo do have_rows e limitado a linha corrente.
  • O the_row() do loop pai foi esquecido antes de abrir o have_rows do filho, fazendo o ACF buscar o sub Repeater sem uma linha pai ativa e não encontrar as linhas filhas.
  • Um have_rows aninhado e iniciado dentro do mesmo Repeater (mesmo nome em pai e filho por copia de código), criando recursao sobre o próprio campo e estourando a memória do PHP.

Como resolver

  1. Faça backup e abra o template em staging: Antes de mexer no código, copie o arquivo do tema que percorre os Repeaters (por exemplo single.php, page.php ou um template de bloco) e trabalhe em um ambiente de teste. Um loop infinito derruba a página inteira, entao reverter precisa ser simples.
    Acesse o site por FTP ou pelo gerenciador de arquivos da hospedagem
    Abra o template do tema que renderiza o Repeater (ex.: wp-content/themes/seu-tema/single.php)
  2. Garanta um the_row() em cada nível do loop: Confirme que tanto o while do Repeater pai quanto o while do Repeater filho chamam the_row() logo após o have_rows. A documentação do ACF e explicita: have_rows sem the_row gera loop infinito e tela branca. Cada nível aninhado precisa do seu próprio par have_rows e the_row.
    while( have_rows('repeater_pai') ) : the_row();
    while( have_rows('repeater_filho') ) : the_row();
  3. Use o nome do sub campo correto no loop filho: O have_rows interno deve receber o nome do Repeater filho exatamente como aparece no grupo de campos, e não o nome do pai. Nome errado faz o ACF reabrir o loop do pai e repetir as linhas. Confira o nome em ACF -> Grupos de Campos abrindo o sub campo do tipo Repeater.
    Painel WP -> ACF -> Grupos de Campos -> abra o sub Repeater e copie o Nome do campo
    Use esse nome dentro do loop pai: while( have_rows('nome_do_sub_repeater') ) : the_row();
  4. Acesse os sub campos dentro do escopo da linha: Chame get_sub_field e the_sub_field somente dentro do while correspondente, pois o escopo do have_rows e limitado a linha atual. Acessar o sub campo do filho fora do laco interno retorna vazio. No nível do pai use get_sub_field do pai; no nível do filho use get_sub_field do filho.
    Dentro do while do filho: $valor = get_sub_field('campo_do_filho');
    Para imprimir direto: the_sub_field('campo_do_filho');
  5. Recarregue a página e confira o log de erros: Limpe qualquer cache de página, recarregue o template corrigido e verifique se as linhas filhas aparecem por linha do pai. Se ainda houver tela branca, abra o debug.log para confirmar que o esgotamento de memória do loop infinito desapareceu.
    Defina WP_DEBUG e WP_DEBUG_LOG como true no wp-config.php para gravar o log
    Abra wp-content/debug.log e procure por 'Allowed memory size' após recarregar
PHP
<?php
// Loop correto de um Repeater dentro de outro Repeater no ACF PRO.
if ( have_rows( 'servicos' ) ) :
    while ( have_rows( 'servicos' ) ) : the_row();

        // Sub campo do nivel pai (escopo = linha atual do pai).
        $titulo = get_sub_field( 'titulo' );
        echo '<h3>' . esc_html( $titulo ) . '</h3>';

        // Repeater filho: nome do sub campo + the_row() obrigatorio.
        if ( have_rows( 'itens' ) ) :
            echo '<ul>';
            while ( have_rows( 'itens' ) ) : the_row();
                // Sub campo do filho lido dentro do laco interno.
                $item = get_sub_field( 'nome_item' );
                echo '<li>' . esc_html( $item ) . '</li>';
            endwhile;
            echo '</ul>';
        endif;

    endwhile;
endif;

Perguntas frequentes

Por que meu Repeater dentro de Repeater no ACF da tela branca
Quase sempre porque o while do Repeater filho chama have_rows sem o the_row. A documentação oficial do ACF afirma que usar have_rows sem the_row cria um loop infinito que resulta em tela branca. Adicione the_row logo após o have_rows em cada nível do loop.
Como percorrer um Repeater aninhado no ACF PRO corretamente
Abra o while( have_rows('repeater_pai') ) : the_row(); e, dentro dele, abra outro while( have_rows('repeater_filho') ) : the_row();. Cada nível precisa do seu próprio par have_rows e the_row, e os sub campos são lidos com get_sub_field dentro do laco correspondente.
Por que o Repeater filho não mostra nenhum item
Em geral o nome passado ao have_rows interno esta errado ou o get_sub_field foi chamado fora do while do filho. Como o escopo do have_rows e limitado a linha atual, acessar o sub campo fora do laco retorna vazio. Confirme o nome do sub Repeater em ACF -> Grupos de Campos.
Posso usar o mesmo nome de campo no Repeater pai e no filho
Não e recomendado. Se o have_rows do filho receber o mesmo nome do pai, o ACF reabre o loop do pai dentro do laco e gera recursao, repetindo linhas ou estourando a memória. Use nomes distintos para o Repeater pai e o sub Repeater.
Qual a diferenca entre get_sub_field e the_sub_field no loop aninhado
get_sub_field retorna o valor do sub campo da linha atual para você manipular em PHP, enquanto the_sub_field imprime o valor direto na tela. Ambos so funcionam dentro do while do nível correspondente, pois o escopo do have_rows e a linha corrente.
Preciso usar get_row_layout em Repeater aninhado
Não para Repeater simples. get_row_layout serve para campos Flexible Content, onde cada linha tem um layout diferente. Para um Repeater dentro de outro Repeater, basta o ciclo have_rows, the_row e get_sub_field em cada nível.
O que fazer se o log mostra esgotamento de memória nesse loop
O esgotamento de memória e sintoma do loop infinito. Verifique se todo while have_rows tem the_row e se os nomes de campo do pai e do filho estão corretos. Corrigido o ciclo, o loop termina e o erro de memória desaparece, sem precisar aumentar o limite de PHP.

Seja PRO.

Tenha acesso a snippets de código premium — PHP, JavaScript, CSS e HTML prontos para usar em seus projetos.

Conhecer o plano Pro →

Uma nova era para o WordPress.

A FULL Services redefine o CMS com uma arquitetura modular que transforma o WordPress em um motor de crescimento digital. 

Painéis personalizados

Um novo nível de controle para o WordPress. Acompanhe métricas, automações e evolução do seu site em um único painel visual.

A força por trás de grandes marcas

Para agências, estúdios e profissionais independentes que desejam oferecer soluções de alto nível com sua própria marca.

Componentes

Hero Sections

30 componentes

Seções de CTA

14 componentes

Login

14 componentes

Blog

14 componentes

Cabeçalhos

24 componentes

Seções de FAQ

53 componentes

Cadastro

53 componentes

Blog individual

53 componentes

Rodapés

28 componentes

Seções de contato

27 componentes

Seções de preços

27 componentes

Faixas

27 componentes

Portfólio

16 componentes

Seções de equipe

12 componentes

Números

12 componentes

Logotipos

12 componentes