{"id":331601,"date":"2026-07-02T09:22:28","date_gmt":"2026-07-02T09:22:28","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/tidy-contact-form\/"},"modified":"2026-07-02T09:21:55","modified_gmt":"2026-07-02T09:21:55","slug":"tidy-contact-form","status":"publish","type":"plugin","link":"https:\/\/ru.wordpress.org\/plugins\/tidy-contact-form\/","author":23467890,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.0.6","stable_tag":"2.0.6","tested":"7.0","requires":"6.0","requires_php":"8.2","requires_plugins":null,"header_name":"Tidy Contact Form","header_author":"Pierre","header_description":"Un formulaire de contact simple, rapide, s\u00e9curis\u00e9, sans marketing et sans tracking.","assets_banners_color":"7a39c6","last_updated":"2026-07-02 09:21:55","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/wordpress.org\/plugins\/tidy-contact-form\/","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":44,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"2.0.6":{"tag":"2.0.6","author":"pierreferrolliet","date":"2026-07-02 09:21:55"}},"upgrade_notice":{"2.0.1":"<p>WordPress.org compliance fix (External services documentation, textdomain auto-load).<\/p>","2.0.0":"<p>Initial release.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3593665,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3593665,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3593665,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3593665,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":{"tidy-contact-form\/form":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"tidy-contact-form\/form","version":"2.0.0","title":"Tidy Contact Form","category":"widgets","icon":"email-alt","description":"Display a simple, fast and secure contact form.","keywords":["contact","form","email","message"],"attributes":{"template":{"type":"string","default":""}},"supports":{"html":false,"multiple":true,"align":["wide","full"]},"textdomain":"tidy-contact-form","editorScript":"file:.\/editor.js","render":"file:.\/render.php"}},"tagged_versions":["2.0.6"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3593665,"resolution":"1","location":"assets","locale":"","width":1600,"height":1192},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3593665,"resolution":"2","location":"assets","locale":"","width":1600,"height":917}},"screenshots":{"1":"The contact form on the frontend (Default template)","2":"Settings \u2014 form design templates with live preview"}},"plugin_section":[262246],"plugin_tags":[362,358,267,361,2419],"plugin_category":[41,42,44],"plugin_contributors":[259182],"plugin_business_model":[],"class_list":["post-331601","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-captcha","plugin_tags-contact-form","plugin_tags-email","plugin_tags-form","plugin_tags-spam-protection","plugin_category-communication","plugin_category-contact-forms","plugin_category-discussion-and-community","plugin_contributors-pierreferrolliet","plugin_committers-pierreferrolliet"],"banners":{"banner":"https:\/\/ps.w.org\/tidy-contact-form\/assets\/banner-772x250.png?rev=3593665","banner_2x":"https:\/\/ps.w.org\/tidy-contact-form\/assets\/banner-1544x500.png?rev=3593665","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/tidy-contact-form\/assets\/icon-128x128.png?rev=3593665","icon_2x":"https:\/\/ps.w.org\/tidy-contact-form\/assets\/icon-256x256.png?rev=3593665","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/tidy-contact-form\/assets\/screenshot-1.png?rev=3593665","caption":"The contact form on the frontend (Default template)"},{"src":"https:\/\/ps.w.org\/tidy-contact-form\/assets\/screenshot-2.png?rev=3593665","caption":"Settings \u2014 form design templates with live preview"}],"raw_content":"<!--section=description-->\n<p>Tidy Contact Form is built on a simple promise: <strong>a contact form that just works<\/strong>.<\/p>\n\n<ul>\n<li>No page builder. No drag &amp; drop. No bloat.<\/li>\n<li>Gutenberg block + shortcode.<\/li>\n<li>Loads CSS and JS <strong>only<\/strong> on pages that use the form.<\/li>\n<li>Under 50 KB total.<\/li>\n<li>Zero required external dependencies.<\/li>\n<\/ul>\n\n<h4>Core features<\/h4>\n\n<ul>\n<li><strong>Gutenberg block:<\/strong> search \"Tidy Contact Form\" in the block inserter, with template picker in the sidebar<\/li>\n<li><strong>Shortcode:<\/strong> <code>[tidy_contact_form]<\/code> with attributes (template, email_to, subject, rgpd, id)<\/li>\n<li><strong>Fields:<\/strong> Name, Email, Subject, Phone (optional), Message, RGPD consent checkbox<\/li>\n<li><strong>Security:<\/strong> WordPress nonce + honeypot + time-check + IP rate limiting<\/li>\n<li><strong>Anti-spam CAPTCHA:<\/strong> Google reCAPTCHA v3 (invisible) or Cloudflare Turnstile (privacy-friendly)<\/li>\n<li><strong>Emails:<\/strong> Admin notification + optional auto-reply to sender<\/li>\n<li><strong>SMTP:<\/strong> Built-in SMTP configuration for reliable delivery<\/li>\n<li><strong>5 templates:<\/strong> Default, Minimal, Card, Inline (2-col), Dark<\/li>\n<li><strong>Dark mode:<\/strong> Auto via CSS custom properties<\/li>\n<li><strong>Works without JavaScript:<\/strong> Progressive enhancement with admin-post.php fallback<\/li>\n<\/ul>\n\n<h4>Message management<\/h4>\n\n<ul>\n<li><strong>Message storage:<\/strong> All submissions saved as a Custom Post Type<\/li>\n<li><strong>Unread badge:<\/strong> Unread message count in the admin menu<\/li>\n<li><strong>Dashboard widget:<\/strong> Recent messages and statistics at a glance<\/li>\n<li><strong>CSV export:<\/strong> One-click download from the messages list<\/li>\n<li><strong>Auto-purge:<\/strong> Delete messages older than X days<\/li>\n<\/ul>\n\n<h4>Integrations<\/h4>\n\n<ul>\n<li><strong>Webhooks:<\/strong> Generic JSON (Zapier, Make, n8n), Slack, Discord<\/li>\n<li><strong>Mailing lists:<\/strong> MailerLite, Brevo, ConvertKit, SendGrid<\/li>\n<li><strong>Import\/Export:<\/strong> Transfer settings between sites as JSON<\/li>\n<\/ul>\n\n<h4>What we deliberately left out<\/h4>\n\n<p>No drag-and-drop builder. No conditional logic engine. No CRM. No upsells. No tracking pixels.<\/p>\n\n<h4>More from Tidy Plugins<\/h4>\n\n<p>If you like this plugin, take a look at the rest of the Tidy suite:<\/p>\n\n<ul>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/tidy-table-of-contents\/\">Tidy Table of Contents<\/a> \u2014 automatic, accessible table of contents<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/tidy-draft-share\/\">Tidy Draft Share<\/a> \u2014 share drafts via secure, expiring preview links<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/tidy-author-box\/\">Tidy Author Box<\/a> \u2014 author bio box with avatar and social links<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/tidy-broken-link-scan\/\">Tidy Broken Link Scan<\/a> \u2014 find broken links and images, no external service<\/li>\n<\/ul>\n\n<h3>External services<\/h3>\n\n<p>This plugin can connect to several third-party services. <strong>All of them are strictly opt-in<\/strong>: no external request is made unless the corresponding option is enabled and credentials\/URLs are configured in the plugin settings.<\/p>\n\n<p><strong>Google reCAPTCHA v3<\/strong> (anti-spam, optional)\n* Host: <code>www.google.com\/recaptcha\/api\/siteverify<\/code> (server side) and <code>www.google.com\/recaptcha\/api.js<\/code> (loaded in the browser).\n* What is sent: the user's reCAPTCHA token, the site secret key, and the visitor's IP address (Google may also collect cookies and browsing data \u2014 see Google's policy).\n* When: each time a visitor submits the form, only if \"Google reCAPTCHA v3\" is selected and a secret key is configured.\n* Privacy: https:\/\/policies.google.com\/privacy \u2014 Terms: https:\/\/policies.google.com\/terms<\/p>\n\n<p><strong>Cloudflare Turnstile<\/strong> (privacy-friendly CAPTCHA, optional)\n* Host: <code>challenges.cloudflare.com\/turnstile\/v0\/siteverify<\/code> (server side) and <code>challenges.cloudflare.com\/turnstile\/v0\/api.js<\/code> (loaded in the browser).\n* What is sent: the Turnstile response token and the site secret key.\n* When: each time a visitor submits the form, only if \"Cloudflare Turnstile\" is selected and a secret key is configured.\n* Privacy: https:\/\/www.cloudflare.com\/privacypolicy\/ \u2014 Terms: https:\/\/www.cloudflare.com\/website-terms\/<\/p>\n\n<p><strong>Webhooks<\/strong> (Slack, Discord, generic JSON for Zapier \/ Make \/ n8n, optional)\n* Host: any URL you configure in the Integrations tab (for example <code>hooks.slack.com<\/code>, <code>discord.com\/api\/webhooks<\/code>, your own endpoint).\n* What is sent: a JSON payload with the submitted form fields (name, email, subject, message, site URL, timestamp).\n* When: each time a visitor submits the form, only if at least one webhook URL is filled in.\n* Privacy\/Terms: Slack \u2014 https:\/\/slack.com\/privacy and https:\/\/slack.com\/terms-of-service ; Discord \u2014 https:\/\/discord.com\/privacy and https:\/\/discord.com\/terms ; for generic endpoints, see the policy of the service you point to.<\/p>\n\n<p><strong>Mailing-list providers<\/strong> (MailerLite, Brevo, ConvertKit, SendGrid, optional)\n* Hosts: <code>connect.mailerlite.com<\/code>, <code>api.brevo.com<\/code>, <code>api.convertkit.com<\/code>, <code>api.sendgrid.com<\/code>.\n* What is sent: the visitor's email address and first name, plus your API key and the configured list\/group identifier.\n* When: each time a visitor submits the form, only if one of these providers is selected, an API key is configured, and the visitor ticked the corresponding opt-in checkbox.\n* Privacy\/Terms: MailerLite \u2014 https:\/\/www.mailerlite.com\/privacy-policy and https:\/\/www.mailerlite.com\/legal\/terms-of-service ; Brevo \u2014 https:\/\/www.brevo.com\/legal\/privacypolicy\/ and https:\/\/www.brevo.com\/legal\/termsofuse\/ ; ConvertKit \u2014 https:\/\/convertkit.com\/privacy and https:\/\/convertkit.com\/terms ; SendGrid \u2014 https:\/\/www.twilio.com\/en-us\/legal\/privacy and https:\/\/www.twilio.com\/en-us\/legal\/tos<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>tidy-contact-form<\/code> folder to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate in <strong>Plugins &gt; Installed Plugins<\/strong>.<\/li>\n<li>Go to <strong>Contact Form &gt; Settings<\/strong> to configure.<\/li>\n<li>Add the form to any page or post:\n\n<ul>\n<li><strong>Gutenberg:<\/strong> Search \"Tidy Contact Form\" in the block inserter<\/li>\n<li><strong>Shortcode:<\/strong> Add <code>[tidy_contact_form]<\/code> to your content<\/li>\n<\/ul><\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"how%20do%20i%20add%20the%20form%20to%20a%20page%3F\"><h3>How do I add the form to a page?<\/h3><\/dt>\n<dd><p>In the Gutenberg editor, click the block inserter (+) and search for \"Tidy Contact Form\". You can also use the shortcode <code>[tidy_contact_form]<\/code> in any page, post, or widget.<\/p><\/dd>\n<dt id=\"how%20do%20i%20change%20the%20recipient%20email%3F\"><h3>How do I change the recipient email?<\/h3><\/dt>\n<dd><p>Go to <strong>Contact Form &gt; Settings &gt; Emails<\/strong> and update the \"Send to\" field.<\/p><\/dd>\n<dt id=\"can%20i%20change%20the%20form%20template%3F\"><h3>Can I change the form template?<\/h3><\/dt>\n<dd><p>Yes. Go to <strong>Contact Form &gt; Settings &gt; Form &gt; Design<\/strong> to set the default template. You can also override it per form: use the block sidebar setting or the shortcode attribute <code>[tidy_contact_form template=\"card\"]<\/code>.<\/p><\/dd>\n<dt id=\"can%20i%20use%20the%20form%20multiple%20times%20on%20the%20same%20page%3F\"><h3>Can I use the form multiple times on the same page?<\/h3><\/dt>\n<dd><p>Yes \u2013 use the <code>id<\/code> attribute: <code>[tidy_contact_form id=\"form-1\"]<\/code> and <code>[tidy_contact_form id=\"form-2\"]<\/code>.<\/p><\/dd>\n<dt id=\"is%20gdpr%20%2F%20rgpd%20compliance%20built%20in%3F\"><h3>Is GDPR \/ RGPD compliance built in?<\/h3><\/dt>\n<dd><p>The plugin includes an optional consent checkbox with a configurable privacy policy link. You are responsible for your site's full compliance.<\/p><\/dd>\n<dt id=\"does%20it%20work%20without%20javascript%3F\"><h3>Does it work without JavaScript?<\/h3><\/dt>\n<dd><p>Yes. The form submits via <code>admin-post.php<\/code> as a standard HTML POST when JS is unavailable.<\/p><\/dd>\n<dt id=\"how%20does%20rate%20limiting%20work%3F\"><h3>How does rate limiting work?<\/h3><\/dt>\n<dd><p>Each IP address is limited to a configurable number of submissions per period (default: 3 per hour). Tracked with WordPress transients \u2013 no custom database tables.<\/p><\/dd>\n<dt id=\"where%20are%20my%20messages%20stored%3F\"><h3>Where are my messages stored?<\/h3><\/dt>\n<dd><p>All submissions are stored as a Custom Post Type in your WordPress database. View them under <strong>Contact Form &gt; Messages<\/strong>. You can export them as CSV.<\/p><\/dd>\n<dt id=\"can%20i%20send%20submissions%20to%20slack%20or%20discord%3F\"><h3>Can I send submissions to Slack or Discord?<\/h3><\/dt>\n<dd><p>Yes. Go to <strong>Contact Form &gt; Settings &gt; Advanced &gt; Webhooks<\/strong> and paste your Slack or Discord incoming webhook URL.<\/p><\/dd>\n<dt id=\"can%20i%20subscribe%20form%20submitters%20to%20my%20mailing%20list%3F\"><h3>Can I subscribe form submitters to my mailing list?<\/h3><\/dt>\n<dd><p>Yes. Go to <strong>Contact Form &gt; Settings &gt; Advanced &gt; Mailing list<\/strong> and configure your provider (MailerLite, Brevo, ConvertKit, or SendGrid).<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.0.6<\/h4>\n\n<ul>\n<li>Hardened output escaping of extension-provided custom-field markup and wrapper attributes (<code>wp_kses()<\/code> \/ <code>esc_attr()<\/code>), removing all <code>phpcs:ignore<\/code> escape suppressions.<\/li>\n<li>The Gutenberg block now renders through the escaped <code>TDCF_Form::output()<\/code> path instead of echoing shortcode output.<\/li>\n<li>SMTP password is stored without <code>sanitize_text_field()<\/code> so special characters are preserved.<\/li>\n<\/ul>\n\n<h4>2.0.5<\/h4>\n\n<ul>\n<li>Fixed a fatal error on the Contact Form admin screen caused by an undefined constant when loading script translations.<\/li>\n<li>Replaced PHP short echo tags for WordPress.org coding standards compliance.<\/li>\n<\/ul>\n\n<h4>2.0.4<\/h4>\n\n<ul>\n<li>Custom fields are no longer capped at 5 \u2014 the form supports the full set (up to 50) for everyone.<\/li>\n<\/ul>\n\n<h4>2.0.3<\/h4>\n\n<ul>\n<li>WordPress.org coding-standards hardening: translators comments for all i18n placeholders (Plugin Check compliance).<\/li>\n<\/ul>\n\n<h4>2.0.2<\/h4>\n\n<ul>\n<li>Hardened admin output escaping: settings and dashboard output now run through <code>wp_kses()<\/code>\/<code>esc_attr()<\/code>\/<code>(int)<\/code> casts, and <code>TDCF_Form<\/code> gains an <code>output()<\/code> method for direct escaped rendering (WordPress.org coding-standards compliance).<\/li>\n<\/ul>\n\n<h4>2.0.1<\/h4>\n\n<ul>\n<li>Added the required \"External services\" section to readme.txt documenting Google reCAPTCHA, Cloudflare Turnstile, webhook destinations and mailing-list providers (WordPress.org guideline 6 compliance).<\/li>\n<li>Removed the <code>load_plugin_textdomain()<\/code> call; translations are auto-loaded by WordPress.org since WP 4.6.<\/li>\n<\/ul>\n\n<h4>2.0.0<\/h4>\n\n<ul>\n<li>Initial release with all features.<\/li>\n<\/ul>","raw_excerpt":"A simple, fast, and secure contact form. No marketing. No tracking. Under 50 KB.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ru.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/331601","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ru.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ru.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ru.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=331601"}],"author":[{"embeddable":true,"href":"https:\/\/ru.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/pierreferrolliet"}],"wp:attachment":[{"href":"https:\/\/ru.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=331601"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ru.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=331601"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ru.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=331601"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ru.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=331601"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ru.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=331601"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ru.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=331601"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}