Как добавить на сайт форму добавления записей для пользователей, чтобы сразу создался черновик
в файл functions.php (уберите пробелы в тегах скрипта)
// 1. Регистрация маршрута REST API add_action( 'rest_api_init', function () { register_rest_route( 'russia247/v1', '/submit-draft', array( 'methods' => 'POST', 'callback' => 'handle_guest_news_submission', 'permission_callback' => '__return_true', ) ); } ); // 2. Функция обработки данных формы function handle_guest_news_submission( WP_REST_Request $request ) { $params = $request->get_json_params(); // Защита от ботов (Honeypot) if ( ! empty( $params['website'] ) ) { return new WP_REST_Response( array( 'success' => true ), 200 ); } // Очистка данных $author_name = sanitize_text_field( $params['authorName'] ?? '' ); $email = sanitize_email( $params['email'] ?? '' ); $title = sanitize_text_field( $params['title'] ?? '' ); $summary = sanitize_textarea_field( $params['summary'] ?? '' ); $content = sanitize_textarea_field( $params['content'] ?? '' ); $images_raw = sanitize_textarea_field( $params['images'] ?? '' ); // Проверки if ( empty( $author_name ) || empty( $email ) || empty( $title ) || empty( $content ) ) { return new WP_Error( 'missing_fields', 'Заполните обязательные поля', array( 'status' => 400 ) ); } if ( ! is_email( $email ) ) { return new WP_Error( 'invalid_email', 'Некорректный email', array( 'status' => 400 ) ); } if ( strlen( $content ) < 100 ) { return new WP_Error( 'short_content', 'Текст слишком короткий', array( 'status' => 400 ) ); } // Формирование красивого контента для админки $post_content = ''; // 1. Имя и Email автора $post_content .= "<p><strong>Предложил:</strong> " . esc_html( $author_name ) . " (" . esc_html( $email ) . ")</p>\n"; $post_content .= "<hr>\n"; // 2. Лид (аннотация) if ( ! empty( $summary ) ) { $post_content .= "<p><strong>Аннотация:</strong><br>" . nl2br( esc_html( $summary ) ) . "</p>\n"; $post_content .= "<hr>\n"; } // 3. Ссылки на изображения $images_array = array_filter( array_map( 'trim', explode( "\n", $images_raw ) ) ); if ( ! empty( $images_array ) ) { $post_content .= "<p><strong>Ссылки на изображения:</strong></p>\n<ul>\n"; foreach ( $images_array as $img ) { if ( filter_var( $img, FILTER_VALIDATE_URL ) ) { $post_content .= "<li>" . esc_url( $img ) . "</li>\n"; } } $post_content .= "</ul>\n"; $post_content .= "<hr>\n"; } // 4. Основной текст статьи $post_content .= "<p><strong>Текст статьи:</strong></p>\n" . wpautop( esc_html( $content ) ); // Создание черновика $post_id = wp_insert_post( array( 'post_title' => wp_strip_all_tags( $title ), 'post_content' => $post_content, 'post_status' => 'draft', 'post_author' => 0, 'post_category' => array( get_option( 'default_category' ) ), ) ); if ( is_wp_error( $post_id ) ) { return new WP_Error( 'db_error', 'Ошибка базы данных', array( 'status' => 500 ) ); } // Сохраняем данные автора в мета-полях (для удобства сортировки или плагинов) update_post_meta( $post_id, '_guest_author_name', $author_name ); update_post_meta( $post_id, '_guest_author_email', $email ); return new WP_REST_Response( array( 'success' => true, 'message' => 'Новость успешно отправлена на модерацию.' ), 200 ); } // 3. Передача актуального ключа безопасности (nonce) для избежания ошибки куки add_action( 'wp_footer', function() { ?> < script> window.russia247FormData = { apiUrl: '<?php echo esc_url_raw( rest_url( 'russia247/v1/submit-draft' ) ); ?>', nonce: '<?php echo wp_create_nonce( 'wp_rest' ); ?>' }; </ script> <?php } );на сайте вставляем код (уберите пробелы в тегах стилей и скрипта)
<!-- Кнопка вызова формы --> <button type="button" id="openArticleModalBtn" class="modal-trigger-btn">Предложить новость</button> <!-- Модальное окно --> <div id="articleModal" class="modal-overlay" aria-hidden="true"> <div class="modal-content" role="dialog" aria-modal="true" aria-labelledby="modalTitle"> <button type="button" class="modal-close-btn" aria-label="Закрыть окно">×</button> <h2 id="modalTitle">Предложить новость</h2> <div class="form-wrapper"> <!-- Форма --> <form id="articleForm" novalidate> <div class="form-group"> <label for="authorName">Имя (как будет указано в публикации) *</label> <input type="text" id="authorName" name="authorName" required minlength="2" maxlength="80"> </div> <div class="form-group"> <label for="email">Email *</label> <input type="email" id="email" name="email" required> </div> <div class="form-group"> <label for="title">Заголовок *</label> <input type="text" id="title" name="title" required minlength="5" maxlength="200"> </div> <div class="form-group"> <label for="summary">Короткая аннотация (лид)</label> <input type="text" id="summary" name="summary" maxlength="300"> </div> <div class="form-group"> <label for="content">Текст *</label> <textarea id="content" name="content" required minlength="100" rows="10" placeholder="Минимум 100 символов."></textarea> </div> <div class="form-group"> <label for="images">Ссылки на изображения (каждая с новой строки)</label> <textarea id="images" name="images" rows="3" placeholder="https://example.com/img1.jpg https://example.com/img2.jpg"></textarea> </div> <!-- Honeypot для защиты от ботов --> <input type="text" name="website" tabindex="-1" autocomplete="off" class="honeypot-field"> <div class="form-group checkbox-group"> <label class="checkbox-label"> <input type="checkbox" name="agreeTerms" required checked> Я согласен с <a href="https://russia247.ru/privacy.html" target="_blank" rel="noopener">правилами публикации</a> * </label> </div> <div class="form-group checkbox-group"> <label class="checkbox-label"> <input type="checkbox" name="agreePrivacy" required checked> Согласен на <a href="https://russia247.ru/privacy.html" target="_blank" rel="noopener">обработку персональных данных</a> * </label> </div> <button type="submit" class="submit-btn">Отправить на модерацию</button> <div id="formStatus" class="form-status" role="status" aria-live="polite"></div> </form> <!-- Блок успешной отправки (скрыт по умолчанию) --> <div id="formSuccess" class="form-success-message"> <p>Спасибо! Ваша новость отправлена на модерацию.</p> </div> </div> </div> </div> < style> /* Кнопка вызова */ .modal-trigger-btn { display: inline-block; padding: 0 20px; color: #ffffff; border: none; border-radius: 4px; background-color: #bf0a30; font-weight: 600; cursor: pointer; transition: background-color 0.2s; } .modal-trigger-btn:hover { background-color: #222; } /* Затемнение фона */ .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.7); display: flex; align-items: center; justify-content: center; z-index: 9999; opacity: 0; visibility: hidden; transition: opacity 0.3s ease, visibility 0.3s ease; padding: 20px; box-sizing: border-box; } .modal-overlay.active { opacity: 1; visibility: visible; } /* Контент модального окна */ .modal-content { background-color: #ffffff; width: 100%; max-width: 800px; max-height: 90vh; overflow-y: auto; border-radius: 8px; padding: 30px; position: relative; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); transform: translateY(-20px); transition: transform 0.3s ease; } .modal-overlay.active .modal-content { transform: translateY(0); } /* Кнопка закрытия */ .modal-close-btn { position: absolute; top: 15px; right: 20px; background: none; border: none; font-size: 32px; line-height: 1; color: #666666; cursor: pointer; padding: 0; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; transition: color 0.2s; } .modal-close-btn:hover { color: #000000; } /* Обертка формы */ .form-wrapper { position: relative; } /* Стили формы */ .modal-content h2 { margin-top: 0; margin-bottom: 20px; font-size: 24px; color: #333333; } .form-group { margin-bottom: 16px; } .form-group label { display: block; margin-bottom: 6px; font-weight: 500; color: #333333; font-size: 14px; } .form-group input[type="text"], .form-group input[type="email"], .form-group textarea { width: 100%; padding: 10px 12px; border: 1px solid #cccccc; border-radius: 4px; font-size: 15px; font-family: inherit; box-sizing: border-box; transition: border-color 0.2s; } .form-group input:focus, .form-group textarea:focus { border-color: #0056b3; outline: none; } .checkbox-group { margin-top: 20px; } .checkbox-label { display: flex; align-items: flex-start; gap: 8px; font-weight: 400; font-size: 14px; cursor: pointer; } .checkbox-label input[type="checkbox"] { margin-top: 3px; cursor: pointer; } .checkbox-label a { color: #0056b3; text-decoration: underline; } .checkbox-label a:hover { text-decoration: none; } .submit-btn { display: block; width: 100%; padding: 12px 20px; background-color: #bf0a30; color: #ffffff; border: none; border-radius: 4px; font-weight: 600; cursor: pointer; margin-top: 24px; transition: background-color 0.2s; } .submit-btn:hover { background-color: #222; } .submit-btn:disabled { background-color: #999; cursor: not-allowed; } .form-status { margin-top: 12px; font-size: 14px; text-align: center; } .form-status.error { color: #dc3545; } /* Скрытие honeypot */ .honeypot-field { position: absolute; left: -9999px; opacity: 0; } /* --- Скрытие формы при успешной отправке --- */ #articleForm.is-hidden { display: none; } /* --- Сообщение об успешной отправке --- */ .form-success-message { display: none; text-align: center; padding: 40px 20px; } .form-success-message.is-visible { display: block; animation: fadeInUp 0.4s ease forwards; } @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .form-success-message p { font-size: 18px; font-weight: 600; margin-bottom: 0; line-height: 1.4; } /* Адаптивность для мобильных */ @media (max-width: 600px) { .modal-content { padding: 20px; max-height: 95vh; } .modal-close-btn { top: 10px; right: 10px; } } </ style> < script> document.addEventListener('DOMContentLoaded', function() { const modal = document.getElementById('articleModal'); const openBtn = document.getElementById('openArticleModalBtn'); const closeBtn = document.querySelector('.modal-close-btn'); const form = document.getElementById('articleForm'); const statusDiv = document.getElementById('formStatus'); const formSuccess = document.getElementById('formSuccess'); if (!openBtn || !modal || !form) return; // Открытие модального окна openBtn.addEventListener('click', function() { modal.classList.add('active'); modal.setAttribute('aria-hidden', 'false'); document.body.style.overflow = 'hidden'; }); // Закрытие модального окна и сброс формы function closeModal() { modal.classList.remove('active'); modal.setAttribute('aria-hidden', 'true'); document.body.style.overflow = ''; // Сбрасываем состояние с небольшой задержкой для плавности setTimeout(() => { form.reset(); form.classList.remove('is-hidden'); formSuccess.classList.remove('is-visible'); statusDiv.textContent = ''; statusDiv.className = 'form-status'; form.agreeTerms.checked = true; form.agreePrivacy.checked = true; }, 300); } closeBtn.addEventListener('click', closeModal); modal.addEventListener('click', function(e) { if (e.target === modal) { closeModal(); } }); document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && modal.classList.contains('active')) { closeModal(); } }); // Обработка отправки формы form.addEventListener('submit', async function(e) { e.preventDefault(); statusDiv.textContent = ''; statusDiv.className = 'form-status'; if (form.website && form.website.value) { return; } if (!form.checkValidity()) { statusDiv.textContent = 'Пожалуйста, заполните все обязательные поля корректно.'; statusDiv.classList.add('error'); return; } const submitBtn = form.querySelector('.submit-btn'); submitBtn.disabled = true; submitBtn.textContent = 'Отправка...'; const formData = { authorName: form.authorName.value.trim(), email: form.email.value.trim().toLowerCase(), title: form.title.value.trim(), summary: form.summary.value.trim(), content: form.content.value, images: form.images.value, agreeTerms: form.agreeTerms.checked, agreePrivacy: form.agreePrivacy.checked, website: form.website ? form.website.value : '' }; try { const apiData = window.russia247FormData || {}; const apiUrl = apiData.apiUrl || '/wp-json/russia247/v1/submit-draft'; const apiNonce = apiData.nonce || ''; const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': apiNonce }, body: JSON.stringify(formData) }); const result = await response.json(); if (!response.ok) { throw new Error(result.message || 'Ошибка сервера: ' + response.status); } // Успешная отправка: скрываем форму, показываем сообщение form.classList.add('is-hidden'); formSuccess.classList.add('is-visible'); } catch (error) { statusDiv.textContent = 'Ошибка: ' + error.message; statusDiv.classList.add('error'); } finally { submitBtn.disabled = false; submitBtn.textContent = 'Отправить на модерацию'; } }); }); </ script>
Как добавить на сайт форму добавления в базу данных Knowledge Base (basepress) для пользователей, чтобы сразу создался черновик
https://zaplata.ru/forum/scripts/kak-dobavit-na-sajt-formu-dobavleniya-v-bazu-dannyh-knowledge-base-basepress-dlya-polzovatelej-chtoby-srazu-sozdalsya-chernovik