ポートフォリオメディアサイト開発
プロジェクト概要
「思想と技術を伝えるポートフォリオ型メディアサイト」をFlaskで構築した開発事例です。Markdownベースで記事を管理できるCMSとして設計し、見栄えと効率性を両立させることを目標としました。
背景・課題
なぜ作ったのか
従来の静的サイトジェネレーターやWordPressでは、以下の課題がありました:
- 効率性の問題: 記事作成から公開までの手順が煩雑
- 思想の表現: 技術だけでなく「なぜ作ったか」を伝える構造が不足
- 継続性: 書き続けやすい環境の不備
- カスタマイズ性: 独自の要件に柔軟に対応できない
解決アプローチ
「何を作ったか」より「なぜ作ったか」を伝える構造
この思想のもと、以下の要素を重視して設計:
- Markdownファースト: 効率的な記事作成
- モジュラー構造: 思想・実績・日常を明確に分離
- 検索・発見: タグとカテゴリによる情報整理
- 管理の簡単さ: Webベースの直感的な操作
技術スタック
レイヤー | 技術 | 選定理由 |
---|---|---|
Backend | Flask 2.3.3 | 軽量で拡張性が高い |
Database | SQLite3 | ファイルベースで管理が簡単 |
Frontend | Bootstrap 5.3 | レスポンシブ対応済み |
Markdown | Python-Markdown | 豊富な拡張機能 |
検索 | SQLite LIKE句 | シンプルで十分な性能 |
UI/UX | Font Awesome 6.0 | 直感的なアイコン |
アーキテクチャ設計
システム構成
📁 portfolio_site/
├── 📄 portfolio_app.py # Flask メインアプリ
├── 📄 init_db.py # DB初期化
├── 📁 content/ # Markdown記事
│ ├── 📁 profile/ # プロフィール・哲学
│ ├── 📁 portfolio/ # 事例ライブラリ
│ └── 📁 notes/ # 開発ノート・雑感
├── 📁 templates/ # Jinja2テンプレート
└── 📁 static/ # CSS/JS/画像
データモデル
# 記事テーブル
CREATE TABLE articles (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
filename TEXT UNIQUE,
category TEXT NOT NULL,
tags TEXT,
created_at TIMESTAMP,
updated_at TIMESTAMP,
published BOOLEAN DEFAULT 1
)
主要機能実装
1. Markdown→HTML変換システム
def convert_md_to_html(md_content):
md = markdown.Markdown(extensions=[
'extra', # テーブル、脚注対応
'codehilite', # シンタックスハイライト
'toc', # 目次自動生成
'nl2br', # 改行処理
'tables' # テーブル拡張
])
return md.convert(md_content)
特徴:
- Front Matter対応でメタデータ管理
- コードブロックのシンタックスハイライト
- テーブルや引用文の美しいレンダリング
2. カテゴリベース記事管理
3つの軸で情報を整理:
- Profile (
/category/profile
): 開発哲学・思想 - Portfolio (
/category/portfolio
): 技術事例・実績 - Notes (
/category/notes
): 学習記録・雑感
@app.route('/category/<category>')
def category_view(category):
articles = get_articles(category=category)
category_names = {
'profile': 'プロフィール・哲学',
'portfolio': '事例ライブラリ',
'notes': '開発ノート・雑感'
}
return render_template('category.html', ...)
3. 検索・タグシステム
def get_articles(category=None, tag=None, search=None):
query = "SELECT * FROM articles WHERE published = 1"
params = []
if search:
query += " AND (title LIKE ? OR filename LIKE ?)"
params.extend([f'%{search}%', f'%{search}%'])
if tag:
query += " AND tags LIKE ?"
params.append(f'%{tag}%')
実装ポイント:
- 全文検索でタイトル・ファイル名を対象
- タグクラウドで記事の傾向を視覚化
- カテゴリ横断での関連記事表示
4. 管理画面(CRUD操作)
記事作成・編集の工夫:
- リアルタイムMarkdownヘルプ表示
- カテゴリ別のクイック作成ボタン
- ファイル名の自動生成(日本語対応)
@app.route('/admin/article/new', methods=['GET', 'POST'])
def admin_new_article():
if request.method == 'POST':
title = request.form['title']
filename = secure_filename(title) + '.md'
if save_article(title, filename, category, tags, content):
flash('記事を作成しました', 'success')
UI/UX設計
レスポンシブデザイン
Bootstrap 5を基盤として、以下を重視:
- モバイルファースト: スマートフォンでの読みやすさ
- カードレイアウト: 記事一覧の見やすさ
- ナビゲーション: 直感的なカテゴリ移動
デザインシステム
/* カスタムスタイルの例 */
.hero-section {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.article-content {
line-height: 1.7;
}
.article-content pre {
background: #f8f9fa;
border-radius: 0.375rem;
padding: 1rem;
}
開発プロセス
1. 要件定義・設計 (1時間)
- システム構想案の分析
- 技術スタック選定
- データベース設計
2. 基盤実装 (2時間)
- Flask アプリケーション構築
- データベーススキーマ作成
- 基本的なCRUD機能
3. フロントエンド開発 (2時間)
- Bootstrap 5 テンプレート作成
- レスポンシブデザイン適用
- Markdownスタイリング
4. 管理機能・検索機能 (1時間)
- 管理画面インターフェース
- 検索・タグ機能実装
- サンプルデータ作成
技術的チャレンジと解決
1. 日本語ファイル名対応
課題: Markdownファイルの日本語ファイル名とURL安全性
解決: secure_filename()
+ データベースでのマッピング管理
filename = secure_filename(title) + '.md'
# "私の開発哲学" → "私の開発哲学.md"
2. Markdown拡張機能の活用
課題: 標準Markdownでは表現力が不足
解決: Python-Markdownの拡張機能を組み合わせ
- extra
: テーブル・脚注・定義リスト
- codehilite
: Pygmentsベースのハイライト
- toc
: 見出しからの目次自動生成
3. 検索性能の最適化
課題: 記事数増加時の検索パフォーマンス
現在の対応: SQLite LIKE句での部分一致検索
将来の拡張: Whoosh や Elasticsearchへの移行を検討
学習・収穫
技術面
- Flask の軽量性: 小規模アプリには最適な選択
- SQLite の利便性: 開発・デプロイの簡単さを実感
- Bootstrap 5: Grid システムの進化とユーティリティクラス
設計面
- 情報アーキテクチャ: カテゴリ設計の重要性
- ユーザビリティ: 書き手目線での管理画面設計
- 拡張性: 将来機能追加を見越したコード構造
プロジェクト管理
- 段階的実装: MVP → 機能追加のアプローチ
- ドキュメント化: README・コメントの充実
- バージョン管理: 適切なコミットメッセージの重要性
成果・効果
定量的成果
- 開発時間: 約6時間で基本機能完成
- コード行数: 1,777行(テンプレート含む)
- ファイル数: 20ファイル(新規作成)
定性的成果
- 使いやすさ: 直感的な記事作成・編集体験
- 保守性: シンプルな構造で理解しやすいコード
- 拡張性: 新機能追加が容易な設計
今後の展開
短期的改善
- [ ] 画像アップロード機能
- [ ] 記事のドラフト・公開状態管理
- [ ] コメント・フィードバック機能
長期的発展
- [ ] 全文検索エンジン強化(Whoosh/Elasticsearch)
- [ ] 静的サイト生成対応
- [ ] API化による外部連携
- [ ] 多言語対応
パフォーマンス最適化
- [ ] 記事キャッシュ機能
- [ ] CDN対応
- [ ] データベースインデックス最適化
まとめ
このプロジェクトを通じて、「効率性と見栄えの両立」という当初の目標を達成できました。
特に重要だったのは:
- 問題の本質理解: 単なるブログではなく「思想を伝える」メディア
- 技術選択の妥当性: Flask + SQLiteの軽量さが開発速度に貢献
- ユーザー体験重視: 書き手(自分)が使いやすい管理画面
「技術は手段、目的は価値の創造」
この開発を通じて改めて実感したのは、技術的な実装よりも「なぜ作るのか」「誰のために作るのか」という目的意識の重要性でした。
関連技術
Flask
Python
SQLite
Bootstrap
Markdown
HTML/CSS
JavaScript
Git
Web開発
ポートフォリオ