Exciting news! We're joining GoDaddy ➡️
WP Development

This short article covers one way of creating hidden fields with the WordPress Settings API. This is useful for more than just creating hidden input fields; for instance I used it when I wanted to render a number of checkboxes in a single field, yet still have the checkbox options managed by the Settings API.

The WordPress Settings API

The WordPress Settings API is a great, if poorly documented addition to WordPress. The two best references I found for understanding and building your own API-based settings are:

Luckily those two articles cover the basics of the Settings API so well that I won’t have to, and can focus on this one specific case.

Adding a Hidden Field

Again, the reason I even wanted to add a hidden field to a Settings page was because I wanted to display a number of checkboxes all within a single field. I did this with a callback passed to the add_settings_field() function, like so:

add_settings_field(

  'checkbox-1',               // unique id
  'Checkboxes',               // field title
  'multiple_checkboxes_html', // display callback
  'my_plugin',                // page name (same as call to do_settings_sections())
  'my_plugin_config'          // settings section (same as 1st arg to add_settings_section())
);

function multiple_checkboxes_html() {

  for ( $i = 2; $i <= 5; $i++ ) {

    if ( $i == 0 ) echo 'Check some boxes
'; echo '<input id="my_plugin_options_checkbox_' . $i . '" name="my_plugin_options_[checkbox-' . $i . ']" type="checkbox" value="1" ' . checked( $this->settings['checkbox-' . $i], 1, false ) . ' />'; echo ' <label for="my_plugin_options_checkbox_' . $i . '">Checkbox ' . $i . '</label>'; if ( $i < 5 ) echo '<br />'; } }

Unfortunately for me that function is meant to be called for every field managed by the Settings API, so I had to then call it for every checkbox that I had already rendered:

for( $i = 2; $i <= 5; $i++ ) {

  add_settings_field(

    'checkbox-' . $i,  // unique id
    null,              // field title
    null,              // display callback
    'my_plugin',       // page name (same as call to do_settings_sections())
    'my_plugin_config' // settings section (same as 1st arg to add_settings_section())
  );
}

This allows the checkboxes to be managed, however even with null passed for the render callback, an empty line is created for each call to add_settings_field(), creating a lot of unsightly whitespace in the settings page.

My solution was to define a simple render function that hides the current row via a javascript call, allowing me to make the required call to add_settings_field():

function hidden_row_html( $args ) {

  echo '<span id="hide-' . $args['name'] . '"></span>';
  echo "<script type="text/javascript">jQuery('#hide-{$args['name']}').parents('tr').hide();</script>";
}

for( $i = 2; $i <= 5; $i++ ) {

  add_settings_field(

    'checkbox-' . $i,   // unique id
    null,               // field title
    'hidden_row_html',  // display callback
    'my_plugin',        // page name (same as call to do_settings_sections())
    'my_plugin_config', // settings section (same as 1st arg to add_settings_section())
     array( 'name' => 'checkbox-' . $i )  // pass a unique name to the callback
  );
}

This hides those extra empty rows and keeps my settings form looking a lot neater. I'd be curious if anyone else has needed this sort of behavior and came up with a different solution, if you have, leave a comment!

Published by Justin Stern

Justin is one of our co-founders, and is our resident overengineer. He likes to write developer tutorials and make black magic happen in our plugins. He thinks that writing code is a lot easier than writing words.