워드프레스에서 플러그인 없이 모달 창을 여는 버튼

No comments

 

워드프레스에서 플러그인 없이 모달 창을 여는 버튼
모달 창과 이를 트리거하는 노란색 버튼 아래의 예시입니다. 버전 1.0

오늘의 코드를 사용하면 워드프레스의 글이나 페이지에 단축 코드가 있는 버튼을 추가하여 클릭하면 원하는 콘텐츠를 추가할 수 있는 모달 창을 열 수 있습니다.

구독 양식, 문의 양식, 일회성 알림, 이미지, 정보 상자 또는 제 경우처럼 오류 알림 양식을 표시하는 데 사용할 수 있습니다.

모든 글 하단에서 작동하는 단축 코드를 테스트할 수 있습니다.

[error_report_form]

이 블로그에서 몇 주 동안 제대로 작동하고 있지만 1.0 버전이며 항상 개선과 디버깅의 여지가 있다는 점을 기억하세요. CSS를 분리하여 더 쉽게 변경할 수 있으며, 원한다면 플러그인으로 전환하여 더 많은 설정과 구성을 추가하여 빠르고 쉽게 액세스할 수도 있습니다.

코드 아래에서 옵션에 대한 설명과 사용 방법에 대한 지침을 확인할 수 있습니다.

코드

/*
 * Versión: 1.0
 * Última actualización: 13-03-2025 17:54:00
 */

