CMS を作ってみる 【Python】

Python

Python を使って、CMS (contents management system) を自作してみることにします。
できる限りシンプルな構成とすることにします。

以下の2つの環境で動作することを確認しています。
環境1: Windows パソコン、Microsoft Edge
・ Python 3 のインストール済み
環境2: Raspberry Pi (bookworm、Linux、Web サーバーとして起動)

背景 ~ CMS を作ってみる

日頃、備忘メモは、パソコン内にテキストファイルで保存することが多いです。しかし、テキストファイルが増えてくると、参照する際にフォルダをクリックして探す手間が増えていきます。
よく参照するテキストは HTML 化して、ブラウザのお気に入りから参照できると便利です。

また、自宅の Wi-Fi のローカルネットワークでは、Linux(Raspberry Pi)を Web サーバーとして活用しています。ローカルで Web サーバーを日々使っていると、よく参照する情報はテキストファイルの形でフォルダに放り込んでおき、ブラウザから参照できると便利です。URL のリンクを書き出しておくと1クリックでジャンプできるようになっていても便利です。

ということで、Python を使って、シンプルな CMS (contents management system)を作ってみることにします。

スクリプト内でテキストファイルを入れたフォルダを指定しておくと、ファイルを読み込んで、Web サイト用の HTML ファイル一式を生成するようにします。
生成した HTML ファイルは、トップページ(index.html)をブラウザのお気に入りにいれてローカルでも使えるようにします。また、HTML のファイルが入ったフォルダをネットワーク内の Web サーバーにコピーすると、Web サイトとしても機能するようにします。

なお、下記のサンプルは、スタンドアロンのパソコンやローカルネットワーク内など、小規模での使用を想定しています。バックアップなど不特定/多数の人々が使う機能は実装していませんので、ご理解をいただきますようお願いします。

基本的な考え方

・ 元データを、カテゴリーごとのフォルダに入れたテキストファイル程度のものとすることで、データを軽くし、設定やバックアップ、移植の手間を最小化するものとします。
・ Python のスクリプト内でフォルダを指定しておくと、フォルダ内のテキストファイルを取得し、対応する HTML を生成するようにします。
・ 加えて、全体のトップページ用の HTML 、各フォルダごとのトップページとなる HTML を生成します。
・ 出力された HTML ファイルは、相互にリンクが設定された程度のシンプルなものとします。
ファイル間の階層構造や依存関係をできるだけ排除・簡素化したものとします。
・ サイトにアクセスしたときの動的な処理も排除します。静的な HTML ファイルとリンクの機能程度でサイト全体を構成するようにします。
・ 上記により、環境に強く依存することなく、サイトの設定や利用がシンプルになるようにします。
ルートディレクトリに入れる HTML ファイルを一式、コピーする程度で、任意のサーバー上で容易にサイトが構築できるようにします。データベースや PHP など、ソフトウェアのインストールや設定も最小化します。
・ 動的な処理を排除することで、ブルートフォース攻撃やインジェクション攻撃などのサイバー攻撃のリスクや対応の手間も最小化します。

設定方法

① 以下を参考に、パソコン内に CMS を扱うためのフォルダ(例:cms1)を作成します。
例: c:\user\cms1
② ①のフォルダ内に、”templates1″、”html1″、”category1″、”category2″ という名前でフォルダを作成します。
さらに、”html1″ フォルダの中に “media1” という名前でフォルダを作成します。
③ 以下の構成となるようテキストファイルを作成し、末尾の各ファイルをコピー&ペーストで保存します。

Python のスクリプト
c:\user\cms1\contents_management_system1.py

テンプレート用フォルダとテンプレートファイル(計4つ)
c:\user\cms1\templates1\index1.html
c:\user\cms1\templates1\header1.html
c:\user\cms1\templates1\aside1.html
c:\user\cms1\templates1\footer1.html

出力用フォルダとメディア用フォルダ(計2つ)
c:\user\cms1\html1
c:\user\cms1\html1\media1

カテゴリー分け用フォルダとテキストファイルのサンプル(一例として)
c:\user\cms1\html1\category1\text1.txt、text2.txt
c:\user\cms1\html1\category2\text3.txt

④ ③の Python のスクリプトを実行します。
例: python c:\user\cms1\contents_management_system1.py

