Feat: integrate tag_cloud
This commit is contained in:
parent
ba64771efb
commit
952d19859c
@ -42,6 +42,7 @@ PLUGINS = [
|
|||||||
'i18n_subsites',
|
'i18n_subsites',
|
||||||
"pelican-page-hierarchy",
|
"pelican-page-hierarchy",
|
||||||
"always_modified",
|
"always_modified",
|
||||||
|
"tag_cloud",
|
||||||
# 'pdf-img',
|
# 'pdf-img',
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ DISPLAY_CATEGORIES_ON_MENU = False
|
|||||||
# Sidebar
|
# Sidebar
|
||||||
DISPLAY_PAGES_ON_SIDE = False
|
DISPLAY_PAGES_ON_SIDE = False
|
||||||
TOCTREE = True
|
TOCTREE = True
|
||||||
|
TAG_CLOUD = True
|
||||||
|
|
||||||
#SITELOGO = ""
|
#SITELOGO = ""
|
||||||
LINKS = ()
|
LINKS = ()
|
||||||
|
98
plugins/tag_cloud/README.rst
Normal file
98
plugins/tag_cloud/README.rst
Normal file
@ -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::
|
||||||
|
|
||||||
|
<ul class="tagcloud">
|
||||||
|
{% for tag in tag_cloud %}
|
||||||
|
<li class="tag-{{ tag.1 }}">
|
||||||
|
<a href="{{ SITEURL }}/{{ tag.0.url }}">
|
||||||
|
{{ tag.0 }}
|
||||||
|
{% if TAG_CLOUD_BADGE %}
|
||||||
|
<span class="badge">{{ tag.2 }}</span>
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
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 <span>.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).
|
2
plugins/tag_cloud/__init__.py
Normal file
2
plugins/tag_cloud/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from .tag_cloud import *
|
||||||
|
|
90
plugins/tag_cloud/tag_cloud.py
Normal file
90
plugins/tag_cloud/tag_cloud.py
Normal file
@ -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)
|
@ -87,7 +87,7 @@ aside {
|
|||||||
color: @sidebar-link-hover-color;
|
color: @sidebar-link-hover-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
div {
|
.title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 50px;
|
margin-bottom: 50px;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
@ -110,59 +110,95 @@ aside {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
nav {
|
||||||
ul {
|
ul {
|
||||||
padding-inline-start: 0px;
|
padding-inline-start: 0px;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
ul.toctree {
|
ul.toctree {
|
||||||
li {
|
li {
|
||||||
a {
|
a {
|
||||||
background-color: @navbar-bg;
|
background-color: @navbar-bg;
|
||||||
color: @navbar-text-color;
|
color: @navbar-text-color;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
li.toctree-l1 {
|
li.toctree-l1 {
|
||||||
li.current{
|
li.current{
|
||||||
background-color: @navbar-toctree-l2-sel-bg;
|
background-color: @navbar-toctree-l2-sel-bg;
|
||||||
color: @navbar-toctree-l2-sel-txt;
|
color: @navbar-toctree-l2-sel-txt;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
li.current{
|
li.current{
|
||||||
a {
|
a {
|
||||||
background-color: @navbar-toctree-l1-sel-bg;
|
background-color: @navbar-toctree-l1-sel-bg;
|
||||||
border-bottom: solid 1px @light-grey;
|
border-bottom: solid 1px @light-grey;
|
||||||
border-left: solid 2px @grey;
|
border-left: solid 2px @grey;
|
||||||
color: @navbar-toctree-l1-sel-txt;
|
color: @navbar-toctree-l1-sel-txt;
|
||||||
}
|
}
|
||||||
a:hover {
|
a:hover {
|
||||||
color: @orange;
|
color: @orange;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
li.toctree-l2 {
|
li.toctree-l2 {
|
||||||
a {
|
a {
|
||||||
border: none;
|
border: none;
|
||||||
background-color: @navbar-toctree-l2-bg;
|
background-color: @navbar-toctree-l2-bg;
|
||||||
color: @navbar-toctree-l2-txt;
|
color: @navbar-toctree-l2-txt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
a:hover {
|
a:hover {
|
||||||
color: @orange;
|
color: @orange;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ul.list {
|
ul.list {
|
||||||
li {
|
li {
|
||||||
display: inline;
|
display: inline;
|
||||||
line-height: 1.6em;
|
line-height: 1.6em;
|
||||||
font-size: 1.28em;
|
font-size: 1.28em;
|
||||||
text-transform: lowercase;
|
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 {
|
main {
|
||||||
|
2
theme/static/stylesheet/style.min.css
vendored
2
theme/static/stylesheet/style.min.css
vendored
File diff suppressed because one or more lines are too long
@ -70,7 +70,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<aside>
|
<aside>
|
||||||
<div>
|
<div class="title">
|
||||||
<!--
|
<!--
|
||||||
<a href="{{ SITEURL }}">
|
<a href="{{ SITEURL }}">
|
||||||
{% if SITELOGO %}
|
{% if SITELOGO %}
|
||||||
@ -86,9 +86,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
{% if TOCTREE %}
|
{% if TOCTREE %}
|
||||||
{% include "partial/toctree.html" %}
|
{% include "partial/toctree.html" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if pages or LINKS%}
|
{% if pages or LINKS%}
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
@ -106,8 +106,12 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
{% if TAG_CLOUD %}
|
||||||
|
{% include "partial/tagcloud.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</aside>
|
</aside>
|
||||||
<main>
|
<main>
|
||||||
{% if MAIN_MENU %}
|
{% if MAIN_MENU %}
|
||||||
|
15
theme/templates/partial/tagcloud.html
Normal file
15
theme/templates/partial/tagcloud.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<div class="tagcloud">
|
||||||
|
<h2>Thèmes</h2>
|
||||||
|
<ul>
|
||||||
|
{% for tag in tag_cloud %}
|
||||||
|
<li class="tag-{{ tag.1 }}">
|
||||||
|
<a href="{{ SITEURL }}/{{ tag.0.url }}">
|
||||||
|
{{ tag.0 }}
|
||||||
|
{% if TAG_CLOUD_BADGE %}
|
||||||
|
<span class="badge">{{ tag.2 }}</span>
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
Loading…
Reference in New Issue
Block a user