I'm using WooCommerce with the "YITH WooCommerce Ajax Navigation" plugin to filter brands. The result is a link that appears as https://example.com/products/racquets/tennis-racquets/?filter_brands=47
Ideally, I would like to use https://example.com/products/racquets/tennis-racquets/brands/wilson instead.
I've tried using an Apache mod_rewrite rule such as:
RewriteRule ^products/racquets/tennis-racquets/?filter_brands=47 /products/racquets/tennis-racquets/wilson [QSA,L]
I've also tried writing a function for my functions.php file but that doesn't seem to catch either. Here's a sample of the code I tried using.
function brand_rewrite_rules() {
add_rewrite_rule( 'products/racquets/tennis-racquets/?filter_brands=47', 'products/racquets/tennis-racquets/wilson', 'top' );
flush_rewrite_rules();
}
add_action( 'init', 'brand_rewrite_rules' );
I did try updating my permalink settings but the function did not do anything. Can anyone propose a solution for this?
It's a matter of adding a Rewrite Endpoint:
Adding an endpoint creates extra rewrite rules for each of the matching places specified by the provided bitmask. A new query var with the same name as the endpoint will also be created. The string following the endpoint definition supplies the value for this query var (e.g. "/foo/bar/" becomes "?foo=bar").
<?php
/**
* Plugin Name: Add a Brand endpoint to the URLs
* Plugin URI: http://stackoverflow.com/a/24331768/1287812
*/
add_action( 'init', function()
{
add_rewrite_endpoint( 'brands', EP_ALL );
});
add_filter( 'query_vars', function( $vars )
{
$vars[] = 'brands';
return $vars;
});
/**
* Refresh permalinks on plugin activation
* Source: http://wordpress.stackexchange.com/a/108517/12615
*/
function WCM_Setup_Demo_on_activation()
{
if ( ! current_user_can( 'activate_plugins' ) )
return;
$plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
check_admin_referer( "activate-plugin_{$plugin}" );
add_rewrite_endpoint( 'brands', EP_ALL ); #source: http://wordpress.stackexchange.com/a/118694/12615
flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'WCM_Setup_Demo_on_activation' );
Then, in the templates use it like:
$brand = get_query_var('brand') ? urldecode( get_query_var('brand') ) : 'Empty endpoint';
echo $brand;
Related
I'm having trouble creating a custom URL for certain single post types. whereas it works for posts. Here is my code to change the URL of only certain posts:
/**
* Rewire the permalink of individual posts so that they direct to the Free Cakes section
*/
add_filter( 'post_link', 'ae_replace_freecakes_posts_link', 90, 2 );
function ae_replace_freecakes_posts_link( $permalink, $post ) {
global $freecakes_blog_page_id;
if ( ae_get_post_acces_level( $post->ID ) >= 110 ) {
return get_permalink( $freecakes_blog_page_id ) . "$post->ID/{$post->post_name}/";
}
return $permalink;
}
/**
* Rewire the permalink of individual videos so that they direct to the Free Cakes section
*/
add_filter( 'post_type_link', 'ae_replace_freecakes_videos_link', 90, 2 );
function ae_replace_freecakes_videos_link( $permalink, $post_object ) {
global $freecakes_video_page_id;
if ( $post_object->post_type != 'video' ) {
return $permalink;
}
if ( ae_get_post_acces_level( $post_object->ID ) >= 110 ) {
return get_permalink( $freecakes_video_page_id ) . "$post_object->ID/{$post_object->post_name}/";
}
return $permalink;
}
And later this:
add_action( 'init', 'ae_add_rewrite_rules' );
function ae_add_rewrite_rules() {
add_rewrite_rule( "^freecakes/video/([0-9]+)/([^/]*)/?$", 'index.php?p=$matches[1]', 'top' );
add_rewrite_rule( "^freecakes/posts/([0-9]+)/([^/]*)/?$", 'index.php?p=$matches[1]', 'top' );
}
The problem is that this doesn't work for videos. If I use this fictional exemplary url it works just fine:
https://mywebsite.com/freecakes/posts/3892/my-first-frecake-post/
But this URL (the one matched to the video custom post type) gives a 404 error:
https://mywebsite.com/freecakes/posts/10109/my-first-frecake-video/
Any clues of what might be my mistake here? Thank you!
Did you flush and regenerate the rewrite rules database after modifying rules. From WordPress Administration Screens, Select Settings -> Permalinks and just click Save Changes without any changes.
As it turns out, even though calling https://mywebsite.com/index.php?p=10109 would normally work while using the navigation bar, it doesn't work for custom post types when using add_rewrite_rule
The rule that works is:
add_rewrite_rule( "^freecakes/posts/([0-9]+)/([^/]*)/?$", 'index.php?video=$matches[2]', 'top' );
Where $matches[2] is the slug of the custom post type (in this case a post_type called "video")
In my wordpress website (nginx hosting) I have a product page with this url:
https://www.officeshop.co.il/product/my-product/
I have developed some functionality that allows to view different product models using get parameter:
https://www.officeshop.co.il/product/my-product/?build=product-572
I want to rewrite this url to make it SEO friendly to look like:
https://www.officeshop.co.il/product/my-product/build/product-572
I understand that the function add_rewrite_rule will do the job, but what parameters should I pass to it in my case?
You can use the below code to your theme's function.php make your link SEO friendly.
add_filter( 'post_type_link', 'change_product_links', 10, 2 );
function change_product_links( $link, $post) {
if ( $post->post_type == 'tribe_events' && tribe_event_in_category('product') ) {
$link = trailingslashit( home_url('/product/' . $post->post_name ) );
}
return $link;
}
add_action( 'init', 'product_rewrite_rule', 5);
function product_rewrite_rule() {
add_rewrite_rule( '^product/([^/]+)/?', 'index.php?tribe_events=$matches[1]&post_type=tribe_events&name=$matches[1]', 'top' );
}
I have added an endpoint to my WP plugin (to manage extra information in my-account section in woocommerce -> my points) - my-account/moje-punkty
I did that all based on bunch of tutorials, the endpoint starts on plugin activation and is followed by a rewrite flush.
My colleague reported to me that this suddenly stops working (returning 404 error) when an user is added to the DB, although I added plenty of users while testing it and never encountered this problem.
However today I noticed that after saving Woo settings, my custom endpoint is also deleted.
Does anyone know how I can make sure that the custom endpoint stays always as long as the pluing in active?
The code reference:
function __construct()
{
register_activation_hook( __FILE__, array( $this, 'foc_points_moje_punkty_endpoints' ) );
register_deactivation_hook( __FILE__, array( $this, 'foc_points_flush_rewrite_rules' ) );
}
add_filter( 'query_vars', array ( $this, 'my_custom_query_vars'), 0 );
function my_custom_query_vars( $vars ) {
$vars[] = 'moje-punkty';
return $vars;
}
add_filter ( 'woocommerce_account_menu_items', array ( $this, 'foc_front_account_menu_points_info') );
function foc_front_account_menu_points_info( $items ) {
echo '<div class="points_dropdown_area">' . esc_html__( 'Your points', 'foc-lang' ) . ': <em>' . $punkty_meta_value . '</em></div>';
$items['moje-punkty'] = esc_html__( 'Points history', 'foc-lang' );
return $items;
}
add_action( 'woocommerce_account_moje-punkty_endpoint', array ( $this, 'foc_front_punkty_endpoint_content' ) );
function foc_front_punkty_endpoint_content() {
// my code
}
/**
* Flush rewrite rules on plugin activation.
*/
function foc_points_moje_punkty_endpoints() {
add_rewrite_endpoint( 'moje-punkty', EP_ROOT | EP_PAGES );
$this->foc_points_flush_rewrite_rules();
}
/**
* Flush rewrite rules on plugin de-activation.
*/
function foc_points_flush_rewrite_rules() {
flush_rewrite_rules();
}
Thank you!
I have custom search page, that have permalink http://mywebsite.com/custom-search/
What should I do to pass the search keyword as a parameter, like this: http://mywebsite.com/custom-search/keyword
I get error 404 page. Or may be there a way to change standard permalink /search/ to /custom-search/ ?
You should use rewrite endpoints
A sample code :
/*!
* URL rewrite
*/
function my_custom_rewrite_rules() {
$page_id = 123;
$page_path = get_page_uri( $page_id );
add_rewrite_endpoint( 'keyword', EP_PAGES );
add_rewrite_rule('^'. $page_path .'/(.*)/?', 'index.php?page_id=' . $page_id . '&keyword=$matches[1]', 'top');
}
add_action('init', 'my_custom_rewrite_rules');
and then add it as a query_var
function my_custom_query_vars($vars) {
if( isset( $_GET['keyword'] ) && !empty( $_GET['keyword'] ) ) {
$vars[] = 'keyword';
}
return $vars;
}
add_filter( 'query_vars', 'my_custom_query_vars', 10, 1 );
you will be able to retrieve the value of the passed keyword via get_query_var("keyword")
hope it helps
Note : You must update your permalinks structure or use flush_rewrite_rules(); after adding these codes
just changed search base with function
function vital_custom_search_base() {
$GLOBALS['wp_rewrite']->search_base = 'custom-search';
}
add_action( 'init', 'vital_custom_search_base' );
function only works after resave in settings > permalinks
Im trying to do something like this.
Add "custom page" without page
I know about adding a wordpress page from admin panel, Pages->Add New, and then link this page to PHP file using the slug. I've already done that. I just want to make this page work without adding it from admin panel, in case if page gets deleted from admin panel it won't work even if exists in the directory.
Please let me know if my question isn't clear enough. Any help is highly appreciated.
Thanks!
Update:
Thanks to #Mike i was able to solve the problem by modifying his code. I just had to add add_rewrite_rule() and its working good now. Don't forget to flush permalinks.
function add_application_endpoint() {
add_rewrite_endpoint( 'view', EP_PERMALINK );
}
add_action( 'init', 'add_application_endpoint' );
function add_endpoint_queryvar( $query_vars ) {
$query_vars[] = 'view';
$query_vars[] = 'ptag';
$query_vars[] = 'product_cat';
return $query_vars;
}
add_filter( 'query_vars', 'add_endpoint_queryvar' );
add_rewrite_rule( '^view/([^/]+)/([^/]+)/?$', 'index.php?pagename=custom-product-tags&ptag=$matches[1]&product_cat=$matches[2]', 'top' );
/**
* Setting up job app template redirect for custom end point rewrite
*/
function job_application_template_redirect() {
global $wp_query;
if ( $wp_query->query_vars['name'] != 'custom-product-tags' ) {
return;
}
include dirname( __FILE__ ) . '/page-custom-product-tags.php';
exit;
}
add_action( 'template_redirect', 'job_application_template_redirect' );
You can do it by creating a custom endpoint and setting up a template redirect in your functions.php file.. Here is an example for a job application page. With this code added to my functions.php file, if I visit '/apply' on my site, the page-job_application.php template is rendered.
Hope this works for your needs.
/**
* Rewrite custom endpoint for job post applications
*/
function add_application_endpoint() {
add_rewrite_endpoint('apply', EP_PERMALINK);
}
add_action( 'init', 'add_application_endpoint');
/**
* Register our custom endpoint as a query var
*/
function add_endpoint_queryvar( $query_vars ) {
$query_vars[] = 'apply';
return $query_vars;
}
add_filter( 'query_vars', 'add_endpoint_queryvar' );
/**
* Setting up job app template redirect for custom end point rewrite
*/
function job_application_template_redirect() {
global $wp_query;
if ( ! isset( $wp_query->query_vars['apply'] ) || ! is_singular() )
return;
include dirname( __FILE__ ) . '/page-job_application.php';
exit;
}
add_action( 'template_redirect', 'job_application_template_redirect' );