Problem with categories

Trying to get the children of a page as categories but it just throws me the error „Undefined variable: products”. Can’t find the mistake i’ve done …

The structure is: Parent -> Children (Categorie) -> Grandchildren (Articles).

Controller

<?php

return function ($site, $pages, $page) {

	$categories = $page->children()->visible();
	$products = $page->grandChildren()->visible();

	if ($categories->count() == 0 and $products->count() == 1) {
		go($products->first()->url());
	}

	return [
		'categories' => $categories,
		'products' => $products,
	];

};

Template

<?php if (page('shop')->children()->count() > 0): ?>
  <div>
    <?php snippet('treemenu',array('subpages' => page('shop')->children())) ?>
  </div>
<?php endif ?>

<ul>
  <?php foreach($page->grandChildren() as $product): ?>
  <li>
    <a href="<?= $product->url() ?>">
      <?= html($product->title()) ?>
    </a>
  </li>
  <?php endforeach ?>
</ul>

Can there be any grandChildren if there are no children? I’m not fully awake yet, so my brain doesn’t work properly yet, but somehow the logic of

if ($categories->count() == 0 and $products->count() == 1) {
		go($products->first()->url());
	}

is not quite clear to me.

But apart from that, the Whoops screen should tell you in what line and file the error is thrown?

On a side note: If you define your $products variable in the controller, it would make sense to use it in the template, instead of calling $page->grandChildren() again.

You’re right, it does not make sense :sweat_smile:

Actually this part:

<ul>
  <?php foreach($page->grandChildren() as $product): ?>
  <li>
    <a href="<?= $product->url() ?>">
      <?= html($product->title()) ?>
    </a>
  </li>
  <?php endforeach ?>
</ul>

is coming from a snippet and there is the error on the first line:

<?php if(count($products) or $products->count()): ?>
<section>
   <?php foreach($products as $product): ?>
   <div>
      <a href="<?php echo $product->url() ?>">
         <div>
            <?php echo $product->title()->html() ?>
         </div>
      </a>
   </div>
   <?php endforeach ?>
</section>
<?php endif ?>

If you call a snippet, you have to pass the variable to it.

But why <?php if(count($products) or $products->count()): ?>?

If there are no products i want to show a message with an if else statement.

Sure, but

<?php if ($products->count()): ?>

would be fully sufficient.

Or you can also use

<?php if ($products->isNotEmpty()): ?>
1 Like

Thanks.

But the actual problem isn’t fixed yet.

Could you again please post template, controller and snippet including that part where the snippet is used.

Sure, here the actual code:

Template category.php and shop.php (exactly the same)

<?php if (page('shop')->children()->count() > 0): ?>
    <div>
      <?php snippet('treemenu',array('subpages' => page('shop')->children())) ?>
    </div>
<?php endif ?>

<?php snippet('product.list') ?>

Snippet product.list.php

<?php if ($products->count()): ?>
  <section>
    <?php foreach($products as $product): ?>
      <a href="<?php echo $product->url() ?>">
        <?php echo $product->title()->html() ?>
      </a>
    <?php endforeach ?>
  </section>
  <?php else: ?>
  <h1>No products</h1>
<?php endif ?>

Controller

<?php

return function ($site, $pages, $page) {

	$categories = $page->children()->visible();
	$products = $page->grandChildren()->visible();

	if ($categories->count() == 0 and $products->count() == 1) {
		go($products->first()->url());
	}

	return [
		'categories' => $categories,
		'products' => $products,
	];

};

As I already mentioned above, you have to pass the variable from the template to the snippet:

<?php snippet('product.list', ['products' => $products]) ?>

I’d remove this from the controller (as I don’t see the logic behind it)

if ($categories->count() == 0 and $products->count() == 1) {
		go($products->first()->url());
	}

I’ve already tested to pass the variable to the snippet but i get the same error. (without your typo :stuck_out_tongue_winking_eye:)

Undefined variable: products

19

Do you have two controllers then for your two templates where this variable is defined?

Do you have two controllers then for your two templates where this variable is defined?

Of course not :man_facepalming:

I’ve copied and renamed the shop controller to category, but it only shows me the else statement now.

If it shows no projects then there either are none, or your reference is wrong, $page always refers to the current page…

It shows me only the message „no projects“ … but what is wrong with the reference?

Wrong filenames? Wrong page? I don’t know your structure…

I’ve controlled all the names and the status of my products, but can’t find any mistake …

Structure: shop (parent) -> category (child) -> product. The categories are shown as links in the header.

You can send me your project and I’ll take a look.

Maybe this helps:

21

Nice offer. I will despair soon :smile: Thank you!

Ok, in that shop folder there is a shop.txt file, right? And then you have a shop.php template and a shop.php controller? And inside the shop.php template, you call the shop-list.php snippet?

Ah, you are calling visible (that’s deprecated, anyway) pages, but your folders are not “visible”, they are published, but not listed.