→ 上記の “html1” フォルダ内に HTML ファイルの一式が生成されたら成功です。

※ index.html がトップ画面の HTML ファイルです。ダブルクリックして確認してください。
※ この “html1” フォルダをコピーすることで、サイト用のデータ一式を簡単に作成・移植・設定できます。

うまく動いたら

うまく動いたら、ページの修正・追加をしてみてください。
また、サイト上部のヘッダー部分の文字列やカラーなど、サイトのデザインをカスタマイズしてみてください。
カスタマイズのポイントを以下にまとめておきます。

カスタマイズ方法

ページの追加・修正

・ category1、category2 フォルダにテキストファイルを追加、修正、削除し、スクリプトを再度実行してみてください。記事を追加、修正等することができます。

・ Python のスクリプトを実行すると、テキストファイルの拡張子 “*.txt” を “.html” に変更し、出力用のフォルダ “html1″ にファイルが出力されます。
一例として、category1 フォルダに、テキストファイル text1.txt を追加したとすると、html1 フォルダ内に text1.html という名前でファイルを作成します。
・ ここでもし、ファイル名に重複が生じた場合は、重複がなくなるよう、text1_2.html というように付番をつけたファイル名として保存します。
このときの HTML のファイル名(text1 の部分)や作成日が、リンクをつけて、サイドバーに表示されるようにしてあります。

・ また、テキストファイル内で、日付、タイトル、パーマネントリンクが指定してあった場合は、指定された内容に差し替えて、HTML ファイルを生成します。記載方法は、末尾の記載例1を参照してください。

パーマネントリンクは、記事の URL に対応する文字列です。上記の例では、text1 の部分に対応しています。ユーザーが自由に設定できるようにしてあります。文書の内容に対応した URL の記載ルールを決めておくことで、文書管理が容易になります。また、他の文書からリンクを設定する場合にも、URL の記載をわかりやすくしておくことで、文書を判別しやすくなります。SEO 対策の点からも有利といわれています。

・ なお、タイトルの指定で空欄を指定しておくと、サイドバーでタイトルを表示をしないように設定することができます。たとえば、以下の例で、トップページをカスタマイズするときは、トップページへのリンクはヘッダー部分だけでよいため、”title1: ” としておくことで、サイドバーでは非表示となるよう設定できます。

画像・音楽・動画の追加

画像の表示、音楽・動画の再生も可能です。
画像・音楽・動画を使う場合、あらかじめ、使用したい画像、音楽、動画を media1 フォルダ内に入れておいてください。
以下の記載例3に、テキストファイルでの書き方の例を挙げておきましたので、画像ファイル名等を差し替えて、画像の表示、音楽・動画の再生をしてみてください。

トップページのカスタマイズ

・ ページ全体のトップページは index.html としています。
HTML の各ページで、上部のヘッダー部分をクリックすると、トップページ index.html に遷移します。このトップページをブラウザのお気に入りに登録しておくことで、生成したサイトをブラウザ経由で活用できるようになります。
・ この index.html は、デフォルトでは空欄となっていますが、文字列や画像を入れることが可能です。
具体的には、category1 フォルダ内などに、index.txt という名前でテキストファイルを作成し、文字列や画像を設定しておきます。
Python のスクリプトを実行すると、拡張子を入れ替えて index.html という名前で HTML ファイルを生成しますので、それがそのままトップページとなります。index.html が作られていない場合は、メイン領域を空欄とした index.html を生成するようにしています。

・ 同様に、ページ上部のヘッダー部分で「カテゴリー1」、「カテゴリー2」をクリックすると、category1.html、category2.html といった各カテゴリーごとのトップページにジャンプします。
これらのページにも同様に文字や画像を設定できます。
具体的には、category1 フォルダ内に category1.txt という名前でテキストファイルを作成し、文字列や画像を設定しておきます。すると、category1.html が生成され、「カテゴリー1」をクリックした際にこのページにジャンプします。
category2 フォルダ内に category2.txt というファイルを作成しても同様です。
このように、「カテゴリー1」、「カテゴリー2」をクリックした際に表示されるページを自由にカスタマイズできます。
・ これらの「category1」、「category2」といった参照フォルダ名や、「カテゴリー1」、「カテゴリー2」といった画面上の文字は、Python のスクリプトで定義しています。スクリプトを修正することで、表示を変更したり、参照フォルダを変更することが可能です。
・ またたとえば、”category2″ として定義しているフォルダ名の部分に、任意のフォルダのフルパスを記載します。すると、そのフォルダ内のテキストファイルを参照しにいき、HTML ファイルを生成します。
これにより、パソコン内のテキストファイルのありかを指定しておくだけで、そのデータ一式をかんたんにウェブサイト化することが可能となります。

