Forum

Thread tagged as: Question, Shop

Runway Routing for Product Categories

Hi,

This is my first attempt at custom routing in Runway so please bear with me. Currently my URL looks like this:

https://newgateclocks.com/shop?category=alarm-clock

I would like this to also be accessible from this URL

https://newgateclocks.com/shop/alarm-clock

I am using the category to do some on-page filtering which I would still need to work. I have tried adding shop/[slug:cat] and shop/[slug:category] as routes, and they show the page, but it is the unfiltered product range.

How can I get my custom URL while still applying the category filter I need?

Below is my complete page code and my diagnostics

Thanks for any help

Mike

<?php

// Include the header. You can find this in tempates/layouts/global
perch_layout('global/header');?>

</head>
<body class="shop"><?php

    if(perch_get('category')) {
        $category = perch_category('products/' . perch_get('category'),[
            'skip-template'=>true
        ]);

        $title = $category['0']['catTitle'];
        $title = $title . 's';

        PerchSystem::set_var('category', $title);


    perch_page_attributes_extend([
    'pageTitle' => $title,
]);

}

    $cart = perch_shop_cart([ 'skip-template' => 'true', ]);

    $currencycode = $cart['currency_code'];

    $currencySymbol = $cart['currency_symbol'];

    PerchSystem::set_var('currency_symbol', $currencySymbol);

    perch_layout('global/main_navigation');

    $productCategories = perch_categories([
        'template' => 'category-select-checkbox',
        'set' => 'product-category',
        'skip-template' => true,
        'return-html' => true,
    ]);

    $clockFamilies = perch_categories([
        'template' => 'category-select-checkbox',
        'set' => 'clock-families',
        'skip-template' => true,
        'return-html' => true,
    ]);

    $productTypes = perch_categories([
        'template' => 'category-select',
        'set' => 'products',
        'skip-template' => true,
        'return-html' => true,
    ]);

    PerchSystem::set_var('product-categories', $productCategories['html']);
    PerchSystem::set_var('clock-families', $clockFamilies['html']);
    PerchSystem::set_var('product-types', $productTypes['html']);


if(!perch_get('q')) {

    if ($_GET) {

        /**************************

        THIS SECTION CONTROLS DISPLAYING THE SELECTED OPTIONS AT THE TOP OF THE PAGE

        **************************/

        $sort = (perch_get('sort'));
        $price = (perch_get('price'));
        $size = (perch_get('size'));
        $colour = (perch_get('colour'));

        $casematerial = (perch_get('casematerial'));
        $casematerial = ucfirst($casematerial);
        $casematerial = str_replace('-', ' ', $casematerial);


        $productcategory = (perch_get('productcategory'));
        $productcategory = ucfirst($productcategory);
        $productcategory = str_replace('-', ' ', $productcategory);

        $clockfamily = (perch_get('clockfamily'));
        $clockfamily = ucfirst($clockfamily);
        $clockfamily = str_replace('-',' ', $clockfamily);



        $category = (perch_get('category'));
        $category = ucfirst($category);
        $category = str_replace('-', ' ', $category);


        echo "<div class='filters'><div class='container'><div class='filterblocks'>";

        if(perch_get('sort')){

            if(perch_get('sort') === "asc"){$sortval = "Price Low to High";}
            if(perch_get('sort') === "desc"){$sortval = "Price High to Low";}

            echo"<p>Sort: " . $sortval . "</p>";
        }

        if(perch_get('price')){

            if(perch_get('price') === "0,50"){$priceval = "Below " . $currencySymbol . "50";}
            if(perch_get('price') === "50,100"){$priceval = $currencySymbol . "50 - " . $currencySymbol . "100";}
            if(perch_get('price') === "100,2000"){$priceval = "Above " . $currencySymbol . "100";}

            echo"<p>Price: " . $priceval . "</p>";
        }

        if(perch_get('size')) {

            if(perch_get('size') === "0,28"){$sizeval = "Small";}
            if(perch_get('size') === "28,38"){$sizeval = "Medium";}
            if(perch_get('size') === "38,52"){$sizeval = "Large";}
            if(perch_get('size') === "52,1000"){$sizeval = "Giant";}

            echo"<p>Size: " . $sizeval . "</p>";
        }

        if(perch_get('category')){echo"<p>Clock Type: " . $category . "</p>";}

        if(perch_get('colour')){echo"<p>Colour: " . $colour . "</p>";}

        if(perch_get('casematerial')){echo"<p>Case Material: " . $casematerial . "</p>";}

        if(perch_get('productcategory')){echo"<p>Category: " . $productcategory . "</p>";}

        if(perch_get('clockfamily')){echo"<p>Family: " . $clockfamily . "</p>";}

        echo"</div></div></div>";

        /**************************

        DISPLAY THE SORT FORM

        **************************/

        perch_form('sort');

        /**************************

        POPULATE ARRAYS WITH CHOSEN FILTERS AND CATEGORIES

        **************************/

        //Create the empty arrays

        $filters = array();
        $categories = array();

        //Add to the arrays

        if (perch_get('price')) {
            $filters[] = array(
                'filter' => 'price.' . $currencycode,
                'match'  => 'eqbetween',
                'value'  => perch_get('price'),
            );
        }

        if (perch_get('size')) {
            $filters[] = array(
                'filter' => 'width',
                'match'  => 'eqbetween',
                'value'  => perch_get('size'),
            );
        }

        if (perch_get('colour')) {
            $filters[] = array(
                'filter' => 'main_colour',
                'match'  => 'eq',
                'value'  => perch_get('colour'),
            );
        }

        if (perch_get('casematerial')) {
            $filters[] = array(
                'filter' => 'main_case_material',
                'match'  => 'eq',
                'value'  => perch_get('casematerial'),
            );
        }

        if (perch_get('sort')) {
            $sortfield = 'price.' . $currencycode;
            $sort = perch_get('sort');
        }

        else {
            $sortfield = 'priority';
            $sort = 'ASC';
        }

        if (perch_get('category')) {
            $categories[] = 'products/' . perch_get('category');
        }

        if (perch_get('productcategory')) {
            $categories[] = 'product-category/' . perch_get('productcategory');
        }

        if (perch_get('clockfamily')) {
            $categories[] = 'clock-families/' . perch_get('clockfamily');
        }

        //Output the products using selected filters, categories and sort

        perch_shop_products([
            'template' => 'products/category_grid',
            'category' => $categories,
            'category-match' => 'all',
            'sort' => $sortfield,
            'sort-order' => $sort,
            'sort-type' => 'numeric',
            'filter'     => $filters,
            'count' => 24,
            'paginate' => true
        ]);

        if(perch_get('clockfamily')) {
            perch_category('clock-families/' . perch_get('clockfamily'),[
            'template'=>'video'
        ]);
        }

    }

    else {

            perch_form('sort');

            perch_shop_products([
                'template' => 'products/category_grid',
                'sort' => 'priority',
                'sort-order' => 'ASC',
                'sort-type' => 'numeric',
                'count' => 24,
                'paginate' => true
            ]);
    }

}

