Change Default ACF Field Name
The Background
As you might know, I am pretty big on using Nuxt/Vue as a frontend and pulling the data from a WordPress backend. I could go into why I like to run things this way, but perhaps that’s time for another post. Anyway, I generally keep my WordPress backend pretty light and only put in custom coded stuff or use Advanced Custom Fields (ACF). That’s basically it. ACF is extremely powerful and flexible, and we can easily grab the data stored with it through the WP Rest API.
The weird thing about having a PHP-based backend with a JS-based frontend is that the code styles are different. For example, JS uses camel case for variables and function names while PHP will use underscores as a separator: functionName vs function_name. This makes things even weirder when you start to mix the two languages together by passing data from the API to the frontend and vice-versa. I prefer to take the approach of keeping my data in-line with where ever I am going to use it most. So for passing data to the frontend then I will stick with JS conventions and if the code is largely for the backend I will stick with PHP there.
The Problem
This all brings me to the way ACF defaults to saving the name field. When you are creating a new field and give it a label, ACF will create a name for that field based on what you have entered. This is really awesome. The problem, for my workflow, is that I am going to be primarily using this data on the frontend and ACF will make the name with underscores. It looks something like this by default:
Up until now, I have been changing these by hand to fit the JS convention, so for the example above I would manually rename it to testFieldName. This works fine, but I am a programmer and I like to be lazy 🙂 So let’s find a way to automate this.
The Solution
Luckily, the other day I stumbled across the JavaScript API docs that ACF has. It is really amazing stuff! If you are familiar with WordPress, then the gist of it is that they basically recreated the action and filter hook system with their JS code. This gives a lot of flexibility to do cool things (and here I am using it for something so bland haha!).
So, I dug through the plugin code and I found a filter that actually wasn’t listed in their documentation. I am not sure if that means it is unsafe to use or not, but I will take my chances. The filter is called generate_field_object_name. We can use this filter by calling the ACF addFilter function in some JS code. I went the easiest way possible (because I was just testing this out mainly) and added it to the admin_footer WordPress hook. So here we go, here is a snippet added into our trusty functions.php and I will explain it a bit more after.
<?php if ( ! function_exists( 'change_acf_default_field_name' ) ) { function change_acf_default_field_name() { ?> <script> acf.addFilter('generate_field_object_name', function(options, $select) { return options.split('_').map((word,index) => index !== 0 ? word.charAt(0).toUpperCase() + word.substr(1) : word).join(''); }); </script> <?php } add_action( 'admin_footer', 'change_acf_default_field_name' ); }
The Breakdown
Alright, so that’s the code snippet. It should be pretty straight-forward, but just in case it’s not. The global object that ACF uses for it’s JS functionality is the acf object. So we can invoke the addFilter function using this object. Once we do that, we pass in the filter we want to run our code through and add a callback function to alter our output. In our case, we pass the 2 parameters, but we really only need the options parameter. The options come in as a string that has already been sanitized and constructed by ACF, basically the full generated name has been created already and is being passed into our function, so now we can easily just alter it. We do some fancy JS chaining to remove all of the underscores and then capitalize the first letter of each word besides the first. Voila! Now your field names will save by default to a more JS friendly convention!
I hope you enjoyed the article, if you have questions feel free to reach out to me on Twitter.