Jump to content

Listing pages under corresponding letter


louisstephens
 Share

Recommended Posts

I have done a bit of searching, but I can not seem to find an actual answer. I have a list of services as child pages under "Services". I can output the services just fine, but I cant wrap my head around how to group them "alphabetically" like:

Services
    A
    - Service "A" 1
    - Service "A" 2
    - Service "A" 3
    B
    - Service "B" 1
    - Service "B" 2
    - Service "B" 3
    C
    - Service "C" 1
    - Service "C" 2
    - Service "C" 3

Has anyone achieved this type of functionality before?

Link to comment
Share on other sites

If you don't want to go to deeply into writing your loop with comparing the previous letter, you could use the PageArray::groupBy method I posted:

With it, you could write something like this (i't a bit of guesswork since I don't know if the "A" "B" "C" parts are really in the title or in a different field, but you should get the gist:

<?php

echo "<h2>Services</h2>";

$children = $page->children();
$children->sort("title"); // Important for grouping to work
$grouped = $children->groupBy(function($pg) {
  // first argument ($pg) is always the page object we are examining
  $letter = preg_replace('/^Server "(.)".*$/', '$1', $pg->title);
  return array($letter);
});

foreach($grouped as $letter => $letterPages) {
  echo "<h3>$letter</h3>";
  echo "<ul>";
  foreach($letterPages as $lpg) {
    echo "<li>{$lpg->title}</li>";
  }
  echo "</ul>";
}

 

  • Like 2
Link to comment
Share on other sites

So I tried your groupBy, and I am currently getting the following:

"Blowing- etc etc"

"Blowing- etc etc"

"Blowing- etc etc"

"Pest- etc etc"

"Pest- etc etc

 

I assume that $letter is just simply finding matches to the whole string in this case and grouping them together? I am sorry, I have not used preg_replace that offten, and couldn't tell you even where to begin in editing it to get the desired result of 

B
Blowing- etc etc
Blowing- etc etc

P
Pest- etc etc
Pest- etc etc
Pest- etc etc

 

Link to comment
Share on other sites

This should work too.  (I used the method to output the month as a heading for a list of events sorted by start_date). What it does:

  1. Gets the first letter of the first child and output it, eg "A"
  2. Gets the next child and compares the first letter of its title with the previous child's title first letter
  3. If the same, it continues on
  4. If different, it outputs the new first letter
<h2>Services</h2>
<?php if ($page->children->count) :
    $children = $page->children('sort=title');
    foreach ($children as $child) :
        $letter = substr($child->title, 0, 1);  // get the first letter of the title
        if ($child->id == $children->first->id) : // first child ?>
            <h2><?=$letter?></h2>
        <?php else :
            $prevLetter = substr($child->prev->title, 0, 1);;
            if ( $prevLetter !== $letter) : // different first letter in title to previous sibling page ?>
                <h2><?=$letter?></h2>
            <?php endif; 
        endif; ?>
		<p><?=$child->title?></p>
    <?php endforeach;
endif; ?>

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...