Dynamically add slug for products - wordpress

We're adding a slug to the product's URL dynamically, like this:
add_filter( 'post_type_link', 'custom_product_link', 1, 2 );
function custom_product_link( $post_link, $post ) {
if ( $post->post_type == 'product') {
//In this point, $post_link is, for example: https://domain.test/business/%vendor_slug%/product-demo/
$vendor = dokan()->vendor->get($post->post_author);
$shop_url = $vendor->get_shop_url();
$pieces = explode("/", $shop_url);
$post_link = str_replace("%vendor_slug%", $pieces[sizeof($pieces)-2], $post_link );
//In this point, previous $post_link is: https://domain.test/business/daniel/product-demo/
}
return $post_link;
}
The URL https://domain.test/business/daniel/ is the store of the vendor ( dokan plugin ), and it's working ok, but when we go to the resultant URL -> https://domain.test/business/daniel/product-demo/ it's returning 404 error code, not found.
In WordPress permalink options, we set following:
We also tried adding:
add_filter('query_vars', 'custom_add_query_vars');
function custom_add_query_vars($qVars){
$qVars[] = "vendor_slug";
return $qVars;
}
add_action( 'init', 'custom_rewrites_init' );
function custom_rewrites_init(){
add_rewrite_rule(
'product/([0-9]+)?$',
'index.php?post_type=product&vendor_slug=$matches[1]',
'top' );
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
But error persists.

Finally I solved by overriding product_cat rule, like following:
In WordPress permalink options, setting following:
/business/%product_cat%/
Updating the code like this:
add_filter( 'post_type_link', 'custom_product_link', 1, 2 );
function custom_product_link( $post_link, $post ) {
if ( $post->post_type == 'product') {
//In this point, $post_link is, for example: https://domain.test/business/%product_cat%/product-demo/
$vendor = dokan()->vendor->get($post->post_author);
$shop_url = $vendor->get_shop_url();
$pieces = explode("/", $shop_url);
$post_link = str_replace("%product_cat%", $pieces[sizeof($pieces)-2], $post_link );
//In this point, previous $post_link is: https://domain.test/business/daniel/product-demo/
}
return $post_link;
}
We can remove the code related to add_filter...query_vars, and also the code related to add_action...init
Summary, we overrided product_cat rule, adding the shop slug instead.

Related

How to rewrite URL of custom post type without post type in URL

I am working on a tour site. Where they have a custom post type built with a custom plugin.
That custom post type has base slug like "/destination/".$post->post_name.
They want to me to remove that base slug so that it could be only $post->post_name
I have tried a code from internet listed below.
It works for single level for that destination.
But when I have a parent destination like New York in United State America.
So it does not work.
Here is an example:
function update_destination_page_link_filter($post_link, $post, $leavename = null, $sample = null ) {
if ( $post->post_type === 'destination' ) {
$post_link = str_replace('/destination/', '/', $post_link);
if($post->post_parent !== 0){
$parent_slug = get_parent_link($post->post_parent, '');
$post_link = '/'.$parent_slug.$post->post_name;
}
$post_link = update_url_base( $post, $post_link );
}
return $post_link;
}
add_filter( 'post_type_link', 'update_destination_page_link_filter', 1, 3 );
function allow_destination_direct_by_name( $query ) {
// Only noop the main query
if ( ! $query->is_main_query() )
return;
// Only noop our very specific rewrite rule match
if ( 2 != count( $query->query )
|| ! isset( $query->query['page'] ) )
return;
// 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
if ( ! empty( $query->query['name'] ) )
$query->set( 'post_type', array( 'post', 'destination', 'page' ) );
}
add_action( 'pre_get_posts', 'allow_destination_direct_by_name', 1);
Single Level
http://siteurl/united-state-america works well
http://siteurl/united-state-america/new-york not working. It should open the new-york location page but it is showing 404
It may also be more specification in location
Like http://siteurl/united-state-america/new-york/brooklyn
The following code may help you, in this regards.
add_filter( 'post_type_link', 'my_post_type_link', 10, 3);
function my_post_type_link($permalink, $post, $leavename) {
if ($post->post_type == <your-post-type>)
{
$p_name=$post->post_name;
$parent_slug = get_parent_link($post->post_parent, '');
if (isset($parent_slug) && !empty($parent_slug))
{
$permalink = home_url( "" . $parent_slug . "/" . $p_name . "/");
}
}
return $permalink;
}
add_filter( 'rewrite_rules_array', 'my_rewrite_rules_array');
function my_rewrite_rules_array($rules) {
$rules = array('([^/]*)/([^/]*)/?$' => 'index.php?post_type=<your-post-type>&name=$matches[2]&meta=$matches[1]') + $rules;
return $rules;
}

remove a particular custom post type slug from the url in wordpress

How to remove a particular custom post type slug from the url in wordpress 4.7
here is that link
http://dmstage.com/gardencity/projects/bridge-construction/
But i need it should come like this
http://dmstage.com/gardencity/bridge-construction/
the projects should be removed from the link..I just tried to rewrite it in the functions.php..But couldnot get the correct way to do it..
Thanks in advance..
Try creating this function :
function na_remove_slug( $post_link, $post, $leavename ) {
if ( 'events' != $post->post_type || 'publish' != $post->post_status ) {
return $post_link;
}
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
return $post_link;
}
add_filter( 'post_type_link', 'na_remove_slug', 10, 3 );

Wordpress Permalink Generating 404 Page

I'm working on changing the permalink of a Custom Post Type to include the taxonomy prior to the post id. I'm capable of it displaying the taxonomy in the URL however when I go to the page I get a 404 Error. It looks like the structure of the permalink is correct however the location of the post isn't synced up w/ the database location.
Any help is appreciated and thanks in advance!
Couple of notes:
My .htaccess file has mod rewrite on.
I've added %tax% to the permalink rewrite for the CPT
I have archive turned on for the CPT
Code
function change_permalink( $link, $post ) {
if ( ‘custom-post-type-name’ == get_post_type( $post ) ) {
// Get post
$post = get_post($post_id);
if (!$post) return $permalink;
// Get taxonomy terms
$terms = wp_get_object_terms($post->ID, ’taxonomy-name’);
if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) $taxonomy_slug = $terms[0]->slug;
else $taxonomy_slug = 'no-taxonomy-listed’;
return str_replace('%tax%', $taxonomy_slug, $link);
}
return $link;
}
add_filter( 'post_type_link', ‘change_permalink’, 10, 2 );
Figured it out. Needed to wp_rewrite:
add_action( 'wp_loaded', 'urban_permastructure' );
function urban_permastructure($post) {
if ( 'custom-post-type-name' == get_post_type( $post ) ) {
global $wp_rewrite;
$structure = '/cat/%tax%';
$wp_rewrite->add_rewrite_tag("%tax%", '([^/]+)', "tax-type=");
$wp_rewrite->add_permastruct('tax-type', $structure, false);
}
}

