<p>Marion Newlevant had a clever, efficient idea in <a href="https://straightupcraft.com/events/code-review-optimized-tag-clouds-with-taggregate" rel="noreferrer">this Straight Up Craft Hangout</a> if you don't mind having a slight lag (like a day) for your tag counts to be up to date. That idea: <strong>store the counts you need in a Preparse field on each tag, and set up a cron job to re-save all tags periodically.</strong></p>

<h1>1. Set Up Preparse</h1>

<p><a href="https://github.com/aelvan/Preparse-Field-Craft" rel="noreferrer">Preparse</a> is a free plugin from André Elvan that renders Twig code to a field when an entry is saved. Install it, add a Preparse field to your Tag elements (like <code>tagCount</code>) for example, and make the contents of said field <code>{{ craft.entries.section('blog').relatedTo(tag).total }}</code>, where <code>blog</code> is the section for which we're building the tag cloud. Be sure to set <em>Column Type</em> → <em>Number</em>, since we're storing a count and we'll sort on it later in our template. </p>

<p><a href="https://i.sstatic.net/kXyaA.png" rel="noreferrer"><img src="https://i.sstatic.net/kXyaA.png" alt="the settings for your Preparse field"></a></p>

<p>When a Tag is saved, Craft will count the entries related to it and store the total in this new <code>tagCount</code> field. Now we just need to make sure tags are saved every now and then!</p>

<h1>2. Set up a task for resaving elements.</h1>

<p>Here we'll make a publicly-accessible PHP script that'll get an instance of Craft (which is easy) and tell it to resave our tags. In this case we'll save <em>all</em> tags, but you can limit the scope in the task settings if you need to.</p>

<p>In your /public folder, create a file called <code>resave-tags.php</code> and drop this in it:</p>

<pre class="lang-php prettyprint-override"><code>&lt;?php

namespace Craft;

$app = require("../craft/app/bootstrap.php");

$app-&gt;tasks-&gt;createTask('ResaveElements', 'Resaving tags!', array(
    'elementType' =&gt; 'Tag'
));
</code></pre>

<p><sub>Note that you don't have to make this public, you can run it from a terminal, shell script, or any old way you'd normally interact with PHP.</sub></p>

<p>Now you should be able to hit yourdomain.craft.dev/resave-tags.php and go confirm that Craft has updated your <code>tagCount</code> values. (You <em>did</em> already set up entries and tags, right?) Now we just need our reliable friend cron to trigger this for us periodically.</p>

<h1>3. Tie cron to your task.</h1>

<p>If you've never used cron, it's a very simple, powerful tool that lets you run commands at intervals, whether it's every second or every second Tuesday or every decade. The process for editing cron tasks depends on your hosting environment, but the vast majority give you <em>some</em> way to edit these tasks.</p>

<p>For this example, we'll hit our URL at midnight every day and ignore the output (because we're brave):</p>

<pre><code>0 0 * * * /usr/bin/wget --spider \"http://foo.dev/resave-elements.php\" &gt;/dev/null 2&gt;&amp;1
</code></pre>

<h1>4. Write Your Template</h1>

<p>Here we'll get our tags and order by <code>tagCount</code> starting with the greatest number. Using just a dash of math, we'll loop through entries and get a number we can use to size text—the biggest tags will be <code>4em</code> and the smallest will be <code>1em</code>, per <code>minScale</code> and <code>maxScale</code>:</p>

<pre class="lang-html prettyprint-override"><code>{% set tags = craft.tags.order('tagCount desc').limit(999) %}

{% if tags | length %}
    {% set minScale = 1 %}
    {% set maxScale = 4 %}
    {% set biggestTagCount = (tags|first).tagCount %}
    {% set smallestTagCount = (tags|last).tagCount %}

    &lt;ul class="cloud"&gt;
        {% for tag in tags %}
            {% set fontSize = ((tag.tagCount - smallestTagCount) / biggestTagCount) * (maxScale - minScale) + minScale  %}
            &lt;li&gt;
                &lt;span style="font-size: {{ fontSize }}em;"&gt;
                    {{ tag.title }}
                &lt;/span&gt;
            &lt;/li&gt;
        {% endfor %}
    &lt;/ul&gt;
{% endif %}
</code></pre>

<p>And that's one way to make a visually-weighted tag cloud.</p>

CC BY-SA 3.0
2016-06-12T03:25:41.253Z
Nice solution, thanks for the write up! There was an update to the Preparse plugin that allows to make it save to numeric db columns, do you don't need the type casting any longer! ;)
carlcs
CC BY-SA 3.0
2016-06-12T03:32:21.897Z
I can't keep up around here, @carlcs! Thanks for mentioning it, I've just updated my answer.
Matt Stein
CC BY-SA 3.0
2016-06-12T02:56:04.643Z
2016-06-12T03:37:09.387Z
2016-06-12T03:37:09.387Z
Matt Stein
<p>Brandon commented on getting tag usage count (and how it can be expensive) in <a href="https://plus.google.com/105335880239855961276/posts/WSy2LNwi21i" rel="nofollow">this Google+ post</a> and again in <a href="https://craftcms.stackexchange.com/questions/1091/how-can-i-best-extend-tagmodel-to-add-a-count-property?lq=1">this SE question</a> where I was trying to think through a plugin.</p>

