The reason I want to do this is non-English product titles are automatically used in the slug that renders a very long URL with percentage signs, e.g. /product/%e9%97%bb%e7%a8%bf%e5%8f%91%e5%b8%83/, which doesn't look good at all, especially when shared as URLs, sometimes inconveniently lengthy.
So it seems much better to use only product ID in the URLs such as /product/1178/
Searched around and never found anything relevant. Tried Settings > Permalinks > Product permalinks > Custom base = "/product/%post_id%/" but the slug is still appended as /product/1178/%e9%97%bb%e7%a8%bf%e5%8f%91%e5%b8%83/
Is there any way to do this programmatically?
Found this answer, is it to modify it to be used for WooCommerce products so product IDs are used for slugs when creating the product?
This worked for me. Now the product IDs are the product slugs every time I create new products.
add_action( 'save_post_product', 'wpse251743_set_title', 10, 3 );
function wpse251743_set_title ( $post_id ){
//This temporarily removes action to prevent infinite loops
remove_action( 'save_post_product', 'wpse251743_set_title' );
//update title
wp_update_post( array(
'ID' => $post_id,
'post_name' => $post_id, //Wordpress would generate the slug based on the post name
));
//redo action
add_action( 'save_post_product', 'wpse251743_set_title', 10, 3 );
}
Related
I need some help. I am trying to create a custom query for my Custom Posts I created in Wordpress, and using Elementor Pro.
On my post, I added a custom field 'sorting' with a numeric value, which I would like to use to order my posts manually.
However, I cannot seem to get this to work.
I am using the latest Elementor pro version.
And I tried following the instructions as per their page: https://developers.elementor.com/custom-query-filter/
Here is my code I added to my theme's functions.php file
// Showing posts ordered by comment count in Posts Widget
add_action( 'elementor/query/speaker_order', function( $query ) {
// Here we set the query to fetch posts with
// ordered by comments count
$query->set( 'orderby', 'sorting' );
} );
I have added 'speaker_order' as the Query ID in the Elementor Editor.
You are close. There's one thing you left out (if I am grasping what you want to do).
It should look like this:
add_action( 'elementor/query/speaker_order', function( $query ) {
// Here we set the query to fetch posts with
// ordered by comments count
$query->set( 'meta_key', 'sorting' );
$query->set( 'orderby', 'sorting' );
} );
You have to add two more lines of code:
// Showing posts ordered by comment count in Posts Widget
add_action( 'elementor/query/speaker_order', function( $query ) {
$query->set('meta_key','sorting');
$query->set('orderby', 'sorting');
$query->set('orderby','ASC');
});
Is there a way to create custom product URL based on the product attributes, I have a product sunglasses which has a couple of attributes tied to it: metal, blue and round, so the current URL is:
website.com/glasses/sunglasses/abram-widana-629/
What I am trying to get is a URL which has those attributes included:
website.com/glasses/sunglasses/abram-widana-meta-blue-round-629/
I would really appreciate if someone would even just point me to the right direction on how to tackle this.
There are two ways to do this, either Manually or Programmatically.
Manually adjusting permalinks:
In your example, you are simply adjusting the product URL to include attributes. This can be achieved manually by editing the permalink on the product itself.
Once the product has been added/saved, you will see the permalink showing directly under the title field like this:
Simply click the Edit button next to it and change it from abram-widana-629 to abram-widana-meta-blue-round-629
Programmatically adding attributes to permalinks:
If you want to try to achieve this permanently for all products you will have to work through the "save_post" filter/hook to add all the attributes to the permalink. The only downfall from this is that you will no longer be able to adjust your individual permalinks for your products as they will simply revert back once you click save.
Below is a code example of how to achieve that:
add_action( 'save_post', 'add_custom_attributes_to_permalink', 10, 3 );
function add_custom_attributes_to_permalink( $post_id, $post, $update ) {
//make sure we are only working with Products
if ($post->post_type != 'product' || $post->post_status == 'auto-draft') {
return;
}
//get the product
$_product = wc_get_product($post_id);
//get the "clean" permalink based on the post title
$clean_permalink = sanitize_title( $post->post_title, $post_id );
//next we get all of the attribute slugs, and separate them with a "-"
$attribute_slugs = array(); //we will be added all the attribute slugs to this array
foreach ($_product->get_attributes(); as $attribute_slug => $attribute_value) {
$attribute_slugs[] = $attribute_value;
}
$attribute_suffix = implode('-', $attribute_slugs);
//then add the attributes to the clean permalink
$full_permalink = $clean_permalink.$attribute_suffix;
// unhook the save post action to avoid a broken loop
remove_action( 'save_post', 'add_custom_attributes_to_permalink', 10, 3 );
// update the post_name (which becomes the permalink)
wp_update_post( array(
'ID' => $post_id,
'post_name' => $full_permalink
));
// re-hook the save_post action
add_action( 'save_post', 'add_custom_attributes_to_permalink', 10, 3 );
}
I am trying to set up a site with very complex "build to order" products. I am using WooCommerce but I realize that it might not be best solution, however, I am not a programmer so I'm trying to work with a pre-existing application. For reference, here is the original site that I'm redesigning: http://www.cabinetstogo.com/ic280Collectionfrm_multiple.asp?prodno=TOFFEE-NS*WC -- click on the tabs to see the detail.
I have explored all the Woo Extensions I can find such as Product Add Ons, Product Bundles, Grouped Products and Composite Products. Currently I am using Product Bundles with Composite Products here:
http://www.cabinetstogo.company/product/westminster-glazed-toffee-base-cabinets/ -- the layout is a bit messy but that isn't my issue, the issue is that while you can pick and choose individual products you can't select individual quantity.
With Grouped Products: http://www.cabinetstogo.company/product/grouped-test/ the layout is perfect but I can't add a Grouped Product to a Composite Product.
Ideally what I need to do is:
Create Product Bundles of simple products that have to be sold together
Organized these Product Bundles into Product Groups -- PROBLEM: Bundled products can't be added to Group Products
Add these Product Groups into a Composite Product for a master group of products like Base Cabinets -- PROBLEM: Grouped products can't be added to Composite Products
I have tried Product Add Ons two but the issue with that is there is no way to set individual SKUs for the Add Ons.
Setting them as Variable Products is another idea but you can't select more than one variation at a time. I have also considered the Gravity Forms Add On but that seems to just be for additional product details not the mix and match features.
I know there is no easy solution but any pointing in the right direction would help as I can think of all different ways to go about I don't know where to start.
It sounds like you're looking for an off the shelf plugin solution for a VERY complicated problem. You're going to need a programmer for this. A good basic plan could be:
FEATURE: Do custom business logic when a particular product is purchased.
When a customer adds something to the cart
Then do some custom business logic, like add "bundled" products to the cart
Here are some useful snippets functions:
Do something on cart add:
add_action( 'woocommerce_add_to_cart', 'custom_add_to_cart', 10, 2 );
function custom_add_to_cart( $cart_item_key, $product_id ) {
if( 123 == $product_id ) { ....
OOP:
add_action( 'woocommerce_thankyou', array($this, 'doSomething') );
Create a product:
$post_id = wp_insert_post( $post, $wp_error );
update_post_meta( $post_id, '_visibility', 'visible' );
update_post_meta( $post_id, '_stock_status', 'instock');
update_post_meta( $post_id, 'total_sales', '0');
update_post_meta( $post_id, '_downloadable', 'no');
update_post_meta( $post_id, '_virtual', 'yes');
update_post_meta( $post_id, '_regular_price', $regularPrice);
update_post_meta( $post_id, '_sale_price', "123" );
I have searched, here is the closes result.
I am building a new wordpress site. I want most posts to have no category in the URL, simply www.site.com/title. However I do want the blog posts to be separate, so I'd like www.site.com/blog/title. I'd also like the option to add more like that in the future, for only specific categories, not the entire site.
There are many questions similar to this here on stackoverflow but most have 0 replies. Any advice would be great. I've even tried Advanced Permalinks without any luck.
You can simply do that by Setting > Permalinks and add to Common Setting > Custom Structure the value /blog/%postname%/. There you will get the blog post accessible from www.site.com/blog/title.
I cannot understand the first question. By:
I want most posts to have no category in the URL
do you mean to NOT HAVING www.site.com/category/category-name? or not having www.site.com/category/post?
EDIT #1
To answer this:
www.site.com/category/post is what I ONLY want for blog posts with the category of "Blog" > if the category is "Shoes" I don't want the category displayed in the URL. –
First: you can set the Permalink to /%postname%/ so all your post will have site/title therefore accessible from that link
Second: You have to filter the permalink to behave differently for the posts under "Blog" category.
Try this
add_filter( 'post_link', 'custom_permalink', 10, 2 );
function custom_permalink( $permalink, $post ) {
// Get the categories for the post
$categories = wp_get_post_categories( $post->ID );
foreach ( $categories as $cat ) {
$post_cat = get_category( $cat );
$post_cats[] = $post_cat->slug;
}
// Check if the post have 'blog' category
// Assuming that your 'Blog' category slug is 'blog'
// Change 'blog' to match yours
if ( in_array( 'blog',$post_cats ) ) {
$permalink = trailingslashit( home_url( 'blog/' . $post->post_name ) );
}
return $permalink;
}
Third: You have to filter rewrite_rules
add_filter( 'rewrite_rules_array', 'custom_rewrite_rule' );
function custom_rewrite_rule( $rules ) {
$new_rules = array(
'blog/([^/]+)/trackback/?$' => 'index.php?name=$matches[1]&tb=1',
'blog/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' => 'index.php?name=$matches[1]&feed=$matches[2]',
'blog/([^/]+)/(feed|rdf|rss|rss2|atom)/?$' => 'index.php?name=$matches[1]&feed=$matches[2]',
'blog/([^/]+)/comment-page-([0-9]{1,})/?$' => 'index.php?name=$matches[1]&cpage=$matches[2]',
'blog/([^/]+)(/[0-9]+)?/?$' => 'index.php?name=$matches[1]&page=$matches[2]'
);
$rules = $new_rules + $rules;
return $rules;
}
Go to permalink setting and save the setting to refresh your rewrite rules and make the changes above active
NOTE: Add those functions on your active theme functions.php template
NOTICE: I haven't test it yet but that's the way you change permalink. I did the similar way to change my permalink on archives and search result.
i need to display the category list related to the current page (based on selected category in admin.) in wordpress site. i tried with get_the_category($post_id). But it's not working. Thanks.
You can try get_the_terms() instead. It should return an array of cats. Wordpress considers categories a taxonomy, so specifying 'category' as the taxonomy type should do the trick.Hope this helps.
$array_of_cats = get_the_terms( $post->ID, 'category' );
foreach($array_of_cats as $key=> $value){
//output as a list...
}
Function reference here.