I've made quite an extensive page.php using ACF-repeaters and the flexible content module (1000+ lines of code). The code is getting really spaghetti-like, and I'm not sure how to structure it so it's easier to read and maintain.

Here's a pseudo-code-version of it:

$all_fields = get_fields(); 
foreach( $all_fields as $field ):
  if( $field == 'field_1' ):
    // Deal with field_1
  elseif( $field == 'field_2' ):
    // Deal with field_2
  elseif( $field == 'field_3' ):
    // Deal with field_3
  ... etc.
  ... etc.

Now I'm facing a challenge that will require me to structure the code better; I will need another page-template (page-foobar.php), that includes the same ACF-code as shown above.

On the one hand side, then I thought about making this whole thing into a (or several) functions and then sticking it in functions.php. But then I'm polluting the functions.php-file, which would suck.

Ideally, I would do this 'the WordPress way', if there is such a thing for what I'm doing, but I haven't heard of such a thing. So if there isn't one, - then I'd prefer to have a folder in my theme called 'acf-modules', and then a file for each field, containing a function like this:

function field_1( $field_information ){
  // Deal with $field_information

But should I then make an action in functions.php, requiring each file upon WordPress' init-hook? Is that really the cleanest/best way to do this?

2 Answers 2


Well, structuring is partly a matter of taste, but it in this case it seems to be a good idea to include all the functions in a separate file. That includes the code that you would have in both template files. And rather than the chain of elseif you could use PHP's switch statement. So you would have:

In your functions.php (just plain, not depending on a hook)

require_once (get_template_directory() . '/field-functions.php');

In your template files

deal_with_fields ();

In your field-functions.php

function deal_with_fields () {
  $all_fields = get_fields (); 
  foreach ($all_fields as $field) {
    switch ($field) {
      case 'field_1' : deal_with_field_1 ($field); break;
      case 'field_2' : deal_with_field_2 ($field); break;

function deal_with_field_1 ($field) {
  do your thing;

function deal_with_field_2 ($field) ....    
  • I've just implemented that. And it works! However... In order to output HTML from inside one of those 'deal_with_field_X'-functions, then I need to echo it. So I would like to be able to write it like this: <?php if( 1 < 3 ): ?><p>Yay!</p><?php endif; ?> ... But I currently have to write it like this: <?php if( 1 < 3 ): echo '<p>Yay!</p>'; endif; ?> ... ?
    – Zeth
    Nov 8, 2018 at 3:34
  • That´s how it goes. Template files are evaluated as html, interrupted by php-calls. Once you're in the PHP-domain, the only way to port things back to the html-domain is to echo it. You cannot have plain html in a functions file. WP wouldn't know what to do with it.
    – cjbj
    Nov 8, 2018 at 8:13

I just ran into the same problem again. Last time, I solve it using @cjbj's answer. This time I did something smarter, easier to deal with.

The downside of cjbj's answer is, that if you want a rendered file, then the functions deal_with_field_1 and deal_with_field_2 doesn't really work (unless you include something inside them or does a echo file_get_contents(...).

What I did this time, was to have a switch-function in my functions.php and then keep all the sections in seperate files in a folder in the theme.

The switch-function looks like this:

function custom_acf_sections( $acf_sections ){
  foreach( $acf_sections as $section ){
    switch( $section['acf_fc_layout'] ){
      case "section_1":
        include( $_SERVER['DOCUMENT_ROOT'] . '/wp-content/themes/THEMENAME/acf-sections/section_1.php' );
      case "section_2":
        include( $_SERVER['DOCUMENT_ROOT'] . '/wp-content/themes/THEMENAME/acf-sections/section_2.php' );
      case "section_3":
        include( $_SERVER['DOCUMENT_ROOT'] . '/wp-content/themes/THEMENAME/acf-sections/section_3.php' );

It's almost the same as @cjbj's answer, - but I didn't figure it out until I had the same problem for the second time. So I figured I would share my solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.