display of additional category content with headings

5 posts by 2 authors in: Forums > CMS Builder
Last Post: September 26, 2014   (RSS)

By Deborah - September 23, 2014

Hi. I've not been able to find an exact recipe for this in the forum and am looking for help. I want to display a category description beneath each category heading, followed by the list of services the admin has chosen to associate with that category.

My 'services' table has a list field 'category', with selections populated by 'Get options from database':
Table name: services_categories
Option values: num
Option labels: title

The 'services_categories' table contains a field for 'title' and one for 'description'.

I can display each category title with it's respective list of services, but I don't know how to display the 'description' field for the category beneath the category headings.

My code:

HEAD
  // categories for headings
    list($services_categoriesRecords, $services_categoriesMetaData) = getRecords(array(
    'tableName'   => 'services_categories',
    'allowSearch' => false,
  ));

 // list of services to display beneath headings
    list($servicesRecords, $servicesMetaData) = getRecords(array(
    'tableName'   => 'services',
  ));
   

HTML
<?php $servicesByCategory = array_groupBy($servicesRecords, 'category', true); ?>
<?php foreach (getListOptions('services', 'category') as $value => $label): ?>

     <?php $services = @$servicesByCategory[$value]; ?>
     <?php if (!$services) { continue; } // skip empty categories ?>
     <?php echo $label;?></br>

     <?php foreach ($services as $service): ?>
          <?php echo htmlencode($service['title']) ?>
     <?php endforeach ?>

<?php endforeach ?>

Probably an easy thing, but I'm not getting there. Any help would be greatly appreciated.

~ Deborah

By claire - September 24, 2014

Hi Deborah

You can't really do this with getListOptions if you need more than the title from the service categories section. What you'll need to do is load the categories records, as you're doing below, then sort them by the value (not the label) being used in the services section to associate each service with a category.

So ideally what you'll want to end up with is an array of categories where you can get the relevant category info by selecting it like so:

$categoriesArray[$service['category']]

Then all you'll need to do is echo the title and description from this as needed.

Does that make sense?

--------------------

Claire Ryan
interactivetools.com

Save time by getting our experts to help with your project.
http://www.interactivetools.com/consulting/

By claire - September 25, 2014

Sorry Deborah, I've got this kinda backwards. I assumed you wanted to output services and then the categories associated with each, instead of the other way around.

Really the best way you can handle this is to get to grips with PHP arrays. Setting up an array with specific, relevant keys is pretty much the solution to everything when you're working with two lists of records.

So let's start from the beginning. Here's how it'd work:

// categories for headings
    list($services_categoriesRecords, $services_categoriesMetaData) = getRecords(array(
    'tableName'   => 'services_categories',
    'allowSearch' => false,
  ));

 // list of services to display beneath headings
    list($servicesRecords, $servicesMetaData) = getRecords(array(
    'tableName'   => 'services',
  ));

You have two arrays to play with here - $services_categoriesRecords and $servicesRecords. You already know that the categories are the main grouping, and that each category should have its own list of services, so the categories are going to come first when you start looping through each array. What you need after that is a way to group the services by their category, and have each group be accessible when you're outputting the category information.

First thing to do is create what's called a multidimensional array - an array of arrays. Here's how it'd look:

$serviceGroups = array(); // create the new multidimensional array, so it's ready for use

foreach ($serviceRecords as $record) { // start looping through the services
    $serviceGroups[$record['category']][] = $record; // make magic happen
}

The bolded line above is the important one. What it does is:

  • Adds a category num as a new key to $serviceGroups.
  • Creates a new array and assigns it to that key.
  • Adds a service record to this new array.

That's basically all the sorting you need, and it's done automatically. The serviceGroups array now consists of a super-array filled with a bunch of little arrays, each of which has a bunch of service records in it. And you can access any of the little arrays using the category num and the usual square bracket array notation.

$arrayOfServices = $serviceGroups[$correctCategoryNum]; // this is just to show you the notation, don't include it in your code

That's everything in the head. Now here's the output:

<?php foreach ($services_categoriesRecords as $record) : ?>
    <?php if(!isset($serviceGroups[$record['num'])) continue; ?> // skip empty categories if no array of services exists for them
   
    <?php echo $record['title']; ?>
    <?php echo $record['description']; ?>
   
    <?php foreach ($serviceGroups[$record['num']] as $service) : ?>
        <?php echo htmlencode($service['title']) ?>
    <?php endforeach; ?>
<?php endforeach; ?>

And that's it. I highly recommend reading up on how to use PHP arrays - http://php.net/manual/en/language.types.array.php. Once you understand arrays, you can do just about anything in PHP.

--------------------

Claire Ryan
interactivetools.com

Save time by getting our experts to help with your project.
http://www.interactivetools.com/consulting/

By Deborah - September 26, 2014

Claire, I can't thank you enough for taking the time to prepare that explanation and example. I can now see how powerful arrays can be and will try to gain a better understanding of the principles of using them.

Thanks again, Interactive Tools for your expert assistance!

~ Deborah