ヘッダー文字・サイトのデザインのカスタマイズ

・ HTML ファイルのテンプレートは、templates1 フォルダ内に入れてあります。
この中のテンプレートを修正することで、ヘッダー文字やカラーなどの変更が可能です。
・ index1.html で、ページ全体のレイアウトを定義しています。
<title>…</title> とした部分で、サイトのタブの文字列を定義していますので、変更してみてください。
・ header1.html では、サイト画面の上部のヘッダー部分を定義しています。タイトル文字の文字列や、ヘッダー部分の背景色などを変更してみてください。変更したら、これらのファイルをダブルクリックすることで見栄えをブラウザで確認できます。
・ footer1.html では、サイト画面の下部のフッター部分を定義しています。文字列や背景色を編集し、デザインを修正してみてください。

・ Python のスクリプトの動きとしては、スクリプトを実行すると、各テンプレートを読み込み、index1.html で定義しである、{{header1}}、{{footer1}}、{{aside1}} とした領域に、header1.html、footer1.html、aside1.html  を差し込むことで、ページ全体のテンプレートを作っています。
・ さらに、テキストファイルの内容を読み込み、トップページやサイドバーのリンクの部分を生成し、テンプレートにそれぞれ差し込みます。
こうしてできたテンプレートに、各ページのテキストの内容を差し込んで各ページを生成しています。
・ トップページのヘッダー部分で、”カテゴリー1″、”カテゴリー2″ とした文字列は、Python のスクリプトで定義しています。作成するサイトの内容に応じて、スクリプト内の文字列を変更してください。
・ また、スクリプトの記載に倣い、”カテゴリー3″、”カテゴリー4″ などを追加等することで、ヘッダー部分の項目(フォルダ)を追加・削除することができます。
・ HTML や Python がわかる方や興味のある方は、自由にカスタマイズをしてみてください。

スクリプトの説明

・ Python のスクリプトを実行すると、まず、テキストファイルが入っているフォルダ(category1, 2 フォルダ)を取得します。
つぎに、get_list1() を実行し、これらのフォルダに入っているテキストファイルの全データを取得します。
つぎに、get_template1() を実行し、templates1 フォルダに入っている HTML ファイルから、サイトのテンプレートを作ります。
get_header_html1() としたところで、ヘッダーに挿入するためのリンクを作り、replace() を実行することで、テンプレートに挿入します。
続いて、get_aside_html1() を実行し、サイドバー用のリンクを作ります。
generate_main_pages1() を実行し、テンプレートに、サイドバー用のリンクと、テキストとを挿入していき、各記事の HTML を生成します。
generate_top_pages1() を実行し、もし、トップページ index.html と、各カテゴリーのトップページ category1.html、category2.html が作られていなければ、これらのページを生成します。

まとめ

今回は、Python を使って、シンプルな CMS を自作してみました。

メモ書き程度のテキストファイルがあれば、 HTML ファイル化することで、Windows パソコンのローカルなどで活用することが可能になりました。
また、ローカルネットワーク内の Raspberry Pi にファイル一式をコピーしてみたところ、Web サイトとしても機能するようになりました。備忘メモ程度のものであっても、日頃、参照したくなる情報を Web サイト化していけばよいことになります。

他にも、Python や HTML のプログラムをまとめ、公開しています。興味のある方は関連リンクなども参照してみてください。

関連リンク
・ Python で HTML ファイルを出力する
・ HTML の棒グラフを出力する 【Python】

・ HTML のカレンダーを生成する 【Python】
・ Python で掲示板を作ってみる 【Windows 版】

テキストファイルの記載例

category1、category2 フォルダ内にテキストファイルを作成して以下の内容で保存し、Python のスクリプトを実行してみてください。各機能の記載例となっています。

