Currently I have a WooCommerce installation where product URLs are produced as such:
domain.com/shop/product-category/product-name/
Due to SEO and current site structure, I would like to change it to:
domain.com/product-category/product-name/
I know how to remove shop from the breadcrumb using the woocommerce_get_breadcrumb filter, but I am unsure how to proceed for the URLs themselves.
All I've found on Stack Overflow are people recommending to install a plugin called Premmerce. This plugin has a premium version and constantly hassles you to upgrade: Removing /product-category/ and /shop/ from URL in WooCommerce
I would like to do this programmatically from my own plugin or just functions.php
WooCommerce forces /product/ on you if you try only inputting /%product_cat%/ in the permalinks panel through class-wc-admin-permalink-settings.php. The wc permalinks is an option called "woocommerce_permalinks". Since I only want to have /%product_cat%/, I can just force it even though it's not the most elegant solution:
add_action( "update_option_woocommerce_permalinks", "apply_product_cat", 10, 3 );
function apply_product_cat( $old_val, $new_val, $option_name ) {
if ($option_name == "woocommerce_permalinks") {
$new_val['product_base'] = "/%product_cat%/";
update_option( "woocommerce_permalinks", $new_val );
}
}
What Premmerce does is effectively offer you another admin panel, where they just save to this option on their own.
Related
I have been trying for a while now to remove the image link from a Woocommerce product. I tried snippets, css and plugins. But nothing seems to work, until I came across Vitaly Gritsienko's answer of Jul 5 2017.
Although the code he suggests (see below) for the functions.php file works, the hand icon is still visible. How can I remove the hand icon?
//Removes links
add_filter( 'woocommerce_product_is_visible','product_invisible');
function product_invisible(){
return false;
}
//Remove single page
add_filter( 'woocommerce_register_post_type_product','hide_product_page',12,1);
function hide_product_page($args){
$args["publicly_queryable"]=false;
$args["public"]=false;
return $args;
}
Actually, the simplest way is to edit the theme's woocommerce listing page to remove the link from the templating engine, although it's better to do it via a child theme so as not to interfere with the main theme's updates.
You can read more about child themes here: https://www.smashingmagazine.com/2016/01/create-customize-wordpress-child-theme/
I have a fresh WordPress and bbPress installed on an internal server.
While I was setting up bbPress I wanted to test the functionalities like creating a forum, topic, etc. When doing these stuff in the back-end (dashboard) there didn't seem to be any problems but when I did it from the front-end I kept getting
ERROR: Are you sure you wanted to do that?
I searched for a solution and found this.
add_filter( 'bbp_verify_nonce_request_url', 'my_bbp_verify_nonce_request_url', 999, 1 );
function my_bbp_verify_nonce_request_url( $requested_url )
{
return 'http://localhost:8888' . $_SERVER['REQUEST_URI'];
}
I simply changed the hard-coded URL to what our internal server is set up to and it fixed the problem.
Now my question: is it possible for me to add this solution to a functions.php that is independent of the theme being used? I asked this because I have 2 concerns:
The current theme might get updated and will overwrite the file
I'm aware that the solution to this is simply create a child theme but my second concern prevents me from doing this.
The WordPress administrator might change themes and so both the functions.php file on the main theme and the child theme will stop working
How could I add the solution above so that I don't have to worry about the theme being updated and/or replaced with a new theme in the future? I don't want to keep adding this solution every time the administrator decides to change themes.
If you can't put it in a theme, put it in a Plugin. If you're worried that the plugin will get de-activated make it a Must Use Plugin.
It's dead simple to create a plugin. Create a file plugin-name.php and place it in a directory wp-content/plugins/plugin-name/. That file should contain the following code:
<?php
/*
Plugin Name: Name Of The Plugin
Plugin URI: http://URI_Of_Page_Describing_Plugin_and_Updates
Description: A brief description of the Plugin.
Version: The Plugin's Version Number, e.g.: 1.0
Author: Name Of The Plugin Author
Author URI: http://URI_Of_The_Plugin_Author
License: A "Slug" license name e.g. GPL2
*/
add_filter( 'bbp_verify_nonce_request_url', 'my_bbp_verify_nonce_request_url', 999, 1 );
function my_bbp_verify_nonce_request_url( $requested_url )
{
return 'http://localhost:8888' . $_SERVER['REQUEST_URI'];
}
If you want it to be a must use plugin, put it in wp-content/mu-plugins/ instead of wp-content/plugins.
I have a specific page on my wordpress website example.com/download/ that I already have a page for. I would like to add some sort of php code to enable the following functionality.
If there is a subpath after the /download/<name>, I would like to fetch a file from some directory based on <name>
If no subpath is specified (/download/) I want to display the page that is already written
Is this possible with Wordpress hooks/filters?
I have a feeling it has something to do with the WP_Rewrite class, but I am not sure exactly what to write, nor where to put it without WP or theme updates wiping the code
Yes, you have to add a custom rewrite rule. You can use your theme's functions.php to add the new functionality.
function custom_rewrite_rule() {
add_rewrite_rule('^download\/([^/]+)\/?','your_url_to_the_downloader_file.php?download=$matches[1]','top');
}
add_action('init', 'custom_rewrite_rule', 10, 0);
To make it work, first you need to go to Admin -> Settings -> Permalinks and click the save button so the new rule is added.
First,I know wordpress won't allow you to use template for posts (WooCommerce's product page is built via post). So I look for the Template Hierarchy.
It says there:
single-{post-type}-{slug}.php (Since 4.4). First, WordPress looks for a template for the specific post.
For example, if post type is product and the post slug is dmc-12, WordPress would look for single-product-dmc-12.php.
single-{post-type}.php – If the post type is product, WordPress would look for single-product.php.
single.php – WordPress then falls back to single.php.
singular.php – Then it falls back to singular.php.
index.php – Finally, as mentioned above, WordPress ultimately falls back to index.php.
So I created a template and name it single-product-ccc (ccc is one of my product's slug name), but nothing happened, nothing was affected.
But by creating a template named single-product will affect all of the product pages.
Why is that happening?
I don't get it. Even a single-2313.php (2313 is one post's id) will overwrite the default single.php for that 2313 post.
Why single-product-slug is not working in the same way?
Thanks.
Let me first correct you at one point. You say: "WooCommerce's product page is built via post".
This is not correct. WooCommerce creates a new post type 'product'. You can see all custom posts types that WooCommerce creates here: https://docs.woocommerce.com/document/installed-taxonomies-post-types/
The 'product' post type uses the template single-product.php.
As you say, WordPress Template Hierarchy Docs say that you can create a template for a particular product:
single-{post-type}-{slug}.php (Since 4.4). First, WordPress looks for a template for the specific post. For example, if post type is product and the post slug is dmc-12, WordPress would look for single-product-dmc-12.php.
WooCommerce is a WordPress plugin and as so, it doesn't always follow WordPress rules strictly, and this is one of those cases. But you can use a filter to correct this very easily. In your theme's functions.php simply add:
add_filter( 'template_include', 'custom_single_product_template_include', 50, 1 );
function custom_single_product_template_include( $template ) {
if ( is_singular('product') && (get_the_ID()==30)) {
$template = get_stylesheet_directory() . '/woocommerce/single-product-30.php';
}
return $template;
}
where get_the_ID() is the id of your Product. Now, you can create a new template as for example single-product-30.php
Try adding this in functions.php
function your_theme_add_woocommerce_support() {
add_theme_support( 'woocommerce' );
}
add_action( 'after_setup_theme', 'your_theme_add_woocommerce_support' );
and now onwards, you can use woocommerce/single-product.php for customisation
I have an installed addon for magento called Fishpig. It essentially runs wordpress through magento allowing both to be used on the main website. The WP install is being used for a blog, and i've the whole initial theme set up for it by altering the magento files as required. What i'm looking for though is a way to change the theme if i look under a certain category related to the representative for the site.
Is there a way to set a different template if i were to choose the category? Will i need to add if statements to the category WP layout file?
If you want to change the whole theme based on the current WordPress category (or any conditions), you would need to listen to for an event and then change the theme programmtically. The most general event that would work would be 'controller_action_predispatch' however if you wanted to only change the theme for WordPress category pages, you would be better suited to use 'controller_action_predispatch_wordpress_post_category_view'.
Attach an event observer method to the event of your choosing and then use the following code:
$_category = Mage::registry('wordpress_category');
if (!$_category) {
return $this;
}
$_categoryId = (int)$_category->getId();
if ($_categoryId === 1) {
Mage::getDesign()
->setPackageName('default')
->setTheme('default');
}
else if ($_categoryId === 2) {
Mage::getDesign()
->setPackageName('default')
->setTheme('default');
}
return $this;
You would need to modify to code to set the correct package/theme (the code below enables the default package and default theme) to match the package/theme you want to set.