add_permastruct()
Adds a new permalink structure for pretty URLs.
Creates not one rule, but several based on one specified permalink structure, what rules to create is determined by the $args parameter and the tags of the structure itself...
Explanation
The permalink structure is an abstract concept and means setting (defining) the rules for how a pretty URL (human-readable URL) should look.
This function allows you to quickly create a group of rules (with regular expressions) that will rewrite the URL into internal query parameters. The new rules will be added to the WP_Rewrite::$extra_permastructs property (array).
When rewrite rules are created by the function WP_Rewrite::rewrite_rules(), all these new permalinks are passed to the function WP_Rewrite::generate_rewrite_rules(), which in turn converts them into regular expressions and determines what URL should result if the regex matches the current request URL.
The $args parameter allows you to control how WP_Rewrite::generate_rewrite_rules() will create the new permalink structure.
Explanation again, in other words.
The added structure, for example, book/%book% is parsed and based on it, the necessary pretty URL rewrite rules are added to the pretty URL settings (see the global variable $wp_query).
The tags specified in the structure, for example %book%, are replaced with the corresponding part of the regular expression that is specified when registering the rewrite tag in add_rewrite_tag().
If unknown tags are specified in the structure, they will not be replaced with groups of regular expressions and will remain in the rewrite rules as is. For example, the pretty URL will look like this if an unregistered tag %order_id% is specified:
[order/%order_id%/?$] => index.php?%order_id%$matches[1]
The tag (placeholder) needs to be registered separately using the function add_rewrite_tag().
This function is usually used in conjunction with the functions: add_rewrite_tag() and add_rewrite_rule()
Works based on the method WP_Rewrite::add_permastruct( $name, $struct, $args ).
No Hooks.
Returns
null. Nothing.
Usage
add_permastruct( $name, $struct, $args );
- $name(string) (required)
- Name of the structure. The name of the post type for which the pretty URL structure is created.
- $struct(string) (required)
- The pretty URL structure itself.
- $args(array)
Parameters for building the link from the specified structure.
For more details, see:
The following parameters are set by default:
$defaults = [ 'with_front' => true, 'ep_mask' => EP_NONE, 'paged' => true, 'feed' => true, 'forcomments' => false, 'walk_dirs' => true, 'endpoints' => true, ];
By default: [] (defaults)
Possible elements of the array:
-
with_front(boolean)
Whether to prepend the structure with the parameter WP_Rewrite::$front.
By default true. -
paged(boolean)
Whether to add rules for post pagination -/post_name/page/xx? If set totrue, then the post can use the shortcode<!--nextpage-->. See wp_link_pages().
By default true. -
feed(boolean)
Whether to add rules for feed pages -/feed/?
By default true. -
forcomments(boolean)
Make the feed link a request for the comment feed. A parameter&withcomments=1will be added.
By default false. -
walk_dirs(boolean)
If set to true, a rewrite rule will be created for each directory specified in the structure. For example, if the structure is specified as/%year%/%month%/%day/, then rules will be created for the directories:/%year%/,/%year%/%month%/and/%year%/%month%/%day%/.
By default true. -
ep_mask(integer)
Indicates which additional (to the base pretty URL) entry points WordPress should create for the rewrite rules. EP - endpoints.Parameters should be combined using bitwise OR:
'rewrite' => [ 'ep_mask' => EP_PERMALINK | EP_ROOT ],
Possible values:
EP_NONE // disables all endpoint rules (attachment, comments, ...). EP_PERMALINK // single post EP_ATTACHMENT // attachment page EP_DATE // any date archives EP_YEAR // year archive EP_MONTH // month archive EP_DAY // day archive EP_ROOT // main blog page EP_COMMENTS // comment pages EP_SEARCH // search page EP_CATEGORIES // category archive EP_TAGS // tag archive EP_AUTHORS // author archive EP_PAGES // pages (post_type=page) EP_ALL_ARCHIVES // EP_DATE | EP_YEAR | EP_MONTH | EP_DAY | EP_CATEGORIES | EP_TAGS | EP_AUTHORS EP_ALL // EP_PERMALINK | EP_ATTACHMENT | EP_ROOT | EP_COMMENTS | EP_SEARCH | EP_PAGES | EP_ALL_ARCHIVES
The code for building the pretty URL with these flags can be found in WP_Rewrite::generate_rewrite_rules()
How it works step by step:
-
At the beginning of the function, the value of the mask is passed as is and does not change anymore.
-
For each directory of the structure, a helper mask
$ep_mask_specificis calculated:%year%→ EP_YEAR%monthnum%→ EP_MONTH%day%→ EP_DAY- otherwise EP_NONE
-
Comment rules
- If the mask contains
EP_PAGESorEP_PERMALINK→/comment-page-N/is added. - Otherwise, if it contains
EP_ROOTand the main page is set →/comment-page-N/is added for the root.
- If the mask contains
-
Endpoint rules ($this->endpoints)
For each registered endpoint:- If
(endpoint_mask & $ep_mask)or(endpoint_mask & $ep_mask_specific)is true → the rule.../<endpoint>/...is added to the current URL template.
- If
-
Nested endpoints of attachments
- For attachments, only
EP_ATTACHMENTis checked for the endpoints themselves,$ep_maskis not involved here.
- For attachments, only
-
If
$ep_mask= EP_NONE (by default)- Comments are not added.
- Endpoints will still be added for dates (
EP_YEAR|EP_MONTH|EP_DAY) becauseep_mask_specificis triggered.
-
If
$ep_maskcontains multiple flags (for exampleEP_PERMALINK|EP_PAGES)- All branches are triggered, the condition uses bitwise
&.
- All branches are triggered, the condition uses bitwise
-
Summary
$ep_maskaffects only:- the generation of pagination comment rules;
- the selection of endpoints that are attached to the URL template.
By default EP_NONE
-
-
endpoints(boolean)
Whether to add endpoints at the end of the pretty URL rewrite rules? Which endpoints to add is specified inep_mask.By default true.
-
Examples
#1 Friendly URL structure for book custom post type
Let's say when registering a post type with register_post_type() we specified parameter rewrite=false. And now we want to manually set Friendly URL for this post type, then we may use this code.
add_action( 'init', 'book_post_type_permastruct' );
function book_post_type_permastruct(){
$post_type = 'book';
$permastruct = "$post_type/%book%"; // Friendly URL structure
$args = [
'with_front' => true,
'paged' => true,
'ep_mask' => EP_NONE,
'feed' => false,
'forcomments' => false,
'walk_dirs' => false,
'endpoints' => false,
];
add_permastruct( $post_type, $permastruct, $args );
// Add a rewrite tag so that add_permastruct() understands it.
// It will then be replaced by the part of the regular
// expression string specified in the second parameter.
add_rewrite_tag( "%book%", '([^/]+)', "post_type=$post_type&name=" );
}
The third parameter in add_permastruct() can be omitted, then the arguments will be default.
After installing the code, you need to reset the Friendly URL rules, for this you just need to go to Settings > Permalinks in the admin panel. Or run function flush_rewrite_rules():
// flush rewrite rules, if your permalink changed (e.g. on plugin activation): flush_rewrite_rules();
Notes
- See: WP_Rewrite::add_permastruct()
- Global. WP_Rewrite.
$wp_rewriteWordPress rewrite component.
Changelog
| Since 3.0.0 | Introduced. |
add_permastruct() add permastruct code WP 6.9.1
function add_permastruct( $name, $struct, $args = array() ) {
global $wp_rewrite;
// Back-compat for the old parameters: $with_front and $ep_mask.
if ( ! is_array( $args ) ) {
$args = array( 'with_front' => $args );
}
if ( func_num_args() === 4 ) {
$args['ep_mask'] = func_get_arg( 3 );
}
$wp_rewrite->add_permastruct( $name, $struct, $args );
}