This blog has now moved to Amazon Amplify. It’s connected to a Bitbucket git repository, and AWS pulls it as soon as it’s pushed. Previously, I was polling the repository manually on a VPS, but this is much quicker.
Setting your domain name for Amplify requires:
- Writing a
CNAMErecord to prove ownership. - Modifying the
ALIASandCNAMErecords of@andwwwto a CloudFront URL provided to you. This automatically enables HTTPS for your site. My domains are in Namecheap, but AWS advertises that using Route 53 is much simpler.
- Writing a
I wrote a script to convert from Pelican’s front matter to YAML front matter used in Hugo. It receives a filename argument (e.g.,
a/index.md) and converts the header to YAML format, backing up the old file asa/index.md.old. For my Turkish blog, it converted about 400 posts quickly. Hugo gives errors in YAML headers with quotation marks, but there were only a few, and I corrected them manually.
```python
#!/usr/bin/python3
import sys
import re
from dateutil import parser
import datetime
import os
fn = sys.argv[1]
fread = open(fn, encoding="utf-8")
lines = fread.readlines()
fread.close()
fmorig = []
for i, l in enumerate(lines):
if len(l.strip()) == 0:
blank_line_i = i
break
else:
fmorig.append(l)
print(fmorig)
fmtarget = {}
for fm in fmorig:
if fm.startswith('Date'):
dt = parser.parse(fm[5:].strip())
fmtarget['date'] = dt
expiryDate = dt + datetime.timedelta(days=365)
fmtarget['expiryDate'] = expiryDate
elif fm.startswith('Title'):
fmtarget['title'] = fm[6:].strip()
elif fm.startswith('Author'):
fmtarget['author'] = fm[7:].strip()
elif fm.startswith('Image'):
imageName = fm[6:].strip().split('/')[2]
fmtarget['image'] = "/images/{}".format(imageName)
elif fm.startswith('Status'):
fmtarget['status'] = fm[7:].strip()
elif fm.startswith('Dp'):
fmtarget['dp'] = fm[3:].strip()
elif fm.startswith('Tags'):
fmtarget['tags'] = fm[5:].strip().split(',')
else:
fmtarget[fm] = fm
dt = fmtarget['date']
dn, bn = os.path.split(fn)
newfrontmatter = """---
title: "{title}"
date: {dt}
expiryDate: {expiryDate}
dp: {dp}
featured_image: "{image}"
images: ["{image}"]
published: {status}
tags: [{tags}]
---
""".format(title=fmtarget['title'],
dt=fmtarget['date'].strftime("%F %H:%M:%S"),
expiryDate = fmtarget['expiryDate'].strftime("%F %H:%M:%S"),
dp = fmtarget['dp'],
image = fmtarget['image'],
status = "true" if fmtarget['status'] == "published" else "false",
tags = ",".join(fmtarget['tags']) if 'tags' in fmtarget else '')
newcontent="""{}
{}
""".format(newfrontmatter, "".join(lines[blank_line_i:]))
print(newfrontmatter)
backup_filename = fn + ".old"
os.rename(fn, backup_filename)
fwrite = open(fn, mode="w", encoding="utf-8")
fwrite.write(newcontent)
fwrite.close()
DEFAULT- For my ebooks in Turkish, I created two covers using Canva. The results are pleasing.
- I wanted to use the former site’s RSS configuration that outputs the feed data to
rss.xml. This seems doable but unnecessarily complex in Hugo.
To achieve this, add the following to config.toml:
[outputs]
home = [ "RSS", "HTML"]
[outputFormats]
[outputFormats.RSS]
mediatype = "application/rss"
baseName = "rss"
TOML- I created two Firefox searches similar to DuckDuckGo bangs. Typing
!gin the omnibar makes a Google search, and!pbsearches my Pinboard bookmarks. This avoids a roundtrip from DuckDuckGo if I’m already using the browser.
To make an S3 bucket public, add the following to the Bucket Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::subdomain.example.com/*"
}
]
}
JSONIt’s possible to give permissions to subfolders by right-clicking on them, but for the entire bucket, you need to write this policy.
- Python’s
datetime.timedeltadoesn’t have ayearsparameter. It acceptsweeksas the longest period, as it’s the longest unambiguous period of 7 days.