Sort collection by translated value from category map

Got the titles to work. But I need a little help with getting the sorting right.

I add the title tag here for others to see later.

<h1><?php echo $categoryName[trim($category)]['value']; ?></h1>

Your page model (/site/models/product.php) only needs a small change as well:

// I assume your template is called product, hence class "Productpage"
// please change Class name and file name as needed
class ProductPage extends Page {

  public function getCategoryOrder) {
    return c::get('job_category_name')[$this->category()->value()]['order'];

As I said above, you can also use a custom page method instead of the model.

And in your template:

$categories = page('products')->children()->visible()->sortBy('getCategoryOrder')->groupBy('category');
// followed by your foreach loop

Made it work with the title. But the sort function I have not idea on how to get put in here corrected.

<?php $groups = page('products')->children()->visible()->filterBy('category', '!=', '') ?>
      <?php $categories = $groups->groupBy('category')->sortBy(); // Here I am not sure how to access the double array. 
      foreach($categories as $category => $items): ?>

Do I need to make a model for it first? If so how? :smile:

It‘s all in my last post? But wait a minute, I‘ll fetch my computer and get back.

Ok, to work!

// I renamed your variables, because this way it's more logical ;)

// grab the product pages and filter out those with empty category
$products = page('products')->children()->visible()->filterBy('category', '!=', '') ;

// sort by page model and group by category (at this point, we don't care about the category map values
$groups = $products->sortBy('getCategoryOrder')->groupBy('category');

// lets loop through the groups
foreach($groups as $category => $items): ?>
<?php // fetch the group name from the config settings array ?>
    <h2><?= c::get('job_category_name')[$category ]['value']?></h2>
      <?php // loop through the items in each group ?>
      <?php foreach($items as $item) : ?>
      <li><?php echo $item->title() ?></li>
      <?php endforeach; ?>
<?php endforeach ?>

I don’t know the name of this template, but anyway, you have to create a page model with the name of this template as explained in my last post. The model must contain this getCategoryTranslation() method that we sort by here.

Sorry did not see it. :wink: I will try it out and then I will let you know how it goes.

So, above you will now find the complete code for your template/snippet

Maybe we should rename the method to getCategoryOrder(), after all, things should be named according to what they are actually made for.

1 Like

Thank you and many thank you @texnixe! Got it all to work now. You deserve a hug! So I send you one here. :wink:

Ah, I feel much better now, thank you :slightly_smiling_face:

BTW: An alternative to using a page model or custom page method is the map() method:

$groups = page('products')->children()->visible()->map(function($p) {
    $p->categoryOrder = c::get('product_categories')[$p->category()->value()]['order'];
    return $p;
1 Like