このブログの現在の運営方法

ブログ運営Web

メモ程度に、このブログを現在どう運営しているかをまとめ。まず、もともとはどこかにサーバーを有料で借りていましたが、静的なサイトなのもあり、GitHub Pagesに置くようにしました。ドメインだけ取得して、入れ替えてます。なので、記事の更新などは直接git pushして毎度やっている形になります。記事の執筆などはVSCodeでやっています。ほぼ完全にhtmlだけのサイトなので、特に何も考えずに書けます。ただ、記事の更新に伴うリンクの更新(blog.htmlの更新、twitter og tagの更新)、などは手動でやっていました。まあ、ほぼテンプレ化していてコストは少ないのですが、やっぱり少し面倒です。

なので、Pythonスクリプトを書いて、ある記事のtitle, contentだけ書けば、git push時にリンクやメタタグの更新、blog.htmlの一覧の更新などを自動でやってくれるようにしました。これで、最終的に更新する場所は記事のHTML内の本文とタイトル部分だけになります。こういうのは地味にいいですね。

もう一個、静的なサイトですが強引にやろうと思っているのはカテゴリ機能の実装です。普通はうしろにバックエンドのシステムがあって、そこにクエリ投げて該当する記事を返す、とかすると思います。が、今やろうと思っているのは完全にstaticで、記事の中身にcategory欄を用意して、タイトル、記事、カテゴリを同時に更新し、カテゴリを全てのブログ記事から毎回集計し、category/XXXX.htmlの中にそのカテゴリの記事の一覧をgit pushのたびに毎回一覧で生成する、というものです。シンプルですが効果的でしょ?時間あればやってみたいと思います。やはりカテゴリ分けは記事を見る側からも楽しいと思いますし、いいっすよね。

本来ならバックエンドサーバが動的に生成するんだと思いますが、記事が更新時しか変わらないという性質上、まったく同じ機能が達成できそうですよね。コメントとか、そういうリアルタイムのものが絡むと無理ですが。

以下にそのscriptを置きます。


import os
import datetime
# several postprocessing when git push
# TODAY format: mmdd, should add 0 in front of single digit
TODAY = datetime.datetime.now().strftime("%m%d")
print(f'Postprocessing for {TODAY}')
"""
1. search "./blogs/2023/ready.html" and rename it to today's date such as "./blogs/2023/0121.html"
"""
def rename_ready_file():
    ready_file = "./blogs/2023/ready.html"
    if os.path.exists(ready_file):
        os.rename(ready_file, "./blogs/2023/" + TODAY + ".html")

"""
2.open the file and replace the date in the file, specifically, replace this meta tag
    <meta
      property="og:url"
      content="http://www.takagrow.com/blogs/20XX/XXXX.html"
    />
    with
    <meta
        property="og:url"
        content="http://www.takagrow.com/blogs/{current_year}/{today}.html"
    />
    such as
    <meta
        property="og:url"
        content="http://www.takagrow.com/blogs/2023/0121.html"
    />
"""
def replace_meta_tag():
    with open("./blogs/2023/" + TODAY + ".html", "r") as f:
        lines = f.readlines()
        for line in lines:
            # update the next line of the line that contains "og:url"
            if "og:url" in line:
                print(f"found og:url, line: {line}")
                print(f'before replace: {lines[lines.index(line) + 1]}')
                idx = lines.index(line)
                lines[idx + 1] = lines[idx + 1].replace("XXXX", TODAY)
                lines[idx + 1] = lines[idx + 1].replace("20XX", "2023")
                print(f'after replace: {lines[lines.index(line) + 1]}')
                break
    with open("./blogs/2023/" + TODAY + ".html", "w") as f:
        f.writelines(lines)
"""
3. update the title in the article
    get the first content of <h1> tag and replace the title in the meta tag that contains "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"""
def update_title() -> str:
    title = ''
    with open("./blogs/2023/" + TODAY + ".html", "r") as f:
        lines = f.readlines()
        for line in lines:
            if "<h1>" in line:
                print(f"found <h1>, line: {line}")
                title = line.split(">")[1].split("<")[0]
                print(f"title: {title}")
                break
    with open("./blogs/2023/" + TODAY + ".html", "r") as f:
        lines = f.readlines()
        for line in lines:
            # 1. update <title> tag
            if "<title>" in line:
                # update next line
                print(f"found <title>, line: {line}")
                idx = lines.index(line)
                lines[idx + 1] = lines[idx + 1].replace("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", title)
            if "og:title" in line:
                print(f"found og:title, line: {line}")
                idx = lines.index(line)
                lines[idx + 1] = lines[idx + 1].replace("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", title)
            if "og:description" in line:
                print(f"found og:description, line: {line}")
                idx = lines.index(line)
                lines[idx + 1] = lines[idx + 1].replace("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", title)
    with open("./blogs/2023/" + TODAY + ".html", "w") as f:
        f.writelines(lines)
    return title

"""
4. update ./blog.html
    insert a new strings in this format
    `{month}/{date}: <a href="blogs/2023/{today}.html">{title}</a><br>`
    right after this line
    `<span style="display: none">XXXX: <a href="blogs/2023/XXXX.html">XXXX</a><br></span>`
"""
def update_blog_html(title: str):
    with open("./blog.html", "r") as f:
        lines = f.readlines()
        for line in lines:
            if '<span style="display: none">XXXX: <a href="blogs/2023/XXXX.html">XXXX</a><br></span>' in line:
                print(f"found separator, line: {line}")
                update_str = f'{TODAY[:2]}/{TODAY[2:]}: <a href="blogs/2023/{TODAY}.html">{title}</a><br>'
                idx = lines.index(line)
                # if duplicate, do not insert
                if update_str in lines[idx + 1]:
                    break
                else:
                    # insert after the separator and new line
                    lines.insert(idx + 1, update_str + "\n")
                break
    with open("./blog.html", "w") as f:
        f.writelines(lines)

if __name__ == "__main__":
    rename_ready_file()
    replace_meta_tag()
    title = update_title()
    update_blog_html(title)