phpwordpresswoocommercemailchimp

MailChimp for WooCommerce: Add the checkbox in the middle of the checkout fields


The MailChimp for WooCommerce plugin is great, but I've just been given a design where the 'Subscribe to our newsletter' checkbox in the WooCommerce checkout is immediately after the email field rather than at the bottom of a particular section:

WooCommerce checkout page showing the first name, last name & email fields, immediately followed by MailChimp's sign-up checkbox

The plugin allows you to type in an action hook for where you'd like the checkbox to appear; for example woocommerce_checkout_before_customer_details, woocommerce_after_checkout_billing_form, etc. which allows you to put the checkbox before or after a certain section (as long as there's a hook for it), but not in amongst the various fields.

Is there a way to add the MailChimp checkbox to very specific point before or after a certain field?


Solution

  • The checkout fields are outputted within a loop, which uses the woocommerce_form_field() function to echo out each field:

    $fields = $checkout->get_checkout_fields( 'billing' );
    
    foreach ( $fields as $key => $field ) {
        woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
    }
    

    this function has a number of filters for each specific field type (e.g. woocommerce_form_field_email), but no action hooks.

    However, you can use one of these filters and just a little trickery to add your own hooks:

    ///
    //  Add MailChimp checkbox after email field
    ///
    
    function vnm_mc_after_email_field($field, $key, $args, $value) {
        ob_start();
    
        do_action('vnm_before_email_field');
    
        echo $field;
    
        do_action('vnm_after_email_field');
    
        return ob_get_clean();
    }
    
    add_filter('woocommerce_form_field_email', 'vnm_mc_after_email_field', 10, 4);
    

    Since a WordPress filter always has to return a version of the first parameter sent to it (in this case $field), all we do is open the output buffer, add our own actions for before and after the field (vnm_before_email_field, vnm_after_email_field), and then return the output buffer.

    Then, in the MailChimp plugin settings under WooCommerce->MailChimp->Audience, just add the hook you've just created for your field:

    MailChimp plugin settings: opt-in checkbox position, with the new vnm_before_email_field action entered

    ...and done. Note you could in fact add action hooks around every WooCommerce checkout field if you wanted, just by adding the following (untested):

    ///
    //  Add `before` & `after` actions around every WooCommerce checkout field
    ///
    
    function vnm_wc_form_field_actions($field, $key, $args, $value) {
        ob_start();
    
        do_action('vnm_before_' . $args['type'] . '_field');
    
        echo $field;
    
        do_action('vnm_after_' . $args['type'] . '_field');
    
        return ob_get_clean();
    }
    
    add_filter('woocommerce_form_field', 'vnm_wc_form_field_actions', 10, 4);