tag cloud
authorM. Taylor Saotome-Westlake <[email protected]>
Sat, 9 Sep 2017 00:57:46 +0000 (17:57 -0700)
committerM. Taylor Saotome-Westlake <[email protected]>
Sat, 9 Sep 2017 00:57:46 +0000 (17:57 -0700)
Markup adapted from the tag-cloud plugin README. It may be worth upstreaming my
alphabetical-sort fix?

pelicanconf.py
plugins/tag_cloud.py [new file with mode: 0644]
theme/static/css/main.css
theme/templates/base.html

index 162365b..e481594 100644 (file)
@@ -58,5 +58,11 @@ PAGINATION_PATTERNS = (
 
 THEME = 'theme'
 
+PLUGIN_PATHS = ["plugins"]
+PLUGINS = ["tag_cloud"]
+
+TAG_CLOUD_STEPS = 6
+TAG_CLOUD_SORTING = "alphabetically"
+
 # Uncomment following line if you want document-relative URLs when developing
 RELATIVE_URLS = True
diff --git a/plugins/tag_cloud.py b/plugins/tag_cloud.py
new file mode 100644 (file)
index 0000000..775977e
--- /dev/null
@@ -0,0 +1,95 @@
+# from https://github.com/getpelican/pelican-plugins as of f4d717ff
+
+# but with a fix to the alphabetical sorting
+
+'''
+tag_cloud
+===================================
+
+This plugin generates a tag cloud from available tags
+'''
+from __future__ import unicode_literals
+
+from collections import defaultdict
+from operator import itemgetter
+
+import logging
+import math
+import random
+
+from pelican import signals
+
+logger = logging.getLogger(__name__)
+
+
+def set_default_settings(settings):
+    settings.setdefault('TAG_CLOUD_STEPS', 4)
+    settings.setdefault('TAG_CLOUD_MAX_ITEMS', 100)
+    settings.setdefault('TAG_CLOUD_SORTING', 'random')
+    settings.setdefault('TAG_CLOUD_BADGE', False)
+
+
+def init_default_config(pelican):
+    from pelican.settings import DEFAULT_CONFIG
+    set_default_settings(DEFAULT_CONFIG)
+    if(pelican):
+            set_default_settings(pelican.settings)
+
+
+def generate_tag_cloud(generator):
+    tag_cloud = defaultdict(int)
+    for article in generator.articles:
+        for tag in getattr(article, 'tags', []):
+            tag_cloud[tag] += 1
+
+    tag_cloud = sorted(tag_cloud.items(), key=itemgetter(1), reverse=True)
+    tag_cloud = tag_cloud[:generator.settings.get('TAG_CLOUD_MAX_ITEMS')]
+
+    tags = list(map(itemgetter(1), tag_cloud))
+    if tags:
+        max_count = max(tags)
+    steps = generator.settings.get('TAG_CLOUD_STEPS')
+
+    # calculate word sizes
+    def generate_tag(tag, count):
+        tag = (
+            tag,
+            int(math.floor(steps - (steps - 1) * math.log(count)
+                / (math.log(max_count)or 1)))
+        )
+        if generator.settings.get('TAG_CLOUD_BADGE'):
+            tag += (count,)
+        return tag
+
+    tag_cloud = [
+        generate_tag(tag, count)
+        for tag, count in tag_cloud
+    ]
+
+    sorting = generator.settings.get('TAG_CLOUD_SORTING')
+
+    if sorting == 'alphabetically':
+        # `.lower()` to avoid putting all uppercase tags lexicographically
+        # before lowercase tags —ZMD
+        tag_cloud.sort(key=lambda elem: elem[0].name.lower())
+    elif sorting == 'alphabetically-rev':
+        tag_cloud.sort(key=lambda elem: elem[0].name, reverse=True)
+    elif sorting == 'size':
+        tag_cloud.sort(key=lambda elem: elem[1])
+    elif sorting == 'size-rev':
+        tag_cloud.sort(key=lambda elem: elem[1], reverse=True)
+    elif sorting == 'random':
+        random.shuffle(tag_cloud)
+    else:
+        logger.warning("setting for TAG_CLOUD_SORTING not recognized: %s, "
+                       "falling back to 'random'", sorting)
+        random.shuffle(tag_cloud)
+
+    # make available in context
+    generator.tag_cloud = tag_cloud
+    generator._update_context(['tag_cloud'])
+
+
+def register():
+    signals.initialized.connect(init_default_config)
+    signals.article_generator_finalized.connect(generate_tag_cloud)
index 4dadf32..f27dcd5 100644 (file)
@@ -307,3 +307,25 @@ li.tag-4 { font-size: 110%; margin: 0 1em; }
     margin: 0 4%;
   }
 }
+
+
+/* tag cloud */
+
+span.tag-1 {
+    font-size: 160%;
+}
+span.tag-2 {
+    font-size: 140%;
+}
+span.tag-3 {
+    font-size: 125%;
+}
+span.tag-4 {
+    font-size: 110%;
+}
+span.tag-5 {
+    font-size: 95%;
+}
+span.tag-6 {
+    font-size: 75%;
+}
index e6d02bc..cc65f94 100644 (file)
                  </aside>
                {% endif %}
 
+                <aside class="tag-cloud">
+                  <h2>Tags</h2>
+                  {% for tag in tag_cloud %}
+                    <span class="tag-{{ tag.1 }}">
+                      <a href="{{ SITEURL }}/{{ tag.0.url }}">
+                        {{ tag.0 }}
+                      </a>
+                    </span>
+                  {% endfor %}
+                </aside>
+
                  </div>
 
          </div>