How to remove taxonomy slug from custom post type url?

I have a custom post type(product) with taxonomy product-type. One of my url like this:
http://www.naturesbioscience.com/product-type/immune-support-supplements/
I want this like:
http://www.naturesbioscience.com/immune-support-supplements/
I have used "rewrite" => array('slug' => '/ ', 'with_front' => false in register_taxonomy function and I got the url like:
http://www.naturesbioscience.com/immune-support-supplements/
But I got 404 not found in other pages.
Anyone can help me?
I think you forgot to rewrite custom taxonomy post slug.
Write this in your register_post_type methord.
'rewrite' => array('slug' => 'product-type')
Now you have to remove product-type slug from your custom products
/**
* Remove the slug from published post permalinks.
*/
function custom_remove_cpt_slug($post_link, $post, $leavename)
{
if ('product-type' != $post->post_type || 'publish' != $post->post_status)
{
return $post_link;
}
$post_link = str_replace('/' . $post->post_type . '/', '/', $post_link);
return $post_link;
}
add_filter('post_type_link', 'custom_remove_cpt_slug', 10, 3);
Now as you have removed the custom post type slug so WordPress will try to match it with page or post so you have tell WP to check the URL in you custom post type also. So use this for that:
function custom_parse_request_tricksy($query)
{
// Only noop the main query
if (!$query->is_main_query())
return;
// Only noop our very specific rewrite rule match
if (2 != count($query->query) || !isset($query->query['page']))
{
return;
}
// 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
if (!empty($query->query['name']))
{
$query->set('post_type', array('post', 'product-type', 'page'));
}
}
add_action('pre_get_posts', 'custom_parse_request_tricksy');
Reference: Remove The Slugs from Custom Post Type URL
Hope this helps!
add_filter( 'post_type_link', 'change_product_request', 10, 3 );
function change_product_request( $post_link, $post, $leavename ) {
if ( 'product' != $post->post_type || 'publish' != $post->post_status ) {
return $post_link;
}
$post_link = str_replace( "/{$post->post_type}/" , '/', $post_link );
return $post_link;
}
Now, you'll get a 404 page because WordPress only allow posts and pages to behave in this way. You'll also have to add the following:
add_action( 'pre_get_posts', 'product_permalink' );
function product_permalink( $query ) {
if ( ! $query->is_main_query() ) {
return;
}
if ( 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
return;
}
if ( ! empty( $query->query['pagename'] ) ) { // name has been updated to pagename so $query->query['pagename']
global $wpdb;
$pt = $wpdb->get_var(
"SELECT post_type FROM `{$wpdb->posts}` " .
"WHERE post_name = '{$query->query['pagename']}'"
);
$query->set( 'post_type', $pt );
}
return $query;
}
I had similar issue. The question is quite old, but anyone looking for apt answer can see this.
Do not pass "/" for rewrite slug, since it causes more problem than it solves, as in this case, causing 404 error in other pages.
First, we need to remove the slug from the URL for the published post. Paste the code in functions.php
/**
* Remove the slug from published post permalinks. Only affect our CPT though.
*/
function sh_remove_cpt_slug( $post_link, $post, $leavename ) {
if ( in_array( $post->post_type, array( 'product-type' ) )
|| 'publish' == $post->post_status )
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
return $post_link;
}
add_filter( 'post_type_link', 'sh_remove_cpt_slug', 10, 3 );
This will still cause error since it specifies that only 'post' and 'page' post types can have url without post-type slug.
Now to teach WP that out CPT will also have URL without slug, we need to get this in our functions.php
function sh_parse_request_tricksy( $query ) {
// Only loop the main query
if ( ! $query->is_main_query() ) {
return;
}
// Only loop our very specific rewrite rule match
if ( 2 != count( $query->query )
|| ! isset( $query->query['page'] ) )
return;
// 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
if ( ! empty( $query->query['name'] ) ) {
$query->set( 'post_type', array( 'product-type' ) );
}
}
add_action( 'pre_get_posts', 'sh_parse_request_tricksy' );
This is it. Ref: https://wordpress.stackexchange.com/a/320711/98322

How can I use category IDs in WordPress permalinks?

I want to use something like:
http://example.com/%category_id%/%postname%/
for the permalink structure.
For example, if a post has a category with an ID of 3, then the URL for the post will be
http://example.com/3/post-name/
Does anyone know how this can be done? I don't mind modifying WordPress core.
This code adds the %category_id% rewrite tag, and filters post permalinks to replace them with the actual category ID (lowest if there are multiple categories). You can place this in a plugin or in your theme file.
add_action( 'init', 'so6159452_init' );
function so6159452_init()
{
add_rewrite_tag( '%category_id%', '([0-9]+)' );
}
add_filter( 'post_link', 'so6159452_post_link', 10, 2 );
function so6159452_post_link( $permalink, $post )
{
if ( false !== strpos( $permalink, '%category_id%' ) ) {
$cats = get_the_category( $post->ID );
if ( $cats ) {
usort( $cats, '_usort_terms_by_ID' ); // order by ID
$category_id = $cats[0]->cat_ID;
} else {
// Error: no category assigned to this post
// Just use a dummy variable
$category_id = '0';
}
$permalink = str_replace( '%category_id%', $category_id, $permalink );
}
return $permalink;
}

Resources