Best way to sort a menu

Hi there, my question is which would be the best way to sort a menu of country-pages by continents.

My menu-code:

<nav class="menu">
	<div class="accordion">
		<?php foreach($pages->visible()-> AS $p): ?>
		<h3>
			<a<?php echo ($p->isOpen()) ? ' class="active"' : '' ?> href="<?php echo $p->url() ?>"><?php echo html($p->title()) ?></a>
		</h3>

		<div><?php if($p->children()->visible()->count()): ?>
			<ul>
				<?php foreach($p->children()->visible() AS $item): ?>
				<li><a<?php echo ($item->isOpen()) ? ' class="active"' : '' ?> href="<?php echo $item->url() ?>"><?php echo html($item->seitentitel()) ?></a></li>
				<?php endforeach ?>
				<?php endif ?>
			</ul>
		</div>
		<?php endforeach ?>
	</div>
</nav>

This displays lists of countries under submenus such as roundtrips etc. but how to sort the pages without putting them into seperate continent-folders (which would also change the url)? and on top: how to add seperators like “Asia”, “Europe”, etc? I looked through the docs but at the moment nothing seems to fit.

Is there a way to add a value/string in the .txt/.md file and to access it in the template?

Thanks in advance!

1 Like

Unfortunately, you haven’t posted your current structure.

But yes, you can add as many fields to your text files as you like and use them to sort or group your content as you like, for example a continent field. Methods to look into:

1 Like

Thank you. By structure you mean the folders?

content ->
  Roundtrips ->
    South africa
    Thailand
  Volunteering ->
    Albania
    China

and so on… the website is: https:www.auszeit-weltweit.de

1 Like

Let’s suppose you had a field called continent in your subpages:

<nav class="menu">
  <div class="accordion">
    <?php foreach($pages->visible() AS $p): ?>
      <h3>
        <a<?php echo ($p->isOpen()) ? ' class="active"' : '' ?> href="<?php echo $p->url() ?>"><?php echo html($p->title()) ?></a>
      </h3>
      <div>
        <?php if($p->children()->visible()->count()): ?>
          
          <?php foreach($p->children()->visible()->groupBy('continent') AS $continent => $items): ?>
            <h4><?= $continent ?></h4>
            <ul>
              <?php foreach($items as $item): ?>
                <li><a<?php echo ($item->isOpen()) ? ' class="active"' : '' ?> href="<?php echo $item->url() ?>"><?php echo html($item->seitentitel()) ?></a></li>
              <?php endforeach ?>
            </ul>
          <?php endforeach ?>
        <?php endif ?>
      </div>
    <?php endforeach ?>
  </div>
</nav>

sorry, I think I have an error somewhere, I get an 500, but also from my initial code.
The line
<?php foreach($pages->visible()-> AS $p): ?>

is wrong, as the -> has to be removed, but this does also not work.

Debugger says:

// make sure that there's always a proper value to group by
      if(!$value) throw new Exception('Invalid grouping value for key: ' . $key);

The code will fail if the pages don’t have the field to group by. It can be empty but it has to exist.

ok. does this also affect excluded pages? Like:

<?php foreach($pages->visible()->not('UeberUns') AS $p): ?>

No, if you exclude those pages, you will be fine.

Edit: But you probably want all pages in the menu. Therefore, I wouldn’t exclude those pages in the first loop but rather use an if statement for the second loop.

Example:

<?php
if($p->is(page('roundtrip') || $p->is(page('volunteering'): ?>
  <!-- grouplist -->
<?php else: ?>
  <!-- code for other subpages if any -->
<?php endif ?>

Thank you for this suggestion. One last question: I now get
Asia
Oceania
Afrika

because it sorts by country name (china (…), fidschi, south africa). is it somehow possible to sort by continent?

Sure, use sortBy('continent', 'asc') before grouping :slight_smile:

This works, thank you very much! :grin: