After a lot of research, I found two approaches for writing WP option pages with code.
METHOD 1:
This style is declarative.
VIA https://presscoders.com/wordpress-settings-api-explained/
PROS:
CONS:
<?php
// SETTINGS STUFF
// Specify Hooks/Filters
register_activation_hook(__FILE__, 'add_defaults_fn');
add_action('admin_init', 'sampleoptions_init_fn');
add_action('admin_menu', 'sampleoptions_add_page_fn');
// Define default option settings
function add_defaults_fn()
{
//this is grabbing the values from the database.
$tmp = get_option('plugin_options');
if (($tmp['chkbox1'] == 'on') || (!is_array($tmp))) {
$arr = array(
"dropdown1" => "Orange",
"text_area" => "Space to put a lot of information here!",
"text_string" => "Some sample text",
"pass_string" => "123456",
"chkbox1" => "",
"chkbox2" => "on",
"option_set1" => "Triangle");
update_option('plugin_options', $arr);
}
}
// Register our settings. Add the settings section, and settings fields
function sampleoptions_init_fn()
{
register_setting('plugin_options', 'plugin_options', 'plugin_options_validate');
add_settings_section('main_section', 'Main Settings', 'section_text_fn', __FILE__);
add_settings_field('plugin_text_string', 'Text Input', 'setting_string_fn', __FILE__, 'main_section');
add_settings_field('plugin_text_pass', 'Password Text Input', 'setting_pass_fn', __FILE__, 'main_section');
add_settings_field('plugin_textarea_string', 'Large Textbox!', 'setting_textarea_fn', __FILE__, 'main_section');
add_settings_field('plugin_chk2', 'A Checkbox', 'setting_chk2_fn', __FILE__, 'main_section');
add_settings_field('radio_buttons', 'Select Shape', 'setting_radio_fn', __FILE__, 'main_section');
add_settings_field('drop_down1', 'Select Color', 'setting_dropdown_fn', __FILE__, 'main_section');
add_settings_field('plugin_chk1', 'Restore Defaults Upon Reactivation?', 'setting_chk1_fn', __FILE__, 'main_section');
}
// Add sub page to the Settings Menu
function sampleoptions_add_page_fn()
{
add_options_page('Options Example Page', 'Options Example', 'administrator', __FILE__, 'options_page_fn');
}
// ************************************************************************************************************
// Callback functions
// Section HTML, displayed before the first option
function section_text_fn()
{
echo '<p>Below are some examples of different option controls.</p>';
}
// DROP-DOWN-BOX - Name: plugin_options[dropdown1]
function setting_dropdown_fn()
{
$options = get_option('plugin_options');
$items = array("Red", "Green", "Blue", "Orange", "White", "Violet", "Yellow");
echo "<select id='drop_down1' name='plugin_options[dropdown1]'>";
foreach ($items as $item) {
$selected = ($options['dropdown1'] == $item) ? 'selected="selected"' : '';
echo "<option value='$item' $selected>$item</option>";
}
echo "</select>";
}
// TEXTAREA - Name: plugin_options[text_area]
function setting_textarea_fn()
{
$options = get_option('plugin_options');
echo "<textarea id='plugin_textarea_string' name='plugin_options[text_area]' rows='7' cols='50' type='textarea'>{$options['text_area']}</textarea>";
}
// TEXTBOX - Name: plugin_options[text_string]
function setting_string_fn()
{
$options = get_option('plugin_options');
echo "<input id='plugin_text_string' name='plugin_options[text_string]' size='40' type='text' value='{$options['text_string']}' />";
}
// PASSWORD-TEXTBOX - Name: plugin_options[pass_string]
function setting_pass_fn()
{
$options = get_option('plugin_options');
echo "<input id='plugin_text_pass' name='plugin_options[pass_string]' size='40' type='password' value='{$options['pass_string']}' />";
}
// CHECKBOX - Name: plugin_options[chkbox1]
function setting_chk1_fn()
{
$options = get_option('plugin_options');
if ($options['chkbox1']) {
$checked = ' checked="checked" ';
}
echo "<input " . $checked . " id='plugin_chk1' name='plugin_options[chkbox1]' type='checkbox' />";
}
// CHECKBOX - Name: plugin_options[chkbox2]
function setting_chk2_fn()
{
$options = get_option('plugin_options');
if ($options['chkbox2']) {
$checked = ' checked="checked" ';
}
echo "<input " . $checked . " id='plugin_chk2' name='plugin_options[chkbox2]' type='checkbox' />";
}
// RADIO-BUTTON - Name: plugin_options[option_set1]
function setting_radio_fn()
{
$options = get_option('plugin_options');
$items = array("Square", "Triangle", "Circle");
foreach ($items as $item) {
$checked = ($options['option_set1'] == $item) ? ' checked="checked" ' : '';
echo "<label><input " . $checked . " value='$item' name='plugin_options[option_set1]' type='radio' /> $item</label><br />";
}
}
// Display the admin options page
function options_page_fn()
{
?>
<div class="wrap">
<div class="icon32" id="icon-options-general"><br></div>
<h2>My Example Options Page</h2>
Some optional text here explaining the overall purpose of the options and what they relate to etc.
<form action="options.php" method="post">
<?php settings_fields('plugin_options'); ?>
<?php do_settings_sections(__FILE__); ?>
<p class="submit">
<input name="Submit" type="submit" class="button-primary" value="<?php esc_attr_e('Save Changes'); ?>" />
</p>
</form>
</div>
<?php
}
// Validate user data for some/all of your input fields
function plugin_options_validate($input)
{
// Check our textbox option field contains no HTML tags - if so strip them out
$input['text_string'] = wp_filter_nohtml_kses($input['text_string']);
return $input; // return validated input
}
Method 2:
Object Oriented way
VIA https://www.twilio.com/blog/build-custom-wordpress-plugin-send-sms-twilio-programmable-messaging
PROS:
CONS:
<?php
class Sendex
{
// 1 - identify the name of the plugin
public $pluginName = "sendex";
public $pluginSettingsName = "sendex-settings-page";
// 2 - Create the Form's UI
// and name the page
public function displaySendexSettingsPage()
{
?>
<form method="POST" action="options.php">
<?php
settings_fields($this->pluginName);
// do_settings_sections('sendex-settings-page');
do_settings_sections($this->pluginSettingsName);
submit_button();
?>
</form>
<?php
}
// 3 - Add it to WordPress, so it can be seen as a option
public function addSendexAdminOption()
{
add_options_page(
"SENDEX SMS PAGE",
"SENDEX",
"manage_options",
$this->pluginName,
[$this, "displaySendexSettingsPage"]
);
}
// 4 - Register the fields
// Also so when we hit save, it saves it in the WP Database
public function sendexAdminSettingsSave()
{
register_setting(
$this->pluginName,
$this->pluginName,
[$this, "pluginOptionsValidate"]
);
// adds a section with a description.
// add_settings_section( string $id, string $title, callable $callback, string $page )
add_settings_section(
"sendex-main",
"Main Settings",
[$this, "sendexSectionText"],
$this->pluginSettingsName,
);
// adds the field itself
// add_settings_field( string $id, string $title, callable $callback, string $page,
// string $section = 'default', array $args = array() )
add_settings_field(
"api_sid",
"API SID",
[$this, "sendexSettingSid"],
$this->pluginSettingsName,
"sendex-main"
);
add_settings_field(
"api_auth_token",
"API AUTH TOKEN",
[$this, "sendexSettingToken"],
$this->pluginSettingsName,
"sendex-main"
);
}
//
public function sendexSectionText()
{
echo '<h3 style="text-decoration: underline;">Edit api details</h3>';
}
/**
* Renders the sid input field
* @since 1.0.0
*/
public function sendexSettingSid() {
$options = get_option($this->pluginName);
echo "
<input
id='$this->pluginName[api_sid]'
name='$this->pluginName[api_sid]'
size='40'
type='text'
value='{$options['api_sid']}'
placeholder='Enter your API SID here'
/>
";
}
/**
* Renders the auth_token input field
*/
public function sendexSettingToken() {
$options = get_option($this->pluginName);
echo "
<input
id='$this->pluginName[api_auth_token]'
name='$this->pluginName[api_auth_token]'
size='40'
type='text'
value='{$options['api_auth_token']}'
placeholder='Enter your API Auth Token here'
/>
";
}
public function pluginOptionsValidate($input) {
$newinput["api_sid"] = trim($input["api_sid"]);
$newinput["api_auth_token"] = trim($input["api_auth_token"]);
return $newinput;
}
}
Method 3:
Advance Custom Fields (ACF) Way
Via https://www.advancedcustomfields.com/resources/options-page/
PROS:
CONS: