{"id":371779,"date":"2026-09-24T20:21:46","date_gmt":"2026-09-24T20:21:46","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/leadgate-content-locker\/"},"modified":"2026-10-16T02:07:16","modified_gmt":"2026-10-16T02:07:16","slug":"g-wiz-it-content-locker","status":"publish","type":"plugin","link":"https:\/\/kaa.wordpress.org\/plugins\/g-wiz-it-content-locker\/","author":23569464,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.12.0","stable_tag":"1.12.0","tested":"7.1.3","requires":"6.5","requires_php":"7.4","requires_plugins":null,"header_name":"GWiz IT Content Locker","header_author":"GWiz IT","header_description":"Turn your WordPress content and downloads into leads \u2014 self-hosted lead generation for gating content, collecting subscribers, and tracking conversions.","assets_banners_color":"558dae","last_updated":"2026-10-16 02:07:16","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/gwizit.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":281,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.12.0":{"tag":"1.12.0","author":"gbecker1983","date":"2026-10-16 02:07:16","revision":3749560}},"upgrade_notice":{"1.7.3":"<p>Bug-fix update: area renaming (Enter and click-outside now save, Escape cancels), the area color picker, and default templates for new areas. Hard-refresh the admin page or clear caches after updating so the updated scripts load.<\/p>","1.7.2":"<p>Compliance update: asset enqueuing, output escaping, and text domain now follow WordPress.org plugin review requirements. No functional changes. Clear any page cache after updating.<\/p>","1.7.0":"<p>Breaking rename release: plugin renamed to &quot;GWiz IT Content Locker&quot;. Shortcode, database tables, and all internal names changed. Export your areas before upgrading, then import after. Update any [gwiz_leadgate] shortcodes in your content to [gwiz_it_content_locker].<\/p>","1.6.2":"<p>WordPress coding standards compliance update. All PHPCS errors and warnings resolved. No functional changes. Clear any page cache after updating.<\/p>","1.6.1":"<p>Bug fix: inline signup forms now correctly hide after dismissing the popup in debug mode. Clear any page cache after updating.<\/p>","1.6.0":"<p>Feature release: clone, export, and import restricted areas with optional contact migration. Backup files include version metadata for safe restores across plugin updates. Clear any page cache after updating.<\/p>","1.5.1":"<p>UI polish release: colored action buttons, stacked style sections, and a labeled preview. Clear any page cache after updating.<\/p>","1.5.0":"<p>Feature release: form\/popup style presets with per-field controls, a unified Form Template editor (now including the Confirm Notice), and an interactive preview modal. Clear any page cache after updating.<\/p>","1.4.1":"<p>UI polish release: debug banner stays at the bottom of the popup with a cookie status line, and admin modals scroll inside the browser window. Clear any page cache after updating.<\/p>","1.4.0":"<p>Feature release: new AJAX &quot;already signed up&quot; \/ &quot;not signed up&quot; flows with templates managed inside the Popup Template editor. Clear any page cache after updating.<\/p>","1.3.2":"<p>Bug fix release: the &quot;Already signed up&quot; link in the inline signup form now works correctly. Clear any page cache after updating.<\/p>","1.3.1":"<p>Bug fix release: CSS-selector gates now reliably hide the locked element and show the signup form until the visitor signs up. Clear any page cache after updating.<\/p>","1.3.0":"<p>Major feature release: inline shortcodes, form builder, email templates, signups viewer with CSV export, statistics, HMAC-signed cookies, and frontend builder support.<\/p>","1.2.0":"<p>Per-area toggles, color picker, and improved settings architecture.<\/p>","1.0.0":"<p>Initial release. Installs the GWiz IT Content Locker administration dashboard and prepares the foundation for lead-gating features.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3711955,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3711955,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3711955,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3711955,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.12.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3711955,"resolution":"1","location":"assets","locale":"","width":747,"height":543},"screenshot-10.png":{"filename":"screenshot-10.png","revision":3711955,"resolution":"10","location":"assets","locale":"","width":1164,"height":542},"screenshot-11.png":{"filename":"screenshot-11.png","revision":3711955,"resolution":"11","location":"assets","locale":"","width":1144,"height":465},"screenshot-12.png":{"filename":"screenshot-12.png","revision":3711955,"resolution":"12","location":"assets","locale":"","width":1147,"height":376},"screenshot-13.png":{"filename":"screenshot-13.png","revision":3711955,"resolution":"13","location":"assets","locale":"","width":1205,"height":480},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3711955,"resolution":"2","location":"assets","locale":"","width":1406,"height":1024},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3711955,"resolution":"3","location":"assets","locale":"","width":994,"height":1248},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3711955,"resolution":"4","location":"assets","locale":"","width":1018,"height":786},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3711955,"resolution":"5","location":"assets","locale":"","width":1144,"height":1101},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3711955,"resolution":"6","location":"assets","locale":"","width":1165,"height":1258},"screenshot-7.png":{"filename":"screenshot-7.png","revision":3711955,"resolution":"7","location":"assets","locale":"","width":1168,"height":1258},"screenshot-8.png":{"filename":"screenshot-8.png","revision":3711955,"resolution":"8","location":"assets","locale":"","width":1183,"height":1035},"screenshot-9.png":{"filename":"screenshot-9.png","revision":3711955,"resolution":"9","location":"assets","locale":"","width":1146,"height":1244}},"screenshots":{"1":"Signup form visitors use to unlock protected content or downloads.","2":"Manage multiple Restricted Areas from one WordPress dashboard.","3":"Configure what each Restricted Area protects and how access is granted.","4":"Build custom lead-capture forms with drag-and-drop fields.","5":"Customize confirmation and congratulations emails.","6":"Customize signup form and popup templates.","7":"Match forms and popups to your website with built-in styling controls.","8":"Preview signup forms and popup states before publishing.","9":"Connect confirmed subscribers to popular email marketing platforms.","10":"Choose from multiple spam-protection and security options.","11":"Protect an entire WordPress page or post by URL.","12":"View, search, and export collected subscribers.","13":"Track views, submissions, confirmations, and conversion performance."}},"plugin_section":[],"plugin_tags":[4252,264,11644,11463,337],"plugin_category":[],"plugin_contributors":[282558,282559],"plugin_business_model":[],"class_list":["post-371779","plugin","type-plugin","status-publish","hentry","plugin_tags-content-locker","plugin_tags-email-marketing","plugin_tags-gated-content","plugin_tags-lead-capture","plugin_tags-lead-generation","plugin_contributors-gbecker1983","plugin_contributors-gwizit","plugin_committers-gbecker1983"],"banners":{"banner":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/banner-772x250.png?rev=3711955","banner_2x":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/banner-1544x500.png?rev=3711955","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/icon-128x128.png?rev=3711955","icon_2x":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/icon-256x256.png?rev=3711955","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-1.png?rev=3711955","caption":"Signup form visitors use to unlock protected content or downloads."},{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-2.png?rev=3711955","caption":"Manage multiple Restricted Areas from one WordPress dashboard."},{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-3.png?rev=3711955","caption":"Configure what each Restricted Area protects and how access is granted."},{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-4.png?rev=3711955","caption":"Build custom lead-capture forms with drag-and-drop fields."},{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-5.png?rev=3711955","caption":"Customize confirmation and congratulations emails."},{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-6.png?rev=3711955","caption":"Customize signup form and popup templates."},{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-7.png?rev=3711955","caption":"Match forms and popups to your website with built-in styling controls."},{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-8.png?rev=3711955","caption":"Preview signup forms and popup states before publishing."},{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-9.png?rev=3711955","caption":"Connect confirmed subscribers to popular email marketing platforms."},{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-10.png?rev=3711955","caption":"Choose from multiple spam-protection and security options."},{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-11.png?rev=3711955","caption":"Protect an entire WordPress page or post by URL."},{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-12.png?rev=3711955","caption":"View, search, and export collected subscribers."},{"src":"https:\/\/ps.w.org\/g-wiz-it-content-locker\/assets\/screenshot-13.png?rev=3711955","caption":"Track views, submissions, confirmations, and conversion performance."}],"raw_content":"<!--section=description-->\n<p><strong>Turn your WordPress content and downloads into leads.<\/strong><\/p>\n\n<p>GWiz IT Content Locker lets you place pages, downloads, sections of content, or individual page elements behind a customizable signup form.<\/p>\n\n<p>Visitors enter their information to unlock your content, giving you a simple way to grow your email list, offer lead magnets, protect downloads, and measure conversions directly from WordPress.<\/p>\n\n<p>The plugin is free and self-hosted. No third-party SaaS service is required to use the content locker or store your signups.<\/p>\n\n<p>Want to use an existing email marketing platform? Confirmed subscribers can optionally be synced automatically to Mailchimp, Brevo, ConvertKit, ActiveCampaign, or phpList.<\/p>\n\n<h4>Watch It In Action<\/h4>\n\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=ADKbOwe-LFw\">GWiz IT Content Locker \u2014 demo video<\/a><\/p>\n\n<h4>What Can You Lock?<\/h4>\n\n<ul>\n<li><strong>Pages and Posts<\/strong> \u2014 Gate an entire WordPress page or post by URL.<\/li>\n<li><strong>File Downloads<\/strong> \u2014 Require visitors to sign up before accessing protected files.<\/li>\n<li><strong>Sections of Content<\/strong> \u2014 Wrap selected content in a simple shortcode.<\/li>\n<li><strong>Page Elements<\/strong> \u2014 Lock specific elements using CSS selectors.<\/li>\n<li><strong>Popup Offers<\/strong> \u2014 Open a signup gate from a custom link anywhere on your site.<\/li>\n<\/ul>\n\n<h4>Great For<\/h4>\n\n<ul>\n<li>Lead magnets<\/li>\n<li>PDF and document downloads<\/li>\n<li>Free guides and checklists<\/li>\n<li>Resource libraries<\/li>\n<li>Bonus content<\/li>\n<li>Email list building<\/li>\n<li>Gated articles or page sections<\/li>\n<li>Downloadable marketing materials<\/li>\n<li>Members-only style resources without requiring a full membership plugin<\/li>\n<\/ul>\n\n<h4>How It Works<\/h4>\n\n<ol>\n<li>Create a Restricted Area in WordPress.<\/li>\n<li>Choose what you want to protect.<\/li>\n<li>Customize your signup form and unlock message.<\/li>\n<li>Visitors complete the form to gain access.<\/li>\n<li>View signups and conversion statistics in WordPress or optionally sync subscribers to your email marketing platform.<\/li>\n<\/ol>\n\n<p>You can create multiple Restricted Areas, each with its own protected content, form, styling, settings, integrations, and subscriber list.<\/p>\n\n<h4>Lead Capture &amp; Content Gating<\/h4>\n\n<ul>\n<li><strong>Multiple Restricted Areas<\/strong> \u2014 Create separate gates for different downloads, pages, campaigns, or content.<\/li>\n<li><strong>Custom Form Builder<\/strong> \u2014 Build signup forms with drag-and-drop fields and 9 available field types. The email field is always required.<\/li>\n<li><strong>Inline Shortcodes<\/strong> \u2014 Gate only part of a page using <code>[gwiz_it_content_locker]<\/code>.<\/li>\n<li><strong>Full-Page Gating<\/strong> \u2014 Protect an entire page or post by URL.<\/li>\n<li><strong>Protected Downloads<\/strong> \u2014 Require signup before visitors can access gated files.<\/li>\n<li><strong>CSS Selector Gating<\/strong> \u2014 Lock specific page elements without changing your page layout: show a customisable sign-up placeholder, or keep the classic visual lock.<\/li>\n<li><strong>Popup Trigger Links<\/strong> \u2014 Open a content-locker popup from a custom anchor link.<\/li>\n<li><strong>Double Opt-In<\/strong> \u2014 Optionally require email confirmation before granting access.<\/li>\n<li><strong>Already Signed Up Verification<\/strong> \u2014 Returning subscribers can verify their email and regain access.<\/li>\n<\/ul>\n\n<h4>Forms &amp; Styling<\/h4>\n\n<ul>\n<li><strong>Visual Form Builder<\/strong> \u2014 Create custom signup forms without coding.<\/li>\n<li><strong>Custom Email Templates<\/strong> \u2014 Edit confirmation and congratulations emails.<\/li>\n<li><strong>Custom Popup Templates<\/strong> \u2014 Control the message visitors see before unlocking content.<\/li>\n<li><strong>Style Presets<\/strong> \u2014 Quickly apply predefined form and popup styles.<\/li>\n<li><strong>Custom Colors &amp; Typography<\/strong> \u2014 Adjust form appearance to match your website.<\/li>\n<li><strong>Custom Borders<\/strong> \u2014 Configure form and popup border width and color.<\/li>\n<li><strong>Custom CSS<\/strong> \u2014 Add styles scoped specifically to an individual form or popup.<\/li>\n<li><strong>Built-In Preview<\/strong> \u2014 Preview form and popup states before publishing.<\/li>\n<\/ul>\n\n<h4>Subscriber Management &amp; Analytics<\/h4>\n\n<ul>\n<li><strong>Signups Viewer<\/strong> \u2014 View and search collected subscribers from WordPress.<\/li>\n<li><strong>Customizable Columns<\/strong> \u2014 Choose which signup information is displayed.<\/li>\n<li><strong>CSV Export<\/strong> \u2014 Export subscriber information for Excel or other tools. Large lists stream in batches.<\/li>\n<li><strong>Data Retention<\/strong> \u2014 Automatically anonymise visitor IPs and purge old statistics on a daily schedule.<\/li>\n<li><strong>Conversion Statistics<\/strong> \u2014 Track views, submissions, confirmations, and conversion performance.<\/li>\n<li><strong>Date Filtering<\/strong> \u2014 Review statistics for specific date ranges.<\/li>\n<li><strong>Clone Restricted Areas<\/strong> \u2014 Duplicate an existing campaign with one click.<\/li>\n<li><strong>Export &amp; Import<\/strong> \u2014 Back up or move Restricted Area settings between WordPress sites.<\/li>\n<li><strong>Optional Contact Migration<\/strong> \u2014 Include subscriber records when cloning, exporting, or importing Restricted Areas.<\/li>\n<\/ul>\n\n<h4>Email Marketing Integrations<\/h4>\n\n<p>Confirmed signups can optionally be sent automatically to:<\/p>\n\n<ul>\n<li><strong>ActiveCampaign<\/strong> \u2014 Add contacts to a list with optional tags.<\/li>\n<li><strong>Brevo (formerly Sendinblue)<\/strong> \u2014 Add contacts to a list.<\/li>\n<li><strong>ConvertKit<\/strong> \u2014 Add subscribers to a sequence or tag.<\/li>\n<li><strong>Mailchimp<\/strong> \u2014 Add subscribers to an audience with optional tags.<\/li>\n<li><strong>phpList<\/strong> \u2014 Add subscribers to a self-hosted phpList mailing list.<\/li>\n<\/ul>\n\n<p>These integrations are optional.<\/p>\n\n<p>You can use GWiz IT Content Locker entirely within WordPress without connecting an external email marketing service.<\/p>\n\n<h4>Spam Protection<\/h4>\n\n<p>Choose the spam-protection method that works best for your site:<\/p>\n\n<ul>\n<li><strong>Google reCAPTCHA v2<\/strong> \u2014 Traditional checkbox CAPTCHA.<\/li>\n<li><strong>Google reCAPTCHA v3<\/strong> \u2014 Invisible score-based spam protection.<\/li>\n<li><strong>ALTCHA<\/strong> \u2014 Self-hosted, privacy-friendly proof-of-work CAPTCHA with no external API calls.<\/li>\n<\/ul>\n\n<h4>Works With Popular Page Builders<\/h4>\n\n<p>GWiz IT Content Locker supports content created with:<\/p>\n\n<ul>\n<li>Elementor<\/li>\n<li>Divi<\/li>\n<li>Beaver Builder<\/li>\n<li>Standard WordPress content<\/li>\n<\/ul>\n\n<p>The plugin detects gated content inside supported page-builder data and only loads its frontend assets when they are needed.<\/p>\n\n<h4>Privacy &amp; Self-Hosted Data<\/h4>\n\n<p>GWiz IT Content Locker stores signup information on your WordPress website.<\/p>\n\n<p>No subscriber information is sent to an external email marketing service unless you configure and enable that integration.<\/p>\n\n<p>The plugin integrates with the WordPress privacy tools: signups appear in <strong>Tools \u2192 Export Personal Data<\/strong>, and <strong>Tools \u2192 Erase Personal Data<\/strong> removes the visitor's email, form answers, source URL and IP address (an anonymised record is kept so your statistics stay accurate) and asks each connected email service to delete the contact. Suggested privacy-policy text is provided under <strong>Tools \u2192 Privacy<\/strong>.<\/p>\n\n<p>Gate activity is kept bounded and privacy-friendly on an automatic schedule: visitor IP addresses are anonymised after 30 days and old events are deleted after 365 days by default (both configurable under Settings \u2192 Data Retention).<\/p>\n\n<p>If you prefer not to use an external CAPTCHA service, the built-in ALTCHA option is fully self-hosted and does not make external API calls.<\/p>\n\n<h4>Built for WordPress<\/h4>\n\n<ul>\n<li>Gated content is <strong>not sent to unauthorised visitors<\/strong>: shortcode content, CSS-selector elements, and protected files are withheld server-side and only delivered after eligibility is re-verified on the server. Nothing is \"hidden with JavaScript only\".<\/li>\n<li>File downloads require a short-lived, single-use download ticket that is issued only after the server confirms the visitor's access \u2014 a download link on its own never serves the file.<\/li>\n<li>Frontend JavaScript and CSS load only on pages where they are needed.<\/li>\n<li>Visitor access cookies are HMAC-signed.<\/li>\n<li>Each Restricted Area can have its own cookie expiration.<\/li>\n<li>Logged-in users automatically bypass gates while editing the site. File downloads additionally require a role with edit capability (customizable via the <code>gwiz_it_content_locker_bypass_logged_in<\/code> filter).<\/li>\n<li>Rate limiting and input size caps protect all visitor-facing signup, confirmation, verification, unlock, and download endpoints.<\/li>\n<li>Debug Mode lets administrators preview and test gates while logged in.<\/li>\n<li>Built-in help explains each major setting in plain English.<\/li>\n<li>Restricted Areas can be exported and imported for backup or migration.<\/li>\n<li>Developer filters are available for advanced integrations and customization.<\/li>\n<\/ul>\n\n<h3>Shortcode Usage<\/h3>\n\n<p>Gate content inline using the shortcode:<\/p>\n\n<pre><code>[gwiz_it_content_locker area=\"AreaName\"]This content is hidden until the visitor signs up.[\/gwiz_it_content_locker]\n<\/code><\/pre>\n\n<p>The <code>area<\/code> attribute uses the Restricted Area's display name.<\/p>\n\n<p>The exact shortcode for each area is shown in the area's <strong>Settings<\/strong> modal with a Copy button.<\/p>\n\n<p>If multiple areas share the same name, automatic name deduplication is applied: <code>AreaName<\/code>, <code>AreaName2<\/code>, <code>AreaName3<\/code>, etc.<\/p>\n\n<p><strong>Important \u2014 logged-in users normally do not see the gate.<\/strong><\/p>\n\n<p>If you are logged in as an administrator or another WordPress user, the plugin intentionally shows the unlocked content without requiring signup.<\/p>\n\n<p>This prevents site administrators and editors from being locked out of their own content.<\/p>\n\n<p>To test the gate as a normal visitor:<\/p>\n\n<ol>\n<li>Log out of WordPress, or<\/li>\n<li>Open the page in a private\/incognito browser window.<\/li>\n<\/ol>\n\n<p>Administrators can also enable <strong>Debug Mode<\/strong> in the Restricted Area settings to preview the gate while logged in.<\/p>\n\n<p>Developers can adjust logged-in bypass behavior with the <code>gwiz_it_content_locker_bypass_logged_in<\/code> filter.<\/p>\n\n<h3>External Services<\/h3>\n\n<p>GWiz IT Content Locker optionally connects to third-party services when configured by the site administrator.<\/p>\n\n<p>No data is sent to these services until the administrator explicitly enables the integration and provides the required credentials.<\/p>\n\n<ul>\n<li><p><strong>ActiveCampaign<\/strong> \u2014 Syncs confirmed subscriber email addresses to your ActiveCampaign account through its API. (<a href=\"https:\/\/www.activecampaign.com\/privacy-policy\/\">ActiveCampaign Privacy Policy<\/a>)<\/p><\/li>\n<li><p><strong>Brevo (formerly Sendinblue)<\/strong> \u2014 Syncs confirmed subscriber email addresses to your Brevo account through its API. (<a href=\"https:\/\/www.brevo.com\/legal\/privacypolicy\/\">Brevo Privacy Policy<\/a>)<\/p><\/li>\n<li><p><strong>ConvertKit<\/strong> \u2014 Syncs confirmed subscriber email addresses to your ConvertKit account through its API. (<a href=\"https:\/\/convertkit.com\/privacy\">ConvertKit Privacy Policy<\/a>)<\/p><\/li>\n<li><p><strong>Mailchimp<\/strong> \u2014 Syncs confirmed subscriber email addresses to your Mailchimp audience through its API. (<a href=\"https:\/\/mailchimp.com\/legal\/privacy\/\">Mailchimp Privacy Policy<\/a>)<\/p><\/li>\n<li><p><strong>phpList<\/strong> \u2014 Syncs confirmed subscriber email addresses to your self-hosted phpList installation through its REST API.<\/p><\/li>\n<li><p><strong>Google reCAPTCHA<\/strong> \u2014 When enabled, loads Google reCAPTCHA to protect signup forms from spam. Google may receive information including the visitor's IP address and browser information for verification. (<a href=\"https:\/\/policies.google.com\/privacy\">Google Privacy Policy<\/a>)<\/p><\/li>\n<\/ul>\n\n<p>All external data transfers occur over HTTPS.<\/p>\n\n<p>The ALTCHA CAPTCHA option is fully self-hosted and does not connect to an external CAPTCHA service.<\/p>\n\n<h3>Hooks<\/h3>\n\n<h4>Filters<\/h4>\n\n<p><strong><code>gwiz_it_content_locker_load_frontend<\/code><\/strong><\/p>\n\n<p>Controls whether GWiz IT Content Locker frontend assets load on the current page.<\/p>\n\n<p>Example:<\/p>\n\n<pre><code>add_filter( 'gwiz_it_content_locker_load_frontend', function( $should_load, $post ) {\n\n    \/\/ Force-load on a specific page template.\n    if ( is_page_template( 'template-custom.php' ) ) {\n        return true;\n    }\n\n    \/\/ Prevent loading on the shop page.\n    if ( is_shop() ) {\n        return false;\n    }\n\n    return $should_load;\n\n}, 10, 2 );\n<\/code><\/pre>\n\n<p>Parameters:<\/p>\n\n<ul>\n<li><code>$should_load<\/code> (bool) \u2014 Whether frontend assets should load. The default is automatically determined based on shortcode or selector presence.<\/li>\n<li><code>$post<\/code> (WP_Post|null) \u2014 The current post object.<\/li>\n<\/ul>\n\n<p><strong><code>gwiz_it_content_locker_bypass_logged_in<\/code><\/strong><\/p>\n\n<p>Allows developers to modify the default behavior that lets logged-in WordPress users bypass content gates.<\/p>\n\n<p>By default, logged-in users are not required to complete signup forms. File downloads are stricter: the default there requires a role with edit capability, so ordinary subscribers do not receive gated files.<\/p>\n\n<p>Parameters:<\/p>\n\n<ul>\n<li><code>$bypass<\/code> (bool) \u2014 Whether logged-in users bypass the gate (the download endpoint passes <code>current_user_can( 'edit_posts' )<\/code> as this default).<\/li>\n<li><code>$area_id<\/code> (int) \u2014 The Restricted Area ID.<\/li>\n<li><code>$settings<\/code> (array) \u2014 The area's parsed settings.<\/li>\n<\/ul>\n\n<h4>Actions<\/h4>\n\n<p><strong><code>gwiz_it_content_locker_caches_cleared<\/code><\/strong><\/p>\n\n<p>Fires after the plugin cleared site caches following a Restricted Area save (see Settings \u2192 Cache Clearing).<\/p>\n\n<ul>\n<li><code>$cleared<\/code> (bool) \u2014 Whether a known cache plugin or host cache was cleared. Use this to hook in your own cache\/CDN purge.<\/li>\n<\/ul>\n\n<p><strong><code>gwiz_it_content_locker_retention_run<\/code><\/strong><\/p>\n\n<p>Fires after a daily data-retention pass (see Settings \u2192 Data Retention).<\/p>\n\n<ul>\n<li><code>$stats<\/code> (array) \u2014 Rows processed in the pass: <code>tickets_purged<\/code>, <code>ips_anonymised<\/code>, <code>events_deleted<\/code>.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Install <strong>GWiz IT Content Locker<\/strong> from the WordPress Plugins screen, or upload the <code>g-wiz-it-content-locker<\/code> folder to the <code>\/wp-content\/plugins\/<\/code> directory.<\/li>\n<li>Activate <strong>GWiz IT Content Locker<\/strong> through the <strong>Plugins<\/strong> screen in WordPress.<\/li>\n<li>Click <strong>GWiz IT Content Locker<\/strong> in the WordPress admin sidebar.<\/li>\n<li>Create your first Restricted Area.<\/li>\n<li>Choose the page, download, shortcode content, or page element you want to protect.<\/li>\n<li>Customize your signup form and settings.<\/li>\n<li>Activate the Restricted Area.<\/li>\n<li>Test the gate while logged out or in a private\/incognito browser window.<\/li>\n<\/ol>\n\n<p>Global templates and security settings can be configured under <strong>GWiz IT Content Locker \u2192 Settings<\/strong>.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"is%20gwiz%20it%20content%20locker%20free%3F\"><h3>Is GWiz IT Content Locker free?<\/h3><\/dt>\n<dd><p>Yes.<\/p>\n\n<p>GWiz IT Content Locker can be installed and used for free to gate content, collect subscribers, manage signups, and track conversions directly from WordPress.<\/p><\/dd>\n<dt id=\"do%20i%20need%20mailchimp%20or%20another%20email%20marketing%20service%3F\"><h3>Do I need Mailchimp or another email marketing service?<\/h3><\/dt>\n<dd><p>No.<\/p>\n\n<p>External email marketing integrations are optional.<\/p>\n\n<p>Signups can be collected and managed directly from your WordPress website without connecting Mailchimp, Brevo, ConvertKit, ActiveCampaign, phpList, or another third-party marketing service.<\/p><\/dd>\n<dt id=\"what%20types%20of%20content%20can%20i%20lock%3F\"><h3>What types of content can I lock?<\/h3><\/dt>\n<dd><p>You can protect:<\/p>\n\n<ul>\n<li>Entire pages or posts<\/li>\n<li>File downloads<\/li>\n<li>Sections of page content<\/li>\n<li>Individual page elements using CSS selectors<\/li>\n<\/ul>\n\n<p>You can also trigger a content-locker popup from a custom anchor link.<\/p><\/dd>\n<dt id=\"can%20i%20use%20the%20plugin%20for%20lead%20magnets%3F\"><h3>Can I use the plugin for lead magnets?<\/h3><\/dt>\n<dd><p>Yes.<\/p>\n\n<p>You can require visitors to complete a signup form before accessing PDFs, guides, checklists, documents, downloads, bonus content, resource libraries, or other gated material.<\/p><\/dd>\n<dt id=\"can%20i%20protect%20downloadable%20files%3F\"><h3>Can I protect downloadable files?<\/h3><\/dt>\n<dd><p>Yes.<\/p>\n\n<p>GWiz IT Content Locker includes a protected file-download system that can require visitors to complete the signup process before accessing a gated file. The file is stored outside the public web directory, and its download link never serves the file on its own \u2014 after the visitor's access is confirmed on the server, a short-lived single-use download token is issued for that specific download.<\/p><\/dd>\n<dt id=\"can%20i%20connect%20signups%20to%20my%20email%20marketing%20platform%3F\"><h3>Can I connect signups to my email marketing platform?<\/h3><\/dt>\n<dd><p>Yes.<\/p>\n\n<p>Confirmed subscribers can optionally be synced automatically to:<\/p>\n\n<ul>\n<li>ActiveCampaign<\/li>\n<li>Brevo<\/li>\n<li>ConvertKit<\/li>\n<li>Mailchimp<\/li>\n<li>phpList<\/li>\n<\/ul><\/dd>\n<dt id=\"can%20i%20use%20double%20opt-in%3F\"><h3>Can I use double opt-in?<\/h3><\/dt>\n<dd><p>Yes.<\/p>\n\n<p>Double opt-in can be enabled individually for each Restricted Area.<\/p>\n\n<p>When enabled, visitors must confirm their email address before receiving access: they get a <strong>confirmation email<\/strong> at signup, and the <strong>welcome email<\/strong> is sent once they click the confirmation link. With double opt-in disabled, a single welcome email is sent right after signup.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20work%20with%20elementor%20or%20divi%3F\"><h3>Does the plugin work with Elementor or Divi?<\/h3><\/dt>\n<dd><p>Yes.<\/p>\n\n<p>The plugin pre-scans Elementor (<code>_elementor_data<\/code>), Divi (<code>_et_pb_post_content<\/code>), and Beaver Builder (<code>_fl_builder_data<\/code>) content for shortcodes and configured selector class names.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20work%20with%20beaver%20builder%3F\"><h3>Does the plugin work with Beaver Builder?<\/h3><\/dt>\n<dd><p>Yes.<\/p>\n\n<p>Beaver Builder content is supported along with Elementor, Divi, and standard WordPress content.<\/p><\/dd>\n<dt id=\"where%20are%20subscriber%20details%20stored%3F\"><h3>Where are subscriber details stored?<\/h3><\/dt>\n<dd><p>Subscriber information is stored on your WordPress website.<\/p>\n\n<p>Data is only sent to an external email marketing service if you explicitly configure and enable that integration.<\/p>\n\n<p>Signups are included in the WordPress personal-data export and erasure tools (<strong>Tools \u2192 Export Personal Data<\/strong> \/ <strong>Tools \u2192 Erase Personal Data<\/strong>), so you can respond to visitor privacy requests directly from the WordPress admin.<\/p><\/dd>\n<dt id=\"how%20do%20i%20find%20the%20shortcode%20for%20my%20restricted%20area%3F\"><h3>How do I find the shortcode for my Restricted Area?<\/h3><\/dt>\n<dd><p>Click the <strong>Settings<\/strong> button on any Restricted Area card.<\/p>\n\n<p>The shortcode is displayed near the top of the settings window with a Copy button.<\/p><\/dd>\n<dt id=\"why%20do%20i%20see%20my%20content%20without%20a%20signup%20form%3F\"><h3>Why do I see my content without a signup form?<\/h3><\/dt>\n<dd><p>You are most likely logged into WordPress.<\/p>\n\n<p>Logged-in users normally receive the unlocked content without seeing the signup form.<\/p>\n\n<p>This is intentional so administrators and editors are not gated on their own website.<\/p>\n\n<p>To test the gate as a visitor, log out or open the page in a private\/incognito browser window.<\/p>\n\n<p>Administrators can also enable <strong>Debug Mode<\/strong> to preview the gate while logged in.<\/p><\/dd>\n<dt id=\"how%20do%20i%20hide%20elements%20by%20css%20selector%3F\"><h3>How do I hide elements by CSS selector?<\/h3><\/dt>\n<dd><p>Open the Restricted Area's <strong>Settings<\/strong> modal and enter CSS selectors in the <strong>Hide by Selector<\/strong> field, one selector per line.<\/p>\n\n<p>For example:<\/p>\n\n<pre><code>div.exampleclass\n<\/code><\/pre>\n\n<p>or:<\/p>\n\n<pre><code>span.highlight\n<\/code><\/pre>\n\n<p>Elements matching those selectors are locked until the visitor signs up. How they look is your choice per Restricted Area (the <strong>Locked Element Style<\/strong> setting):<\/p>\n\n<ul>\n<li><strong>Locked section<\/strong> (default) \u2014 the content is removed from the page before it is sent to the visitor's browser (it is not in the page source or the DOM) and replaced with a visible, customisable placeholder: background and text colors, message text, and button text, colors and CSS class. Clicking the element opens the signup form in a popup modal.<\/li>\n<li><strong>Visual lock (classic)<\/strong> \u2014 the element keeps its place in your page and is styled with your Custom Lock Style and an optional hover tooltip. Two checkboxes control what happens to the content server-side: <strong>Strip Locked Content<\/strong> removes the matched element entirely from the page source (most secure), and <strong>Remove Child Elements<\/strong> keeps the styled element shell but removes its children (images and other embeds are removed entirely, since their content is their source URL). With neither checked, the content stays in the page and is only hidden visually \u2014 like the original version of this feature.<\/li>\n<\/ul>\n\n<p>In every mode the removed content is restored into the page after the visitor signs up (and confirms, when double opt-in is enabled).<\/p>\n\n<p>Supported selectors: tag names, <code>*<\/code>, <code>#id<\/code>, <code>.class<\/code>, attribute selectors (<code>[href]<\/code>, <code>[type=\"text\"]<\/code>, <code>[class*=\"x\"]<\/code>, <code>[href^=\"https\"]<\/code>, <code>[href$=\".pdf\"]<\/code>, <code>[rel~=\"x\"]<\/code>, <code>[lang|=\"en\"]<\/code>), the descendant\/child\/sibling combinators (space, <code>&gt;<\/code>, <code>+<\/code>, <code>~<\/code>), comma-separated lists, and <code>:first-child<\/code>, <code>:last-child<\/code>, <code>:nth-child(n|odd|even)<\/code>. Any other pseudo-class (for example <code>:hover<\/code> or <code>:has()<\/code>) is applied as a visual lock only \u2014 for those selectors the plugin falls back to locking the element client-side, which hides it visually but does not remove it from the page source.<\/p><\/dd>\n<dt id=\"can%20i%20show%20the%20signup%20form%20on%20only%20one%20section%20of%20the%20page%3F\"><h3>Can I show the signup form on only one section of the page?<\/h3><\/dt>\n<dd><p>Yes.<\/p>\n\n<p>Place the shortcode around the content where you want the signup form to appear.<\/p>\n\n<p>If you need to protect additional elements without displaying additional forms, use CSS selectors to lock those elements.<\/p><\/dd>\n<dt id=\"will%20my%20caching%20plugin%20be%20cleared%20when%20i%20save%3F\"><h3>Will my caching plugin be cleared when I save?<\/h3><\/dt>\n<dd><p>Yes \u2014 by default the plugin clears popular caching plugins (WP Rocket, WP Super Cache, W3 Total Cache, LiteSpeed Cache, WP Fastest Cache, Cache Enabler, Comet Cache, SG Optimizer, WP-Optimize, Swift Performance, Autoptimize, Nginx Helper and Hummingbird) and host-level caches on <strong>GoDaddy Managed WordPress, WP Engine, Kinsta, Pantheon and Cloudways<\/strong> whenever anything in a Restricted Area is saved, so gating changes appear immediately. You can turn this off under <strong>GWiz IT Content Locker \u2192 Settings \u2192 Cache Clearing<\/strong>. If your host also runs a WAF\/CDN cache (for example GoDaddy's WAF), that layer may still need a manual clear from your hosting dashboard.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20load%20javascript%20and%20css%20on%20every%20page%3F\"><h3>Does the plugin load JavaScript and CSS on every page?<\/h3><\/dt>\n<dd><p>No.<\/p>\n\n<p>The plugin checks the current page content, including supported page-builder data, and only loads frontend assets when a shortcode or relevant selector is detected.<\/p><\/dd>\n<dt id=\"can%20i%20clone%20a%20restricted%20area%3F\"><h3>Can I clone a Restricted Area?<\/h3><\/dt>\n<dd><p>Yes.<\/p>\n\n<p>Click the <strong>Clone<\/strong> button on a Restricted Area.<\/p>\n\n<p>You can choose whether subscriber\/contact records should also be included.<\/p>\n\n<p>The duplicated area is created as a disabled copy with a unique name.<\/p><\/dd>\n<dt id=\"can%20i%20export%20and%20import%20restricted%20areas%3F\"><h3>Can I export and import Restricted Areas?<\/h3><\/dt>\n<dd><p>Yes.<\/p>\n\n<p>Click <strong>Export<\/strong> on a Restricted Area to download a ZIP backup.<\/p>\n\n<p>To import a backup, use <strong>Import Settings<\/strong> on an existing Restricted Area or <strong>Import Area<\/strong> to create a new one.<\/p>\n\n<p>You can optionally include subscriber\/contact records.<\/p>\n\n<p>Backup files contain plugin version information so older backups can be handled safely as the plugin evolves.<\/p><\/dd>\n<dt id=\"can%20i%20transfer%20contacts%20between%20restricted%20areas%3F\"><h3>Can I transfer contacts between Restricted Areas?<\/h3><\/dt>\n<dd><p>Yes.<\/p>\n\n<p>When cloning, exporting, or importing an area, you can choose to include contacts.<\/p>\n\n<p>Imported contacts are added as new signup records and are not automatically de-duplicated by email address.<\/p><\/dd>\n<dt id=\"is%20the%20csv%20export%20compatible%20with%20excel%3F\"><h3>Is the CSV export compatible with Excel?<\/h3><\/dt>\n<dd><p>Yes.<\/p>\n\n<p>CSV exports include a UTF-8 BOM so applications such as Microsoft Excel correctly recognize UTF-8 text, including accented and non-English characters.<\/p><\/dd>\n<dt id=\"how%20do%20i%20force%20frontend%20assets%20to%20load%20on%20a%20specific%20page%3F\"><h3>How do I force frontend assets to load on a specific page?<\/h3><\/dt>\n<dd><p>Developers can use the <code>gwiz_it_content_locker_load_frontend<\/code> filter documented in the Hooks section below.<\/p><\/dd>\n<dt id=\"what%20email%20placeholders%20are%20available%3F\"><h3>What email placeholders are available?<\/h3><\/dt>\n<dd><p><strong>Confirmation Email<\/strong><\/p>\n\n<ul>\n<li><code>{{confirm_link}}<\/code><\/li>\n<li><code>{{site_name}}<\/code><\/li>\n<li><code>{{email}}<\/code><\/li>\n<li><code>{{area_name}}<\/code><\/li>\n<li><code>{{source_url}}<\/code><\/li>\n<\/ul>\n\n<p><strong>Congratulations Email<\/strong><\/p>\n\n<ul>\n<li><code>{{site_name}}<\/code><\/li>\n<li><code>{{email}}<\/code><\/li>\n<li><code>{{area_name}}<\/code><\/li>\n<li><code>{{source_url}}<\/code><\/li>\n<\/ul>\n\n<p><strong>Popup Template<\/strong><\/p>\n\n<ul>\n<li><code>{{form}}<\/code><\/li>\n<li><code>{{already_signed_up_link}}<\/code><\/li>\n<li><code>{{site_name}}<\/code><\/li>\n<li><code>{{area_name}}<\/code><\/li>\n<li><code>{{file_name}}<\/code><\/li>\n<\/ul><\/dd>\n<dt id=\"how%20does%20the%20%22i%20have%20already%20signed%20up%22%20link%20work%3F\"><h3>How does the \"I have already signed up\" link work?<\/h3><\/dt>\n<dd><p>The popup template includes an <code>{{already_signed_up_link}}<\/code> placeholder.<\/p>\n\n<p>When visitors click it, they are shown an email verification form.<\/p>\n\n<p>If the email exists as a confirmed signup for that Restricted Area, the visitor receives an access cookie and the protected content is unlocked.<\/p>\n\n<p>If the address is not found, a generic response is shown to help prevent email enumeration.<\/p><\/dd>\n<dt id=\"where%20can%20i%20find%20help%20for%20each%20button%20and%20setting%3F\"><h3>Where can I find help for each button and setting?<\/h3><\/dt>\n<dd><p>Click the <strong>Help<\/strong> button at the top of the Restricted Areas page.<\/p>\n\n<p>The plugin includes a detailed plain-English guide explaining the available buttons, settings, and options.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.12.0<\/h4>\n\n<ul>\n<li>Fixed: the ALTCHA checkbox appeared to solve but every submission still failed with \"Please complete the captcha verification to continue.\" \u2014 the page read the solution from a property the ALTCHA v2 widget does not have (a v1 API), so no solution was ever sent to the server. The payload is now read from the widget's actual API (<code>getState().payload<\/code> and the hidden input it creates on solve). The challenge URL also carries a version tag so host or page caches (e.g. GoDaddy Varnish, WP Rocket) can never serve a challenge issued by an older plugin release.<\/li>\n<li>Fixed: reCAPTCHA v2 retries could fail forever with \"Please complete the captcha verification to continue.\" while the box still looked checked. reCAPTCHA tokens are single-use at Google, so any request rejected after verification (a validation error, rate limit, or hiccup) burned the token. Input validation now runs before captcha verification, and the widget is automatically reset after any failed submit so retries work. reCAPTCHA v2 widgets are now rendered explicitly with tracked ids (works in popups and multi-form pages).<\/li>\n<li>Improved: the reCAPTCHA v3 Score Threshold help text now warns that 0.5 is strict \u2014 real visitors on simple pages often score 0.3\u20130.6, so 0.3\u20130.4 is the recommended starting point.<\/li>\n<\/ul>\n\n<h4>1.11.0<\/h4>\n\n<ul>\n<li>Fixed: the ALTCHA (self-hosted) captcha always failed with \"Please complete the captcha verification to continue.\" even after the widget was solved \u2014 the widget never returns an <code>expires<\/code> field in its solution, but the server required one, so every submission was rejected. The expiry timestamp now travels inside the signed salt (which the widget does return), verification accepts the widget's actual payload format, a solution number of 0 is now accepted, and challenge responses are marked no-store so page caches can't serve stale, already-expired challenges. Note: challenges issued by 1.10.0 and earlier stop verifying after this update (they live only 5 minutes) \u2014 visitors simply solve the fresh widget.<\/li>\n<li>Added: the three default-template boxes on the Settings page (<strong>Confirm Notice \/ Already Signed Up \/ Not Signed Up<\/strong>) are now visual\/code editors \u2014 the same TinyMCE editor with a \"Text\" tab used in the Restricted Areas dialogs \u2014 so templates can be edited visually or as HTML. The plain textareas remain as a no-JavaScript fallback.<\/li>\n<li>Fixed: with double opt-in enabled, the welcome email after clicking the confirmation link was skipped when an area's Congrats Template was empty (e.g. areas imported from older backups). Both signup flows now always send the welcome email and share the same built-in fallback template.<\/li>\n<li>Fixed: the plugin now passes the WordPress Plugin Check cleanly (prefixed a global variable in <code>uninstall.php<\/code>; documented the third-party LiteSpeed Cache hook name used by the cache clearer).<\/li>\n<li>Added: a demo walkthrough video (see <strong>Watch It In Action<\/strong> at the top of this readme) covering signup, confirmation and download access.<\/li>\n<\/ul>\n\n<h4>1.10.0<\/h4>\n\n<ul>\n<li>Fixed: saving in a Restricted Area's settings dialog could show a save error even though the save had succeeded (and a save with no changes answered with a request error). Two causes: \"nothing changed\" was misread as a failed database write, and cache-clearing code from caching plugins\/hosts \u2014 which can emit PHP notices or run slowly, e.g. GoDaddy's Varnish flush \u2014 ran inside the save request and corrupted its JSON response. Saves now respond cleanly first; cache clearing runs afterwards, fully quarantined (no output, no exceptions), and every cache\/host purge call is individually isolated so one broken integration cannot affect the rest.<\/li>\n<li>Added: <strong>Clear cache on save<\/strong> setting (on by default) \u2014 whenever anything in a Restricted Area is saved (settings, styles, templates, URLs, areas), the plugin now clears caches automatically: caching plugins (WP Rocket, WP Super Cache, W3 Total Cache, LiteSpeed Cache, WP Fastest Cache, Cache Enabler, Comet Cache, SG Optimizer, WP-Optimize, Swift Performance, Autoptimize, Nginx Helper, Hummingbird) <strong>and hosting caches<\/strong> on GoDaddy Managed WordPress, WP Engine, Kinsta, Pantheon and Cloudways. This means gating changes show up immediately instead of after the cache expires \u2014 no more manual flushes in the GoDaddy dashboard. Can be turned off under <strong>GWiz IT Content Locker \u2192 Settings<\/strong>; host WAF\/CDN caches may still need a manual clear.<\/li>\n<li>Added: <strong>Locked Element Style<\/strong> setting for CSS Selector gates \u2014 choose per area between \"Locked section (sign-up placeholder)\" and \"Visual lock (classic)\". Visual mode adds two checkboxes: strip the locked content out of the page source entirely, or keep the element shell and remove only its child elements. Removed content is always restored after signup. Settings travel with area export\/import backups.<\/li>\n<li>Fixed: CSS-selector locked elements no longer appear as an empty, faded box. When content is removed server-side the element now shows a visible \"locked\" placeholder with a sign-up button (clicking it opens the signup popup), and the Custom Lock Style is no longer applied over the placeholder \u2014 it still styles visual locks, where the real content remains on the page.<\/li>\n<li>Fixed: the <strong>Custom Lock Style<\/strong> setting was not saved when the settings dialog was closed (it was sent to the server but silently ignored). It now saves correctly.<\/li>\n<li>Fixed: replaced all uses of the deprecated <code>jQuery.trim<\/code> (removed in jQuery 4) with a local equivalent, so lock styling and admin saves keep working on sites that upgrade jQuery.<\/li>\n<li>Added: WordPress privacy tools integration \u2014 signups (email, custom form fields, source page, IP, timestamps) appear in <strong>Tools \u2192 Export Personal Data<\/strong>, together with which third-party services received the signup and the visitor's gate activity.<\/li>\n<li>Added: <strong>Tools \u2192 Erase Personal Data<\/strong> support \u2014 erasure deletes the visitor's email, form answers, source URL and IP address (an anonymised record is kept so submission\/confirmation statistics stay accurate, shown with an \"Erased\" badge), removes the integration records, anonymises the gate-activity IPs, and asks each connected email service (Mailchimp, Brevo, ConvertKit, ActiveCampaign, phpList) to delete the contact. If a service cannot be reached, the privacy request log tells you to remove the contact there manually.<\/li>\n<li>Added: <strong>Data Retention<\/strong> settings with a daily cleanup cron \u2014 visitor IPs in gate activity are anonymised after 30 days and old events deleted after 365 days by default (both configurable, 0 = keep forever; signups are never deleted automatically). Runs in small indexed batches via WP-Cron, so large statistics tables are never processed in one request.<\/li>\n<li>Added: suggested privacy-policy text under <strong>Tools \u2192 Privacy<\/strong> describing what the plugin collects, what is sent to each integration, the access cookies, and how long data is kept.<\/li>\n<li>Improved: deleting the plugin now <strong>restores protected files to their original locations<\/strong> (instead of leaving them in the private folder) and removes all plugin options and the scheduled cleanup event.<\/li>\n<li>Improved: the signups <strong>CSV export streams from the server in indexed batches<\/strong>, so large lists export reliably instead of loading every signup into a single request.<\/li>\n<li>Improved: the translation template (<code>languages\/g-wiz-it-content-locker.pot<\/code>) has been regenerated with every current string and translator comment. A WP-CLI-free generator (<code>tools\/make-pot.php<\/code>, development files, not shipped in the zip) reproduces it with <code>php tools\/make-pot.php<\/code>.<\/li>\n<\/ul>\n\n<h4>1.9.0<\/h4>\n\n<ul>\n<li>Security: gated shortcode content and CSS-selector elements are now removed from the page SERVER-SIDE before it reaches the browser \u2014 previously they were only hidden with JavaScript and were readable in the page source and DOM. Locked markup is stored server-side and delivered only after the visitor's access is re-verified, through a dedicated unlock endpoint. Cached pages continue to work: every visitor receives the same stripped page, and eligible visitors' content is inserted after the access check.<\/li>\n<li>Security: protected file downloads now require a short-lived, single-use download ticket issued only after server-side eligibility is confirmed. Previously the file URL plus an access cookie was enough. A nonce-checked form fallback keeps downloads working without JavaScript.<\/li>\n<li>Security: the download endpoint no longer serves files to any logged-in user \u2014 a role with edit capability is now required (customizable via the <code>gwiz_it_content_locker_bypass_logged_in<\/code> filter).<\/li>\n<li>Security: gated files with active content types (HTML, SVG, XML, \u2026) are now served as attachments instead of inline, closing a stored-XSS vector for gated uploads.<\/li>\n<li>Security: fixed a bypass where appending <code>?gwiz_it_bg_preview=1<\/code> to a gated URL skipped the page gate entirely. The background preview (and the blurred gated-page background behind the gate overlay) is now rendered for privileged users only.<\/li>\n<li>Security: gated page content no longer leaks through the REST API (<code>content.rendered<\/code>) or RSS feeds.<\/li>\n<li>Security: rate limiting on the confirmation link, pending-status, resend, unlock, and download endpoints (signup and verification were already limited), plus hard size caps on all submitted form fields.<\/li>\n<li>Improved: re-submitting while pending double opt-in now reuses the existing signup record (same confirmation token) instead of creating duplicate rows and emails; a UNIQUE (area, email) key with automatic deduplication of old duplicates backs this up at the database level.<\/li>\n<li>Improved: double opt-in continues to hold content and downloads until the confirmation link is clicked; confirming is idempotent.<\/li>\n<li>Improved: CSV export and analytics tables are unaffected in this release; a batched export, retention cleanup, and WordPress privacy exporter\/eraser are planned next.<\/li>\n<li>Note for CSS Selector users: unsupported selector syntax (pseudo-classes such as <code>:hover<\/code> or <code>:has()<\/code>) falls back to the previous visual-only lock. The supported server-side subset is documented in the FAQ.<\/li>\n<\/ul>\n\n<h4>1.8.1<\/h4>\n\n<ul>\n<li>Fixed: statistics now track every popup\/form display \u2014 popups opened from CSS\/HTML elements and from the Popup Trigger Link now count as Views in the restricted area's statistics (previously only the Add\/Edit URL gate and the inline shortcode form were counted). Popup views are recorded when the popup actually opens, so they are counted correctly even on cached pages.<\/li>\n<li>Fixed: submitting the form with an email that has already signed up now counts as a Submission (previously repeat submissions were not counted). The signup itself stays idempotent \u2014 no duplicate signups or emails.<\/li>\n<\/ul>\n\n<h4>1.8.0<\/h4>\n\n<ul>\n<li>Added: Popup Trigger Link (Settings page) \u2014 define a custom anchor link (e.g. #gwiz_it_content_locker) that opens a content-locker popup when clicked, just like clicking a locked element. The link opens the FIRST popup available on the page (an inline shortcode form, then a CSS\/element selector area, then an Add\/Edit URL popup). Any active area with CSS selectors configured makes its popup available through this link on every page of the site \u2014 even where its selectors match nothing \u2014 so the link can double as a site-wide \"Unlock\" button. Only when no active area uses CSS selectors and the page has no shortcode or URL rule does clicking do nothing.<\/li>\n<li>Added: Form\/Popup Styles \u2014 input\/textarea background and text colors (inputs are no longer transparent; defaults are white background \/ black text), available for both inline forms and full-page popups, with defaults in every style preset.<\/li>\n<li>Added: Form\/Popup Styles \u2014 background and text color pickers for the Google reCAPTCHA and ALTCHA (local) captcha widgets (defaults: white background, black text). Both captcha widgets respect the Text Align setting.<\/li>\n<li>Added: Form\/Popup Styles \u2014 Border Width and Border Color for the form card \/ popup dialog (set the width to 0 to remove the border, e.g. a thin light line around the popup).<\/li>\n<li>Added: Form\/Popup Styles \u2014 Custom CSS box per form\/popup. Every selector is automatically scoped to that form or popup, so the styles can never bleed into other elements on the page.<\/li>\n<li>Added: ALTCHA self-hosted captcha option (proof-of-work, no external service required).<\/li>\n<li>Fixed: the popup dialog now follows the \"Full-Page Popup\" styles instead of the \"Inline Form\" styles \u2014 the two style columns are fully independent (\"Inline Form\" styles the inline shortcode form; \"Full-Page Popup\" styles every popup dialog and the URL-gate popup).<\/li>\n<li>Fixed: captcha widget labels (e.g. ALTCHA's checkbox label) now follow the Captcha Text Color instead of being forced to the form's Text Color.<\/li>\n<\/ul>\n\n<h4>1.7.3<\/h4>\n\n<ul>\n<li>Fixed: restricted area rename \u2014 pressing Enter or clicking outside the name field now saves the change, and Escape cancels it.<\/li>\n<li>Fixed: the area color picker no longer crashes with a JavaScript error and opens correctly.<\/li>\n<li>Fixed: form and email template editors no longer open blank for newly created areas \u2014 they are pre-filled with the default templates.<\/li>\n<li>Improved: the logged-in bypass is now documented where users look for shortcode help (area settings modal, help page, and readme FAQ).<\/li>\n<\/ul>\n\n<h4>1.7.2<\/h4>\n\n<ul>\n<li>Fixed: scripts and styles are now registered and enqueued via the WordPress scripts and styles API.<\/li>\n<li>Fixed: shortcode callback output is now escaped with wp_kses and an explicit allowlist.<\/li>\n<li>Fixed: text domain renamed to g-wiz-it-content-locker to match the plugin slug.<\/li>\n<\/ul>\n\n<h4>1.7.0<\/h4>\n\n<ul>\n<li>Breaking: plugin renamed from \"GWiz GWiz IT\" to \"GWiz IT Content Locker\" to avoid trademark confusion with Gravity Wiz.<\/li>\n<li>Breaking: shortcode changed from [gwiz_leadgate] to [gwiz_it_content_locker]. Update any existing pages\/posts using the old shortcode.<\/li>\n<li>Breaking: all internal prefixes renamed (text domain, function names, option names, database table names, CSS classes, JS variables).<\/li>\n<li>Breaking: database tables renamed from wp_gwiz_gwiz_it_* to wp_gwiz_it_content_locker_*.<\/li>\n<li>If upgrading from 1.6.x: export your areas first, uninstall the old version, install the new version, then import your areas from backup.<\/li>\n<li>Improved: WordPress coding standards compliance \u2014 resolved all PHPCS errors and warnings.<\/li>\n<\/ul>\n\n<h4>1.6.2<\/h4>\n\n<ul>\n<li>Improved: WordPress coding standards compliance \u2014 resolved all PHPCS errors and warnings from the WordPress Plugin Checker.<\/li>\n<li>Improved: added missing translators comments for all translatable strings with placeholders.<\/li>\n<li>Improved: nonce verification annotations for all AJAX handlers (nonce checks were already present via verify_ajax()).<\/li>\n<li>Improved: replaced deprecated functions \u2014 unlink() with wp_delete_file(), parse_url() with wp_parse_url().<\/li>\n<li>Improved: input sanitization and validation for cookie values and server variables.<\/li>\n<li>Improved: database query annotations for custom table operations (DirectDatabaseQuery, InterpolatedNotPrepared).<\/li>\n<li>Improved: moved HTML tags outside translatable strings for proper i18n compliance.<\/li>\n<li>Improved: added isset() checks for $_SERVER superglobal access.<\/li>\n<li>No functional changes or database schema updates.<\/li>\n<\/ul>\n\n<h4>1.6.1<\/h4>\n\n<ul>\n<li>Fixed: the debug-mode \"temporarily close\" button now respects the \"Keep inline signup forms visible after popup is dismissed\" setting. Previously, closing the popup with debug mode enabled did not set the session flag, so inline forms remained visible on subsequent page loads even when the setting was unchecked.<\/li>\n<\/ul>\n\n<h4>1.6.0<\/h4>\n\n<ul>\n<li>Added Clone feature: duplicate any restricted area with one click. The clone is created disabled with a unique name suffix (-1, -2, -3, etc.) and a different color. Optionally include contacts in the clone.<\/li>\n<li>Added Export feature: download a ZIP backup of any restricted area containing all settings, templates, URLs, and optionally contacts. The backup includes a manifest with plugin version metadata for forward-compatible restores.<\/li>\n<li>Added Import feature: restore area settings from a ZIP backup. Import creates a new area (with automatic name deduplication) or overwrites an existing area's settings with a confirmation warning. Version mismatch warnings are shown when importing backups from older plugin versions.<\/li>\n<li>Added top-of-page \"Import Area\" button alongside \"Add New Area\" for creating new areas from backup files.<\/li>\n<li>Added \"Include contacts\/users?\" option to all clone, export, and import operations (defaults to No for clone\/export, No for import).<\/li>\n<li>Backup files use a ZIP format with separate JSON files (manifest.json, area.json, urls.json, signups.json) for maximum compatibility and readability.<\/li>\n<\/ul>\n\n<h4>1.5.1<\/h4>\n\n<ul>\n<li>Added background colors to the new Form Template, Form\/Popup Styles, and Preview buttons.<\/li>\n<li>Stacked the Inline Form and Full-Page Popup style sections vertically instead of side-by-side columns.<\/li>\n<li>Added a title above the preview showing which form\/popup state is currently displayed.<\/li>\n<\/ul>\n\n<h4>1.5.0<\/h4>\n\n<ul>\n<li>Renamed \"Popup Template\" to \"Form Template\" and moved the Confirm Notice template under it (removed the separate Confirm Notice button).<\/li>\n<li>Added a \"Form\/Popup Styles\" option with presets (Default, Modern, Dark, Rounded, Minimal) plus per-field controls for font, colors, size, radius, alignment, and position \u2014 separately for inline forms and full-page popups.<\/li>\n<li>Added a \"Preview\" button that opens a modal previewing every form\/popup state, with prev\/next arrows to navigate and non-interactive forms.<\/li>\n<li>Styles are applied via CSS variables to both the inline form card and the full-page popup overlay.<\/li>\n<\/ul>\n\n<h4>1.4.1<\/h4>\n\n<ul>\n<li>Debug mode banner is now always pinned to the bottom of the inline form and full-page popup, below any AJAX views.<\/li>\n<li>Added a green\/red cookie status line above the debug banner showing whether the area access cookie is currently valid.<\/li>\n<li>Admin modals are now constrained to the browser window with an internal vertical scroll bar, so they stay on screen at high zoom levels.<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>Added a \"Not Signed Up\" template shown (via AJAX) when a visitor verifies an email on the \"already signed up\" form that has not signed up, with a link back to the signup form.<\/li>\n<li>The \"Already Signed Up\" template now includes a close button by default (new <code>{{close_label}}<\/code> placeholder).<\/li>\n<li>Moved the \"Already Signed Up\" template editor into the Popup Template modal (Popup \/ Already Signed Up \/ Not Signed Up) and removed the separate button on each restricted area.<\/li>\n<li>The \"already signed up\" email check is now fully AJAX on inline forms \u2014 no page refresh; closing the already-signed-up view reveals the content immediately.<\/li>\n<li>Added global defaults for the new templates on the Settings page.<\/li>\n<li>Added the <code>not_signedup_template<\/code> database column (automatic migration).<\/li>\n<\/ul>\n\n<h4>1.3.2<\/h4>\n\n<ul>\n<li>Fixed: the \"Already signed up\" link in popup templates that use the older <code>gwiz-it-already-signed-up<\/code> class now opens the verification form instead of refreshing the page.<\/li>\n<li>Fixed: the default popup templates no longer nest an anchor inside the <code>{{already_signed_up_link}}<\/code> placeholder (invalid HTML).<\/li>\n<li>Fixed: no duplicate \"already signed up\" link is appended when the template already contains one.<\/li>\n<\/ul>\n\n<h4>1.3.1<\/h4>\n\n<ul>\n<li>Fixed: elements matched by the CSS Selector setting were not hidden because the generated hide class never matched the stylesheet rule (attribute selector now matches classes anywhere in the class list, plus a data-attribute fallback).<\/li>\n<li>Fixed: selector-matched elements are now hidden with an inline style as well, so the gate still blocks content when the stylesheet is served from cache.<\/li>\n<li>Fixed: selector gates are injected immediately at script parse time (no flash of unprotected content) and can no longer be injected twice.<\/li>\n<li>Added: with Debug Mode enabled on an area, logged-in administrators now see the gate so they can preview it on the frontend.<\/li>\n<li>Added: <code>gwiz_it_content_locker_bypass_logged_in<\/code> filter for controlling the logged-in bypass.<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>Added <code>[gwiz_it_content_locker]<\/code> shortcode for inline content gating with Windows-style area name deduplication.<\/li>\n<li>Added hide-by-CSS-selector feature with first\/all display modes.<\/li>\n<li>Added lead-capture form builder with drag-and-drop fields (9 field types).<\/li>\n<li>Added email templates (confirmation + congratulations) with TinyMCE visual editors.<\/li>\n<li>Added popup template editor with form and already-signed-up placeholders.<\/li>\n<li>Added signups viewer with expandable detail rows, customizable columns, and form snapshot storage.<\/li>\n<li>Added CSV export with UTF-8 BOM for Excel compatibility and field selection.<\/li>\n<li>Added statistics modal with date-range filtering (views, submissions, confirmations, conversion rate).<\/li>\n<li>Added per-area settings: debug mode, cookie expiration, double opt-in.<\/li>\n<li>Added HMAC-signed per-area visitor cookies with configurable expiration.<\/li>\n<li>Added confirmation link handler for double opt-in flow.<\/li>\n<li>Added \"I have already signed up\" verification flow.<\/li>\n<li>Added frontend builder support (Elementor, Divi, Beaver Builder shortcode detection).<\/li>\n<li>Added performance optimization: frontend assets only load when shortcode or hide selectors are detected on the page.<\/li>\n<li>Added <code>gwiz_it_content_locker_load_frontend<\/code> filter for developer control over asset loading.<\/li>\n<li>Added new database tables for signups and analytics.<\/li>\n<li>Security: all visitor-facing AJAX endpoints use nonce verification, input sanitization, and SameSite cookies.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Removed global enable toggle \u2014 each restricted area now has its own on\/off toggle.<\/li>\n<li>Added per-area settings: rename, color picker with preset colors, save button.<\/li>\n<li>New areas spawn with a random color and inactive by default.<\/li>\n<li>Areas store settings as JSON in the database (extensible for future features).<\/li>\n<li>Frontend gating now only enforces active areas (is_active = 1).<\/li>\n<li>Database migration runs automatically on version upgrade.<\/li>\n<li>Area cards show active\/inactive state with visual opacity and toggle switch.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Added custom database tables for restricted areas, URLs, and gated files.<\/li>\n<li>Added Restricted Areas admin page with expandable area cards, URL management, and autocomplete.<\/li>\n<li>Added Settings page with \"Enable Lead Gating\" toggle.<\/li>\n<li>Added frontend gate overlay for restricted page\/post URLs.<\/li>\n<li>Added gated file download system with tokenized URLs and private file storage.<\/li>\n<li>Added confirmation modals for destructive actions.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial plugin foundation.<\/li>\n<li>Added the GWiz IT Content Locker administration dashboard.<\/li>\n<li>Added translation-ready and GPL-licensed plugin structure.<\/li>\n<\/ul>","raw_excerpt":"Gate WordPress content and downloads behind signup forms. Capture leads, track conversions, and sync subscribers \u2014 free and self-hosted.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/kaa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/371779","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kaa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/kaa.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/kaa.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=371779"}],"author":[{"embeddable":true,"href":"https:\/\/kaa.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/gbecker1983"}],"wp:attachment":[{"href":"https:\/\/kaa.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=371779"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/kaa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=371779"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/kaa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=371779"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/kaa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=371779"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/kaa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=371779"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/kaa.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=371779"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}