I came up with a solution that on the settings page will display all the names of flexible content layouts along with a checkbox where you can deselect layouts from the list when you click the Add button when you try to add a new layout.
As a brief introduction, I used acf-json to get all the flexible layout names, and then created another json file that contains the names of the layouts that I want to disable. Then I run a function that looks at each layout name, checks to see if it is in the disabled list, and if it is, it will be deleted.
To start, I initialized the local JSON in ACF. To do this, follow the steps https://www.advancedcustomfields.com/resources/local-json/ .
Then I created a new settings page in functions.php :
<?php function add_theme_menu_item() { add_options_page("Flexible Layouts", "Flexible Layouts", "manage_options", "flexible-layouts", "theme_settings_page", null, 99); } add_action("admin_menu", "add_theme_menu_item"); ?>
As part of the theme_settings_page function theme_settings_page you will need to decode JSON for a flexible content group:
<?php $jsonURL = get_template_directory_uri(). "/acf-json/flexible_content_group.json"; $contents = file_get_contents("{$jsonURL}"); $data = json_decode($contents); ?>
Then I did the same for the JSON file, which will contain all disabled fields (I will explain how this file is created in the near future):
<?php $jsonDisabledFieldsURL = get_template_directory_uri(). "/acf-json/disabledFields.json"; $disabledFieldsContents = file_get_contents("{$jsonDisabledFieldsURL}"); $disabledFieldsData = json_decode($disabledFieldsContents); ?>
Then I moved all the layout names to the $availableOptions array:
<?php $availableOptions = []; foreach($data->fields as $field) { foreach($field->layouts as $layout) { array_push($availableOptions, $layout->name); } } ?>
So, we need a list of all the fields with checkboxes and a submit button. Using the submit button, I used ajax to post disabled fields, which I put in an array:
<script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/js/lib/sweetalert2.js"></script> <script> jQuery('.submit_json_handler').click(function(e){ e.preventDefault(); var self = jQuery(this); var array = []; jQuery('input:checkbox:not(:checked)').each(function() { array.push(jQuery(this).val()); }); jQuery.ajax({ type:'POST', url:'<?php echo get_template_directory_uri(); ?>/acf-json/custom_json_handler.php', data: { 'disabled_fields' : array }, success:function(data){ console.log(data); swal( 'Success!', 'The active layouts have now been updated.', 'success' ) } }); }); </script>
I used the SweetAlert2 plugin ( https://sweetalert2.imtqy.com/ ) to process a success message when the fields were changed.
My code for custom_json_handler.php gets published disabled fields and pops them into an array. Then the array is encoded into the JSON file mentioned earlier (disabledFields.json):
<?php $disabledFields = $_POST['disabled_fields']; $disabledFieldsArray = []; try { foreach($disabledFields as $field) { array_push($disabledFieldsArray, $field); } $fp = fopen($_SERVER['DOCUMENT_ROOT']."/wp-content/themes/pblite-theme/acf-json/disabledFields.json","wb"); fwrite($fp,json_encode($disabledFieldsArray)); fclose($fp); } catch(Exception $e) { return $e; } echo "Success!"; ?>
The last piece of the puzzle in the theme_settings_page function is creating a form in which all layouts will be displayed, next to which there are flags that can be checked / unchecked based on the selected disabled fields:
<?php $activeLayouts = array_diff($availableOptions, $disabledFieldsData); echo "<form action=\"post\">"; echo "<table>"; foreach($data->fields as $field) { foreach($field->layouts as $layout) { if(in_array($layout->name, $activeLayouts)) { $checked = "checked"; } else { $checked = ""; } echo "<tr><td><input type=\"checkbox\" {$checked} name=\"disabled_flexible_layouts[]\" value=\"{$layout->name}\" /></td><td>{$layout->label}</td></tr>"; } } echo "</table>"; echo "<p class=\"submit\"><input type=\"button\" value=\"Submit\" name=\"submit\" class=\"button button-primary submit_json_handler\" /></p>"; echo "</form>"; ?>
This will give you a list of layouts in which disabled fields will be unchecked.
Finally, I needed to use disabled JSON fields to remove the list items in the "Add" button on the page where you select the layout. To do this, I created another function in functions.php that intercepts acf/input/admin_head (so the function will be funny if ACF is present):
<?php function acf_admin_head_layout( $field ) { ?> <script type="text/javascript"> (function($) { $(document).ready(function(){ $.get('<?php echo get_template_directory_uri(); ?>/acf-json/disabledFields.json', function(data) { </script> <?php } add_action('acf/input/admin_head', 'acf_admin_head_layout', 10, 1); ?>
This will find the class on the page where the line contains layout options, converts it to HTML so that we can manipulate the contents and store it in a temporary variable. Then we scroll through each of the disabled fields that were present in the JSON file and try to find a match in the data-layout attribute, and if there is a match, then the cabinet list item (it's parent) will be deleted.
Then we need to add the <script> tags back and return back to the page so that the new cleared list is used, not the old one.
Once all this is done, you should have an area in your settings menu where you have all your layouts that you can enable / disable. Then you can add / edit the page and select the Add button, and you should see only the layouts that you selected on the settings page.