在仪表板的woocommerce电子邮件设置选项卡中添加字段

I wanted to add a field in WooCommerce > Settings > Emails tab. In this section there is a list of email template and on clicking any template you can see this screen.

enter image description here

I want to add another field to this section for every template.

I manage to achieve it but I'm feeling its not a proper way.

My code is as follow:

add_filter( 'woocommerce_settings_tabs_email', 'emailText' );

function emailText($args) {

        ?>
        <div class="EmailText">
            <label for="EmailText">Email Text</label>
            <textarea id="EmailText" class="widefat" name="email_text"></textarea>
        </div>
        <?php

    }

It displays the field but I cannot save anything in it.

Instead of using 'woocommerce_settings_tabs_email' filter try using 'woocommerce_email_settings_after' hook for creating your field.

The WooCommerce Email Settings tab has a table with all of the available email templates such as 'New Order', 'Canceled Order', 'Failed Order', etc. These are usually defined by extending the WC_Email class. Take a look in /plugins/woocommerce/includes/emails for examples.

As WildProgrammers has pointed out, the 'woocommerce_settings_api_form_fields_{email-id}' can be easily used to add a setting to a specific email class. You can see the definition on the WooCommerce Settings API Code Reference page. It provides us with the array of form fields for the email class.

For this example lets add an additional option to the 'New Order' email template. We can look in the WC_Email_New_Order class constructor (found in class-wc-email-new-order.php) to find/verify the id to replace {email-id} in our hook. In this case the WC_Email_New_Order class id is 'new_order' so to add a setting or form field to the New Order options our hook will look like, add_action( 'woocommerce_settings_api_form_fields_new_order', 'add_my_custom_email_setting',10,1);

Now in the 'add_my_custom_email_setting' function all we need to do is add our new setting to the form_fields array and return it:

function add_my_custom_email_setting($form_fields){
    $form_fields['my_custom_id']=['title'=>'My Custom Option',
                                  'description'=>'This is a text area we added to the new order email settings page.',
                                  'type'=>'textarea',
                                  'default'=>''
    ];

    return $form_fields;
}

Take a look at the 'init_form_fields' function in WC_Email class for examples of how to build the options array.

You asked how to add an option to all of the available templates. To do this we could simply manually define a hook for every email class, add_action('woocommerce_settings_api_form_fields_new_order','add_my_custom_email_setting'); add_action('woocommerce_settings_api_form_fields_failed_order','add_my_custom_email_setting'); add_action('woocommerce_settings_api_form_fields_processing_order','add_my_custom_email_setting'); ... but if we can get a list of all of the id's then we can do it programatically instead. Lucky for us WooCommerce provides us with the 'woocommerce_email_classes' filter which is called right after WC instantiates all of the email classes. Now all we need is a function that iterates over the array of email classes provided by the 'woocommerce_email_classes' filter, get the class id's, and add a hook to 'woocommerce_settings_api_form_fields_{email-id}' for each id:

add_action( 'woocommerce_email_classes', 'add_email_custom_setting');

function add_email_custom_setting($email_class_list){
    foreach($email_class_list as $email_class){
        add_action( 'woocommerce_settings_api_form_fields_' . $email_class->id,'add_my_custom_email_setting',10,1);
    }

    return $email_class_list;
}`

We can then use this option in our template files with $email->get_option('my_custom_id');.

You might ask why not simply add the option to the form_fields array in add_email_custom_setting?