Skip to content

Instantly share code, notes, and snippets.

@EnigmaCurry
Created June 17, 2010 18:40
Show Gist options
  • Save EnigmaCurry/442543 to your computer and use it in GitHub Desktop.
Save EnigmaCurry/442543 to your computer and use it in GitHub Desktop.
Blogofile tag cloud filter
import blogofile_bf as bf
import math
# A Blogofile based tag cloud with linear distribution.
# This works for either tags or categories.
# Ryan McGuire - www.blogofile.com
# Usage:
# In your template, add the following:
# ${bf.filter.run_chain("tag_cloud","categories")}
# or
# ${bf.filter.run_chain("tag_cloud","tags")}
tag_cloud = None
category_cloud = None
#Posts -- where to get the posts from?
# bf.posts in 0.6
# bf.blog.posts in 0.7+
posts = bf.posts
def run(content):
divisions = 6
global tag_cloud, category_cloud
if content == "categories":
if category_cloud is None:
category_cloud = build_cloud("categories", divisions)
return category_cloud_to_html(category_cloud)
if content == "tags":
if tag_cloud is None:
tag_cloud = build_cloud("tags", divisions)
return tag_cloud_to_html(tag_cloud)
def category_cloud_to_html(cloud):
html = ["<div id='tag_cloud'>"]
for category in sorted(cloud):
size = cloud[category]
link = category.path
html.append("<a href='%(link)s' class='size_%(size)s'>%(category)s</a>" % locals())
html.append("</div>")
return "\n".join(html)
def tag_cloud_to_html(cloud):
#TODO: make the links actually go to a tag controller
html = ["<div id='tag_cloud'>"]
for tag in sorted(cloud):
size = cloud[tag]
html.append("<a href='/tag/' class='size_%(size)s'>%(tag)s</a>" % locals())
html.append("</div>")
return "\n".join(html)
def build_cloud(cloud_type, divisions):
cloud = {}
#Count the tag hits
tag_counts = {}
for post in posts:
for tag in getattr(post, cloud_type):
tag_counts[tag] = tag_counts.get(tag,0) + 1
#Divide the range from the minimum tag count to the maximum tag count into
#(divisions) font sizes. This is done linearly, if you have disparate tag
#counts, you might want to use a logarithmic distribution.
max_t = max(tag_counts.values())
min_t = min(tag_counts.values())
dist = float(max_t - min_t) / (divisions - 1)
i = min_t
ranges = []
while i<=max_t:
r = (i, i+dist)
i += dist
ranges.append(r)
#Put the tags in the right bins
for tag, tag_n in tag_counts.items():
bin = 0
for r_min,r_max in ranges:
if tag_n >= r_min and tag_n < r_max:
cloud[tag] = bin
bin += 1
return cloud
#tag_cloud .size_5 {
font-size: 2.75em;
}
#tag_cloud .size_4 {
font-size: 2.4em;
}
#tag_cloud .size_3 {
font-size: 2.05em;
}
#tag_cloud .size_2 {
font-size: 1.7em;
}
#tag_cloud .size_1 {
font-size: 1.35em;
}
#tag_cloud .size_0 {
font-size: 1.0em;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment