Skip to content

ACF compatibility ​

While ACF is active ​

While ACF (or ACF PRO, or Secure Custom Fields) is active, WP Freeform Fields leaves it alone:

  • ACF-named functions are not defined, and acf/… hooks are not fired;
  • acf-json folders are not read, and blocks whose block.json has only an acf key stay ACF's;
  • an admin notice explains how to finish the switch.

Without ACF ​

The compatibility layer is on. Turn it off with WPFF_ACF_COMPAT or the wpff/acf_compat filter.

  • Functions are defined on setup_theme, before the theme's functions.php. If the active theme bundles its own copy of ACF, they are not defined at all, so the theme's ACF can load (filter: wpff/theme_bundles_acf).
  • Hooks: each of these runs as wpff/… and then as acf/…, with ACF's arguments and /type=, /name=, /key= variants where ACF has them: init, include_fields, load_field, load_value, format_value, update_value, validate_value, prepare_field, load_field_groups, save_post, pre_save_post, submit_form, settings/{name}, fields/{post_object|relationship|page_link|taxonomy|user}/query, input/admin_enqueue_scripts. During acf/save_post, $_POST['acf'] holds the submitted values, as ACF callbacks expect.
  • Extra functions: get_field_objects(), acf_get_field(), acf_get_fields(), acf_get_field_group(), acf_get_field_groups(), acf_add_local_field(), update_sub_field(), delete_sub_field(), acf_esc_html(), acf_get_options_page(), acf_get_options_pages(), acf_form_head(), acf_form(). Their wpff_ versions: wpff_get_field_objects(), wpff_get_field_settings(), wpff_get_group_fields(), wpff_get_field_groups(), wpff_update_sub_field(), wpff_delete_sub_field().
  • Raw values (get_field( $name, $id, false ), get_fields( $id, false )) have ACF's shape: group, repeater and flexible content values are keyed by field keys, and empty rows are false.
  • Before migration, field groups and options pages saved in ACF's tables are read from there (read-only, source is acf). Turn it off with the wpff/read_acf_groups filter. The list is cached in a transient that changes when ACF's groups change.
  • ACF to REST API: while the acf-to-rest-api plugin is active and ACF is not, its acf/v3/{rest_base}/{id}[/{field}] and acf/v3/options/{id}[/{field}] routes and the acf property in wp/v2 are served from WP Freeform Fields. Only fields of the groups shown on the object are served, never other meta or options, and Password fields are left out. Posts, terms and users follow the core REST API's visibility rules. Options page fields need the page's capability unless their group is shown in REST; the wpff/acf_to_rest_api/public_options filter makes them public, as in the original. Filter: wpff/emulate_acf_to_rest_api.

Front-end forms ​

acf_form() takes ACF's settings: id, post_id ('new_post' with new_post args creates a post), field_groups, fields, post_title, post_content, return (%post_id%, %post_url%), html_before_fields, html_after_fields, submit_value, updated_message, honeypot, kses and others. Submissions are saved on template_redirect, so acf_form_head() is optional.

The form settings travel signed: a visitor cannot point the form at another post. As in ACF, the template decides who sees the form. Validation runs on the server, and rejected fields are highlighted on the returned page.

See also Known differences.

GPL-2.0-or-later. Not affiliated with ACF or WP Engine.