<p>So to completely steal from that, you could loop through your tags and get a count for each...</p>

<pre><code>{% set tags = craft.tags.find() %}

{% for tag in tags %}
    {% set count = craft.entries.section('blog').relatedTo(tag).total() %}
    &lt;a href="/entries/{{ tag.slug }}" data-count="{{ count }}"&gt;{{ tag.name }}&lt;/a&gt;
{% endfor %}
</code></pre>

<p>Then manipulate the listing with JavaScript or find the max count and loop again to apply inline CSS percentages or <code>font-size</code>s that are scaled accordingly. As Brandon noted in that post, be sure to wrap everything in <code>{% cache %}</code> tags since this will be an intense template to render.</p>

<p><em>Update:</em></p>

<p>Since this answer, Phil Birnie released <a href="https://github.com/philbirnie/CraftPopularTags" rel="nofollow">a plugin for this</a> he's linked to below, and I came up <a href="https://gitlab.com/workingconcept/craft-taggregate" rel="nofollow">with my own</a> that we trashed in <a href="https://straightupcraft.com/events/code-review-optimized-tag-clouds-with-taggregate" rel="nofollow">a Straight Up Craft Hangout</a> thanks to Marion's stellar idea of using a Preparse field to tally counts, which I've added here as an alternative answer.</p>

CC BY-SA 3.0
2015-10-07T17:26:37.157Z
Nice work, @PhilB! You might post that to #announcements in the Craft Slack account. I'll take a look here when I get some free time.
Matt Stein
CC BY-SA 3.0
2015-10-07T19:56:36.653Z
Sorry for reposting - noticed I misspelled "popular" in the repo name and couldn't edit the comment - thanks @MattStein, I'll post to slack. https://github.com/philbirnie/CraftPopularTags
Phil Birnie
CC BY-SA 3.0
2016-06-17T08:50:42.303Z
craft-taggregate is really nice, but can't be cached.
MISC
CC BY-SA 3.0
2016-06-17T15:50:10.220Z
@MISC and with enough tags, it'd be a problem _before_ it could even be cached. A brilliant plugin it is not.
Matt Stein
CC BY-SA 3.0
2016-07-04T10:30:16.380Z
Is there a simple way to limit the tags to a specific group within a section? I have 3 tag groups within my section and would use:

{% set tagsAll = craft.tags.group('projectSkills').relatedTo(allEntries) %}

Any help would be appreciated
Scott Robinson
CC BY-SA 3.0
2016-07-05T17:19:43.577Z
That should be exactly what you need, @ScottRobinson, but if it's not working you should post a separate question.
Matt Stein
CC BY-SA 3.0
2014-07-10T02:24:33.953Z
Would it be less expensive if done via a plugin?
Natetronn
CC BY-SA 3.0
2014-07-10T03:00:23.567Z
@Natetronn I guess it depends on the plugin itself, but probably. It'd be nice to get counts and limit to X most-used tags, for example. Off the top of my head, I'm not sure how I'd approach this.
Matt Stein
CC BY-SA 3.0
2014-07-10T03:23:54.327Z
A plugin could utilize an aggregate table, for example, to make the query less expensive.
Brad Bell
CC BY-SA 3.0
2014-07-10T03:27:36.237Z
I may be able to pull a Low and answer with that plugin, but not in the immediate future.
Matt Stein
CC BY-SA 3.0
2014-07-10T03:34:23.620Z
"pull a Low", nice! :)
carlcs
CC BY-SA 3.0
2014-07-10T16:59:13.290Z
By all means, "pull a Low"! :)
Natetronn
CC BY-SA 3.0
2014-07-10T01:41:26.303Z
2016-06-12T02:58:32.707Z
2016-06-12T02:58:32.707Z
Matt Stein
<p>I kind of want a tag archive page where it doesn't just list all the tags and links to entries based on that tag, but where the sizes of the actual tag link vary based on frequency of use.</p>

<p>Any idea how?</p>

<tags><format><archives>
How can I create a visually weighted tag cloud?
# How can I create a visually weighted tag cloud?

(Asked by: username_0 on 2014-07-10)

I kind of want a tag archive page where it doesn't just list all the tags and links to entries based on that tag, but where the sizes of the actual tag link vary based on frequency of use.

Any idea how?

**Tags:** tags, format, archives

---

## 2 answers

### Answer by username_1 on 2014-07-10. Score: 15 | Accepted answer

Brandon commented on getting tag usage count (and how it can be expensive) in this Google+ post and again in this SE question where I was trying to think through a plugin.
So to completely steal from that, you could loop through your tags and get a count for each...
{% set tags = craft.tags.find() %}

{% for tag in tags %}
    {% set count = craft.entries.section('blog').relatedTo(tag).total() %}
    {{ tag.name }}
{% endfor %}