// Shortcode para mostrar el botón y el formulario modal actualizado en jrmora.com
function error_report_form_shortcode() {
    // Generar números aleatorios para la operación matemática
    $num1 = rand(1, 9);
    $num2 = rand(1, 9);
    $sum = $num1 + $num2;

    // Iniciar sesión si no está iniciada
    if (!session_id()) {
        session_start();
    }

    // Guardar la suma en una variable de sesión para validar después
    $_SESSION['captcha_sum'] = $sum;

    // HTML del botón y el modal
    ob_start();
    ?>
    <button id="openErrorModal" style="padding: 10px 20px; background-color: #ffcc00; color: black; border: none; border-radius: 6px; cursor: pointer; font-weight: bold;">
        ⚠ Comunicar error
    </button>

    <div id="errorModalOverlay" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 999;">
        <div id="errorModal" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 20px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); z-index: 1000; border-radius: 7px; width: 90%; max-width: 500px;">
            <span id="closeModalBtn" style="position: absolute; top: 10px; right: 10px; cursor: pointer; font-size: 20px; background-color: black; color: white; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; line-height: 30px;">&times;</span>
            <h3 style="font-size: 18px;">Comunicar error (Para errores ortográficos o de malfuncionamiento del sitio)</h3>
            <form id="errorForm" method="post">
                <input type="hidden" name="action" value="submit_error_report">
                <label for="name" style="font-size: 14px;">Nombre:</label>
                <input type="text" id="name" name="name" required style="background-color: #f5f5f5; padding: 8px; border: 1px solid #ddd; border-radius: 4px; width: 100%; margin-bottom: 12px;">
                <div id="nameError" style="color: red; display: none; font-size: 12px; margin-bottom: 12px;">No se permiten enlaces o dominios en el campo "Nombre".</div>
                <label for="message" style="font-size: 14px;">Descripción del error:</label>
                <textarea id="message" name="message" required style="background-color: #f5f5f5; padding: 8px; border: 1px solid #ddd; border-radius: 4px; width: 100%; margin-bottom: 12px;"></textarea>
                <div id="messageError" style="color: red; display: none; font-size: 12px; margin-bottom: 12px;">No se permiten enlaces o dominios en el campo "Mensaje".</div>
                <label for="captcha" style="font-size: 14px;">¿Eres humano? ¿Cuánto es <?php echo $num1; ?> + <?php echo $num2; ?>?</label>
                <input type="text" id="captcha" name="captcha" required style="background-color: #f5f5f5; padding: 8px; border: 1px solid #ddd; border-radius: 4px; width: 100%; margin-bottom: 12px;">
                <div id="captchaError" style="color: red; display: none; font-size: 12px; margin-bottom: 12px;">El resultado de la suma es incorrecto.</div>
                <!-- Opcional: Añadir reCaptcha si se proporcionan las claves -->
                <?php if (defined('RECAPTCHA_SITE_KEY') && defined('RECAPTCHA_SECRET_KEY')) : ?>
                    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
                    <div class="g-recaptcha" data-sitekey="<?php echo RECAPTCHA_SITE_KEY; ?>" style="margin-bottom: 12px;"></div>
                <?php endif; ?>
                <div style="text-align: center;">
                    <input type="submit" value="Enviar" style="background-color: #bc080e; color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; font-weight: bold; display: inline-block;">
                </div>
            </form>
            <div id="successMessage" style="color: green; display: none; margin-top: 10px; font-size: 14px; text-align: center;">Gracias por comunicar el error.</div>
        </div>
    </div>

    <style>
        /* Estilos para dispositivos móviles */
        @media (max-width: 768px) {
            #errorModal {
                width: 90% !important; /* Ajusta el ancho del modal al 90% de la pantalla */
                max-width: 90% !important; /* Asegura que no exceda el 90% del ancho */
                padding: 15px !important; /* Reduce el padding para más espacio */
            }

            #errorForm input, #errorForm textarea {
                font-size: 16px !important; /* Aumenta el tamaño de la fuente para mejor legibilidad */
            }

            #errorForm label {
                font-size: 16px !important; /* Aumenta el tamaño de la fuente de las etiquetas */
            }
        }
    </style>

    <script>
        // Abrir modal
        document.getElementById('openErrorModal').addEventListener('click', function() {
            document.getElementById('errorModalOverlay').style.display = 'block';
        });

        // Cerrar modal al hacer clic en el aspa
        document.getElementById('closeModalBtn').addEventListener('click', function() {
            document.getElementById('errorModalOverlay').style.display = 'none';
        });

        // Cerrar modal al hacer clic fuera de él
        document.getElementById('errorModalOverlay').addEventListener('click', function(event) {
            if (event.target === document.getElementById('errorModalOverlay')) {
                document.getElementById('errorModalOverlay').style.display = 'none';
            }
        });

        // Función para validar si hay enlaces o dominios en el texto
        function containsUrlOrDomain(text) {
            // Expresión regular para detectar enlaces o dominios
            const urlPattern = /(http|https|www|\[url|\[link)|(\b\w+\.(com|org|net|io|co|edu|gov|mil|biz|info|xyz|me|tv|us|uk|ca|au|de|fr|es|it|nl|ru|jp|cn|in|br|mx|ar|cl|pe|ve|co\.uk|co\.jp|co\.in|ac\.uk|gov\.uk|edu\.au|com\.au|org\.uk|net\.au)\b)/i;
            return urlPattern.test(text);
        }

        // Manejar el envío del formulario con AJAX
        document.getElementById('errorForm').addEventListener('submit', function(e) {
            e.preventDefault(); // Evitar envío tradicional del formulario

            // Ocultar mensajes de error previos
            document.getElementById('nameError').style.display = 'none';
            document.getElementById('messageError').style.display = 'none';
            document.getElementById('captchaError').style.display = 'none';

            // Validar campos
            var name = document.getElementById('name').value;
            var message = document.getElementById('message').value;
            var captcha = document.getElementById('captcha').value;
            var hasError = false;

            // Validar enlaces o dominios en el nombre
            if (containsUrlOrDomain(name)) {
                document.getElementById('nameError').style.display = 'block';
                hasError = true;
            }

            // Validar enlaces o dominios en el mensaje
            if (containsUrlOrDomain(message)) {
                document.getElementById('messageError').style.display = 'block';
                hasError = true;
            }

            // Validar el captcha
            if (captcha !== '<?php echo $sum; ?>') {
                document.getElementById('captchaError').style.display = 'block';
                hasError = true;
            }

            // Si hay errores, detener el envío
            if (hasError) {
                return;
            }

            // Enviar el formulario si no hay errores
            var formData = new FormData(this);
            fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
                method: 'POST',
                body: formData
            })
            .then(response => response.text())
            .then(data => {
                // Mostrar mensaje de éxito
                document.getElementById('successMessage').style.display = 'block';

                // Ocultar el formulario
                document.getElementById('errorForm').style.display = 'none';

                // Esperar 3 segundos y cerrar el modal
                setTimeout(function() {
                    document.getElementById('errorModalOverlay').style.display = 'none';
                    document.getElementById('successMessage').style.display = 'none';
                    document.getElementById('errorForm').style.display = 'block'; // Restaurar el formulario
                }, 3000);
            })
            .catch(error => console.error('Error:', error));
        });
    </script>
    <?php
    return ob_get_clean();
}
add_shortcode('error_report_form', 'error_report_form_shortcode');

// Manejar el envío del formulario
function handle_error_report_form() {
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'submit_error_report') {
        // Iniciar sesión si no está iniciada
        if (!session_id()) {
            session_start();
        }

        // Validar el captcha
        if (!isset($_SESSION['captcha_sum']) || !isset($_POST['captcha']) || $_POST['captcha'] != $_SESSION['captcha_sum']) {
            wp_die('Captcha incorrecto. Por favor, intenta de nuevo.');
        }

        // Validar que no haya enlaces o dominios en los campos
        $name = isset($_POST['name']) ? sanitize_text_field($_POST['name']) : '';
        $message = isset($_POST['message']) ? sanitize_text_field($_POST['message']) : '';
        if (preg_match('/(http|https|www|\[url|\[link)|(\b\w+\.(com|org|net|io|co|edu|gov|mil|biz|info|xyz|me|tv|us|uk|ca|au|de|fr|es|it|nl|ru|jp|cn|in|br|mx|ar|cl|pe|ve|co\.uk|co\.jp|co\.in|ac\.uk|gov\.uk|edu\.au|com\.au|org\.uk|net\.au)\b)/i', $name . $message)) {
            wp_die('No se permiten enlaces o dominios en los campos.');
        }

        // Validar reCaptcha (opcional)
        if (defined('RECAPTCHA_SITE_KEY') && defined('RECAPTCHA_SECRET_KEY')) {
            if (!isset($_POST['g-recaptcha-response'])) {
                wp_die('Por favor, completa el reCaptcha.');
            }

            $recaptcha_response = $_POST['g-recaptcha-response'];
            $recaptcha_secret = RECAPTCHA_SECRET_KEY;
            $recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
            $recaptcha_data = [
                'secret' => $recaptcha_secret,
                'response' => $recaptcha_response,
                'remoteip' => $_SERVER['REMOTE_ADDR']
            ];

            $recaptcha_options = [
                'http' => [
                    'header' => "Content-type: application/x-www-form-urlencoded\r\n",
                    'method' => 'POST',
                    '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) {
                wp_die('Por favor, completa el reCaptcha correctamente.');
            }
        }

        // Obtener la URL de origen
        $url = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'URL desconocida';

        // Enviar correo electrónico
        $to = get_option('admin_email'); // Correo del administrador
        $subject = 'Comunicación de Error desde ' . $url;
        $body = "Nombre: $name\n\nMensaje: $message\n\nURL: $url";
        $headers = array('Content-Type: text/plain; charset=UTF-8');

        if (wp_mail($to, $subject, $body, $headers)) {
            echo 'success';
        } else {
            echo 'Hubo un error al enviar el mensaje.';
        }

        exit;
    }
}
add_action('wp_ajax_submit_error_report', 'handle_error_report_form');
add_action('wp_ajax_nopriv_submit_error_report', 'handle_error_report_form');

// Definir claves de reCaptcha (opcional)
// define('RECAPTCHA_SITE_KEY', 'TU_SITE_KEY');
// define('RECAPTCHA_SECRET_KEY', 'TU_SECRET_KEY');

양식의 기능


  • 쇼트코드:
[error_report_form]
  • 오류 신고를 위한 모달 양식을 여는 버튼을 표시합니다.
  • 이 양식에는 이름, 메시지 및 간단한 수학 캡차 입력란이 포함되어 있습니다.
  • 필드에 링크나 도메인이 입력되지 않았는지 확인합니다.
  • 블로그 관리자에게 오류에 대한 자세한 내용을 담은 이메일을 보냅니다.

  • 양식 필드
    :폴리랑 플레이스홀더는 수정하지 않습니다.

  • 유효성
    검사: 폴리랑 플레이스홀더는 수정하지 않습니다.

  • 양식 제출
    : 폴리랑 플레이스홀더는 수정하지 않습니다.

  • 스팸 방지
    : 폴리랑 플레이스홀더는 수정하지 않습니다.

양식 스타일


  • 오류 신고" 버튼
    :폴리랑 플레이스홀더는 수정하지 않습니다.

  • 모달(팝업 창)
    : 폴리랑 플레이스홀더는 수정하지 않습니다.
  • 닫기 핸들(모달을 닫는 버튼의 클래스는 id="closeModalBtn")
    :폴리랑 플레이스홀더는 수정하지 않습니다.
  • 양식 필드
    :폴리랑 플레이스홀더는 수정하지 않습니다.

  • 보내기" 버튼
    :폴리랑 자리 표시자는 수정하지 않습니다.

  • 오류 메시지
    :폴리랑 플레이스홀더가 수정되지 않습니다.
  • 성공 메시지
    :폴리랑 자리 표시자를 수정하지 않습니다.

스타일 수정 방법


  • 색상 수정
    : 폴리랑 플레이스홀더는 수정하지 않습니다.

  • 글꼴 크기 수정
    : 폴리랑 플레이스홀더는 수정하지 않습니다.

  • 테두리 및 둥근 모서리 수정
    : 폴리랑 플레이스홀더는 수정하지 않습니다.

  • 간격 수정
    : 폴리랑 플레이스홀더는 수정하지 않습니다.

  • 필드 너비 수정
    : 폴리랑 플레이스홀더는 수정하지 않습니다.

추가 옵션


  • 재캡차
    :폴리랑 자리 표시자는 수정하지 않습니다.

  • 이메일 개인화
    : 폴리랑 자리 표시자는 수정하지 않습니다.

사용 지침


  • 코드를 복사하여 테마의 functions.php 파일에 붙여넣습니다.
  • 페이지 또는 글에서 쇼트코드를 사용합니다.
  • 필요에 따라 스타일을 사용자 지정하세요.
  • 재캡차를 사용하려면 '추가 옵션' 섹션의 지침을 따르세요.

Suscripción por email

관련 문서

Leave a Comment

Este blog se aloja en LucusHost

LucusHost, el mejor hosting