diff --git a/pelicanconf.py b/pelicanconf.py
index 424f4cb..9728a29 100644
--- a/pelicanconf.py
+++ b/pelicanconf.py
@@ -42,6 +42,7 @@ PLUGINS = [
'i18n_subsites',
"pelican-page-hierarchy",
"always_modified",
+ "tag_cloud",
# 'pdf-img',
]
@@ -77,6 +78,7 @@ DISPLAY_CATEGORIES_ON_MENU = False
# Sidebar
DISPLAY_PAGES_ON_SIDE = False
TOCTREE = True
+TAG_CLOUD = True
#SITELOGO = ""
LINKS = ()
diff --git a/plugins/tag_cloud/README.rst b/plugins/tag_cloud/README.rst
new file mode 100644
index 0000000..4619969
--- /dev/null
+++ b/plugins/tag_cloud/README.rst
@@ -0,0 +1,98 @@
+tag_cloud
+=========
+
+This plugin generates a tag-cloud.
+
+Installation
+------------
+
+In order to use to use this plugin, you have to edit(*) or create(+) the following files::
+
+ blog/
+ ├── pelicanconf.py *
+ ├── content
+ ├── plugins +
+ │ └── tag_cloud.py +
+ └── themes
+ └── mytheme
+ ├── templates
+ │ └── base.html *
+ └── static
+ └── css
+ └── style.css *
+
+In **pelicanconf.py** you have to activate the plugin::
+
+ PLUGIN_PATHS = ["plugins"]
+ PLUGINS = ["tag_cloud"]
+
+Into your **plugins** folder, you should add tag_cloud.py (from this repository).
+
+In your theme files, you should change **base.html** to apply formats (and sizes) defined in **style.css**, as specified in "Settings", below.
+
+Settings
+--------
+
+================================================ =====================================================
+Setting name (followed by default value) What does it do?
+================================================ =====================================================
+``TAG_CLOUD_STEPS = 4`` Count of different font sizes in the tag
+ cloud.
+``TAG_CLOUD_MAX_ITEMS = 100`` Maximum number of tags in the cloud.
+``TAG_CLOUD_SORTING = 'random'`` The tag cloud ordering scheme. Valid values:
+ random, alphabetically, alphabetically-rev, size and
+ size-rev
+``TAG_CLOUD_BADGE = True`` Optionnal setting : can bring **badges**, which mean
+ say : display the number of each tags present
+ on all articles.
+================================================ =====================================================
+
+The default theme does not include a tag cloud, but it is pretty easy to add one::
+
+
+
+You should then also define CSS styles with appropriate classes (tag-1 to tag-N,
+where N matches ``TAG_CLOUD_STEPS``), tag-1 being the most frequent, and
+define a ``ul.tagcloud`` class with appropriate list-style to create the cloud.
+You should copy/paste this **badge** CSS rule ``ul.tagcloud .list-group-item .badge``
+if you're using ``TAG_CLOUD_BADGE`` setting. (this rule, potentially long , is suggested to avoid
+conflicts with CSS libs as twitter Bootstrap)
+
+For example::
+
+ ul.tagcloud {
+ list-style: none;
+ padding: 0;
+ }
+
+ ul.tagcloud li {
+ display: inline-block;
+ }
+
+ li.tag-1 {
+ font-size: 150%;
+ }
+
+ li.tag-2 {
+ font-size: 120%;
+ }
+
+ /* ... add li.tag-3 etc, as much as needed */
+
+ ul.tagcloud .list-group-item span.badge {
+ background-color: grey;
+ color: white;
+ }
+
+By default the tags in the cloud are sorted randomly, but if you prefers to have it alphabetically use the `alphabetically` (ascending) and `alphabetically-rev` (descending). Also is possible to sort the tags by it's size (number of articles with this specific tag) using the values `size` (ascending) and `size-rev` (descending).
diff --git a/plugins/tag_cloud/__init__.py b/plugins/tag_cloud/__init__.py
new file mode 100644
index 0000000..a7004f5
--- /dev/null
+++ b/plugins/tag_cloud/__init__.py
@@ -0,0 +1,2 @@
+from .tag_cloud import *
+
diff --git a/plugins/tag_cloud/tag_cloud.py b/plugins/tag_cloud/tag_cloud.py
new file mode 100644
index 0000000..bf91055
--- /dev/null
+++ b/plugins/tag_cloud/tag_cloud.py
@@ -0,0 +1,90 @@
+'''
+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 = tags[0]
+ min_count = tags[-1]
+ 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 - min_count + 1)
+ / (math.log(max_count - min_count + 1) 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':
+ tag_cloud.sort(key=lambda elem: elem[0].name)
+ 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)
diff --git a/theme/static/stylesheet/style.less b/theme/static/stylesheet/style.less
index e3e1253..e8f0385 100644
--- a/theme/static/stylesheet/style.less
+++ b/theme/static/stylesheet/style.less
@@ -87,7 +87,7 @@ aside {
color: @sidebar-link-hover-color;
}
- div {
+ .title {
text-align: center;
margin-bottom: 50px;
margin-top: 50px;
@@ -110,59 +110,95 @@ aside {
}
nav {
- ul {
- padding-inline-start: 0px;
- display: block;
- }
- ul.toctree {
- li {
- a {
- background-color: @navbar-bg;
- color: @navbar-text-color;
- border: none;
- }
- }
- li.toctree-l1 {
- li.current{
- background-color: @navbar-toctree-l2-sel-bg;
- color: @navbar-toctree-l2-sel-txt;
- padding: 10px;
- }
- }
- li.current{
- a {
- background-color: @navbar-toctree-l1-sel-bg;
- border-bottom: solid 1px @light-grey;
- border-left: solid 2px @grey;
- color: @navbar-toctree-l1-sel-txt;
- }
- a:hover {
- color: @orange;
- }
- }
- li.toctree-l2 {
- a {
- border: none;
- background-color: @navbar-toctree-l2-bg;
- color: @navbar-toctree-l2-txt;
- }
- }
- a {
- padding: 10px;
- }
- a:hover {
- color: @orange;
- }
- }
- ul.list {
- li {
- display: inline;
- line-height: 1.6em;
- font-size: 1.28em;
- text-transform: lowercase;
- }
- }
-}
+ ul {
+ padding-inline-start: 0px;
+ display: block;
+ }
+ ul.toctree {
+ li {
+ a {
+ background-color: @navbar-bg;
+ color: @navbar-text-color;
+ border: none;
+ }
+ }
+ li.toctree-l1 {
+ li.current{
+ background-color: @navbar-toctree-l2-sel-bg;
+ color: @navbar-toctree-l2-sel-txt;
+ padding: 10px;
+ }
+ }
+ li.current{
+ a {
+ background-color: @navbar-toctree-l1-sel-bg;
+ border-bottom: solid 1px @light-grey;
+ border-left: solid 2px @grey;
+ color: @navbar-toctree-l1-sel-txt;
+ }
+ a:hover {
+ color: @orange;
+ }
+ }
+ li.toctree-l2 {
+ a {
+ border: none;
+ background-color: @navbar-toctree-l2-bg;
+ color: @navbar-toctree-l2-txt;
+ }
+ }
+ a {
+ padding: 10px;
+ }
+ a:hover {
+ color: @orange;
+ }
+ }
+ ul.list {
+ li {
+ display: inline;
+ line-height: 1.6em;
+ font-size: 1.28em;
+ text-transform: lowercase;
+ }
+ }
+ }
+
+ .tagcloud {
+ h2 {
+ background-color: @sidebar-bg;
+ margin-bottom: 0;
+ }
+
+ ul {
+ list-style: none;
+ padding: 0;
+ }
+
+ ul li {
+ display: inline-block;
+ }
+
+ li.tag-0 {
+ font-size: 170%;
+ }
+
+ li.tag-1 {
+ font-size: 150%;
+ }
+
+ li.tag-2 {
+ font-size: 120%;
+ }
+
+ li.tag-3 {
+ font-size: 100%;
+ }
+
+ li.tag-4 {
+ font-size: 80%;
+ }
+ }
}
main {
diff --git a/theme/static/stylesheet/style.min.css b/theme/static/stylesheet/style.min.css
index 970aabd..7cb21d3 100644
--- a/theme/static/stylesheet/style.min.css
+++ b/theme/static/stylesheet/style.min.css
@@ -1 +1 @@
-html,body{width:100%;height:100%}h1,h2,h3,h4,h5,h6{font-weight:300;line-height:1.1}h1{font-size:2.4em}h2{font-size:2em;background-color:#eeeeee;padding:4px}h3{font-size:1.6em}h4{font-size:1.36em}h5{font-size:1.2em}h6{font-size:1.1em}body{margin:0;padding:0;background-color:#ffffff;color:#242121;font-family:'Source Sans Pro','Roboto','Open Sans','Liberation Sans','DejaVu Sans','Verdana','Helvetica','Arial',sans-serif;font-size:1.02em;line-height:1.2em}a{color:#D9411E;text-decoration:none}a:hover{color:#FF5A09}hr{color:#eeeeee;background-color:#eeeeee;height:1px;border:none;margin-top:40px;margin-bottom:40px}img{max-width:100%}aside{background-color:#333333;color:#ffffff}aside a{color:#ffffff;display:block}aside a:hover{color:#eeeeee}aside div{text-align:center;margin-bottom:50px;margin-top:50px}aside div img{padding:20px;border-radius:50%;max-width:140px}aside div h1{margin:15px 0 5px 0}aside div p{margin:0 0 15px 0;font-size:.92em}aside nav ul{padding-inline-start:0px;display:block}aside nav ul.toctree li a{background-color:#242121;color:#ffffff;border:none}aside nav ul.toctree li.toctree-l1 li.current{background-color:#eeeeee;color:#333333;padding:10px}aside nav ul.toctree li.current a{background-color:#242121;border-bottom:solid 1px #eeeeee;border-left:solid 2px #333333;color:#eeeeee}aside nav ul.toctree li.current a:hover{color:#D9411E}aside nav ul.toctree li.toctree-l2 a{border:none;background-color:#999999;color:#333333}aside nav ul.toctree a{padding:10px}aside nav ul.toctree a:hover{color:#D9411E}aside nav ul.list li{display:inline;line-height:1.6em;font-size:1.28em;text-transform:lowercase}main nav{text-align:center;text-transform:uppercase;font-size:.72em;padding:14px 0 14px 0;border-bottom:#eeeeee 1px solid}main nav a,main .translations a{padding:0 4px 0 4px;border-left:#eeeeee 1px solid;border-right:#eeeeee 1px solid}main nav :first-child,main .translations :first-child{border-left:none}main nav :last-child,main .translations :last-child{border-right:none}main .neighbors{margin:4% 0% 4% 0%;height:20px}main .pagination{margin:4% 8% 4% 8%;height:20px}main .social-share p{font-size:.8em}main article{margin:0 8% 2% 8%}main article header h1,main article header h2{margin-bottom:0}main article header p{color:#999999;font-size:.86em}main article header .translations{float:right}main article header .translations .active{font-weight:600}main article code,main article kbd,main article samp,main article pre{font-family:'Source Code Pro','Consolas','Liberation Mono','DejaVu Sans Mono',monospace}main article blockquote,main article pre{background-color:rgba(128,128,128,0.05);border-top-right-radius:5px;border-bottom-right-radius:5px;border-left:8px solid rgba(128,128,128,0.075);border-left-width:10px}main article blockquote{padding:10px 20px;font-weight:300;font-size:1.1em}main article pre{padding:4px;font-size:.9em;overflow-x:auto}main article samp{white-space:pre;display:block;overflow-x:auto}main article kbd{padding:.1em .6em;border:1px solid rgba(63,63,63,0.25);box-shadow:0 1px 0 rgba(63,63,63,0.25);background-color:#fff;color:#333;border-radius:3px;display:inline-block;margin:0 .1em;white-space:nowrap;font-size:.78em}main article *:not(pre)>code{font-size:.8em;white-space:nowrap;color:#c25;padding:1px 3px;background-color:#f7f7f9;border:1px solid #e1e1e8;border-radius:3px}main article .comment-count{font-size:.8em}main article table{border-collapse:collapse;border-spacing:0}main article table thead:first-child tr:first-child th{border-top:0}main article table th,main article table td{padding:8px;line-height:20px;vertical-align:top;border-top:1px solid #ddd}main footer{padding-top:4px;border-top:#eeeeee 1px solid}main footer p{margin:2px;text-align:center;padding:0 40px 0 40px;color:#999999;font-size:11px}.about{text-align:center;border-top:#eeeeee 1px solid;padding-top:1em}.tag-cloud{text-align:center}.tag-cloud a{background-color:#D9411E;padding:.2em .6em .2em;font-size:.74em;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.tag-cloud a:hover{background-color:#FF5A09}a.btn{background-color:#D9411E;padding:.6em .6em;font-size:.8em;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.btn:hover{background-color:#FF5A09}.center,.text-center{text-align:center}.img-center{margin-left:auto;margin-right:auto;display:block}.align-center{margin-left:auto;margin-right:auto;display:block}.float-left{float:left}.float-right{float:right}div.related-posts{margin:15px 0 15px 0;padding-bottom:20px;border-top:#eeeeee 1px solid;border-bottom:#eeeeee 1px solid}div.related-posts h4{margin:20px 0 25px 0}div.related-posts ul{font-size:1.1em;padding-left:12px}div.related-posts ul li{padding:4px 0 4px 0}ul.list,ul.social,ul.related-posts{list-style-type:none;margin:0;padding:0}ul.list{padding:1em 0 1em 0}ul.list li{padding:4px}ul.breadcrumb{padding:5px 10px;list-style:none;background-color:#eee;font-size:.9em}ul.breadcrumb li{display:inline;font-size:18px}ul.breadcrumb li a{color:#D9411E;text-decoration:none}ul.breadcrumb li a:hover{color:#FF5A09}ul.breadcrumb li+li:before{padding:8px;color:black;content:"/\00a0"}ul.social{font-size:1.6em;padding-top:20px}ul.social li{display:inline}ul.social a:hover{z-index:2;-webkit-transform:translateY(-5px);transform:translateY(-5px)}ul.social a{display:inline-block;width:36px;height:36px;border-radius:100%;text-align:center;font-size:.8em;line-height:36px}@media screen and (min-width:768px){aside{width:20%;max-width:250px;height:100%;position:fixed;top:0;left:0;overflow-y:auto}aside div nav ul li{padding:0;display:block}aside div ul.social{padding-top:32px}main{width:75%;height:100%;position:absolute;top:0;right:2.5%}main article.single{min-height:80%}main article ul.list li{padding:2px}}
\ No newline at end of file
+html,body{width:100%;height:100%}h1,h2,h3,h4,h5,h6{font-weight:300;line-height:1.1}h1{font-size:2.4em}h2{font-size:2em;background-color:#eeeeee;padding:4px}h3{font-size:1.6em}h4{font-size:1.36em}h5{font-size:1.2em}h6{font-size:1.1em}body{margin:0;padding:0;background-color:#ffffff;color:#242121;font-family:'Source Sans Pro','Roboto','Open Sans','Liberation Sans','DejaVu Sans','Verdana','Helvetica','Arial',sans-serif;font-size:1.02em;line-height:1.2em}a{color:#D9411E;text-decoration:none}a:hover{color:#FF5A09}hr{color:#eeeeee;background-color:#eeeeee;height:1px;border:none;margin-top:40px;margin-bottom:40px}img{max-width:100%}aside{background-color:#333333;color:#ffffff}aside a{color:#ffffff;display:block}aside a:hover{color:#eeeeee}aside .title{text-align:center;margin-bottom:50px;margin-top:50px}aside .title img{padding:20px;border-radius:50%;max-width:140px}aside .title h1{margin:15px 0 5px 0}aside .title p{margin:0 0 15px 0;font-size:.92em}aside nav ul{padding-inline-start:0px;display:block}aside nav ul.toctree li a{background-color:#242121;color:#ffffff;border:none}aside nav ul.toctree li.toctree-l1 li.current{background-color:#eeeeee;color:#333333;padding:10px}aside nav ul.toctree li.current a{background-color:#242121;border-bottom:solid 1px #eeeeee;border-left:solid 2px #333333;color:#eeeeee}aside nav ul.toctree li.current a:hover{color:#D9411E}aside nav ul.toctree li.toctree-l2 a{border:none;background-color:#999999;color:#333333}aside nav ul.toctree a{padding:10px}aside nav ul.toctree a:hover{color:#D9411E}aside nav ul.list li{display:inline;line-height:1.6em;font-size:1.28em;text-transform:lowercase}aside .tagcloud h2{background-color:#333333;margin-bottom:0}aside .tagcloud ul{list-style:none;padding:0}aside .tagcloud ul li{display:inline-block}aside .tagcloud li.tag-0{font-size:170%}aside .tagcloud li.tag-1{font-size:150%}aside .tagcloud li.tag-2{font-size:120%}aside .tagcloud li.tag-3{font-size:100%}aside .tagcloud li.tag-4{font-size:80%}main nav{text-align:center;text-transform:uppercase;font-size:.72em;padding:14px 0 14px 0;border-bottom:#eeeeee 1px solid}main nav a,main .translations a{padding:0 4px 0 4px;border-left:#eeeeee 1px solid;border-right:#eeeeee 1px solid}main nav :first-child,main .translations :first-child{border-left:none}main nav :last-child,main .translations :last-child{border-right:none}main .neighbors{margin:4% 0% 4% 0%;height:20px}main .pagination{margin:4% 8% 4% 8%;height:20px}main .social-share p{font-size:.8em}main article{margin:0 8% 2% 8%}main article header h1,main article header h2{margin-bottom:0}main article header p{color:#999999;font-size:.86em}main article header .translations{float:right}main article header .translations .active{font-weight:600}main article code,main article kbd,main article samp,main article pre{font-family:'Source Code Pro','Consolas','Liberation Mono','DejaVu Sans Mono',monospace}main article blockquote,main article pre{background-color:rgba(128,128,128,0.05);border-top-right-radius:5px;border-bottom-right-radius:5px;border-left:8px solid rgba(128,128,128,0.075);border-left-width:10px}main article blockquote{padding:10px 20px;font-weight:300;font-size:1.1em}main article pre{padding:4px;font-size:.9em;overflow-x:auto}main article samp{white-space:pre;display:block;overflow-x:auto}main article kbd{padding:.1em .6em;border:1px solid rgba(63,63,63,0.25);box-shadow:0 1px 0 rgba(63,63,63,0.25);background-color:#fff;color:#333;border-radius:3px;display:inline-block;margin:0 .1em;white-space:nowrap;font-size:.78em}main article *:not(pre)>code{font-size:.8em;white-space:nowrap;color:#c25;padding:1px 3px;background-color:#f7f7f9;border:1px solid #e1e1e8;border-radius:3px}main article .comment-count{font-size:.8em}main article table{border-collapse:collapse;border-spacing:0}main article table thead:first-child tr:first-child th{border-top:0}main article table th,main article table td{padding:8px;line-height:20px;vertical-align:top;border-top:1px solid #ddd}main footer{padding-top:4px;border-top:#eeeeee 1px solid}main footer p{margin:2px;text-align:center;padding:0 40px 0 40px;color:#999999;font-size:11px}.about{text-align:center;border-top:#eeeeee 1px solid;padding-top:1em}.tag-cloud{text-align:center}.tag-cloud a{background-color:#D9411E;padding:.2em .6em .2em;font-size:.74em;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.tag-cloud a:hover{background-color:#FF5A09}a.btn{background-color:#D9411E;padding:.6em .6em;font-size:.8em;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.btn:hover{background-color:#FF5A09}.center,.text-center{text-align:center}.img-center{margin-left:auto;margin-right:auto;display:block}.align-center{margin-left:auto;margin-right:auto;display:block}.float-left{float:left}.float-right{float:right}div.related-posts{margin:15px 0 15px 0;padding-bottom:20px;border-top:#eeeeee 1px solid;border-bottom:#eeeeee 1px solid}div.related-posts h4{margin:20px 0 25px 0}div.related-posts ul{font-size:1.1em;padding-left:12px}div.related-posts ul li{padding:4px 0 4px 0}ul.list,ul.social,ul.related-posts{list-style-type:none;margin:0;padding:0}ul.list{padding:1em 0 1em 0}ul.list li{padding:4px}ul.breadcrumb{padding:5px 10px;list-style:none;background-color:#eee;font-size:.9em}ul.breadcrumb li{display:inline;font-size:18px}ul.breadcrumb li a{color:#D9411E;text-decoration:none}ul.breadcrumb li a:hover{color:#FF5A09}ul.breadcrumb li+li:before{padding:8px;color:black;content:"/\00a0"}ul.social{font-size:1.6em;padding-top:20px}ul.social li{display:inline}ul.social a:hover{z-index:2;-webkit-transform:translateY(-5px);transform:translateY(-5px)}ul.social a{display:inline-block;width:36px;height:36px;border-radius:100%;text-align:center;font-size:.8em;line-height:36px}@media screen and (min-width:768px){aside{width:20%;max-width:250px;height:100%;position:fixed;top:0;left:0;overflow-y:auto}aside div nav ul li{padding:0;display:block}aside div ul.social{padding-top:32px}main{width:75%;height:100%;position:absolute;top:0;right:2.5%}main article.single{min-height:80%}main article ul.list li{padding:2px}}
\ No newline at end of file
diff --git a/theme/templates/base.html b/theme/templates/base.html
index 3561d12..8ab93b8 100644
--- a/theme/templates/base.html
+++ b/theme/templates/base.html
@@ -70,7 +70,7 @@