Tag cloud limited to most popular tags

So I currently have a tag cloud working properly, but I’m trying to figure out a way to display a limited number sorted by popularity. Here’s my controller for dealing with tags…

<?php

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

    $twins = $site->find('twins')->children()->visible()->flip();
    $tags = $twins->pluck('tags', ',', true);

    if($tag = urldecode(param('tag'))) {
	$twins = $twins->filterBy('tags', $tag, ',');
    }

    return compact('twins', 'tags');

};

?>

You may want to have a look at this post: Tag Cloud with multiple page templates

I did take a look at that thread, but it doesn’t cover how to limit tags. You can limit pages, but that would omit some tags from the popularity count.

Untested, but it shows the idea:

// get all tags from subpages of 'twigs' page
$tags = page('twins')->children()->visible()->pluck('tags', ',', true);

// get counts for all tags as a measure of popularity
$tags = array_map(function($tag) { 
  $count = page('twins')->children()->visible()->filterBy('tags', $tag, ',')->count();
  return array('name' => $tag, 'count' => $count);
}, $tags);

// sort them
$sorted = a::sort($tags, 'count DESC');

// display, e.g. 3 tags
for($x = 1; $x <= 3; $x++) {
    echo $sorted[$x]['name'].' ('.$sorted[$x]['count'].')<br>';
}
1 Like

This solution worked for me.

// get all tags from subpages of 'twigs' page
$tags = page('blog')->children()->visible()->pluck('tags', ',', true);

// get counts for all tags as a measure of popularity
$tags = array_map(function($tag) { 
  $count = page('blog')->children()->visible()->filterBy('tags', $tag, ',')->count();
  return array('name' => $tag, 'count' => $count);
}, $tags);

usort($tags, function($a, $b) {
    return $b['count'] - $a['count'];
});

// display, e.g. top 3 tags
for($x = 0; $x <= 2; $x++) {
    echo $tags[$x]['name'].' ('.$tags[$x]['count'].')<br>';
} 
1 Like

how could i use this but replace the

$x <= 3

with a dynamic number; the number of tag types (in my case categories). When i run this now i get errors if i can’t fill the quota. In this case “3”. Example: if i have only one category i get 2 following errors.

how i’m using this code (below)

	<?php  
			// get all categories from subpages of 'twigs' page
		$categories = page('blog')->children()->visible()->pluck('categories', ',', true);

		// get counts for all categories as a measure of popularity
		$categories = array_map(function($category) { 
		  $count = page('blog')->children()->visible()->filterBy('categories', $category, ',')->count();
		  return array('name' => $category, 'count' => $count);
		}, $categories); ?>


		<ul>
		<?php for($x = 1; $x <= 6; $x++) { ?>
			<li>
		    <?php echo ucwords($categories[$x]['name']).' ('.$categories[$x]['count'].')<br>'; ?>
		    </li>
		<?php } ?>

Two solutions:

  1. Replace the for loop with a foreach loop

    <?php foreach($categories as $category) : ?>
       <li>
          <?php echo ucwords($category['name']) .' ('. $category['count'] .')'; ?>
       </li>
    <?php endforeach ?>
    
  2. Get number of elements in array

    <?php
    $i = count($categories);
    for($x = 1; $x <= $i; $x++): ?>
      <li>
        <?php echo  ucwords($categories[$x]['name']).' ('.$categories[$x]['count'].')'; 
      </li>
    <?php endfor ?>