Below is my code for a simple plugin settings page. It works and saves an option ("EN", "CZ").

However, what I intend to do is run a function after the options get saved (see at the very bottom). I use this wordpress function for it:

do_action( "update_option_{$option}", mixed $old_value, mixed $value, string $option )

Funnily enough, the very same code did work last week; right now, anything I try to echo inside the function just doesn't get printed, so I assume the function doesn't even start running.

Could anyone please point me in the right direction here?

add_action( 'admin_menu', 'cmi_csv_import_plugin_page' );

// tick
function cmi_csv_import_plugin_page() {
        'CSV Import - PUDR', // page <title>Title</title>
        'CSV Import', // menu link text
        'manage_options', // capability to access the page
        'cmi-csv-import', // page URL slug
        'cmi_csv_page_content', // callback function /w content
        5 // priority

function cmi_csv_page_content () {
    <div class="wrap">
        <h2>Import CSV</h2>
        <form action="options.php" method="post">
        // this is what the setting is called and how you retrieve the option later! (with get_options)
        settings_fields( 'cmi_lang' );
        // slug name of the page whose settings sections you want to output
        // Use this in a settings page callback function to output all the 
        // sections and fields that were added to that $page with add_settings_section() and add_settings_field()
        do_settings_sections( 'cmi-csv-import' );
        submit_button( 'Aktualizovat metadata', 'primary' );


// add an action on admin init
add_action ('admin_init', 'cmi_csv_admin_init');

function cmi_csv_admin_init () {
    // a/ register settings
    $args = array(
        'type' => 'string',
        // ↓ callable
        'sanitize_callback' => 'cmi_csv_validate_options',
        'default' => NULL
    register_setting ('cmi_lang', 'cmi_lang', $args);

    // b/ add a settings section
    add_settings_section (
        'Import CSV (metadata PUDR)',
        // callable ↓ - echoes anything in the section
        // page name

    // c/ add a settings field
    add_settings_field (
        'Jazyk aktualizovaného pole',
        // ↓ callback

function cmi_csv_section_text() {

    echo '<p>Nastavte jazyk.</p>';


function cmi_csv_setting_jazyk () {
    // Get option 'beast_mode' value from the database
    // Set to 'disabled' as a default if the option does not exist
    $options = get_option( 'cmi_lang', 'EN');
    // Define the radio button options
    $items = array( 'EN', 'CZ');
    /*$jazyk = get_option ('cmi_lang');*/
    foreach( $items as $item ) {
        // Loop the two radio button options and select if set in the option value
        echo "<label><input " . checked( $item, $options, false) . " 
        value='" . esc_attr( $item ) . "' name='cmi_lang' 
        type='radio'/> " . esc_html( $item ) . "</label><br/>";

function cmi_csv_validate_options ($input) {
    $input = sanitize_text_field( $input );
    return $input;
add_action('update_option_cmi_lang', function($old, $new) {

    if (!$new) {
        echo "didn't run";


}, 1, 2);
  • 1
    can you fix the indenting of your code? it's very confusing and difficult to read
    – Tom J Nowell
    Apr 28, 2021 at 10:24
  • @TomJNowell I have made an honest attempt at fixing the indentation, but I'm a newbie and I'm not sure I know what the best practices are... is it any better now? May 3, 2021 at 11:38

1 Answer 1


Answer: the code above works perfectly fine; it just doesn't echo anything inside the admin section. The 'stuff' I did with the update_option hook didn't work for reasons independent of the code above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.