In my header.php file, I've been trying to retrieve the slug of the current page, to check it's WooCommerce Products Archive/shop page. I followed this similar question's answer, to no avail; instead of the current page's slug being returned, the first item being sold slug was returned. My questions are these:

  • Why does $post->post_name return test-product-magazine, instead of the correct, shop?

<code>test-product-magazine</code>, instead of the correct, <code>shop</code>

    global $post;
    echo "post_name: " . $post->post_name;

Why is test-product-magazine, instead of the correct, shop?

The global $post object is not a reliable way to determine anything about archive pages because the object will typically be the first post of the main query when outside the loop. Since the main query is for the posts in the archive and not the archive itself (which normally isn't even a page), then the $post object will not represent any page that might be being used for the archive.

This is because the shop page, and blog page, are not being actually displayed. So they don't need the global post object to be set for template tags. The bits of the pages that are used, like the title, are not pulled from the global post object with the_title(), they're pulled directly by the ID for the page in the database. See these lines from woocommerce_page_title() for an example of how WooCommerce does it:

$shop_page_id = wc_get_page_id( 'shop' );
$page_title   = get_the_title( $shop_page_id );

And for the Posts page WordPress never uses the global $post object for that page, it just checks if the queried page name is the posts page as set in the database and modifies the query accordingly:

if  ( 'page' == get_option('show_on_front') && isset($this->queried_object_id) && $this->queried_object_id == get_option('page_for_posts') ) {
    $this->is_page = false;
    $this->is_home = true;
    $this->is_posts_page = true;

So the correct way to get the Shop page and Posts page is to use the appropriate conditional functions, then check the database for the relevant ID and use that for retrieving any information you want. For the Shop page, that would be:

if  ( is_shop() ) {
    $shop_page_id = wc_get_page_id( 'shop' );
    $shop_page_object = get_post( $shop_page_id );

    // echo $shop_page_object->post_name;

And for the Posts page that would be:

if  ( is_home() && ! is_front_page() ) {
    $posts_page_id = get_option( 'page_for_posts' );
    $posts_page_object = get_post( $posts_page_id );

    // echo $posts_page_object->post_name;

How can I create a custom Page Template for WooCommerce Products Archive/shop page?

This is off topic here (the first question probably was too, but its relevance to the posts page as well I think justified an answer), but if you look at the WooCommerce Documentation on the issue:

WooCommerce template files contain the markup and template structure for frontend and HTML emails of your store.


Template files can be found within the /woocommerce/templates/ directory:


You can edit these files in an upgrade-safe way using overrides. Copy it into a directory within your theme named /woocommerce keeping the same file structure but removing the /templates/ subdirectory.

The relevant file you're asking about is woocommerce/templates/archive-product.php. But note this is also used for category/tag/etc. archives. If you want the shop page - and only the shop page - to be different, you'll need to check is_shop() inside the template and output different markup accordingly.

  • Thank you @jacob-peattie. This is a really good answer, I appreciate the time you spent and help you gave answering my questions. I knew my question might be off topic, but I've been struggling on this for a long time, and really needed some help. About my second question, I know how to edit WooCommerce' template, I was wondering about creating a template for that shop archive page, a template that would work in a theme, if that makes sense, but you've provided enough help already, so thank you again. Nov 29 '17 at 5:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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