This is the code for a Youtube tutorial I posted on my channel.
Creating and processing forms is a very common task in web development. It’s no surprise some of the most successful plugins in the WordPress ecosystem deal with form creation.
While they do make your life easier there are some advantages for writing your own forms. First, it is free; second you can add advanced processing and third you can customize the forms however you want.
In this video we are going to create a newsletter subscription form that saves email addresses in the database.The form will have a captcha for preventing spam, and security protections against cross site request forgery.
PHP Code added in the snippet
add_shortcode( 'subscribe_form', function () {
global $wpdb;
if (isset($_POST["sub-submit"])) {
if (! isset( $_POST['sub-nonce'] )
|| ! wp_verify_nonce( $_POST['sub-nonce'], 'sub-action' )) {
return "<div class='sub-failure'>Security error.</div>";
}
$response = wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', array(
'body' => array(
'secret' => RECAPTCHA_SECRET,
'response' => $_POST['g-recaptcha-response']
),
)
);
$response_js = json_decode($response["body"], true);
if (! $response_js['success']) {
return "<div class='sub-failure'>Security error.</div>";
}
$insert_result = $wpdb->insert(
$wpdb->prefix . 'subs',
array(
'email' => $_POST['email']
)
);
if (!$insert_result) {
return "<div class='sub-failure'>Database error.</div>";
}
return "<div class='sub-success'>Thank you for subscribing <b>{$_POST['email']}</b></div>";
}
ob_start();
?>
<form action="#" method="post">
<div id="sub-form">
<?php wp_nonce_field( 'sub-action', 'sub-nonce' ); ?>
<label for="email">Email</label>
<input type="email" name="email" id="email">
<div class="g-recaptcha" data-sitekey="6LfA5LkcAAAAACjDo1vpGa6kdqZxb45ZXJpE91tV"></div>
<input type="submit" name="sub-submit" value="Subscribe">
</div>
</form>
<?php
return ob_get_clean();
} );
add_action( 'wp_head', function () { ?>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<?php } );
CSS added to the customizer
#sub-form input {
display: block;
}
#sub-form label {
font-size: var(--heading--font-size-h3);
font-weight: normal;
}
#sub-form input[type=email] {
margin-left: 0px;
margin-bottom: 1rem;
}
#sub-form input[type=submit] {
margin-top: 1rem;
}
.sub-success {
background-color: #CCDBD5;
padding: 1rem;
}
.sub-failure {
background-color: #F0A0A0;
padding: 1rem;
}