Skip to content

Instantly share code, notes, and snippets.

@fgdaniel
Last active April 18, 2024 03:02
Show Gist options
  • Save fgdaniel/0db00c891eaf5a8be0c2619d747eec6b to your computer and use it in GitHub Desktop.
Save fgdaniel/0db00c891eaf5a8be0c2619d747eec6b to your computer and use it in GitHub Desktop.
Custom permalink from the root of the site
<?php
if (!defined('ABSPATH')) return; // Exit if accessed directly.
// Attention
// You must have ACF and ACF Extended installed, you need a group made with a slug field that will be called 'custom_permalink' and select on which post-type to appear. Example: https://i.imgur.com/aTNpHoU.png
// For custom permalink of an archive you have to activate the option here: https://i.imgur.com/SOvcbBj.png and in the group with the field 'custom_permalink' you have to select on which archive to appear, example: https://i.imgur.com/dKLfDEJ.png
// Example of an archive: https://i.imgur.com/owENTRB.png if you do not complete 'custom_permalink' then the default will be the '$default_slug' variable
// If you do not want custom url rewrite on an archive you can comment the line 'add_filter('post_type_archive_link', [$this, 'archive_link'], 10, 2);' and line '$rules['^' . $custom_url . '/?$'] = $path;'
// Replace 'example' with your post-type name
// Note: This method work fine with polylang when i used, sometimes maybe do not work as expected, i do not tested with wpml, but if you have a fix for that, you can pull-request with the fix.
class exemple_rewrite
{
public $post_type = 'exemple';
public $default_slug = 'exemple';
public $acf_query = 'exemple_archive';
public function __construct()
{
add_filter('generate_rewrite_rules', [$this, 'rewrite_rules']);
add_filter('post_type_link', [$this, 'post_link'], 10, 2);
add_filter('post_type_archive_link', [$this, 'archive_link'], 10, 2);
flush_rewrite_rules();
}
public function rewrite_rules($wp_rewrite)
{
$rules = [];
$custom_url = get_field('custom_permalink', $this->acf_query) ? get_field('custom_permalink', $this->acf_query) : $this->default_slug;
$path = 'index.php?post_type=' . $this->post_type;
$rules['^' . $custom_url . '/?$'] = $path; // The base url(Archive)
$qry = get_posts([
'post_type' => $this->post_type,
'posts_per_page' => -1,
'post_status' => ['publish'],
'fields' => 'ids',
'cache_results' => true,
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
]);
if(empty($qry)) return;
foreach($qry as $post) {
$post_slug = get_field('custom_permalink', $post) ? get_field('custom_permalink', $post) : sanitize_title(get_the_title($post)); // Get slug from acf field otherwise default from title
wp_update_post([ 'ID' => $post, 'post_name' => $post_slug ]); // Store it to db, make feel as default behavior
$rules['^' . $post_slug . '/?$'] = $path . '&p=' . $post;
}
wp_reset_postdata();
$wp_rewrite->rules = $rules + $wp_rewrite->rules;
}
public function post_link($permalink, $post)
{
if ($post->post_type !== $this->post_type) return $permalink;
$post_id = $post->ID;
$custom_url_slug = get_field('custom_permalink', $post_id);
$permalink = home_url($custom_url_slug ? $custom_url_slug : sanitize_title(get_the_title($post_id))); // Set post slug from acf field otherwise default from title
return $permalink;
}
public function archive_link($link, $post_type)
{
if ($post_type != $this->post_type) return $link;
$custom_url = get_field('custom_permalink', $this->acf_query) ? get_field('custom_permalink', $this->acf_query) : $this->default_slug;
$link = str_replace('?post_type=' . $this->post_type, $custom_url, $link); // Replace archive slug from acf field otherwise default
return $link;
}
}
new exemple_rewrite();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment