=== AddonLogic Role Content Visibility ===
Contributors: snehalpancholi
Tags: role, visibility, content restriction, user role, shortcode
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 8.1
Stable tag: 1.0.0
License: GPL-2.0+
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Shortcodes to show or hide WordPress content based on the viewer's user role. Server-side filtering — excluded content never reaches the browser.

== Description ==

**AddonLogic Role Content Visibility** gives you three lightweight shortcodes to control exactly who sees what on your site — purely on the server side. Excluded content is never sent to the browser at all, unlike CSS-based visibility tricks.

= Shortcodes =

**[rcv_show role="..."]**
Shows the enclosed content only to users who have at least one of the listed roles.
Use `role="logged_in"` to show content to any authenticated user.

**[rcv_hide role="..."]**
Hides the enclosed content from users who have at least one of the listed roles.
Use `role="logged_out"` to hide from guests only.

**[rcv_guest]**
Shows the enclosed content only to non-logged-in visitors.

= Special Values =

* `logged_in` — any authenticated user (any role)
* `logged_out` — any guest / not logged in

= Features =

* Pure server-side filtering — excluded content never reaches the browser
* Supports all built-in and custom WordPress roles
* Comma-separated role lists in a single attribute
* Nested shortcodes render correctly inside visibility wrappers
* Informational admin page at Settings > Role Visibility listing all site roles and their slugs
* Zero configuration required — drop shortcodes into any post, page, or widget
* No CSS, no JavaScript, no cookies
* PHP 8.1+ procedural code, no classes

== Installation ==

1. Upload the `role-content-visibility` folder to `/wp-content/plugins/`.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Navigate to **Settings > Role Visibility** for the shortcode reference and a list of all roles on your site.
4. Insert shortcodes into any post, page, or widget.

== Frequently Asked Questions ==

= Does excluded content appear in the page source? =

No. The shortcode callbacks return an empty string on the server before the page is sent to the browser. The content does not appear in the HTML source at all.

= Can I use multiple roles in one shortcode? =

Yes. Separate role slugs with commas: `role="editor,author,contributor"`. The shortcode matches if the viewer has **any** of the listed roles.

= Can I nest shortcodes? =

Yes. `do_shortcode()` is called on the inner content, so nested shortcodes — including other `[rcv_*]` shortcodes — process correctly.

= What happens if the `role` attribute is omitted on [rcv_show]? =

The shortcode returns an empty string, showing the content to nobody. Always specify a `role` attribute on `[rcv_show]`.

= What happens if the `role` attribute is omitted on [rcv_hide]? =

The shortcode shows the content to everyone — no restriction is applied.

= Does this work with custom roles created by membership plugins? =

Yes. The plugin reads roles directly from `WP_User::$roles`, so any role registered on the site — including those added by WooCommerce, MemberPress, or custom code — is supported.

= Does [rcv_guest] conflict with caching plugins? =

If your caching plugin serves a single cached page to all visitors, role-based content will not work correctly. Configure your cache to either bypass the cache for logged-in users (most caching plugins do this by default) or use fragment caching. The guest shortcode works correctly when the page is not cached at all.

== Screenshots ==

1. Settings > Role Visibility — shortcode reference and site roles table.
2. [rcv_show] in the block editor — content visible only to administrators.
3. [rcv_guest] in the block editor — login prompt for non-logged-in visitors.

== Changelog ==

= 1.0.0 =
* Initial release.
* Shortcodes: [rcv_show], [rcv_hide], [rcv_guest].
* Admin page: Settings > Role Visibility with role slug reference.
* Server-side filtering — excluded content is never sent to the browser.