記載例1 text1.txt

##見出しの事例

# 見出し1
## 見出し2
### 見出し3

※ 冒頭を #、##、### とした行を書くことで、見出し用の文字を設定できます。

----- 
##日付、記事のタイトル、記事のURL の設定例
日付、記事のタイトル、記事のURLを設定する場合は、以下のように記載します。

--- 
date1: 2025/05/01
title1: 日付・タイトルの設定例
permanent_link1: date_title_link1 
--- 

"---" とした行の2か所で囲っておくことで
日付、記事のタイトル、記事のURL(パーマネントリンク)を指定できます。
日付、記事のタイトルの設定は、サイドバーの表示に反映されます。
パーマネントリンクの設定は、HTML のファイル名に反映されます。

---
date1: 2025/05/01
title1: 記載例1
permanent_link1: sample1
---

記載例2 text2.txt


## リンクの記載例1
"https:… " から始まる1行で URL を記載しておくと、リンクを設定します。

YouTube
https: //www.youtube.com/

----- 
## リンクの記載例2
HTML のタグを直接記載しても機能します。
```
<a href="https://www.youtube.com/" target="www1">https://www.youtube.com/</a><br>
```

-----
## コードの記載例
 ``` とした行の2か所で囲っておくと、その領域はコードとして扱います。

```
yahoo<br>
<a href="https://www.yahoo.co.jp/" target="www1">https://www.yahoo.co.jp/</a><br>
```
※ HTML のタグなどをそのまま記載できます。


---
date1: 2025/05/01
title1: 記載例2
permanent_link1: sample2
---

記載例3 text3.txt


##画像の設定例

```
<img style="width:40%; " src="./media1/sample1.svg">
```
<img style="width:40%; " src="./media1/sample1.svg">
※ 画像ファイル名を1行で記載しておいても設定できます。

##音楽の設定例

```
<audio controls>
  <source src="./media1/music1.mp3" type="audio/mpeg">
</audio>
```

<audio controls>
  <source src="./media1/music1.mp3" type="audio/mpeg">
</audio>

##動画の設定例
```
<video width="100%" controls>
  <source src="./media1/video1.mp4" type="video/mp4">
