How to change Wordpress' default posts permalinks programmatically? - php

In the backend of Wordpress I use the default http://localhost/sitename/example-post/ value for creating permalinks.
For custom post types I defined a custom slug this way, here is services for example:
register_post_type( 'service',
array(
'labels' => array(
'name' => __( 'Services' ),
'singular_name' => __( 'Service' )
),
'public' => true,
'has_archive' => true,
'rewrite' => array(
'slug' => 'services',
'with_front' => true
),
'supports' => array(
'title',
'editor',
'excerpt',
'thumbnail'
),
'taxonomies' => array( 'category' ),
)
);
It creates services/post-name.
I also use this hook to create a custom page to create a custom page permalink:
function custom_base_rules() {
global $wp_rewrite;
$wp_rewrite->page_structure = $wp_rewrite->root . '/page/%pagename%/';
}
add_action( 'init', 'custom_base_rules' );
It creates page/post-name
Now the only thing I need to do is to create another custom permalink path for the normal Wordpress posts.
So the outcome world be for the post type of post:
post/post-name
I can't use the backed for this because I already defined a default way of handling the permalinks. I already managed to rewrite the paths of custom post types and pages...
How do I rewrite the normal post post type permalink path in Wordpress programmatically?

You need to do it in two steps.
First enable rewrite with 'with_front' => true for the buildin post registration
add_filter(
'register_post_type_args',
function ($args, $post_type) {
if ($post_type !== 'post') {
return $args;
}
$args['rewrite'] = [
'slug' => 'posts',
'with_front' => true,
];
return $args;
},
10,
2
);
This way urls like http://foo.example/posts/a-title work but generated links in are now wrong.
Links can be fixed by forcing custom permalink structure for the buildin posts
add_filter(
'pre_post_link',
function ($permalink, $post) {
if ($post->post_type !== 'post') {
return $permalink;
}
return '/posts/%postname%/';
},
10,
2
);
See https://github.com/WordPress/WordPress/blob/d46f9b4fb8fdf64e02a4a995c0c2ce9f014b9cb7/wp-includes/link-template.php#L166

Posts have to use the default permalink structure, they do not have a special entry in the rewrite object in the same way that pages or custom post types do. If you want to change the default structure programmatically, you can add something like this to your hook.
$wp_rewrite->permalink_structure = '/post/%postname%';
I'm not super clear what you mean when you say
I can't use the backed for this because I already defined a default way of handling the permalinks. I already managed to rewrite the paths of custom post types and pages...
It sounds as though you're overriding the default behavior for permalinks everywhere except for posts so if you changed the default it would likely only affect posts anyway.

The permalink_structure property suggested by GentlemanMax did not work for me. But I found a method that does work, set_permalink_structure(). See code example below.
function custom_permalinks() {
global $wp_rewrite;
$wp_rewrite->page_structure = $wp_rewrite->root . '/page/%pagename%/'; // custom page permalinks
$wp_rewrite->set_permalink_structure( $wp_rewrite->root . '/post/%postname%/' ); // custom post permalinks
}
add_action( 'init', 'custom_permalinks' );

Related

Custom Post Type single page not found

I use a plugin that has a custom post type and when I publish a post it is displayed on a single page but when the post is automatically published using an author's robot plugin, unfortunately, the single page is not found and shows error 404!!
//------------------------
//function init
//-------------------------
static function init(){
add_action( 'init', array( __CLASS__, 'register_post_types' ) );
}
//------------------------
//register post type
//-------------------------
static function register_post_types(){
$labels = array(
//custom post type
);
$args = array(
'labels' => $labels,
'public' => true,
'show_ui' => true,
'hierarchical' => false,
'rewrite' => array('slug' => 'jobtest'),
'query_var' => true,
'has_archive' => true,
'supports' => array('title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' )
);
register_post_type( 'iwj_job' , $args );
}
I have the main plugin file with this function:
public function init_hooks() {
register_activation_hook( __FILE__, array( 'IWJ_active', 'activate' ) );
}
Then within my class, I have this:
static function activate() {
IWJ_Post_Types::register_post_types();
flush_rewrite_rules();
}
I don't know why when I use the Author Robot Plugin for publishing a post, custom post type single page not found?? but it works when I manually update it again!
For fixing custom post not found please use below code in your functions.php:
flush_rewrite_rules( false );
And,
Simply go to settings>permalinks and choose a permalink structure if you haven’t done so already. Once done click “save changes” and make any changes to .htaccess if prompted to do so. Now view you custom post again and all should be right with the world.