else {

        $query = perch_get('q');

            perch_content_search($query,[

            'template'=>'results_product_grid',
            'apps'=>[PerchShop],
            'sort' => 'priority',
            'sort-order' => 'ASC',
            'sort-type' => 'numeric',
            'count' => 24,
            'paginate' => true
        ]);

}

?>
<div class="product-added-modal">
    <div class="product-added">
    </div>
</div>
<?php

  // Include the footer. You can find this in tempates/layouts/global
  perch_layout('global/footer');

    perch_content('Analytics'); ?>

    </body>
    </html>
SUMMARY INFORMATION

Perch Runway: 2.8.32, PHP: 5.6.26, MySQL: mysqlnd 5.0.11-dev - 20120503 - $Id: 76b08b24596e12d4553bd41fc93cccd5bac2fe7a $, with PDO
Server OS: Linux, cgi-fcgi
Installed apps: content (2.8.32), assets (2.8.32), categories (2.8.32), perch_blog (5.0), perch_forms (1.8.3), perch_shop_orders (1.0.10), perch_shop_products (1.0.10), perch_shop (1.0.10), perch_members (1.5), perch_mailchimp (3.0.1), perch_twitter (3.6.2)
App runtimes: <?php $apps_list = array( 'content', 'categories', 'perch_forms', 'perch_mailchimp', 'perch_twitter', 'perch_members', 'perch_shop', 'perch_blog' );
PERCH_LOGINPATH: /admin
PERCH_PATH: /home/newgateclocks/public_html/admin
PERCH_CORE: /home/newgateclocks/public_html/admin/core
PERCH_RESFILEPATH: /home/newgateclocks/public_html/admin/resources
Image manipulation: GD
PHP limits: Max upload 128M, Max POST 128M, Memory: 128M, Total max file upload: 128M
F1: 2edba60ed1f613d6dd804feb202456a2
Resource folder writeable: Yes
DOCUMENT_ROOT: /home/newgateclocks/public_html
HTTP_HOST: newgateclocks.com
REQUEST_URI: /admin/core/settings/diagnostics/
SCRIPT_NAME: /admin/core/settings/diagnostics/index.php
Mike Harrison

Mike Harrison 37 points

  • 4 years ago
Drew McLellan

Drew McLellan 2638 points
Perch Support

shop/[slug:category] is the one you want. That token is matching a slug and naming it category. That corresponds to perch_get('category') which you're using to access it.

Thanks for the fast response!

So I have set the URL pattern to be shop/[slug:category] in Perch, but I am still seeing an unfiltered list. You can see the difference from these two links:

https://newgateclocks.com/shop/alarm-clock

https://newgateclocks.com/shop?category=alarm-clock

Do I need to make any adjustments to the page, or anywhere else, to make this work?

Drew McLellan

Drew McLellan 2638 points
Perch Support

Have you checked the debug at the bottom of the page?

OK

On the one that is working (?category=alarm-clock) there is this line:

SELECT DISTINCT idx.itemID FROM clocks_shop_index idx JOIN clocks_shop_products main ON idx.itemID=main.productID AND idx.itemKey='productID' AND ((idx.indexKey='_category' AND idx.indexValue LIKE 'products/alarm-clock%' OR idx.indexKey='_category' AND idx.indexValue='products/alarm-clock')) GROUP BY idx.itemID HAVING COUNT(idx.itemID)=1

That is missing on the one using the route. There is this which looks important:

0.5672  0.0213  Matched route: shop/[slug:category]
0.5674  0.0002  Using master page: /templates/pages/shop.php
0.5674  0.0001  Page arguments:
Array
(
    [0] => /shop/alarm-clock
    [category] => alarm-clock
    [1] => alarm-clock
)
Drew McLellan

Drew McLellan 2638 points
Perch Support

So it looks like perch_get('category') will return alarm-clock on your routed page. That's good. Is that what you're seeing?

Yes it is - if I echo that out I get alarm-clock. Hmm, so that really should be working....

Duncan Revell

Duncan Revell 78 points
Registered Developer

Mike,

you've wrapped a chunk of your code in if ($_GET) { - a Runway route variable isn't stored in the _GET array, so that bunch of code isn't being called.

Ah thanks Duncan great spot - that may well be it! Will take a look now

Yeah that was it - thanks for the help. Unfortunately I can't do if(perch_get()) without a variable so I can't replicate that filter like for like. But that was the issue, will have to look at restructuring the page