1

I am new to Wordpress development and am tired of fighting with Contact form 7 to style it how I would like. Is it possible and not considered 'bad practice' to put a html form on my contact page and have it post to a php page which handles the form submission? Or is that just simply not done?

closed as too broad by Michael, Krzysiek Dróżdż, Nathan Johnson, Dave Romsey, Christine Cooper Apr 3 '18 at 7:18

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • have you tried Smart Grid-layout Extension that allows you to create rich form layouts using a grid UI, it might reconcile you with CF7 – Aurovrata Apr 1 '18 at 16:07
  • 1
    One thing I would add to any form you hand code is both a hidden field to check for to make sure the submission actually took place from the form, and a CSS (as well as ARIA) hidden field that you check to make sure is empty as an "inverse torture test" – Cedon Apr 1 '18 at 22:45
3

This is my very simple implementation of contact form:

class WPSE_299521_Form {

    /**
     * Class constructor
     */
    public function __construct() {

        $this->define_hooks();
    }

    public function controller() {

        if( isset( $_POST['submit'] ) ) { // Submit button

            $full_name   = filter_input( INPUT_POST, 'full_name', FILTER_SANITIZE_STRING );
            $email       = filter_input( INPUT_POST, 'email', FILTER_SANITIZE_STRING | FILTER_SANITIZE_EMAIL );
            $color       = filter_input( INPUT_POST, 'color', FILTER_SANITIZE_STRING );
            $accessories = filter_input( INPUT_POST, 'accessories', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY );
            $comments    = filter_input( INPUT_POST, 'comments', FILTER_SANITIZE_STRING );

            // Send an email and redirect user to "Thank you" page.
        }
    }

    /**
     * Display form
     */
    public function display_form() {

        $full_name   = filter_input( INPUT_POST, 'full_name', FILTER_SANITIZE_STRING );
        $email       = filter_input( INPUT_POST, 'email', FILTER_SANITIZE_STRING | FILTER_SANITIZE_EMAIL );
        $color       = filter_input( INPUT_POST, 'color', FILTER_SANITIZE_STRING );
        $accessories = filter_input( INPUT_POST, 'accessories', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY );
        $comments    = filter_input( INPUT_POST, 'comments', FILTER_SANITIZE_STRING );

        // Default empty array
        $accessories = ( $accessories === null ) ? array() : $accessories;

        $output = '';

        $output .= '<form method="post">';
        $output .= '    <p>';
        $output .= '        ' . $this->display_text( 'full_name', 'Name', $full_name );
        $output .= '    </p>';
        $output .= '    <p>';
        $output .= '        ' . $this->display_text( 'email', 'Email', $email );
        $output .= '    </p>';
        $output .= '    <p>';
        $output .= '        ' . $this->display_radios( 'color', 'Color', $this->get_available_colors(), $color );
        $output .= '    </p>';
        $output .= '    <p>';
        $output .= '        ' . $this->display_checkboxes( 'accessories', 'Accessories', $this->get_available_accessories(), $accessories );
        $output .= '    </p>';
        $output .= '    <p>';
        $output .= '        ' . $this->display_textarea( 'comments', 'comments', $comments );
        $output .= '    </p>';
        $output .= '    <p>';
        $output .= '        <input type="submit" name="submit" value="Submit" />';
        $output .= '    </p>';
        $output .= '</form>';

        return $output;
    }

    /**
     * Display text field
     */
    private function display_text( $name, $label, $value = '' ) {

        $output = '';

        $output .= '<label>' . esc_html__( $label, 'wpse_299521' ) . '</label>';
        $output .= '<input type="text" name="' . esc_attr( $name ) . '" value="' . esc_attr( $value ) . '">';

        return $output;
    }

    /**
     * Display textarea field
     */
    private function display_textarea( $name, $label, $value = '' ) {

        $output = '';

        $output .= '<label> ' . esc_html__( $label, 'wpse_299521' ) . '</label>';
        $output .= '<textarea name="' . esc_attr( $name ) . '" >' . esc_html( $value ) . '</textarea>';

        return $output;
    }

    /**
     * Display radios field
     */
    private function display_radios( $name, $label, $options, $value = null ) {

        $output = '';

        $output .= '<label>' . esc_html__( $label, 'wpse_299521' ) . '</label>';

        foreach ( $options as $option_value => $option_label ):
            $output .= $this->display_radio( $name, $option_label, $option_value, $value );
        endforeach;

        return $output;
    }

    /**
     * Display single checkbox field
     */
    private function display_radio( $name, $label, $option_value, $value = null ) {

        $output = '';

        $checked = ( $option_value === $value ) ? ' checked' : '';

        $output .= '<label>';
        $output .= '    <input type="radio" name="' . esc_attr( $name ) . '" value="' . esc_attr( $option_value ) . '"' . esc_attr( $checked ) . '>';
        $output .= '    ' . esc_html__( $label, 'wpse_299521' );
        $output .= '</label>';

        return $output;
    }

    /**
     * Display checkboxes field
     */
    private function display_checkboxes( $name, $label, $options, $values = array() ) {

        $output = '';

        $name .= '[]';

        $output .= '<label>' . esc_html__( $label, 'wpse_299521' ) . '</label>';

        foreach ( $options as $option_value => $option_label ):
            $output .= $this->display_checkbox( $name, $option_label, $option_value, $values );
        endforeach;

        return $output;
    }

    /**
     * Display single checkbox field
     */
    private function display_checkbox( $name, $label, $available_value, $values = array() ) {

        $output = '';

        $checked = ( in_array($available_value, $values) ) ? ' checked' : '';

        $output .= '<label>';
        $output .= '    <input type="checkbox" name="' . esc_attr( $name ) . '" value="' . esc_attr( $available_value ) . '"' . esc_attr( $checked ) . '>';
        $output .= '    ' . esc_html__( $label, 'wpse_299521' );
        $output .= '</label>';

        return $output;
    }

    /**
     * Get available colors
     */
    private function get_available_colors() {

        return array(
            'red' => 'Red',
            'blue' => 'Blue',
            'green' => 'Green',
        );
    }

    /**
     * Get available accessories
     */
    private function get_available_accessories() {

        return array(
            'case' => 'Case',
            'tempered_glass' => 'Tempered glass',
            'headphones' => 'Headphones',
        );
    }

    /**
     * Define hooks related to plugin
     */
    private function define_hooks() {

        /**
         * Add action to send email
         */
        add_action( 'wp', array( $this, 'controller' ) );

        /**
         * Add shortcode to display form
         */
        add_shortcode( 'contact', array( $this, 'display_form' ) );
    }
}

new WPSE_299521_Form();

After pasting code you can use shortcode [contact] to display it.

  • Where would you put this code? – user8463989 Apr 2 '18 at 6:38
  • Probably I would create simple plugin. – kierzniak Apr 2 '18 at 6:48
  • @user8463989 - this could go into your functions.php file in your childtheme... you are working with a child theme, right? – HPWD Feb 11 at 20:36
  • Oddly after finding this answer, I had an opportunity arise to use this code as a starting point. Very nice. – HPWD Feb 15 at 14:21
  • Nice implementation. Where do I control the form's action, i.e., where the form is sent? – Mattypants Sep 4 at 7:02
2

All form plugins are horrible, it is just that forms are typically very complex to code correctly, especially when the site admin should be able to design them.

There is nothing wrong with coding a form yourself, it is just that you will probably need to recreate stuff which other people have already perfected, or at least have a good foundations for (formatting emails, storing in the DB and probably more).

So it is really depends on your specific requirements, if flexibility is not required, and sending email is good enough, it should be easier to write your own than "fighting" with the plugins.

  • My biggest problem is actually trying to style checkboxes and radio buttons using contact form 7 or any other contact form plugin. It is killing me slowly which is why I thought of just using an html form and then using php to send the form. – user8463989 Apr 1 '18 at 13:34
  • @user8463989, maybe you should use a different plugin. CF7 IMHO is too basic, but I didn't ever used it so maybe I am just not familiar enough to criticize it. All of them have all kinds of kinks, none is truly perfect. – Mark Kaplun Apr 1 '18 at 13:46
  • I have tried a few which all work but I have the same problem. The CSS breaks. Maybe because I am trying to convert html form to wordpress, I don't know. – user8463989 Apr 1 '18 at 18:09
1

Since your not performing CRUD on the DB, I don't see why not. I've done it before where I used a page template for form processing and pointed my contact <form ...> action to it action="<?php echo home_url( 'my-form-processing-page-template-slug' ); ?>".

Alternatively, use the actual single post type to process it i.e. action="<?php echo get_the_permalink();?>" (needs to be a is_single() || is_singular() to use get_the_permalink()).

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