How to change slug in wordpress?

I have this URL for my Resort page page-resorts.php:
http://localhost/testwordpress/resorts/
After clicking the link to a post under Resort custom page I will have this URL for my custom page template (CPT) single-resort.php:
http://localhost/testwordpress/resort/kurumba-maldives/
As you can see the resorts was changed to resort because I can't use resorts slug for the slug post.
How can I achive this kind of URL:
http://localhost/testwordpress/resorts/kurumba-maldives/
where the resorts word is used and not resort word only?
I've heard about custom slug and search for it, but I still can't understand it.
You can create your custom post type this way.
function create_posttype() {
register_post_type( 'resort',
array(
'labels' => array(
'name' => __( 'Resorts' ),
'singular_name' => __( 'Resort' )
),
'public' => true,
'has_archive' => true,
'rewrite' => array('slug' => 'resorts'),
)
);
}
add_action( 'init', 'create_posttype' );
'rewrite' => array('slug' => 'resorts'), this used to add the slur on URL. this way you can acheive your URL.
Or you can override your current slug in functions.php
add_filter( 'register_post_type_args', 'wpse247328_register_post_type_args', 10, 2 );
function wpse247328_register_post_type_args( $args, $post_type ) {
if ( 'resort' === $post_type ) {
$args['rewrite']['slug'] = 'resorts';
}
return $args;
}
For more, please visit.
register post type
Change Custom Post Type slug

Wordpress Costum Post Type - ACF in URL

I have some problem that I need help in them -
I register costum post type - is slug is "project"
But I need to make 3 categories (with ACF) and make url changed due to it
category1 = http://www.example.com/mycaturl/nameoftitle
category2 = http://www.example.com/othercat/nameoftitle
category3 = http://www.example.com/customedit/nameoftitle
How can I make it without plugins...?
Thanks for helpers :)
Tested and verified:
I am writting in steps to make it clear:
Make sure when you registered your custom post type rewrite for more: register custom post type
'rewrite' => array('slug' => '/%project_categories%','with_front' => FALSE),
Then register your taxonomies project_categories
You need to register custom taxonomy project_categories for this custom (project) post type. register_taxonomy please read here for more
function project_taxonomy() {
register_taxonomy(
'project_categories', //The name of the taxonomy. Name should be in slug form (must not contain capital letters or spaces).
'project', //post type name
array(
'hierarchical' => true,
'label' => 'project store', //Display name
'query_var' => true,
'rewrite' => array(
'slug' => 'project', // This controls the base slug that will display before each term
'with_front' => false // Don't display the category base before
)
)
);
}
add_action( 'init', 'project_taxonomy');
Last make, your post type liks filters.
function filter_post_type_link($link, $post)
{
if ($post->post_type != 'project')
return $link;
if ($cats = get_the_terms($post->ID, 'project_categories'))
$link = str_replace('%project_categories%', array_pop($cats)->slug, $link);
return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);
Note: if you see post not found error. then change your permalink settings to default and save changes. And again set permalink to Post name and it will work.

WordPress: Why Can't get_terms() See Custom Taxonomy Registered inside Class?

