|
1
|
""" |
|
2
|
Patches common Hugo deprecations in theme layout files so they work with Hugo >= v0.128. |
|
3
|
|
|
4
|
Call patch_theme(theme_dir) after copying theme files to the output directory. |
|
5
|
""" |
|
6
|
|
|
7
|
import logging |
|
8
|
import os |
|
9
|
import re |
|
10
|
|
|
11
|
# Map of (pattern, replacement) for deprecated Hugo template variables/functions |
|
12
|
TEMPLATE_PATCHES = [ |
|
13
|
# .Site.DisqusShortname → .Site.Config.Services.Disqus.Shortname |
|
14
|
(r'\.Site\.DisqusShortname', '.Site.Config.Services.Disqus.Shortname'), |
|
15
|
# .Site.GoogleAnalytics → .Site.Config.Services.GoogleAnalytics.ID |
|
16
|
(r'\.Site\.GoogleAnalytics\b', '.Site.Config.Services.GoogleAnalytics.ID'), |
|
17
|
# absLangURL → absLangURL still works but absURL is preferred for simple cases |
|
18
|
# safeHTMLAttr is fine, no change needed |
|
19
|
] |
|
20
|
|
|
21
|
# Config key patches: (old_pattern, replacement) |
|
22
|
CONFIG_PATCHES = [ |
|
23
|
# paginate → [pagination] pagerSize |
|
24
|
(r'^paginate\s*=\s*(\d+)$', r'[pagination]\n pagerSize = \1'), |
|
25
|
# googleAnalytics = "UA-xxx" → [services.googleAnalytics] id = "UA-xxx" |
|
26
|
(r'^googleAnalytics\s*=\s*"([^"]+)"', r'[services.googleAnalytics]\n id = "\1"'), |
|
27
|
# disqusShortname = "xxx" → [services.disqus] shortname = "xxx" |
|
28
|
(r'^disqusShortname\s*=\s*"([^"]+)"', r'[services.disqus]\n shortname = "\1"'), |
|
29
|
] |
|
30
|
|
|
31
|
|
|
32
|
def patch_theme(theme_dir: str): |
|
33
|
"""Patch deprecated Hugo APIs in all layout files under theme_dir/layouts/.""" |
|
34
|
layouts_dir = os.path.join(theme_dir, 'layouts') |
|
35
|
if not os.path.isdir(layouts_dir): |
|
36
|
return |
|
37
|
|
|
38
|
patched = 0 |
|
39
|
for root, dirs, files in os.walk(layouts_dir): |
|
40
|
for fname in files: |
|
41
|
if not fname.endswith('.html'): |
|
42
|
continue |
|
43
|
path = os.path.join(root, fname) |
|
44
|
with open(path, 'r', errors='replace') as f: |
|
45
|
content = f.read() |
|
46
|
|
|
47
|
new_content = content |
|
48
|
for pattern, replacement in TEMPLATE_PATCHES: |
|
49
|
new_content = re.sub(pattern, replacement, new_content) |
|
50
|
|
|
51
|
if new_content != content: |
|
52
|
with open(path, 'w') as f: |
|
53
|
f.write(new_content) |
|
54
|
patched += 1 |
|
55
|
|
|
56
|
if patched: |
|
57
|
logging.info(f"Patched {patched} template file(s) in {theme_dir}") |
|
58
|
|
|
59
|
|
|
60
|
def patch_config(config_path: str): |
|
61
|
"""Patch deprecated keys in a hugo.toml / config.toml file.""" |
|
62
|
with open(config_path, 'r') as f: |
|
63
|
content = f.read() |
|
64
|
|
|
65
|
new_content = content |
|
66
|
for pattern, replacement in CONFIG_PATCHES: |
|
67
|
new_content = re.sub(pattern, replacement, new_content, flags=re.MULTILINE) |
|
68
|
|
|
69
|
if new_content != content: |
|
70
|
with open(config_path, 'w') as f: |
|
71
|
f.write(new_content) |
|
72
|
logging.info(f"Patched deprecated config keys in {config_path}") |
|
73
|
|