One of the most versatile option Advanced Custom Fields (ACF) has is Flexible Contents. You can create all sort of things with it and it gives you much more control in creating a dynamic webpage.
Here are couple of screenshots from ACF Official Flexible Contents page.


Let’s try to print each field from the image above step by step.
First of all, you need to check if there is any contents in flexible contents field. Here’s how to do that:
// Check if the flexible content value exists.
if( have_rows('content') ):
...
...
endif;
If so, we need to use while loop to go through each flebile blocks:
// Check if the flexible content value exists.
if( have_rows('content') ):
// Loop through rows.
while ( have_rows('content') ) : the_row();
...
...
endwhile;
...
...
endif;
Now, we need to check each and every case for our desired layout and get the variables or print them.
// Check if the flexible content value exists.
if( have_rows('content') ):
// Loop through rows.
while ( have_rows('content') ) : the_row();
// Case: Paragraph layout.
if( get_row_layout() == 'paragraph' ):
$text = get_sub_field('text');
echo '' . $text . '
';
// Case: Download layout.
elseif( get_row_layout() == 'download' ):
$file = get_sub_field('file');
// Do something...
endif;
endwhile;
...
...
endif;
You can add group or a repeater blocks instead of simple variables too.
ACF advanced content blocks custom display flexible repeater