Support

Account

Home Forums Feature Requests Filter for flexible content layouts Reply To: Filter for flexible content layouts

  • The examples above were very helpful in guiding me to the solution I’ve landed on. Wanted to share in case it’s helpful for anyone else…

    In my functions.php, I define a constant that maps ACF flexible content layout names to arrays of allowed types and allowed (or blocked) IDs. Obviously the field’s display rules will override this. Note that if you’re using older versions of PHP, you’ll need to serialize and unserialize this array.

    define('ADMIN_ACF_LAYOUTS', [
        // show on all pages and posts
        'intro' => ['page', 'post'], 
        // show only on pages
        'testimonials' => ['page'], 
        // show on a specific page / post ID
        'faq' => [7],
        // show only on campsite post types and a specific page ID 
        // Example: "Our Campsites" page
        'map' => ['campsite', 12],
        // show on all pages *except* page ID 15 (note negative ID)
        'callouts' => ['page', -15],
    ]);

    In whatever file you prefer to define filters, replacing YOUR_ACF_FIELD_NAME with your specific Flexible Content field name:

    add_filter('acf/prepare_field/name=YOUR_ACF_FIELD_NAME', function($field) {
    
        global $post;
    
        // get the layout mapping, or an empty array 
        // just in case it's not defined
        $mapping = defined('ADMIN_ACF_LAYOUTS') ? ADMIN_ACF_LAYOUTS : [];
    
        // from John Huebner's clever approach...
        $layouts = $field['layouts'];
        $field['layouts'] = [];
    
        foreach ($layouts as $layout) {
    
            $key = $layout['name'];
    
            // if the layout name isn't in our mapping array
            // assume it available for all posts that the field rules allow
            if ( ! array_key_exists($key, $mapping)) {
                $field['layouts'][] = $layout;
                continue;
            }
    
            $allow_type = in_array($post->post_type, $mapping[$key]);
            $allow_id = in_array($post->ID, $mapping[$key]);
            $block_id = in_array(-1 * $post->ID, $mapping[$key]);
    
            // enable the layout if the current post type or post ID is allowed 
            // and the current ID is not explicitly excluded (note negative ID)
            if (($allow_type || $allow_id) && !$block_id) {
                $field['layouts'][] = $layout;
            }
        }
    
        return $field;
    });

    Hope this helps!