There comes a time in a WordPress theme’s life where it has room to grow. Sometimes, a plugin will do the trick. Sometimes, you need to dig in and write your own PHP. Luckily, using the flexibility of WordPress, there are several ways to approach a custom admin button. A common approach is invoking a JavaScript function on click, then using AJAX to send a request to a PHP file. Though this is a nice solution, there are alternative ways to approach it.
In this article, I go over how to utilize ACF to create button(s) on any field group that send POST data. The process is fairly straightforward.
Here are the steps
-
Decide the best place for the button.
-
Hook up a JavaScript file with your admin button.
-
On click, append your inputs with optional data.
-
In a PHP file, look at the $_POST array and perform your logic.
From there, it’s up to you to add the logic you or your client wants. Setting it up is a multi-step process, but it’s not too much overhead and shouldn’t require any plugins. You technically don’t even need ACF to do this. However, I’ll use ACF as an example since it’s my favorite plugin. Let’s dig into it!
Where To Put the Admin Button(s)?
Technically, you can add buttons inside any
element. You can even use it outside of a form since we’re using JavaScript to append the <form>
elements. Where you end up placing the button depends on usability. Will this button update a certain part of the site? Will it change how backend admin functionality works?<input>
Let’s use an admin button that refreshes cached API data as an example. You want to refresh the cache of all testimonials on your site.
To refresh a single testimonial:
Place the admin button under each single testimonial. This is easily done with ACF by simple assigning a field to the testimonials post type.
To refresh all testimonials:
You can place an options page under the testimonials section of your admin sidebar. When that button is clicked in the global options page, you can add functionality to loop through each testimonial and refresh the cache on all of them.
if( function_exists('acf_add_options_page') ) { acf_add_options_sub_page(array( 'page_title' => 'Testimonial Global Options', 'menu_title' => 'Testimonial Global Options', 'parent_slug' => 'edit.php?post_type=testimonials', )); }
Buttons can now easily be added to this options subpage.
Adding a button globally:
To add a button globally, make a regular options page.
function my_custom_menu_page() { add_menu_page( 'My Options', // Page title 'My Options', // Menu title 'manage_options', // Capability 'my_custom_options', // Menu slug 'my_custom_options_page' // Callback function ); } add_action('admin_menu', 'my_custom_menu_page');
These are just examples. At the end of the day, you should make it easier for whoever will actually be using it. It might be a client, and not you. Think about what would be easiest for them.
Introducing the ACF Message Field
If you haven’t heard of the message field already, it’s a great way to add instructions under any field group. While not the prettiest solution, you should be able to add markup to it.
For a simple button, this option provides a lot of flexibility for placement. A simple button will look like this:
<div id="refresh-button-container"> <button type="button" class="button-secondary" id="refresh-cache">Refresh Testimonial Data </button> </div>
Using the message field, you can add this markup under any defined field group. So the button is in place.. now what?
Linking JavaScript to Your Admin Page
In order for the button to do anything.. it needs to perform an action on click. This obviously requires JavaScript, so let’s set that up. Doing so isn’t difficult and is already documented here.
We can use
to load a JavaScript file, but we only want to load it for the relevant admin page.admin_enqueue_scripts
add_action( 'admin_enqueue_scripts', function ($hook) { //only load this script for a certain URL page slug if($hook == 'your-url-page-slug') { $path = asset_path('scripts/admin.js'); wp_enqueue_script( 'textdomain/custom-admin-js', $path, ['jquery']); } } );
Here’s what’s happening: We’re using the
parameter admin_enqueue_scripts
$hook
to check which admin page to load the JavaScript. You can get a specific ACF page’s slug by checking the URL. It should be after the &page=
query parameter.
Once the conditional passes, simply enqueue the script like any other. I placed this in a file called admin.php
, but it can be loaded in your functions.php
file. You can also load it from your plugin files if you’re packaging this up into a separate plugin.
From your JS file, test to make sure everything is working.
import $ from 'jquery'; $(document).ready(function($) { console.log('Im working!'); });
Appending Data To Your Form Using JavaScript/jQuery
In the last example, we loaded the JavaScript file with jQuery as a dependency. However, this solution is simple enough to use vanilla JS, if preferred.
From here, it’s a two step process.
-
Add a click event listener to the admin button
-
Attach hidden input fields to the ACF element
Here’s the code to accomplish this:
import $ from 'jquery'; $(document).ready(function($) { Admin.init(); }); let Admin = { init() { this.setEventListeners(); }, setEventListeners() { $('#refresh-cache').click(Admin.refreshCache); }, refreshCache() { //attach hidden input then submit the form Admin.attachData(); $('#post').submit(); }, attachData() { let $buttonContainer = $('#refresh-button-container'); let inputField = '<input type="hidden" name="refresh-cache" value="1" />'; $buttonContainer.append(inputField); }, }
This is a basic example and only attaches a single input. Yours may need multiple pieces of data, so you could simply attach more
fields. Once the button is clicked, the JavaScript code will submit the form automatically. Once the form is submitted, the last step is to check the POST data that is sent through.<input>
Processing POST Data in Your PHP Files
Where you perform PHP logic depends on your theme’s file structure. I’d recommend performing the logic in a separate file outside of functions.php
, or even in its own packaged plugin. However you do it, the process is pretty straightforward.
//Here, we're only checking if the POST data has been sent through //so we can outsource the logic to the refreshCache function if($_POST['refresh-cache'] == 1) { refreshCache(); }
If you’re passing multiple bits of data, you should be able to access it using the $_POST
array.
if($_POST['refresh-cache'] == 1) { $exampleArg1 = $_POST['example_data']; $exampleArg2 = $_POST['more_example_data']; refreshCache($exampleArg1, $exampleArg2); }
From there, what logic you implement is up to you. That’s pretty much it! Have fun, and make something awesome.
Posted on
Very nicely described, thank you!
Posted on
You are very welcome!
More Posts
Using debounce in Vue.js templates
Learn how to easily add a custom button to your WordPress backend. In this post, I help you get up and running using ACF and JavaScript.
Read More
Converting jQuery Blog Post Component To Vanilla JS
Learn how to easily add a custom button to your WordPress backend. In this post, I help you get up and running using ACF and JavaScript.
Read More
[Demo] Defining Reusable Column Extends with SCSS
Learn how to easily add a custom button to your WordPress backend. In this post, I help you get up and running using ACF and JavaScript.
Read More
Let’s Learn Laravel Blade Layouts
Learn how to easily add a custom button to your WordPress backend. In this post, I help you get up and running using ACF and JavaScript.
Read More
Vue 3: Making An Input Component with v-model Support
Learn how to easily add a custom button to your WordPress backend. In this post, I help you get up and running using ACF and JavaScript.
Read More
[Tutorial] Implement Parenthesis Multiplication Using JavaScript & Regex
Learn how to easily add a custom button to your WordPress backend. In this post, I help you get up and running using ACF and JavaScript.
Read More