=== Webkoding AgeWall – Age Verification and Age Gate ===
Contributors: webkoding
Tags: age verification, age gate, age restriction, restricted content, compliance
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Age verification and age gate that withholds restricted content on the server — an unverified visitor never receives it.

== Description ==

Webkoding AgeWall adds real, server-side age verification to WordPress. Unlike simple "click to confirm" overlays that only hide content with CSS or JavaScript, AgeWall withholds protected content on the server: an unverified visitor never receives the restricted markup in the HTTP response, so it cannot be revealed by disabling scripts or reading the page source.

Gate your whole site, or just the pages, posts and blocks that need it. Set the minimum age, choose how visitors prove it, and decide what happens when they have not — all from one settings screen.

= Key features =

* **True server-side enforcement.** Protected content, shortcodes and blocks are withheld before the response is sent. The gate requirement (minimum age and method) is signed and re-derived on the server, so it cannot be weakened by tampering with the request.
* **Whole-site gate or per-content gates.** Gate the entire site with an overlay or a dedicated page, or gate individual pieces of content with the `[agewall]` shortcode and the AgeWall block.
* **Per-post and per-category restrictions.** Mark any post, page, custom post type or term as age-restricted, with its own minimum age and method.
* **Two verification methods.**
  * Confirmation ("I am over N") — a lightweight self-declared check.
  * Date of birth (DOB) — a self-declared date, validated on the server.
* **Choose your enforcement.** Withhold the content entirely (the default and the strictest), redirect to a gate page, or cover the page with an overlay when you need search engines to keep seeing it.
* **Search-engine friendly.** Optionally allow known search-engine bots to bypass the gate for SEO.
* **Customizable gate appearance.** Set the gate title, message and logo, and choose an overlay, modal or inline template.
* **No accounts, no tracking, no third-party calls.** AgeWall stores no personal data and contacts no external service.
* **Translation ready.** All strings use the `webkoding-agewall` text domain and a `languages/webkoding-agewall.pot` template is included.

= Developers =

AgeWall is built to be extended. Documented hooks let you add your own verification provider (`agewall/register_providers`), supply your own rule set (`agewall/rules`), resolve the visitor's country (`agewall/visitor_country`), observe every verification attempt (`agewall/verification_attempt`), and add your own settings tabs and admin screens (`agewall/settings_tabs`, `agewall/admin_menu`).

== Installation ==

1. Upload the `webkoding-agewall` folder to the `/wp-content/plugins/` directory, or install the plugin through the WordPress Plugins screen.
2. Activate the plugin through the "Plugins" screen in WordPress.
3. Go to **AgeWall** in the admin menu, set your minimum age, verification method and appearance.
4. (Optional) Mark individual posts, pages or terms as age-restricted from the AgeWall box on their edit screen.

== Frequently Asked Questions ==

= Does AgeWall really hide content from unverified visitors, or is it just a visual overlay? =

It genuinely withholds the content on the server. Restricted content is never placed in the HTTP response for an unverified visitor, so it cannot be exposed by disabling JavaScript, editing CSS, or viewing the page source.

This depends on the rule's action, and the difference is important: **withhold** and **redirect** are content-withholding — the protected page is never rendered or sent to an unverified visitor — and withhold is the default. **Overlay** is a soft/SEO mode: the page still renders and is sent in the response with the gate painted over it, so use it only when you want search engines and existing rankings to keep seeing the page, not when the content must actually be withheld.

= Which verification methods are included? =

Confirmation ("I am over N") and self-declared date of birth. Both are checked on the server, and a visitor verified by the stronger method also satisfies the weaker one.

= What personal data does AgeWall store? =

None. AgeWall stores no personal data about your visitors, creates no database tables, and makes no third-party requests. A visitor's proof of age is held in a signed cookie that records only the scope, the minimum age and the method it was granted for — never a date of birth.

= Can I enforce a different age for different countries? =

No. Every visitor is held to the same rule, which you set once in Settings. The plugin does not geolocate visitors and does not vary the minimum age by country. Developers can hook `agewall/rules` and `agewall/visitor_country` to match on their own criteria.

= Can I add my own verification method? =

Yes. Implement `Agewall\Providers\ProviderInterface` and register it on the `agewall/register_providers` action. It will appear automatically everywhere a method can be chosen.

= Is AgeWall translation ready? =

Yes. Every user-facing string uses the `webkoding-agewall` text domain, and a `languages/webkoding-agewall.pot` template is bundled for translators.

== Screenshots ==

1. Server-side enforcement: an unverified visitor's page source contains no restricted markup at all. The protected text is absent from the HTTP response, not hidden with CSS.
2. A page gated with the whole-page age gate, asking the visitor for a date of birth.
3. A public article with one age-restricted section locked by the `[agewall]` shortcode. The surrounding paragraphs stay public.
4. The AgeWall Gate block. The blocks nested inside it are rendered on the server only after the visitor verifies.
5. Settings: minimum age, verification method, and what happens when a visitor is unverified — withhold, redirect or overlay.
6. The "Age restriction (AgeWall)" box on the edit screen, setting a minimum age and method for a single page.

== Changelog ==

= 1.0.1 =
* Renamed: the listing now says what the plugin does, not only what it is called. No functional change.

= 1.0.0 =
* Initial release.
