Organize products by group and category? How do you do it?

I have a couple of products sorted by their group. Additionally i want to introduce Categories, each having a title, description, color associated with it, and add the products to these categories.

- Product Group
 - Product
 - Product
 - Product
..
- Product Group
 - Product 
 - Product
...
- Product Group
 - Product
 - Product
... 
- Categories (Invisible)
  - Category ...
  - Category ...

Optionally i want to end up with the following routes:

site.com/products/group/product
site.com/products/group/
site.com/products/categories/category/

I tried to archive this by:

  • adding new invisible folder: called categories
  • adding new categories in the categories folder
  • Use checkboxes to assign products to category
  • create routes for products/(:any) and categories/categories/(:any) and redirect them to the product page
  • use the controller to filter the products to be displayed.

The problem i am still having is, that for the english translation, the german content is still being served. Also i am not confident this is the best solution, since my controller looks rather hacky.

Here is a summary of the code i am using:

Routes
array(
    'pattern' => 'products/(:any)',
    'action'  => function($group) {

      $data = array(
        'group' => $group
      );

      return array(site()->visit('products', site()->language->code()), $data);
    },
),
array(
    'pattern' => 'products/categories/(:any)',
    'action'  => function($category) {

      $data = array(
        'category' => $category
      );

      return array(site()->visit('products', site()->language->code()), $data);
    },
),
Controller
<?php

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

  // All Groups and Categories and Products
  $lang = $site->language()->code();
  $groups = $page->children()->visible();
  $categories =  $pages->index()->filterBy('template','category');
  $products = $page->index()->filterBy('template','product')->visible();
  $bool;

  // Check which arguments were supplied
  if (count($args) > 0 ) {
    if (array_key_exists ( "group" , $args ) || array_key_exists ( "category" , $args ) ){
      if (array_key_exists ( "group" , $args ) && page($page->uri().'/'.$args["group"])){
        $bool = true;
      } elseif (array_key_exists ( "category" , $args ) && page($categories->first()->parent()->uri().'/'.$args["category"])){
        $bool = false;
      }
    } else {
      return $page;
    }
  };

  if (isset($bool)) {
    $products = $products->filter(function($product) use( $page, $args, $bool, $groups, $categories ){

      // filter groups
      if ($bool){
        if ($product->parent()->uid() != $args["group"]) {
          return false;
        }
      // filter categories
      } else {
        //Get Page of the current Category
        $categoryPage = $page->grandChildren()->findBy('uid', $args["category"]);
        //Get list of Category Products
        $productCategories = $categoryPage->products()->split();

        if (!in_array( $product->uri(), $productCategories )){
          return false;
        }
      }

      // otherwise return the product page
      return $product;

    });
  }

  $products = $products->group(function($p){
    return $p->parent();
  });

  return compact('groups', 'categories', 'lang','products');
};
Template
 <?php foreach($products->data as $data => $group ): ?>
   <?php echo page($data)->title() ?>
   <?php foreach( $group as $product ): ?>
     <?php echo $product->title() ?>
   <?php endforeach ?>
<?php endforeach ?>

EDIT: Changed title to better reflect my question and reformatted the text to avoid double posting, since i still have trouble with this. (sorry for pushing up this topic - again :confused: )

2 Likes

Looking for a solution to this problem too :pensive:

To get this right: I assume that German is your default language and the German content is served for pages where English content is not available? Is that correct? Or is the English content not served at all?

My pages are translated into german and english, where german is my default and english is my alternative language.

The routing is.

German:
site.com

English
site.com/en

I am also open for an alternative, simpler solution. Since mine is probably a little dirty / or improvements, tips overall… :slight_smile:

Thanks

Hi,
I don’t have a direct answer for your question but why don’t you use tags for this?

@JanStieler: @philipp wants to add more information to his categories (adescription, an image etc.), you can’t just use tags in this case, I’m afraid.

Hi,
I’m not 100% sure, but he could make a invisible page for the category fields and tag it also and than the fields from the invisible page are also connected with the tag and he could display this in the template.

Cheers.

Thats exactly how my categories relate to my products… :slight_smile: each category has a checkbox field in it’s blueprints, that queries the page uri of pages with the product template. I use routes to neglect the category page & it’s template though, since i felt that i don’t need an additional template for the filtered results.

The problem is, that the solution i posted above doesn’t work in a multi-language context and i dont understand why. My navigation is displayed in englisch, but the page-content is german …
Furthermore the routing and filters take a lot of performance (or at least it feels really slow). That’s why i asked for some tips / help to improve my code, performance and maybe my solution.

But sometimes it could be work better in a multilang config when you try to get it work with the tags.
I would try it on a new test installation.

Sorry but another help could I don’t give.

Cheers.