</video>
```
<video width="100%" controls>
  <source src="./media1/video1.mp4" type="video/mp4">
</video>

---
date1: 2025/05/01
title1: 記載例3
permanent_link1: sample3
---

テンプレート

以下の4つのテンプレートを templates1 フォルダ内に保存します。
サイトのデザインのベースの部分は、これらのファイルで定義をしています。

ページ全体のレイアウト用のテンプレート index1.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Contents Management System v0.01</title>
  <style>
    body { 
      background-color:#ffffff; 
      color:#000000; 
      font-size:18px; 
      font-family:Helvetica,Arial,meiryo; 
      display: grid;
      grid-template-areas:
        "header1 header1"
        "main1 aside1"
        "footer1 footer1";
      grid-template-rows: auto 1fr auto;
      grid-template-columns: 7fr 3fr;
      height: 100vh;
      margin: 0;
    }
  </style>
</head>
<body>
  <header style="grid-area:header1; width:100%; height:100px; position:fixed; z-index:1000; " >
{{header1}} 
  </header>
  <main style="grid-area:main1; margin-top:150px; margin-bottom:50px; padding-left:60px; padding-right:20px; z-index:500; " >
{{main2}} 
  </main>
  <aside style="grid-area:aside1; margin-top:150px; margin-bottom:50px; padding-left:20px; padding-right:30px; max-height:400px; overflow:auto; z-index:500; " >
{{aside1}} 
  </aside>
  <footer style="grid-area:footer1; " >
{{footer1}} 
  </footer>
</body>
</html>

ヘッダー用のテンプレート header1.html

<div style="background-color:#fffcef; color:#000000; font-size:20px; font-family:Helvetica,Arial,meiryo; overflow:hidden; ">
<a href="./index.html" style="text-decoration:none; color:inherit; ">
<h1 style="font-size:28px; margin-left:20px; ">Contents Management System v0.01</h1>
</a>
<hr style="margin-bottom:-10px; width:100%; border:1px solid #888888;"><br>
<div style="padding-left:20px; padding-right:20px; "> {{header2}} </div> 
<hr style="margin-bottom:0px; margin-top:10px; width:100%; border:1px solid #888888; ">
</div>

サイドバー用のテンプレート aside1.html

<div style="font-size:17px; font-family:Helvetica,Arial,meiryo; overflow:hidden; ">
{{aside2}} 
</div>

フッター用のテンプレート footer1.html

<div style="background-color:#333333; color:#ffffff; height:50px; text-align:right; font-size:16px; font-family:Helvetica,Arial,meiryo; display:block; padding-top:10px; padding-right:20px;  ">
&copy; 2025 Contents Management System v0.01   
</div>

サンプルスクリプト

コンテンツ管理システム contents_management_system1.py


import os 
import re 
import glob as gl1 
import datetime as dt1 
from operator import itemgetter 

def read1( file1 ): 
    str1 = ""
    with open( file1, 'r', encoding='utf-8' ) as f1: 
        str1 = f1.read() 
    return str1 

def write1( file1, str1 ): 
    with open( file1, 'w', encoding='utf-8' ) as f1: 
        f1.write( str1 ) 
    return 0 

def get_template1(path1): 
    file1 = path1 + "templates1/" + "index1.html" 
    str1 = read1(file1) 
    file1 = path1 + "templates1/" + "header1.html" 
    str2 = read1(file1) 
    str1 = str1.replace("{{header1}}", str2) 
    file1 = path1 + "templates1/" + "footer1.html" 
    str2 = read1(file1) 
    str1 = str1.replace("{{footer1}}", str2) 
    file1 = path1 + "templates1/" + "aside1.html" 
    str2 = read1(file1) 
    str1 = str1.replace("{{aside1}}" , str2) 
    return str1 

def get_yaml_dic1(str1): 
    dic1 = {} 
    a1 = str1.strip().split("\n") 
    for i1 in range(len(a1)): 
        a2 = a1[i1].split(":") 
        if len(a2) == 2: 
            val1 = a2[1].strip() 
            dic1[a2[0].strip()] = val1 if not val1.isdigit() else int(val1) 
    return dic1 

def get_yaml1(str1): 
    str2 = str1 
    str3 = "" 
    pattern1 = r"\n---\n(.*?)\n---\n"                               # yaml pattern 
    dic1 = {} 
    search1 = re.search(pattern1, str2, re.DOTALL) 
    if search1: 
        start1, end1 = search1.span() 
        str3 = (str2[:start1] + "\n" + str2[end1:]).strip()         # normal text 
        str4 = str2[start1+4 : end1-4].strip()                      # yaml 
        dic1 = get_yaml_dic1(str4) 
        str2 = str3 
    return str2, dic1 

def code_block_html1(str1): 
    str2 = f'<div style="background-color: #f4f4f4; border: 1px solid #dddddd; padding: 10px; overflow:auto; ">{str1}</div>'
    return str2 

def code_block1(str1): 
    str2 = str1 
    pattern1 = r"\n```\n(.*?)\n```\n" 
    flag1 = True 
    while flag1: 
        search1 = re.search(pattern1, str2, re.DOTALL) 
        if search1: 
            start1, end1 = search1.span() 
            str3 = str2[:start1] 
            str4 = str2[start1+4:end1-3] 
            str4 = re.sub(r"<([^>]+)>", r"<\1>", str4)
            str4 = code_block_html1(str4) 
            str5 = str2[end1:] 
            str2 = str3 + str4 + str5 
        else: 
            flag1 = False 
    return str2 

def markdown1(path1, str1): 
    a1 = str1.split("\n") 
    str2 = "" 
    for i1 in range(len(a1)): 
        str3 = a1[i1]
        if str3.startswith("###"): 
            str3 = '<h3>' + str3[3:] + '</h3>' 
        elif str3.startswith("##"): 
            str3 = '<h2>' + str3[2:] + '</h2>' 
        elif str3.startswith("#"): 
            str3 = '<h1>' + str3[1:] + '</h1>' 
        elif str3.startswith("https:"): 
            str3 = '<a href="' + str3 + '" style="word-break:break-word;" target="www1">' + str3 + '</a>' + '<br>' 
        elif str3.endswith((".jpg", ".png", ".svg", ".gif")): 
            file1 = path1 + "html1/media1/" + str3
            if os.path.isfile(file1): 
                str3 = '<img style="width:100%; border:1px solid rgba(0, 0, 0, 0.2); " src="./media1/' + str3 + '">' + '<br>' 
        elif str3.endswith((".mp3")): 
            file1 = path1 + "html1/media1/" + str3
            if os.path.isfile(file1): 
                str3 = '<video width="100%" controls><source src="./media1/' + str3 + '" type="video/mp4"></video>' + '<br>'
                str3 = '<audio controls><source src="./media1/' + str3 + '.mp3" type="audio/mpeg"></audio>' + '<br>' 
        elif str3.endswith((".mp4")): 
            file1 = path1 + "html1/media1/" + str3
            if os.path.isfile(file1): 
                str3 = '<video width="100%" controls><source src="./media1/' + str3 + '" type="video/mp4"></video>' + '<br>'
        elif re.fullmatch(r'-{4,}', str3.rstrip()): 
                str3 = '<hr>' 
        else: 
            str3 = str3 + "<br>" 
        str2 = str2 + str3 + "\n" 
    return str2 

def get_yyyymmdd1(str1): 
    str2 = os.path.getmtime(str1)                                   # date1   getctime() or getmtime() 
    str3 = dt1.datetime.fromtimestamp(str2).strftime("%Y/%m/%d") 
    return str3 

def duplication_check1(str1, dic0): 
    str2 = str1 
    for i1 in range(10): 
        if str2 in dic0: 
            dic0[str1] += 1 
            str2 = str1 + "_" + str(dic0[str1]) 
        else: 
            dic0[str2] = 1 
            break 
    return str2, dic0 

def get_list1(path1, a1): 
    dic0 = {}                                                       # for duplication check 
    a2 = [] 
    for i1 in range(len(a1)):                                       # category 
        str1 = a1[i1][1]                                            # folder or path 
        path2 = ""
        if os.path.isdir(str1): 
            path2 = str1 
        elif os.path.isdir(path1+str1): 
            path2 = path1 + str1 
        pattern1 = path2 + "/*.txt" 
        a3 = gl1.glob(pattern1) 
        a4 = [] 
        for i2 in range(len(a3)): 
            str1 = a3[i2]                                           # path 
            str2 = os.path.basename(str1).split(".")[0]             # filename 
            str3 = get_yyyymmdd1(str1)                              # date, yyyy/mm/dd 
            str4 = read1(str1)                                      # text 
            str5, dic1 = get_yaml1(str4)                            # normal text, yaml dictionary 
            str5 = code_block1(str5)                                # tags < ... > conversion 
            str5 = markdown1(path1, str5) 
            str6 = str2                                             # title1 
            str7 = str2                                             # document url / permanent_link 
            if "title1" in dic1: 
                str6 = dic1["title1"] 
            if "date1" in dic1: 
                str3 = dic1["date1"] 
            if "permanent_link1" in dic1: 
                str7 = dic1["permanent_link1"] 
            str7, dic0 = duplication_check1(str7, dic0)             # duplication check 
            a5 = [str3, str6, str7, str5, str2, str1, dic1]         # [date, title, permanent_link, text, filename, path, dictionary] 
            a4.append(a5) 
        a4.sort( key=itemgetter(1) ) 
        a4.reverse()                                                # title 
        a4.sort( key=itemgetter(0) ) 
        a4.reverse()                                                # latest order 
        a2.append(a4) 
    return a2 

def get_header_html1(path1, a1): 
    str1 = "" 
    for i1 in range(len(a1)): 
        str2 = a1[i1][0]                                            # header title 
        str3 = a1[i1][1]                                            # folder name 
        path2 = "" 
        if os.path.isdir(str3): 
            path2 = str3 
        elif os.path.isdir(path1+str3): 
            path2 = path1 + str3 
        str4 = os.path.basename(path2) 
        str5 = '<a href="./' + str4 + '.html" style="text-decoration:none; color:inherit; margin-left:10px; margin-right:10px; font-size:17px; " >' +str2 + '</a>' + ' ' 
        str1 = str1 + str5 
    return str1 

def get_aside_html1(a1): 
    a2 = [] 
    for i1 in range(len(a1)): 
        a3 = a1[i1] 
        str1 = "" 
        for i2 in range(len(a3)): 
            str2 = a3[i2][0]                                        # date 
            str3 = a3[i2][1]                                        # title 
            str4 = a3[i2][2]                                        # permanent link 
            if str3 != "": 
                str5 = '<a href="./' + str4 + '.html" style="text-decoration:none; color:inherit; display:block; min-height:16px; font-size:17px; " >' + str3 + '</a>' 
                str5 = '<div style="display:inline; min-height:16px; font-size:12px; ">' + ' ' + str5 + '  ' + str2 + '</div><br>\n' 
                str1 = str1 + str5 
        a2.append(str1) 
    return a2 

def prev_next_html1(a1, n0): 
    str1 = "" 
    if a1[n0][1] != "": 
        for i1 in range(len(a1)-1): 
            n1 = n0-1-i1 
            if a1[n1][1] != "": 
                break 
        for i1 in range(len(a1)-1): 
            n2 = n0+1+i1-len(a1)
            if a1[n2][1] != "": 
                break 
        str2 = '<a href="./' + a1[n1][2] + '.html" style="text-decoration:none; color:inherit; display:block; min-height:16px; font-size:17px; " >previous</a>' 
        str2 = '<div style="display:inline-block; padding:5px 5px; border:1px solid #bbbbbb; border-radius:5px; text-align:center; width:100px; " >' + str2 + '</div>' 
        str3 = '<a href="./' + a1[n2][2] + '.html" style="text-decoration:none; color:inherit; display:block; min-height:16px; font-size:17px; " >next</a>' 
        str3 = '<div style="display:inline-block; padding:5px 5px; border:1px solid #bbbbbb; border-radius:5px; text-align:center; width:100px;" >' + str3 + '</div>' 
        str1 = '<br>\n<hr style="margin-bottom:0px; margin-top:10px; width:100%; border:1px solid #aaaaaa; "><br>\n' 
        str1 = str1 + '<div style="display:flex;" >' + str2 + ' ' + str3 + '</div>' 
    return str1 

def generate_main_pages1(path1, str1, a1, a2): 
    dic0 = {} 
    for i1 in range(len(a1)):                                       # category 
        a3 = a1[i1]  
        str2 = a2[i1]                                               # aside HTML 
        for i1 in range(len(a3)):                                   # page 
            str3 = a3[i1][3]                                        # text 
            str3 = str3 + prev_next_html1(a3, i1) 
            str4 = a3[i1][2]                                        # permanent link 
            dic0[str4] = 1 
            str5 = str1.replace("{{main2}}", str3) 
            str5 = str5.replace("{{aside2}}", str2) 
            file1 = path1 + "html1/" + str4 + ".html"               # permanent_link1 
            write1(file1, str5) 
    return dic0 

def generate_top_pages1(path1, str1, a1, a2, dic1): 
    str2 = str1.replace("{{main2}}", "")                            # template 
    if not "index" in dic1: 
        str3 = str(a2[0]) if len(a2) > 0 else "" 
        str4 = str2.replace("{{aside2}}", str3) 
        file1 = path1 + "html1/" + "index.html"                     # top page 
        write1(file1, str4) 
    for i1 in range(len(a2)): 
        if not a1[i1][1] in dic1: 
            str3 = os.path.basename(a1[i1][1])                      # folder name 
            str4 = str2.replace("{{aside2}}", a2[i1]) 
            file1 = path1 + "html1/" + str3 + ".html"               # category top page 
            write1(file1, str4) 

path1 = os.path.dirname(__file__) + "/" 

a1 = [ 
    ["カテゴリー1", "category1"], 
    ["カテゴリー2", "category2"]
]                                                                   # category 

a2 = get_list1(path1, a1)                                           # list 

str1 = get_template1(path1) 

str2 = get_header_html1(path1, a1) 
str1 = str1.replace("{{header2}}", str2) 

a3 = get_aside_html1(a2)                                            # side bar HTML 

dic1 = generate_main_pages1(path1, str1, a2, a3) 

generate_top_pages1(path1, str1, a1, a3, dic1) 


タイトルとURLをコピーしました