2

I'm creating a plugin for WooCommerce, it needs a parameter in the url of shop page like this http://domain/wp/shop/?param=value. It worked fine until I set the shop page as front page, when I access http://domain/wp, it is showing the shop page, but when I access it with the parameter (http://domain/wp/?param=value), it's showing the blog index page.

So, I want to ask where exactly in the Wordpress code that redirects the url to WooCommerce shop page? so I may be able to change the redirection behaviour or something else.

2 Answers 2

1

You could add a rewrite rule to improve the appearance of the URL while maintaining the same functionality:

As an example:

add_action('init', 'custom_shop_param');

function custom_shop_param() {
    add_rewrite_tag('%param%','([^&]+)');
    add_rewrite_rule('^shop/([^/]+)/?$','index.php?page=shop&param=$matches[1]','top');
}

When you visit http://site/wp/shop/{somevalue} the value that proceeds the /shop/ portion of the URL will be matched and stored in the query var param which is registered throught he use of add_rewrite_tag, the $matches[1] variable holds the value of the regex for the first matched group of your expression, http://site/wp/shop/discountproduct would equate to param=discountproduct for which is accessible via accessing the query_vars as part of the request:

//somewhere in your code....
function parse_shop_request() {
    global $wp_query;
    if ( isset($wp_query->query_vars['param']) ) {
         //do something with $wp_query->query_vars['param']
    }
}

You may also use get_query_var('param') to retrieve query variables.

If http://domain/wp/shop/value clashes or has the potential to clash with products or categories or other pages at that URL depth, then you can extend the rewrite rule a little further:

http://site/wp/shop/get/value

add_action('init', 'custom_shop_param');

function custom_shop_param() {
    add_rewrite_tag('%param%','([^&]+)');
    add_rewrite_rule('^shop/get/([^/]+)/?$','index.php?page=shop&param=$matches[1]','top');
}

Of course, replace /get/ with whatever suits your verbiage or context.

You may even do:

add_action('init', 'custom_shop_param');

function custom_shop_param() {
    add_rewrite_tag('%param%','([^&]+)');
    add_rewrite_rule('^shop/?param=([^/]+)$','index.php?page=shop&param=$matches[1]','top');
}

Helpful links:

3
  • 2
    This adds a valuable knowledge how to add a parameter to shop page. Thank you.
    – xdim222
    Jun 26, 2014 at 4:04
  • Sorry, I hit add comment button too early. Btw, the problem is when we set the shop page to appear on front page, so the url is now [code]domain/wp[/code] instead of [code]domain/shop[/code], and wordpress seems to remove any parameter that was added to url (in my case when using [code]?param=value[/code], I'm not sure if using your approach, I'll try it later, right now I'm using different approach to always redirect to shop page from a link).
    – xdim222
    Jun 26, 2014 at 4:13
  • I'm trying this, so I can hit /shop/vendorname/ and have the url remain /shop/vendorname/ but hit the normal shop page, with the contents of vendorname in a query var. Using your code, everything after /shop/ is stripped and the query var is empty Apr 29, 2015 at 17:13
1

The following is the relevant WooCommerce code. It is hooking into the template_redirect WordPress hook. If the page id matches the page you've set as the shop page, WordPress will redirect to the product post type archive.

/**
 * Handle redirects before content is output - hooked into template_redirect so is_page works.
 *
 * @return void
 */
function wc_template_redirect() {
    global $wp_query, $wp;

    // When default permalinks are enabled, redirect shop page to post type archive url
    if ( ! empty( $_GET['page_id'] ) && get_option( 'permalink_structure' ) == "" && $_GET['page_id'] == wc_get_page_id( 'shop' ) ) {
        wp_safe_redirect( get_post_type_archive_link('product') );
        exit;
    }

    // When on the checkout with an empty cart, redirect to cart page
    elseif ( is_page( wc_get_page_id( 'checkout' ) ) && sizeof( WC()->cart->get_cart() ) == 0 && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) ) {
        wp_redirect( get_permalink( wc_get_page_id( 'cart' ) ) );
        exit;
    }

    // Logout
    elseif ( isset( $wp->query_vars['customer-logout'] ) ) {
        wp_redirect( str_replace( '&', '&', wp_logout_url( get_permalink( wc_get_page_id( 'myaccount' ) ) ) ) );
        exit;
    }

    // Redirect to the product page if we have a single product
    elseif ( is_search() && is_post_type_archive( 'product' ) && apply_filters( 'woocommerce_redirect_single_search_result', true ) && $wp_query->post_count == 1 ) {
        $product = get_product( $wp_query->post );

        if ( $product->is_visible() ) {
            wp_safe_redirect( get_permalink( $product->id ), 302 );
            exit;
        }
    }

    // Ensure payment gateways are loaded early
    elseif ( is_add_payment_method_page() ) {

        WC()->payment_gateways();

    }

    // Checkout pages handling
    elseif ( is_checkout() ) {
        // Buffer the checkout page
        ob_start();

        // Ensure gateways and shipping methods are loaded early
        WC()->payment_gateways();
        WC()->shipping();
    }
}
add_action( 'template_redirect', 'wc_template_redirect' );

Not the answer you're looking for? Browse other questions tagged or ask your own question.