Created
November 23, 2022 18:46
-
-
Save mikeckennedy/20a205602111ac32dbfb61544f15a488 to your computer and use it in GitHub Desktop.
Python script to build a tag cloud for Hugo websites
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# You need to write a topics_template.md file with the [TOPIC_CLOUD] in the location to have the tag cloud injected. | |
# You also need to add topics.md to your config.toml for Hugo. | |
# This will read content/posts/*.md and pull out 'tags' from the frontmatter section to create topics.md | |
from collections import Counter | |
import json | |
from pathlib import Path | |
def main(): | |
topics = count_topics() | |
tag_text = build_tag_text(topics) | |
text = get_template_text() | |
new_topics_text = text.replace('[TOPIC_CLOUD]', tag_text) | |
write_topics_file(new_topics_text) | |
print("Wrote to topics.md") | |
def write_topics_file(topics_text: str): | |
topics_file = Path(__file__).parent.parent / "mksite" / "content" / "topics.md" | |
topics_file.write_text(topics_text) | |
def build_tag_text(topics: list[str]): | |
c = Counter(topics) | |
counted_topics = c.most_common() | |
print("Generated topics list:") | |
print(counted_topics) | |
text = "" | |
max_count = max(ct[1] for ct in counted_topics) | |
min_count = min(ct[1] for ct in counted_topics) | |
max_em = 2.5 | |
min_em = .75 | |
for tag, count in counted_topics: | |
tag = tag.replace(' ', '-').lower().strip() | |
ratio = count/(max_count-min_count) | |
em = (max_em - min_em)*ratio | |
# text += f"- [{count}] [{tag}](/tags/{tag}/)\n" | |
text += f'<a style="margin: 10px; font-size: {em}em;" class="badge-tag tag badge" href="/tags/{tag}/">{tag}</a>' | |
return text | |
def count_topics() -> list[str]: | |
all_tags = [] | |
posts_folder = Path(__file__).parent.parent / "mksite" / "content" / "posts" | |
for file in posts_folder.glob("*.md"): | |
tags = get_tags_from_file(file) | |
all_tags.extend(tags) | |
all_tags.sort() | |
return all_tags | |
def get_tags_from_file(file: Path) -> list[str]: | |
for line in file.read_text().splitlines(): | |
if line.startswith("tags: ["): | |
fake_json = '{"tags": ' + line[5:].replace("'", '"') + "}" | |
tags = json.loads(fake_json)["tags"] | |
return tags | |
return [] | |
def get_template_text() -> str: | |
template_file = Path(__file__).parent / "topics_template.md" | |
template_md = template_file.read_text() | |
return template_md | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See it in action at https://mkennedy.codes/topics/