I am building a plugin, I created a new admin page and subpage, and inside that subpage, I want to add some Settings. That's why I'm building them using the Settings API.
I am using Composer and Object-Oriented Programming. I have a folder called SettingsAPI, with the following namespace namespace Blocks\Pages\SettingsAPI;
Inside that folder, I have three files: AddSettings.php
, Settings.php
and SettingsLayout.php
. All three of them are correctly connected. The files have the case-sensitive names of the Classes. Settings.php
has a Class named Settings
, and so on.
Content
- Some Context to my Structure
- What I have already tried
- What to do?
Some Context to my Structure
Inside Settings.php
I have a function that holds a variety of arrays, inside of those arrays are the values I want to use for the Settings API. This means I have arrays that are used for register_setting()
, add_settings_section()
and add_settings_field()
.
Inside AddSettings.php
I have the three functions just mentioned. Both register_settings()
and add_settings_field()
work great. I have problems with add_settings_field()
.
Inside SettingsLayout.php
I have a very simple layout for where the form should be printed, which is also shown on the Subpage. Just the inputs are missing.
Inside AddSettings.php
I used a foreach()
to loop over the array, if I need to. Which is used for both register_setting()
and add_settings_field()
, that's because both of those arrays have arrays inside of them. I'll show some code used for register_setting()
and the foreach()
.
Settings.php
$configs = [
[ // Icon
"option_group" => "iw_" . $n,
"option_name" => "iw_icon_" . $n,
"args" => $iconConfigs
],
[ // Titel
"option_group" => "iw_" . $n,
"option_name" => "iw_title_" . $n,
"args" => $titleConfigs
],
[ // Beschreibung
"option_group" => "iw_" . $n,
"option_name" => "iw_description_" . $n,
"args" => $descriptionConfigs
],
[ // Farbauswahl
"option_group" => "iw_" . $n,
"option_name" => "iw_colour_" . $n,
"args" => $colourConfigs
]
];
The array above is being passed, alongside the other arrays, to the AddSettings
Class and the next function that will process them.
$this->add_settings->setForm( $configs, $segments, $inputs )->register();
setForm()
does the following with the arguments.
AddSettings.php
public function setForm( array $configs, array $segments, array $inputs ) {
$this->settings = $configs;
$this->sections = $segments;
$this->fields = $inputs;
return $this;
}
The variables $settings
, $sections
and $fields
have been created at the beginning of the class as public and empty arrays.
public $settings = array();
public $sections = array();
public $fields = array();
Which then gets registered with the following function:
public function functionToAdd() {
return $this->registerForm($this->settings, $this->sections, $this->fields);
}
registerForm()
hold all the Settings API functions from WP, here is register_setting()
.
foreach( $this->settings as $setting ) {
register_setting( $setting["option_group"], $setting["option_name"], isset( $setting["args"] ) ? $setting["args"] : "" );
}
This part works great. It also works with add_settings_section()
. What doesn't work, are the inputs. Which I will present now as well:
Settings.php
Inside this Class is the function/method setForm( $n = NULL )
, that's where all the arrays are, like the one I showed above. Right now $n
has no meaning, but it's going to be a number, so I can loop all over those arrays and settings to create more forms. Whether I keep it at NULL
or I change it to 1
, has no effect on the end-result, same thing.
Here is the array for the fields.
$inputs = [
[
"id" => "iw_icon_" . $n,
"title" => "Icon Auswahl",
"callback" => function() use($n) { return $this->iconInput( $n ); },
"page" => "info_kreis_bearbeiten",
"section" => "iw_item_" . $n,
"args" => [ "label_for" => "iw_icon_" . $n ]
],
[
"id" => "iw_title_" . $n,
"title" => "Titel",
"callback" => function() use($n) { return $this->titleInput( $n ); },
"page" => "info_kreis_bearbeiten",
"section" => "iw_item_" . $n,
"args" => [ "label_for" => "iw_title_" . $n ]
],
[
"id" => "iw_description_" . $n,
"title" => "Kurz Beschreibung",
"callback" => function() use($n) { return $this->descriptionInput( $n ); },
"page" => "info_kreis_bearbeiten",
"section" => "iw_item_" . $n,
"args" => [ "label_for" => "iw_description_" . $n
],
[
"id" => "iw_colour_" . $n,
"title" => "Farbe auswählen",
"callback" => function() use($n) { return $this->colourInput( $n ); },
"page" => "info_kreis_bearbeiten",
"section" => "iw_item_" . $n,
"args" => [ "label_for" => "iw_colour_" . $n ]
]
];
So this is an array with three arrays inside of it. This array has callbacks, and it's the callbacks that do not work at all. No matter where I put them or how I write them, they are not being echo'd. At the bottom I will list all of the things I have tried.
Like with the settings arrays, they are allso processed like this:
$this->add_settings->setForm( $configs, $segments, $inputs )->register();
AddSettings.php
And then
public function setForm(array $configs, array $segments, array $inputs) {
$this->settings = $configs;
$this->sections = $segments;
$this->fields = $inputs;
return $this;
}
and
public function functionToAdd() {
return $this->registerForm($this->settings, $this->sections, $this->fields );
}
Which then gets passed to registerForm()
with the following function:
foreach( $this->fields as $field) {
add_settings_field( $field["id"], $field["title"], isset( $field["callback"] ) ? $field["callback"] : "", $field["page"], $field["section"] = 'default', $field["args"] = array() );
}
And then nothing. No inputs on my Subpage. Everything but the fields are being echo'd.
As you can see, the callback used by the section works and shows me the title and description. But the inputs are missing. To show some context on how I called the callback for the sections, here is the one line with the callback from the section array, inside Settings.php
:
"callback" => function() use($n) { echo "<p>Bearbeite hier die Info Nummer " . $n . "</p>"; }
And the function add_settings_section()
inside AddSettings.php
, no foreach()
was used for this one:
add_settings_section( $sections["id"], $sections["title"], isset( $sections["callback"] ) ? $sections["callback"] : "", $sections["page"] );
It's being called the same way like the fields. But the fields still do not echo anything. Any before anyone says I am echoing inside the anonymous callback function instead of returning another function:
What I have already tried
I have tried a few things. One of the first things I tried was to edit the way the callback is written. So instead of a function that returns another function I wrote something simple.
"callback" => function() { echo "Echo this please."; },
Didn't work.
"callback" => array( $this, "iconInput" ),
Also not working I also tried
"callback" => $this->iconInput( $n ),
Which then called the function and echo'd the inputs, but not in the right position. They were at the very top of the page. And if I loop everything, all inputs will be at the top, with the sections below in the right print order. So that's not the solution either.
What I also tried was to move the callback to AddSettings.php
and call it like that.
add_settings_field( $field["id"], $field["title"], function() { return $this->iconInput(); }, $field["page"], $field["section"] = 'default', $field["args"] = array() );
Didn't work either. When I tried to just directly write the function in there, like so
add_settings_field( $field["id"], $field["title"], function() { echo "Please echo this"; }, $field["page"], $field["section"] = 'default', $field["args"] = array() );
Didn't work either. I also always put die;
at the end, just to see if it's being called at all, and it has not been. It's like the function doesn't exist.
I have also tried to immediately run the function by adding ()
to it:
add_settings_field( $field["id"], $field["title"], isset( $field["callback"] ) ? $field["callback"]() : "", $field["page"], $field["section"] = 'default', $field["args"] = array() );
Same result like earlier. It echo'd the inputs, but not in the right position.
I tried looking for an answer, but couldn't really find one that was similar to mine. I found these questions and solution, tried them, and that also didn't work: How to pass arguments from add_settings_field() to the callback function? and Add_settings_field() parameterizing callback?
And for clarification, my SettingsLayout.php
is build like this:
<form method="post" action="options.php" id="iw_form_<?php echo $i?>">
<?php
settings_fields( "iw_" . $i );
do_settings_sections( "info_kreis_bearbeiten" );
submit_button( $text = NULL, $type = "primary", $name = "submit_" . $i );
?>
</form>
$i
is the same as $n
.
What to do?
I have run out of options to try. At least of options, I know of. If anyone has any kind of solution, I would be HAPPY to hear them. I also explained myself as best as I could.
Edit
Which I forgot to mention, inside my foreach()
I also echoed field["id"]
to see if that works, and it does echo the right ID.