한 가지 이해가 안 되는 점은 워드프레스에 아직 간단하지만 완전한 문의 양식이 기본적으로 포함되어 있지 않다는 점입니다.
여기와 타사 사이트 모두에서 워드프레스 최적화 작업을 정기적으로 수행하면서 불필요하게 부풀려진 플러그인, 사용되지 않거나 필요하지 않은 옵션, 블록, 장식 등을 코드로 대체하여 부하를 가볍게 하는 경우가 많습니다.
이 문의 양식은 안전하고 사용하기 쉬우며 사용자 개인정보를 존중하도록 설계된 워드프레스를 위한 완벽한 사용자 정의 솔루션입니다. 또한 원하는 대로 옵션을 추가하거나 제거할 수 있습니다. 제가 사용하는 양식입니다 .
다음은 단축 코드를 사용하여 블로그의 모든 페이지 또는 게시물에 추가하는 방법과 주요 기능 및 특징입니다.
구조 및 옵션 1. 양식 필드 이름 : 사용자가 자신의 이름을 입력하는 필수 필드입니다.이메일 주소 : 이메일 주소: 사용자가 이메일 주소를 입력하는 필수 입력란입니다.메시지 : 사용자가 메시지를 작성하는 필수 입력란입니다. 길이는 15자 이상이어야 합니다.합계 캡차 : 사용자에게 1에서 9 사이의 난수 두 개를 합산하여 풀도록 요청하는 간단한 캡차입니다.개인정보처리방침동의 : 양식을 제출하기 전에 개인정보처리방침에 동의하는 필수 확인란입니다. 유효성 검사 및 보안 필수 필드의 유효성 검사 : 모든 필드는 필수입니다. 누락된 필드가 있으면 오류 메시지가 표시됩니다.링크 유효성 검사 : 이름 또는 메시지 필드에는 링크(URL)를 사용할 수 없습니다.추가 캡차 : 사용자에게 간단한 수학 연산을 풀도록 요구하여 자동 스팸을 방지합니다.Google reCAPTCHA(선택 사항) : Google reCAPTCHA 키를 구성하면 봇을 방지하기 위한 두 번째 보안 수준이 추가됩니다. reCAPTCHA 키를 코드에 추가하지 않으면 코드가 양식에 추가되지 않습니다.금지 단어 확인 : 선택적으로 메시지에서 특정 단어(예: 파인애플, 피자, 비트코인(쉼표로 구분하고 공백 없음))를 차단할 수 있습니다.논스 보안 : CSRF(사이트 간 요청 위조) 공격으로부터 보호합니다.3. 개인 정보 보호 데이터 저장 없음 : 사용자 데이터가 저장되지 않습니다(이메일, IP, 참조 URL 등 아무것도 저장되지 않음). 이 방식은 개인정보를 수집하거나 저장하지 않으므로 GDPR과 같은 개인정보 보호 규정을 준수합니다.개인정보처리방침 : 사용자가 양식을 제출하기 전에 반드시 읽고 동의해야 하는 개인정보처리방침 링크가 포함됩니다.4. 피드백 메시지 오류 메시지 : 유효성 검사에 오류가 있는 경우 양식 상단의 블록에 표시됩니다.성공 메시지 : 양식을 성공적으로 제출하면 성공 메시지가 녹색, 14px 크기, 굵은 글씨로 표시됩니다:"감사합니다! 메시지가 전송되었습니다 ."라는 메시지가표시됩니다 . 코드에서 이 텍스트와 서식을 변경할 수 있습니다. 노란색 배경, 양식이 포함된 상자의 테두리 및 그림자와 같은 나머지 스타일과 여기에서 볼 수 있는 기타 외부 요소는 GenerateBlocks 컨테이너로 추가되므로 코드에 포함되지 않습니다.5. 개인화 캡차 텍스트 : 사용자 지정 가능(기본값: "당신은 인간입니까? 이 합계를 풀어보세요:").금지 단어 : 쉼표로 구분된 금지 단어 목록을 추가할 수 있습니다.Google 재캡차 : 선택 사항이며, 캡차의 사이트 및 비밀 키를 구성하고 코드에 추가하는 경우에만 추가됩니다.6. 성능 이 코드는 쇼트코드가 있는지 확인하고 쇼트코드가 없는 경우 아무것도 표시하지 않으므로 쇼트코드가 추가된 페이지 또는 글에서만 실행됩니다.
표시되는 위치의 성능이 최적입니다.
설치 및 구성 지침 1. 코드를 복사하여 추가합니다. 워드프레스 테마의 functions.php 파일을 엽니다(테마를 수정하거나 코드 조각을 사용하지 않으려면 사용자 정의 플러그인을 생성하세요). 전체 양식 코드를 복사하여 functions.php 파일에 붙여넣습니다. 2. Google reCAPTCHA 설정(선택 사항) Google 리캡챠로 이동합니다.재캡차 v2를 선택하고 '나는 로봇이 아닙니다' 확인란을 선택합니다.웹사이트를 등록하고 키를 받으세요:폴리랑 플레이스홀더는 수정하지 마세요. 양식 코드에서 'YOUR_SITE_KEY
' 및 'YOUR_SECRET_KEY
'를 획득한 키로 바꿉니다.Polylang 자리 표시자는 수정하지 않습니다. 3. 금지 단어 설정(선택 사항) 1 - 양식 코드에서 해당 줄을 찾습니다:
$palabras_prohibidas = ' ';
2 - 차단하려는 단어를 쉼표로 구분하여 추가합니다. 예를 들어
$palabras_prohibidas = 'caca,culo,pedo,pis';
단어를 차단하지 않으려면 변수를 비워두세요.
4. 합계의 캡차 텍스트 사용자 지정(선택 사항) 양식 코드에서 이 줄을 찾습니다:
<label for="captcha">¿Eres humano? Resuelve esta suma: <strong><?php echo $num1; ?> + <?php echo $num2; ?> = </strong></label>
"당신은 인간인가요? 이 합을 풀어보세요:"를 표시하려는 텍스트로 변경합니다.
5. 개인정보처리방침의 URL 추가 이 줄에서 예제 URL을 사이트의 개인정보처리방침 URL로 바꿉니다:
$politica_privacidad_url = 'https://tuweb.com/declaracion-de-privacidad/';
6. 단축 코드 양식을 표시할 페이지 또는 글에 쇼트코드를 추가합니다.
[formulario_contacto]
마지막으로 테스트하여 이메일이 전송되고 도착하는지 확인하고 사용법을 관찰하여 수학적 캡차를 복잡하게 만들거나 두 캡차를 동시에 활성화하여 끈질긴 스패머가 몰래 들어오는 것을 방지하면 됩니다. 코드는 언제든지 개선할 수 있으며 디버깅 및 최적화할 수 있습니다. 다른 언어로 사용해야 하는 경우 번역할 수도 있습니다.
결과에 따라 코드를 변경하거나 개선하면 여기에 메모를 추가하겠습니다.
코드 //Crea un shortcode que genera un formulario de contacto para añadir en cualquier página o post de tu blog. Código actualizado en https://jrmora.com/formulario-contacto-wordpress-sin-plugin/
// Shortcode para mostrar el formulario de contacto
function contacto_form_shortcode() {
// Verificar si el shortcode está presente en el contenido actual
if (!has_shortcode(get_the_content(), 'formulario_contacto')) {
return ''; // Si no está el shortcode, no mostrar nada
}
ob_start(); // Iniciar el buffer de salida
// Claves de Google reCAPTCHA (cambia estas por las tuyas)
$site_key = 'TU_CLAVE_DEL_SITIO'; // Clave del sitio de reCAPTCHA
$secret_key = 'TU_CLAVE_SECRETA'; // Clave secreta de reCAPTCHA
// Verificar si las claves son las predeterminadas
$recaptcha_enabled = ($site_key !== 'TU_CLAVE_DEL_SITIO' && $secret_key !== 'TU_CLAVE_SECRETA');
// Lista de palabras prohibidas (separadas por comas)
// Ejemplo: $palabras_prohibidas = 'spam,publicidad,oferta';
$palabras_prohibidas = ''; // No hay palabras prohibidas por defecto
// Convertir la lista de palabras prohibidas en un array
$palabras_prohibidas_array = !empty($palabras_prohibidas) ? explode(',', $palabras_prohibidas) : [];
// Variables para almacenar errores
$errors = [];
// Verificar si el formulario ha sido enviado
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['contacto_nonce'])) {
// Verificar el nonce para seguridad
if (!wp_verify_nonce($_POST['contacto_nonce'], 'contacto_form_nonce')) {
$errors[] = 'Error de seguridad. Inténtalo de nuevo.';
} else {
// Validar el captcha de suma
$captcha = sanitize_text_field($_POST['captcha']);
$captcha_correct = sanitize_text_field($_POST['captcha_correct']);
if ($captcha !== $captcha_correct) {
$errors[] = 'El resultado de la operación es incorrecto. Inténtalo de nuevo.';
} else {
// Validar la aceptación de la política de privacidad
if (!isset($_POST['aceptar_privacidad'])) {
$errors[] = 'Debes aceptar la política de privacidad para enviar el formulario.';
} else {
// Validar Google reCAPTCHA (solo si está habilitado)
if ($recaptcha_enabled) {
if (isset($_POST['g-recaptcha-response'])) {
$recaptcha_response = sanitize_text_field($_POST['g-recaptcha-response']);
$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_data = [
'secret' => $secret_key,
'response' => $recaptcha_response,
];
$recaptcha_options = [
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query($recaptcha_data),
],
];
$recaptcha_context = stream_context_create($recaptcha_options);
$recaptcha_result = file_get_contents($recaptcha_url, false, $recaptcha_context);
$recaptcha_json = json_decode($recaptcha_result);
if (!$recaptcha_json->success) {
$errors[] = 'Por favor, verifica que no eres un robot.';
}
} else {
$errors[] = 'Por favor, completa el reCAPTCHA.';
}
}
// Si no hay errores, procesar el formulario
if (empty($errors)) {
$nombre = sanitize_text_field($_POST['nombre']);
$email = sanitize_email($_POST['email']);
$mensaje = sanitize_textarea_field($_POST['mensaje']);
// Validar campos obligatorios
if (empty($nombre)) {
$errors[] = 'El campo nombre es obligatorio.';
}
if (empty($email)) {
$errors[] = 'El campo email es obligatorio.';
}
if (empty($mensaje)) {
$errors[] = 'El campo mensaje es obligatorio.';
}
// Validar que no se hayan añadido enlaces en los campos
if (preg_match('/http|www|\[url|\[link|href=/i', $nombre . $mensaje)) {
$errors[] = 'No se permiten enlaces en los campos del formulario.';
}
// Validar que el mensaje tenga al menos 15 caracteres
if (strlen($mensaje) < 15) {
$errors[] = 'El mensaje debe tener al menos 15 caracteres.';
}
// Validar palabras prohibidas (solo si hay palabras en la lista)
if (!empty($palabras_prohibidas_array)) {
foreach ($palabras_prohibidas_array as $palabra) {
if (stripos($mensaje, $palabra) !== false) {
$errors[] = 'El mensaje contiene palabras no permitidas.';
break; // Detener la validación al encontrar una palabra prohibida
}
}
}
// Si no hay errores, enviar el correo
if (empty($errors)) {
$to = get_option('admin_email'); // Correo del administrador
$subject = 'Nuevo mensaje de contacto desde el sitio web';
$headers = array('Content-Type: text/html; charset=UTF-8', 'From: ' . $nombre . ' <' . $email . '>');
$body = "<p><strong>Nombre:</strong> $nombre</p>";
$body .= "<p><strong>Email:</strong> $email</p>";
$body .= "<p><strong>Mensaje:</strong> $mensaje</p>";
if (wp_mail($to, $subject, $body, $headers)) {
// Redirigir para evitar reenvío al refrescar la página
wp_redirect(add_query_arg('contacto', 'success', wp_get_referer()));
exit;
} else {
$errors[] = 'Hubo un error al enviar el mensaje. Inténtalo de nuevo.';
}
}
}
}
}
}
}
// Mostrar mensaje de éxito después de la redirección
if (isset($_GET['contacto']) && $_GET['contacto'] === 'success') {
echo '<p style="font-size: 14px; font-weight: bold; color: green;">¡Gracias! Tu mensaje ha sido enviado.</p>';
}
// Generar un captcha de suma de dos números aleatorios entre 1 y 9
$num1 = rand(1, 9); // Primer número aleatorio entre 1 y 9
$num2 = rand(1, 9); // Segundo número aleatorio entre 1 y 9
$captcha_result = $num1 + $num2; // Resultado de la suma
// URL de la política de privacidad
$politica_privacidad_url = 'https://tuweb.com/declaracion-de-privacidad/';
// Mostrar el formulario
?>
<?php if (!empty($errors)) : ?>
<div style="color: red; margin-bottom: 20px;">
<?php foreach ($errors as $error) : ?>
<p><?php echo esc_html($error); ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form action="" method="post">
<p>
<label for="nombre">Nombre:</label><br>
<input type="text" name="nombre" id="nombre" value="<?php echo isset($nombre) ? esc_attr($nombre) : ''; ?>" required>
</p>
<p>
<label for="email">Email:</label><br>
<input type="email" name="email" id="email" value="<?php echo isset($email) ? esc_attr($email) : ''; ?>" required>
</p>
<p>
<label for="mensaje">Mensaje:</label><br>
<textarea name="mensaje" id="mensaje" rows="5" required><?php echo isset($mensaje) ? esc_textarea($mensaje) : ''; ?></textarea>
</p>
<p>
<label for="captcha">¿Eres humano? Resuelve esta suma: <strong><?php echo $num1; ?> + <?php echo $num2; ?> = </strong></label><br>
<input type="text" name="captcha" id="captcha" required>
<input type="hidden" name="captcha_correct" value="<?php echo $captcha_result; ?>">
</p>
<?php if ($recaptcha_enabled) : ?>
<p>
<div class="g-recaptcha" data-sitekey="<?php echo esc_attr($site_key); ?>"></div>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</p>
<?php endif; ?>
<p>
<input type="checkbox" name="aceptar_privacidad" id="aceptar_privacidad" required>
<label for="aceptar_privacidad">He leído y acepto la <a href="<?php echo esc_url($politica_privacidad_url); ?>" target="_blank">política de privacidad</a>.</label>
</p>
<p>
<?php wp_nonce_field('contacto_form_nonce', 'contacto_nonce'); ?>
<input type="submit" value="Enviar">
</p>
</form>
<?php
return ob_get_clean(); // Devolver el contenido del buffer
}
add_shortcode('formulario_contacto', 'contacto_form_shortcode');