Skip to content

Instantly share code, notes, and snippets.

@maciejbis
Last active October 25, 2022 14:27
Show Gist options
  • Save maciejbis/d97758820d60f1bdadc4e34ec2028d33 to your computer and use it in GitHub Desktop.
Save maciejbis/d97758820d60f1bdadc4e34ec2028d33 to your computer and use it in GitHub Desktop.
Filter default post & term permalinks (Permalink Manager)
<?php
/**
* 1A. How to programmatically modify post permalink formats (permastructures)
*
* @param string $permastructure The permastructure string used when default custom permalink is generated.
* @param WP_Post|WP_Term $post Post or term object
* @return string The new, filtered permastructure string used when default custom permalink is generated (for new posts or existing ones if "Regenerate/reset" tool is used)
*/
function pm_filter_post_permastructure($permastructure, $post) {
// Filter only 'Post' permalinks
if(empty($post->post_type) || $post->post_type !== 'post') {
return $permastructure;
}
// A. Post assigned to either 'Category A' or 'Category B'
if(has_term(array('Category A', 'Category B'), 'category', $post)) {
$permastructure = '%category%/%postname%';
}
// B. Post assigned to other categories
else {
$permastructure = '%year%/%monthnum%/%day%/%postname%';
}
return $permastructure;
}
add_filter('permalink_manager_filter_permastructure', 'pm_filter_post_permastructure', 10, 2);
<?php
/**
* 1B. How to programmatically modify product permalink formats (permastructures)
*
* @param string $permastructure The permastructure string used when default custom permalink is generated.
* @param WP_Post|WP_Term $product Post or term object
* @return string The new, filtered permastructure string used when default custom permalink is generated (for new products or existing ones if "Regenerate/reset" tool is used)
*/
function pm_filter_product_permastructure($permastructure, $post) {
// Filter only 'Product' permalinks
if(empty($post->post_type) || $post->post_type !== 'product' || !function_exists('get_product')) {
return $permastructure;
}
$product = get_product($post->ID);
// A. Virtual products
if($product->is_virtual()) {
$permastructure = 'course/%product%';
}
// B. Other products
else {
$permastructure = 'store/%product%';
}
return $permastructure;
}
add_filter('permalink_manager_filter_permastructure', 'pm_filter_product_permastructure', 10, 2);
<?php
/**
* 1C. How to programmatically modify term permalink formats (permastructures)
*
* @param string $permastructure The permastructure string used when default custom permalink is generated.
* @param WP_Post|WP_Term $term Post or term object
* @return string The new, filtered permastructure string used when default custom permalink is generated (for new terms or existing ones if "Regenerate/reset" tool is used).
*/
function pm_filter_category_permastructure($permastructure, $term) {
// Filter only 'Category' permalinks
if(empty($term->taxonomy) || $term->taxonomy !== 'category') {
return $permastructure;
}
// Get parent term
$parent_term = (!empty($term->parent)) ? get_term_by('id', $term->parent, $term->taxonomy) : '';
// Use term ID instead of slug for all subcategories of 'Clothes'
if(!empty($parent_term->slug) && $parent_term->slug == 'clothes') {
$permastructure = '%term_id%';
}
return $permastructure;
}
add_filter('permalink_manager_filter_permastructure', 'pm_filter_category_permastructure', 10, 2);
<?php
/**
* 2A. How to programmatically modify post permalinks?
*/
function pm_filter_default_post_uris($default_uri, $native_slug, $post, $slug, $native_uri) {
// Do not change native permalinks or different post types
if($native_uri || $post->post_type != 'post') { return $default_uri; }
// Get the year when the post was published
$year = date("Y", strtotime($post->post_date));
// Get post author meta - it can be user_login, user_email, ID or other field:
// Reference: https://developer.wordpress.org/reference/functions/get_the_author_meta/
$author = get_the_author_meta('user_login', $post->post_author);
// 1A. Blog posts (you can use either category name, slug or its ID)
// Example URL: http://example.com/blog/lorem-ipsum/
if(in_category('blog', $post)) {
$default_uri = "blog/{$slug}";
}
// 1B. Press releases
// Example URL: http://example.com/news-and-resources/press-releases/2016/dolor-sit-amet/
else if(in_category('press-releases', $post)) {
$default_uri = "news-and-resources/press-releases/{$year}/{$slug}";
}
// 2. Posts added by John Doe
// Example URL: http://example.com/interviews/2018/john-doe/etiam-ullamcorper/
else if($author == 'john-doe') {
// Get the author full name
$author_name = sprintf("%s %s",
get_the_author_meta('first_name', $post->post_author),
get_the_author_meta('last_name', $post->post_author)
);
// Sanitize the author name, so it can be safely used inside URI
$author_safename = sanitize_title($author_name);
$default_uri = "interviews/{$year}/{$author_safename}/{$slug}";
}
// 3A. Posts published in and after 2017
// Example URL: http://example.com/news-and-resources/malesuada-ultricies/
else if(intval($year) >= 2017) {
$default_uri = "news-and-resources/{$slug}";
}
// 3B. Posts published before 2017
// Example URL: http://example.com/archive/2016/nulla-imperdiet/
else {
$default_uri = "archive/{$year}/{$slug}";
}
return trim($default_uri, "/");
}
add_filter('permalink_manager_filter_default_post_uri', 'pm_filter_default_post_uris', 10, 5);
<?php
/**
* 2B. How to programmatically modify term permalinks?
*/
function pm_filter_default_term_uris($default_uri, $native_slug, $term, $slug, $native_uri) {
// Do not change the native permalinks => Apply the filter only to the custom permalinks
if($native_uri) { return $default_uri; }
// Get the parent term
if(isset($term->parent)) {
$parent_term = get_term_by('id', $term->parent, $term->taxonomy);
}
// Do not filter the default custom permalink if no parent term is set
else {
return $default_uri;
}
// A. Terms that are children of "shoes" category
// Example URL: http://example.com/adidas-shoes/
if($parent_term->slug == 'shoes') {
$default_uri = "{$slug}-shoes";
}
// B. Terms that are children of "jackets" category
// Example URL: http://example.com/outerwear/jackets/north-face
else if($parent_term->slug == 'jackets') {
$default_uri = "outerwear/{$parent_term->slug}/{$slug}";
}
return trim($default_uri, "/");
}
add_filter('permalink_manager_filter_default_term_uri', 'pm_filter_default_term_uris', 10, 5);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment