Last Modified: KB » WooCommerce Restrictions
Protecting Content by URI Pattern

Protecting content with URI Patterns allows you to protect almost any content served by WordPress. You can protect multiple Posts and Pages using wildcards and regular expressions with WRegx™ (Watered-Down Regex).

Dashboard Location

DashboardRestrictionsAdd Restriction

Here you will find a meta box: Protected URI Patterns, where you can protect one or more URI Patterns. This functionality makes it easy to protect nearly any aspect of a site powered by WordPress.


URI Pattern Examples

What is a URI?

In this URL:

This is the URI (everything after the domain name).


Example 1 (Begins With)

If I want to protect every URI that begins with /members/, I would use this URI Pattern:


Note: ** matches zero or more characters of any kind, including a /. So this will match /members/anything/, /members/anything/page/2/, and many others. However, it will not match /anything/members/ because that doesn't begin with /members/, which is what my Pattern looks for explicitly.

Example 2 (Contains)

If I want to protect every URI that contains /members/, in any location, I would use this Pattern:


Note: ** matches zero or more characters of any kind, including a /. This Pattern will match /members/anything/, /anything/members/page/2/, /anything/members/, /anything/else/members/page/2/, and many others. However, it will not match /member/profile/ — that's singular.

Tip: If I want to cover both singular and plural, I could use this Pattern:


WRegx™ (Watered-Down Regex)

URI Patterns are constructed using a watered-down version of a powerful search pattern syntax called Regular Expressions. Our watered-down version (we call it WRegx™), offers you the following wildcard characters, along with advanced syntax that can be helpful in certain scenarios.

Wildcard Characters in a URI Pattern

  • * Matches zero or more characters that are not a /
  • ** Matches zero or more characters of any kind, including a /

  • ? Matches exactly one character that is not a /

  • ?? Matches exactly one character of any kind, including a /

Advanced Syntax Supported in URI Patterns

  • [abc] Matches exactly one character: a, b, or c.
  • [a-z0-9] Matches exactly one character: a thru z or 0 thru 9.
  • [!abc] A leading ! inside [] negates; i.e., anything that is not: a, b, or c.

  • {abc, def} Matches the fragment abc or def (one or the other).

  • {abc,def,} Matches abc, def, or nothing; i.e., an optional match.
  • {/**,} Matches a / followed by zero or more characters, or nothing.

  • [*?[]!{},] Matches a literal special character. One of: * ? [ ] ! { }, explicitly.

Other Details Worth Mentioning

  • Comparison is always caSe-insensitive (i.e., caSe does not matter).

  • Your Pattern must match an entire URI (beginning to end) not just a portion of the URI.

  • A URI always starts with a slash (e.g., /example-post/). The smallest possible URI (the home page) is: /

  • If your current Permalink Settings in WordPress indicate that all URIs on your site have a trailing slash, you must match that trailing slash in your Patterns. For this reason, it's a good idea to always end your pattern with /** or {/**,} so you're covering all bases. More on this in the next list item.

  • In WordPress, it is common for any given URI to accept additional endpoint directives, such as paginated locations: /example-post/page/2/, /example-post/comments-page/2/. Therefore, we suggest a Pattern that covers all possible endpoint variations. For example: /example-post{/**,} matches the base URI by itself and it also matches a possible trailing slash with any endpoint directives it may accept.

  • Any query string variables on the end of a URI (e.g., ?p=123&key=value) are stripped before comparison. However, if your Pattern contains: [?] (literally, a ? question mark in square brackets) it indicates that you do want to check the query string, and they are not stripped away in that case. Just remember that query string variables can appear in any order, as entered by a user. If you check for query strings, use {**&,} and {&**,} around the key=value pair you're trying to find. For instance: /example-post{/**,}[?]{**&,}key=value{&**,}. If you're forced to look for multiple variables, the best you can do is: {**&,}key=value{&**&,&,}another=value{&**,}. Note that key=value is still expected to be first in this example, so please use caution.

  • It is possible to protect (and grant) access to portions of /wp-admin/ with URI Patterns too. However, please remember that for a user to do anything inside the admin panel, they must have Capabilities which grant them additional permissions, such as the ability to edit_posts. See: Role Capabilities as a form of protection if you would like more information.

  • It is possible to restrict access to every page on the entire site using the Pattern /** as a catch-all. In this scenario, everything is off-limits, except for just a few special URIs on your site, which will be listed in your Dashboard in the location where URI Patterns are entered. Be careful when using a catch-all Pattern though, because everything (yes, everything) is off-limits, including your home page! We suggest this as a last resort only. Instead, restrict Posts, Pages, Categories, Tags and other distinct URIs. It is best to restrict only portions of a site from public access.

  • Restrictions rely upon PHP as a server-side scripting language. Therefore, you can protect any location served by WordPress via PHP, but you cannot protect static files. For instance, files ending in .jpg, .pdf, and .zip are static. Generally speaking, if you upload something to the Media Library, it is a static asset. Therefore it cannot be protected here. Instead, configure a 'Downloadable Product' with WooCommerce.