Skip to content

Commit 1940d17

Browse files
authored
Merge pull request #90 from weeklydevchat/feature/update-create-post-scripts-with-tags-and-categories
Add categories and tags placeholders in create post scripts. Also add a script to show existing tags/categories.
2 parents 6c9ce04 + 6884682 commit 1940d17

4 files changed

Lines changed: 157 additions & 14 deletions

File tree

README.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,13 @@ These scripts will:
9797
authors:
9898
- chris
9999
categories:
100-
- Category Name
100+
# use existing categories when possible, in YAML list format.
101+
- CATEGORY_ONE
102+
- CATEGORY_TWO
101103
tags:
102-
- relevant-tag
104+
# use existing tags when possible, in YAML list format.
105+
- TAG_ONE
106+
- TAG_TWO
103107
---
104108
```
105109

@@ -116,11 +120,21 @@ These scripts will:
116120

117121
### Categories and Tags
118122

119-
Categories are broad topic groupings and tags are specific topic labels for filtering. New categories and tags can be added as needed — these are the ones currently in use.
123+
Categories are broad topic groupings and tags are specific topic labels for filtering. **Please use existing categories and tags when possible** to keep the taxonomy consistent. New ones can be added when truly needed.
120124

121-
**Categories**: Business, Career, Community, Culture, Security, Technical
125+
To see all categories and tags currently in use, run:
122126

123-
**Tags**: `administration`, `advent-of-code`, `advent-of-cyber`, `agile`, `ai`, `architecture`, `branding`, `cancelled`, `career`, `change-management`, `claude`, `code-quality`, `coding-challenges`, `coding-practices`, `community`, `conferences`, `creativity`, `ctf`, `culture`, `curriculum`, `cybersecurity`, `data`, `databases`, `design-patterns`, `devops`, `editors`, `education`, `entrepreneurship`, `ergonomics`, `estimation`, `ethics`, `events`, `finance`, `github-copilot`, `goals`, `gratitude`, `growth`, `habits`, `hacktoberfest`, `hardware`, `health`, `hiring`, `history`, `holiday`, `industry`, `infrastructure`, `innovation`, `inspiration`, `irl`, `job-market`, `learning`, `local-tech`, `marketing`, `meetup`, `meetups`, `metaphors`, `methodology`, `metrics`, `mob-programming`, `motivation`, `naming`, `networking`, `open-discussion`, `open-source`, `optimization`, `organizations`, `pair-programming`, `performance`, `philosophy`, `picoctf`, `predictions`, `priorities`, `privacy`, `productivity`, `project-management`, `prototyping`, `quality-assurance`, `reflection`, `remote-work`, `resilience`, `security`, `self-hosting`, `self-improvement`, `side-projects`, `society`, `supply-chain`, `surveys`, `swap-meet`, `systems`, `tdd`, `teaching`, `teamwork`, `technology`, `testing`, `thinking`, `time-management`, `tools`, `trends`, `unconference`, `version-control`, `watch-party`, `wellness`, `work-life-balance`, `workplace`, `workspace`, `year-in-review`
127+
**Bash (Linux/macOS)**:
128+
```bash
129+
python3 scripts/find_tags_categories.py
130+
```
131+
132+
**PowerShell (Windows)**:
133+
```powershell
134+
python scripts/find_tags_categories.py
135+
```
136+
137+
This script requires `pyyaml`, which is included in `requirements.txt`. It is also run automatically by the `create_post` scripts when scaffolding a new post.
124138

125139
## Project Structure
126140

@@ -131,6 +145,8 @@ Categories are broad topic groupings and tags are specific topic labels for filt
131145
├── docker-compose.yml # Docker development environment
132146
├── create_post.sh # Bash script to create blog posts
133147
├── create_post.ps1 # PowerShell script to create blog posts
148+
├── scripts/
149+
│ └── find_tags_categories.py # List all existing tags and categories
134150
├── .github/
135151
│ ├── dependabot.yml # Dependabot configuration
136152
│ └── workflows/

create_post.ps1

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ title: "$title"
4343
date: $date
4444
authors:
4545
- chris | norm | omar
46+
categories:
47+
# use existing categories when possible, in YAML list format.
48+
- CATEGORY_ONE
49+
- CATEGORY_TWO
50+
tags:
51+
# use existing tags when possible, in YAML list format.
52+
- TAG_ONE
53+
- TAG_TWO
4654
---
4755
4856
TOPIC_INTRODUCTION_HERE
@@ -55,4 +63,17 @@ Everyone and anyone are welcome to [join](https://weeklydevchat.com/join/) as lo
5563
# Write the content to the file
5664
Set-Content -Path $filePath -Value $yamlContent
5765

58-
Write-Output "Blog post template created at $filePath"
66+
Write-Output "Blog post template created at $filePath"
67+
Write-Output ""
68+
Write-Output "Reminder: Use existing categories and tags when possible."
69+
# Optionally suggest existing tags and categories using the helper script, if available
70+
$pythonCmd = Get-Command python -ErrorAction SilentlyContinue
71+
if ($null -ne $pythonCmd) {
72+
& python "./scripts/find_tags_categories.py"
73+
if ($LASTEXITCODE -ne 0) {
74+
Write-Warning "python ./scripts/find_tags_categories.py exited with code $LASTEXITCODE. The blog post file was created, but tag/category suggestions may be unavailable."
75+
}
76+
}
77+
else {
78+
Write-Warning "Python was not found on this system. Skipping tag/category suggestion step."
79+
}

create_post.sh

100644100755
Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
#!/bin/bash
22

33
# Calculate the next Tuesday (or today if it's Tuesday)
4-
# In Linux date, weekday: 0=Sunday, 1=Monday, ..., 6=Saturday
54
current_weekday=$(date +%w) # 0=Sun ... 6=Sat
65
days_to_tuesday=$(( (2 - current_weekday + 7) % 7 ))
76

8-
# If today is Tuesday, days_to_tuesday will be 0 → perfect
9-
# Add the calculated days
10-
tuesday=$(date -d "+${days_to_tuesday} days" +%Y-%m-%d)
7+
# Add the calculated days (compatible with both macOS and Linux)
8+
if date -v +0d &>/dev/null; then
9+
# macOS (BSD date)
10+
tuesday=$(date -v "+${days_to_tuesday}d" +%Y-%m-%d)
11+
else
12+
# Linux (GNU date)
13+
tuesday=$(date -d "+${days_to_tuesday} days" +%Y-%m-%d)
14+
fi
1115

12-
year=$(date -d "$tuesday" +%Y)
13-
month=$(date -d "$tuesday" +%02m)
14-
day=$(date -d "$tuesday" +%02d)
16+
year=${tuesday%%-*} # 2026
17+
month=${tuesday#*-}; month=${month%-*} # 02
18+
day=${tuesday##*-} # 24
1519

1620
# Define paths
1721
folder_path="docs/posts/$year/$month/$day"
@@ -27,6 +31,14 @@ title: "Your Blog Post Title"
2731
date: $tuesday
2832
authors:
2933
- chris | norm | omar
34+
categories:
35+
# use existing categories when possible, in YAML list format.
36+
- CATEGORY_ONE
37+
- CATEGORY_TWO
38+
tags:
39+
# use existing tags when possible, in YAML list format.
40+
- TAG_ONE
41+
- TAG_TWO
3042
---
3143
3244
TOPIC_INTRODUCTION_HERE
@@ -36,4 +48,14 @@ Everyone and anyone are welcome to [join](https://weeklydevchat.com/join/) as lo
3648
![alt text](${tuesday}_image_filename.webp)
3749
EOF
3850

39-
echo "Blog post template created at $file_path"
51+
echo "Blog post template created at $file_path"
52+
echo ""
53+
echo "Reminder: Use existing categories and tags when possible."
54+
55+
# Optionally suggest existing tags and categories using the helper script, if available
56+
if command -v python3 &>/dev/null; then
57+
python3 "./scripts/find_tags_categories.py" || echo "Warning: tag/category suggestion script failed, but the blog post file was created."
58+
else
59+
echo "Warning: Python 3 was not found on this system. Skipping tag/category suggestion step."
60+
fi
61+

scripts/find_tags_categories.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Lists all unique tags and categories found in YAML front matter of .md files.
4+
Looks for both 'tags' and 'categories' keys (common variations).
5+
"""
6+
7+
import yaml
8+
from pathlib import Path
9+
from typing import Any
10+
11+
DOCS_DIR = Path(__file__).parent.parent / "docs"
12+
EXTENSIONS = (".md", ".markdown", ".mkd")
13+
14+
15+
def extract_frontmatter(file_path: Path) -> dict[str, Any]:
16+
"""Extract YAML front matter if present."""
17+
content = file_path.read_text(encoding="utf-8")
18+
if not content.startswith("---"):
19+
return {}
20+
try:
21+
parts = content.split("---", 2)
22+
if len(parts) < 3:
23+
return {}
24+
fm = yaml.safe_load(parts[1])
25+
if not isinstance(fm, dict):
26+
return {}
27+
return fm
28+
except yaml.YAMLError:
29+
print(f"Warning: Invalid YAML in {file_path}")
30+
return {}
31+
32+
33+
def collect_tags() -> tuple[set[str], set[str]]:
34+
all_tags = set()
35+
all_categories = set()
36+
37+
docs_path = Path(DOCS_DIR)
38+
if not docs_path.is_dir():
39+
print(f"Error: Directory not found: {docs_path}")
40+
return all_tags, all_categories
41+
42+
for file_path in docs_path.rglob("*"):
43+
if not file_path.is_file() or file_path.suffix.lower() not in EXTENSIONS:
44+
continue
45+
46+
fm = extract_frontmatter(file_path)
47+
48+
tags = fm.get("tags") or []
49+
if isinstance(tags, str):
50+
tags = [tags]
51+
elif not isinstance(tags, list):
52+
tags = []
53+
all_tags.update(str(t).strip() for t in tags if t)
54+
55+
cats = fm.get("categories") or []
56+
if isinstance(cats, str):
57+
cats = [cats]
58+
elif not isinstance(cats, list):
59+
cats = []
60+
all_categories.update(str(c).strip() for c in cats if c)
61+
62+
all_tags.discard('TAG_ONE')
63+
all_tags.discard('TAG_TWO')
64+
all_categories.discard('CATEGORY_ONE')
65+
all_categories.discard('CATEGORY_TWO')
66+
67+
return all_tags, all_categories
68+
69+
70+
def main() -> None:
71+
tags, categories = collect_tags()
72+
73+
print("\nExisting categories:")
74+
for cat in sorted(categories):
75+
print(f" {cat}")
76+
print(f"\nExisting tags:")
77+
for tag in sorted(tags):
78+
print(f" {tag}")
79+
80+
81+
if __name__ == "__main__":
82+
main()
83+
84+

0 commit comments

Comments
 (0)