Background
I register a custom post type and custom taxonomy inside a class. Inside the WP admin, I see both the post type, and I see the taxonomy.
Simplified Code:
class Custom_Post_Type {
function __construct($init_data) {
if ( is_admin() ) {
add_action( 'init', array( $this, 'create_ctp' ) );
add_action( 'admin_head', array( $this, 'create_ctp_icons' ) );
add_action( 'save_post', array( $this, 'save_ctp_custom_metadata' ), 1, 2 );
}
}
function create_ctp_taxonomy() {
register_taxonomy(
$post_type.'_type',
$post_type,
array(
'labels' => array(
'name' => $taxonomy_label,
'add_new_item' => 'Add New '.$taxonomy_label
),
'public' => true,
'show_ui' => true,
'show_tagcloud' => true,
'hierarchical' => true,
'show_in_nav_menus' => true,
'show_admin_column' => true
)
);
register_post_type($post_type_slug,
array(
'labels' => array(),
'public' => true,
'has_archive' => false,
'supports' => $this->supports,
'register_meta_box_cb' => array( $this, 'create_ctp_custom_metaboxes' ),
'taxonomies' => array( $taxonomy_slug ),
)
);
}
}
Again, this works inside the admin area. I can add posts, and I can see the taxonomy and add terms.
Problem
On the front end, get_taxonomies() doesn't see the new custom taxonomy, and get_terms() doesn't see the terms inside it.
I tried several examples of of register_taxonomy, and when I used it outside of the class, it appears on the front end. However, when I moved the examples into my internal create_ctp_taxonomy function, they are suddenly invisible to get_taxonomies.
Any ideas why this would be occurring?
Edit
I've been playing around with different things and I think the issue here is the timing of the init action. When I call the setup function direction from the __construct function, rather than adding an action, then things start working. Example:
class Custom_Post_Type {
function __construct($init_data) {
if ( is_admin() ) {
//add_action( 'init', array( $this, 'create_ctp' ) );
add_action( 'admin_head', array( $this, 'create_ctp_icons' ) );
add_action( 'save_post', array( $this, 'save_ctp_custom_metadata' ), 1, 2 );
}
$this->create_cpt();
}
}
By doing this, I skip using init at all. However, this seems to violate standard practice. Is there a downside that anyone knows of for doing it this way?
There are a couple of things you need to be aware of when registering taxonomies to custom post types.
Register the taxonomies first. This seems a bit counter intuitive but taxonomies are registered to post types, so they need to exist before the post type is created.
You also need to register the taxonomy to the post type using the taxonomies argument of the register_post_type function.
Eg.
register_post_type('cpt_name',array(
'taxonomies'=>array(
'taxomony_name1',
'taxomony_name2')
,other_arguments...)
);
From the docs
When registering a post type, always register your taxonomies using
the taxonomies argument. If you do not, the taxonomies and post type
will not be recognized as connected when using filters such as
parse_query or pre_get_posts. This can lead to unexpected results and
failures
Not Problems
1.) The problem isn't a race condition.
Conditionals like is_admin() still work when run from functions.php directly. This contradicts some information on the web, but as of WordPress 4.4, these do work.
2.) Calling the registration from add_action() rather than directly from __construct()
Switching to calling the registration directly had zero change. To be clear, there is no difference between:
$this->create_ctp()
add_action('init', array( $this, 'create_ctp' ) );
3.) Order of registering taxonomy vs CTP
When I moved my registration of the taxonomy in front of the CTP, it had zero change in behavior.
The Problem
I was using a conditional check of is_admin(), which I'd added previous to wrap when I added the admin dashicon. This is why my CTP was appearing on the backend, but not on the front.
I had removed it from my simplified example, so there was no way to tell from looking at the code that I'd posted.
So all I needed to do was remove the is_admin() check. A silly mistake it turns out, but useful to find the information about what things aren't actually problems.

How to remove custom taxonomy-base from URL in WordPress

Please help me in wordpress.
I want to remove custom texnonomy base from URL in wordpress
http://domainname/travel-category/beaches
to
http://domainname/beaches
where "travel-category" is custom register taxonomy base and "beaches" is category
MY CODE IS :
register_taxonomy(
'travel-category', //taxonomy base
'destination', // custom post type
...
);
DO one thing add the following code for the rewrite argument for register_taxonomy function:
'rewrite' => array( 'slug' => '/', 'with_front' => FALSE ),
Hope this works and if not try refreshing the permalink page.

Categories