$wp_rewrite
. When I modify it, everything works as I put it, but the rest as the pages stop working. Here the code:
public function rewrite(): void {
global $wp_rewrite;
$wp_rewrite->add_rewrite_tag("%category%", '([^/]+)', "category=")
$wp_rewrite->add_permastruct( 'category', '%category%' );
$wp_rewrite->add_rewrite_tag("%product_cat%", '([^/]+)', "product_cat=");
$wp_rewrite->add_permastruct( 'product_cat', '%product_cat%' );
$wp_rewrite->add_rewrite_tag("%product%", '([^/]+)', "product=");
$wp_rewrite->add_permastruct( 'product', '%product_cat%/%product%' );
}
This function is executed with the hook init
.
Does anyone know why it doesn’t work or is it a bug?
I also tried modifying the array of extra_permastructs
, but it doesn’t work either.
I have custom post type (“example”).
For this custom post type I created 3 taxonomies (“taxonomy1″,”taxonomy2” and “taxonomy3”).
Now I would like to build a pretty urls something like:
https://example.com/example/post-1 – this could be done by rewrite I got this.
when I visit taxonomy1, I want every custom post type (example) with this taxonomy for example:
https://example.com/taxonomy1/ – and there is
post-1
post-2
post-3
when i visit https://example.com/taxonomy1/taxonomy2/, I want every custom post type (example) with these taxonomies (1 and 2)
post-2
post-3
and when i visit https://example.com/taxonomy1/taxonomy2/taxonomy3/, I want every custom post type (example) with these taxonomies (1,2 and 3)
post-3
I just did all of this by adding permastructure add_permastruct( ‘permastruct’, ‘/%taxonomy1%/%taxonomy2%/%taxonomy3%/’, false );
it works fine – finally BUT I wonder if its even possible make it more complicated :D…
like, I want custom posts from taxonomy3 and taxonomy1 on link https://example.com/taxonomy1/taxonomy3/ there is always 404 bcos its looking for taxonomy1 first then taxonomy2 and 3 etc.
Is it possible, is there some1 who can help me?
Thank you for your response!
I need a specific permalink structure for a custom post type.
This is the structure: /%custom_taxonomy%/%postname%/%subpage%/
So in example this would be: /ferrari/f430/ as main information page and /ferrari/f430/specs/ or /ferrari/f430/speed/ as subpages.
The subpages don’t need post edit screens in the backend, it’s database generated.
How would you archieve this?
My current solution uses custom permastructs in combination with the post_type_link filter. I then use Endpoints in combination with the single_template filter for the subpages.
$permalink = '%cars_slug%/%brands%/%cars%/';
$wp_rewrite->add_rewrite_tag( '%cars_slug%', '(cars)','post_type=cars&slug=' );
$wp_rewrite->add_rewrite_tag( "%brands%", '(.+?)', "brands=" );
$permalink = trim($permalink, "/" );
$rewrite_args = $args->rewrite;
$rewrite_args["walk_dirs"] = false;
$wp_rewrite->add_permastruct( $post_type, $permalink, $rewrite_args);
But somehow it doesn’t feel right.
]]>i have a custom posttype ‘products’ and a custom taxonomy ‘prodcategory’
For the products i created a custom permastruct which looks like:
/products/%prodcategory%/%product%/
$products_structure = '/products/%prodcategory%/%mline_products%';
add_rewrite_tag("%prodcategory%", '([^/]+)', "prodcategory=");
add_rewrite_tag("%mline_products%", '([^/]+)', "mline_products=");
add_permastruct('mline_products', $products_structure, false);
i also added a filter to the post_type_link filter to create the permalinks.
// Adapted from get_permalink function in wp-includes/link-template.php
function mline_cpt_products_permalink($permalink, $post, $leavename) {
//global $wp_query;
$rewritecode = array(
'%year%',
'%monthnum%',
'%day%',
'%hour%',
'%minute%',
'%second%',
$leavename? '' : '%postname%',
'%post_id%',
'%category%',
'%prodcategory%',
'%author%',
$leavename? '' : '%pagename%'
);
if ( empty($post->ID) )
return false;
if ( '' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft')) ) {
$unixtime = strtotime($post->post_date);
$category = '';
if ( strpos($permalink, '%category%') !== false ) {
$cats = get_the_category($post->ID);
if ( $cats ) {
usort($cats, '_usort_terms_by_ID'); // order by ID
$category = $cats[0]->slug;
if ( $parent = $cats[0]->parent )
$category = get_category_parents($parent, false, '/', true) . $category;
}
// show default category in permalinks, without
// having to assign it explicitly
if ( empty($category) ) {
$default_category = get_category( get_option( 'default_category' ) );
$category = is_wp_error( $default_category ) ? '' : $default_category->slug;
}
}
$prodCategory = '';
if ( strpos($permalink, '%prodcategory%') !== false ) {
// get the genre:
$terms = get_the_terms($post->ID, 'prodcategory');
if( is_wp_error($terms) || !$terms ) {
$prodCategory = 'uncategorised';
}
else {
$prodCategory_obj = array_pop($terms);
$prodCategory = $prodCategory_obj->slug;
}
}
$author = '';
if ( strpos($permalink, '%author%') !== false ) {
$authordata = get_userdata($post->post_author);
$author = $authordata->user_nicename;
}
$date = explode(" ",date('Y m d H i s', $unixtime));
$rewritereplace =
array(
$date[0],
$date[1],
$date[2],
$date[3],
$date[4],
$date[5],
$post->post_name,
$post->ID,
$category,
$prodCategory,
$author,
$post->post_name
);
$permalink = str_replace($rewritecode, $rewritereplace, $permalink);
} else { // if they're not using the fancy permalink option
}
return $permalink;
}
add_filter('post_type_link', 'mline_cpt_products_permalink', 10, 3);
This all works fine, my product-slugs look like i.e. /products/pillows/pillow-1
now, i want to create a new endpoint /compare to compare a specific product. (i’m aware that i can use a different ep-mask, but for testing i’m using EP_ALL so i can test it on pages without a custom permastruct.
add_rewrite_endpoint( 'compare', EP_ALL);
function compare_template_redirect() {
global $wp_query;
if (!isset( $wp_query->query_vars['compare'])) :
return;
endif;
if (have_posts()) :
the_post();
endif;
include get_template_directory() . '/template_compare.php';
exit;
}
add_action( 'template_redirect', 'compare_template_redirect' );
now, when i go to a page with this endpoint, i.e. /contact/compare
i get the correct template-file (template_compare.php) and i also get the correct data. But when i go to /products/pillows/pillow-1/compare i DO get the correct template-file, but i don’t get the custom-post-type data (have_posts() returns false).
Anyone has an idea how this happens? When i do a var_dump of $wp_query i can see that on my custom-permastruct page it tries to get an attachment and no post_type is set.
I can’t figure out what i’m doing wrong here. Perhaps it has something to do with the filter? Also, when i comment out the add_permatruct and add_rewrite_tag, the compare endpoint works just fine aswell on this custom-post-type
]]>Here is my code, and I will comment what I’ve done. I hope you will find what is wrong.
1) Registering of custom post type called “product”:
add_action('init', 'my_products_init');
function my_products_init() {
$args = array(
'label' => __('My Product DB'),
'singular_label' => __('My Product DB'),
'public' => true,
'show_ui' => true,
'_builtin' => false,
'_edit_link' => 'post.php?post=%d',
'capability_type' => 'post',
'hierarchical' => false,
'publicly_queryable' => true,
'query_var' => true,
'rewrite' => false,
'supports' => array('title', 'editor', 'thumbnail', 'comments')
);
register_post_type( 'product' , $args );
}
I created a lot of custom posts “products” so no problem at this stage.
2/ I registered a custom permalink structure for “product” post types, which is composed of 2 %tags% :
add_action('init', 'my_rewrite_init');
function my_rewrite_init()
{
global $wp_rewrite;
$wp_rewrite->add_rewrite_tag("%product%", '([^/]+)', "product=");
$wp_rewrite->add_rewrite_tag("%producttitle%", '([^/]+)', 'producttitle=');
$products_structure = '/Product-DB/%producttitle%/%product%/The-Product';
$wp_rewrite->add_permastruct('product', $products_structure, false);
}
At this stage, the link of each post is well replaced my the permalink structure “products_structure”. So no problem at this stage too.
3/ Substitution rules of %producttitle% tag with “_producttitle” custom field.
add_filter('post_type_link', 'producttitle_permalink', 10, 3);
function producttitle_permalink($permalink, $post, $leavename)
{
$no_data = 'no-title';
$post_id = $post->ID;
if($post->post_type != 'product' || empty($permalink) || in_array($post->post_status, array('draft', 'pending', 'auto-draft')))
return $permalink;
$var1 = get_post_meta($post_id, '_producttitle', true);
$var1 = sanitize_title($var1);
if(!$var1) { $var1 = $no_data; }
$permalink = str_replace('%producttitle%', $var1, $permalink);
return $permalink;
}
Again, each %tag% is replaced.
A sample target link of my custom products post is https://www.mysite.com/my-wpmu-blogid/Product-DB/product-title-sample/s79925215/The-Product/ BUT when I load this link I got a 404 error. I don’t understand why because, again, EVERYTHING was working well since 1 week, till I decided to “flush rewrite rules”.
I installed Rewrite Rules Inspector and this plugin says 3 rules match my custom products URLs :
Product-DB/[^/]+/[^/]+/([^/]+)/?$ index.php?attachment=$matches[1] missing
Product-DB/([^/]+)/([^/]+)/The-Product(/[0-9]+)?/?$ index.php?producttitle=$matches[1]&product=$matches[2]&page=$matches[3] missing
(.?.+?)(/[0-9]+)?/?$ index.php?pagename=$matches[1]&page=$matches[2] page
I don’t know why the “page” post type is matched… perhaps this is the source of my problem. And if so, I don’t understand why it doesn’t work anymore as it worked yesterday.
Any idea ?
Best regards,
–Looic
With this plugin (which is SO close to what I need) I get URLs of “.com/%post_type%/%product_type%/%postname%” which outputs to “.com/product/press/product-name” or “.com/product/support/product-name”.
I need my permastructs to be “.com/%product_type%/%postname%” which would output to “.com/press/product-name” and “.com/support/product-name”.
I understand that removing the post-type from the permastruct isn’t recommended in most cases, but the “Product Type” taxonomy is registered only to the “Product” post type. So any result that is returned true by this permastruct could only return true for posts in the “Product” post-type.
Where can I edit out the slug that this plugin is prepending by default?
https://www.ads-software.com/extend/plugins/custom-post-type-permalinks/
]]>myblog.com/category/my-category/
to myblog.com/my-category/
).
The plugin requires no setup or modifying core wordpress files and will not break any links.
]]>I took a look at my apache logs and here seems to be the culprit.
[error] [client 127.0.0.1] PHP Fatal error: Call to a member function get_page_permastruct() on a non-object in C:\\Apache\\htdocs\\wp-tb\\wp-includes\\link-template.php on line 139, referer: https://tb.dev/?page_id=3
The curious part is that it posts the info to the database, but gives the page error in IE after that. If I comment out the line: wp_insert_post($tb_form_post);
Everything seems to work fine – except that it isn’t posting to the database.
I was thinking redirect, or link issue? Any ideas?
Thanks.