Then manipulate the listing with JavaScript or find the max count and loop again to apply inline CSS percentages or font-sizes that are scaled accordingly. As Brandon noted in that post, be sure to wrap everything in {% cache %} tags since this will be an intense template to render.
Update:
Since this answer, Phil Birnie released a plugin for this he's linked to below, and I came up with my own that we trashed in a Straight Up Craft Hangout thanks to Marion's stellar idea of using a Preparse field to tally counts, which I've added here as an alternative answer.

> **Comments:**
> **username_6**: Would it be less expensive if done via a plugin?  
> **username_1**: @Natetronn I guess it depends on the plugin itself, but probably. It'd be nice to get counts and limit to X most-used tags, for example. Off the top of my head, I'm not sure how I'd approach this.  
> **username_7**: A plugin could utilize an aggregate table, for example, to make the query less expensive.  
> **username_1**: I may be able to pull a Low and answer with that plugin, but not in the immediate future.  
> **username_2**: "pull a Low", nice! :)  
> **username_6**: By all means, "pull a Low"! :)  
> **username_1**: Nice work, @PhilB! You might post that to #announcements in the Craft Slack account. I'll take a look here when I get some free time.  
> **username_3**: Sorry for reposting - noticed I misspelled "popular" in the repo name and couldn't edit the comment - thanks @MattStein, I'll post to slack. https://github.com/philbirnie/CraftPopularTags  
> **username_4**: craft-taggregate is really nice, but can't be cached.  
> **username_1**: @MISC and with enough tags, it'd be a problem _before_ it could even be cached. A brilliant plugin it is not.  
> **username_5**: Is there a simple way to limit the tags to a specific group within a section? I have 3 tag groups within my section and would use:  {% set tagsAll = craft.tags.group('projectSkills').relatedTo(allEntries) %}  Any help would be appreciated  
> **username_1**: That should be exactly what you need, @ScottRobinson, but if it's not working you should post a separate question.  

---

### Answer by username_1 on 2016-06-12. Score: 14

Marion Newlevant had a clever, efficient idea in this Straight Up Craft Hangout if you don't mind having a slight lag (like a day) for your tag counts to be up to date. That idea: store the counts you need in a Preparse field on each tag, and set up a cron job to re-save all tags periodically.
1. Set Up Preparse
Preparse is a free plugin from André Elvan that renders Twig code to a field when an entry is saved. Install it, add a Preparse field to your Tag elements (like tagCount) for example, and make the contents of said field {{ craft.entries.section('blog').relatedTo(tag).total }}, where blog is the section for which we're building the tag cloud. Be sure to set Column Type → Number, since we're storing a count and we'll sort on it later in our template. 

When a Tag is saved, Craft will count the entries related to it and store the total in this new tagCount field. Now we just need to make sure tags are saved every now and then!
2. Set up a task for resaving elements.
Here we'll make a publicly-accessible PHP script that'll get an instance of Craft (which is easy) and tell it to resave our tags. In this case we'll save all tags, but you can limit the scope in the task settings if you need to.
In your /public folder, create a file called resave-tags.php and drop this in it:
tasks->createTask('ResaveElements', 'Resaving tags!', array(
    'elementType' => 'Tag'
));

Note that you don't have to make this public, you can run it from a terminal, shell script, or any old way you'd normally interact with PHP.
Now you should be able to hit yourdomain.craft.dev/resave-tags.php and go confirm that Craft has updated your tagCount values. (You did already set up entries and tags, right?) Now we just need our reliable friend cron to trigger this for us periodically.
3. Tie cron to your task.
If you've never used cron, it's a very simple, powerful tool that lets you run commands at intervals, whether it's every second or every second Tuesday or every decade. The process for editing cron tasks depends on your hosting environment, but the vast majority give you some way to edit these tasks.
For this example, we'll hit our URL at midnight every day and ignore the output (because we're brave):
0 0 * * * /usr/bin/wget --spider \"http://foo.dev/resave-elements.php\" >/dev/null 2>&1

4. Write Your Template
Here we'll get our tags and order by tagCount starting with the greatest number. Using just a dash of math, we'll loop through entries and get a number we can use to size text—the biggest tags will be 4em and the smallest will be 1em, per minScale and maxScale:
{% set tags = craft.tags.order('tagCount desc').limit(999) %}

{% if tags | length %}
    {% set minScale = 1 %}
    {% set maxScale = 4 %}
    {% set biggestTagCount = (tags|first).tagCount %}
    {% set smallestTagCount = (tags|last).tagCount %}

    
        {% for tag in tags %}
            {% set fontSize = ((tag.tagCount - smallestTagCount) / biggestTagCount) * (maxScale - minScale) + minScale  %}
            
                
                    {{ tag.title }}
                
            
        {% endfor %}
    
{% endif %}

And that's one way to make a visually-weighted tag cloud.

> **Comments:**
> **username_2**: Nice solution, thanks for the write up! There was an update to the Preparse plugin that allows to make it save to numeric db columns, do you don't need the type casting any longer! ;)  
> **username_1**: I can't keep up around here, @carlcs! Thanks for mentioning it, I've just updated my answer.  

---

