Forum

Thread tagged as: Question, Add-on-development, PayPal

Can I use PerchSystem::set_vars() with perch_shop_custom?

I want to be able to use PerchSystem::set_vars() with perch_shop_custom so that I don't have to call a query twice within the same page to load the product information (several products for several categories on one page) and use the listing template but I can't seem to get it to work and not sure if the 2 do work together or not.

After getting the categories, the first thing I do is get 4 products per category ensuring that there are no duplicate products being displayed:

$products = perch_shop_products_by_category($cat->categorySlug(), 4, false, $product_ids);

I then run the products array through a foreach loop and (currently) use the product id to again get the product information to enable me to use my template:

foreach ($products as $product) {
                                perch_shop_product($product['productID'], 'home_page_listing.html');
                                $product_ids[] = $product['productID'];
                            }

What I want to do is:

foreach ($products as $product) {
                                PerchSystem::set_vars(array(
                                    'productSlug' => $product['productSlug'],
                                    'productImage' => $product['productImage'],
                                    'productTitle' => $product['productTitle'],
                                    'shortTitle' => $product['shortTitle'],
                                    'productPrice' => $product['productPrice']
                                ));

                                perch_shop_custom(array(
                                    'template'=>'home_page_listing.html'
                                ));

                                $product_ids[] = $product['productID'];
                            }

But it isn't working - no products are displayed using this method.

The template code is:

<li>
    <a href="/agility-equipment/<perch:shop id="productSlug" />" rel="bookmark">
        <perch:if exists="productImage">
            <img src="<perch:shop id="productImage" type="image" width="136" bucket="shop-images" />" alt="<perch:shop id="productTitle" />" />
        </perch:if>
        <h3>
            <perch:if exists="shortTitle">
                <perch:shop id="shortTitle" />
            <perch:else />
                <perch:shop id="productTitle" />
            </perch:if>
        </h3>
        <perch:if exists="additionalCosts">From </perch:if><span class="product-listing-price">&pound;<perch:shop id="productPrice" /></span>
    </a>
</li>

Can you confirm if this is possible and if so what I am doing wrong to get it working as expected.

Emma Davis

Emma Davis 0 points

  • 6 years ago
Drew McLellan

Drew McLellan 2638 points
Perch Support

Yes, PerchSystem::set_vars() injects the variables directly into the templating engine, so it doesn't matter which page function is used as long as the template is processed.

Does <perch:showall /> show the data you're passing in?

Yes that works

Drew McLellan

Drew McLellan 2638 points
Perch Support

Ok, so the data is getting into the template. Can you give an example of a field that isn't working?

Well that is bizarre, it is displaying the data now but I also have a new problem in that it is loading all products for each category (i.e. not just all products for that category or the 4 products required but all products in the system).

Back to the drawing board on that now :(

Now I need help again - I have just commented out the PerchSystem::set_vars() and perch_shop_custom() sections and just echo'd out the product name and that works as it should but as soon as I allocate the product data to PerchSystem::set_vars() and load the data through the template I get the problem of all products as mentioned above.

Any ideas?

Rachel Andrew

Rachel Andrew 394 points
Perch Support

What does your code look like at this point?

It really looks the same as before.

foreach ($products as $product) {
    PerchSystem::set_vars(array(
        'productSlug' => $product['productSlug'],
        'productImage' => $product['productImage'],
        'productTitle' => $product['productTitle'],
        'shortTitle' => $product['shortTitle'],
        'productPrice' => $product['productPrice']
    ));

    perch_shop_custom(array(
        'template'=>'home_page_listing.html'
    ));

    $product_ids[] = $product['productID'];
}

And the template:

<li>
    <a href="/agility-equipment/<perch:shop id="productSlug" />" rel="bookmark">
        <perch:if exists="productImage">
            <img src="<perch:shop id="productImage" type="image" width="136" bucket="shop-images" />" alt="<perch:shop id="productTitle" />" />
        </perch:if>
        <h3>
            <perch:if exists="shortTitle">
                <perch:shop id="shortTitle" />
            <perch:else />
                <perch:shop id="productTitle" />
            </perch:if>
        </h3>
        <perch:if exists="additionalCosts">From </perch:if><span class="product-listing-price">&pound;<perch:shop id="productPrice" /></span>
    </a>
</li>

However if I use a basic echo within the foreach loop it does just display the 4 products per category:

foreach ($products as $product) {
    echo $product['productSlug'].'<br>';

    $product_ids[] = $product['productID'];
}
Drew McLellan

Drew McLellan 2638 points
Perch Support

Should perch_shop_custom() not have some sort of filtering applied to it?

I have just been playing around a bit more and it now seems that the loading of the template is the problem. I have removed everything else within the foreach loop and just left

perch_shop_custom(array(
    'template'=>'home_page_listing.html'
));

This still seems to pass all the data through correctly but still lists all products in the database and I can see why now, when I use perch_shop_custom, I am running that function again. So how do I set the variables, load the template and use the variables in the template without perch_shop_custom running $r = $Products->get_custom($opts); again?

Drew McLellan

Drew McLellan 2638 points
Perch Support

I think you just need to filter for the product you want to show in that loop iteration.

But won't that still run the function and query and therefore a second unnecessary call to the database? That is the main thing I am trying to avoid as all the data is already available from

$products = perch_shop_products_by_category($cat->categorySlug(), 4, false, $product_ids);
Drew McLellan

Drew McLellan 2638 points
Perch Support

So why are you calling perch_shop_custom() in the loop?

Because I don't know how else to call the template and populate it, which is why I was trying out PerchSystem::set_vars() - I presumed that is what I needed to take the data already queried from the db and load it into the necessary template and the only way I could find to load the template and populate it from the PerchSystem::set_vars() (per the documentation) was to use perch_shop_custom().

So, how do I load the listing_html template and populate it with the correct data within my foreach loop?

Drew McLellan

Drew McLellan 2638 points
Perch Support

Oh how I knew it would be a simple solution that I just couldn't find :) Thanks Drew.

Just want to point out that even though this is a shop template, I had to change perch:shop to perch:content for it to work.

Maybe a template to add in: perch_shop_template() ??