Skip to content

Yoochanryan/portpolio

Repository files navigation

Flask Blog + GitHub Pages Export

로컬에서는 Flask로 실행하고, 배포용으로는 정적 HTML을 docs/에 생성할 수 있는 블로그 예제입니다.

기능

  • Flask + Jinja2 템플릿 기반
  • Markdown 포스트 자동 로딩
  • 검색, 태그 목록, 상세 페이지
  • 게시글 CRUD 편집 기능 (웹 인터페이스에서 작성/수정/삭제)
  • 프로필/사이드바 위젯
  • docs/에 정적 HTML 생성 후 GitHub Pages 업로드 가능

📚 교육용 가이드

이 프로젝트는 Flask 백엔드 개발을 학습하기 위한 교육 자료로 제작되었습니다.

학습 목표

  • Flask 라우팅 및 요청 처리
  • 파일 I/O 및 Markdown 파싱
  • HTML 템플릿 렌더링
  • Form 데이터 처리

구현할 부분 (Skeleton Code)

다음 함수들을 직접 구현해야 합니다. 각 함수의 TODO 주석을 참고하세요.

1단계: 파일 저장 함수 (content.py)

  • save_post() - 포스트를 마크다운 파일로 저장

    • 난이도: ⭐ 쉬움
    • 핵심: 파일 쓰기, 딕셔너리 조작, 경로 처리
    • 힌트: Path.write_text(), datetime.now(), _build_front_matter()
  • delete_post() - 포스트 파일 삭제

    • 난이도: ⭐ 매우 쉬움
    • 핵심: 파일 존재 여부 확인, 파일 삭제
    • 힌트: Path.exists(), Path.unlink()
  • get_post_raw() - 마크다운 원본 로드

    • 난이도: ⭐ 쉬움
    • 핵심: 파일 읽기, 메타데이터 파싱
    • 힌트: Path.read_text(), _parse_front_matter()

2단계: Flask 라우트 (app.py)

  • admin_posts() - 관리 페이지 (포스트 목록)

    • 난이도: ⭐ 매우 쉬움
    • 핵심: 함수 호출, 템플릿 렌더링
    • 힌트: load_posts(), render_template()
  • admin_create() - 새 포스트 작성

    • 난이도: ⭐⭐ 보통
    • 핵심: GET/POST 처리, 폼 데이터 추출, 유효성 검사
    • 힌트: request.method, request.form.get(), save_post(), redirect()
  • admin_edit() - 포스트 편집

    • 난이도: ⭐⭐⭐ 어려움
    • 핵심: 기존 데이터 로드, 수정된 데이터 저장, slug 변경 처리
    • 힌트: get_post_raw(), delete_post(), save_post(), abort(404)
  • admin_delete() - 포스트 삭제

    • 난이도: ⭐ 매우 쉬움
    • 핵심: 삭제 함수 호출, 리다이렉트
    • 힌트: delete_post(), redirect()

구현 순서 (권장)

  1. 파일 저장 함수 (content.py)

    # 간단한 것부터 시작
    delete_post()  # 가장 간단함
    get_post_raw()  # 파일 읽기 연습
    save_post()  # 파일 쓰기와 메타데이터 조합
  2. 라우트 구현 (app.py)

    # 기본부터 고급까지
    admin_posts()  # 기존 코드 사용 (로드만)
    admin_delete()  # 파일 삭제만
    admin_create()  # 폼 처리 + 파일 저장
    admin_edit()  # 모든 것을 종합

테스트 방법

# 1. 파이썬 실행
python app.py

# 2. 브라우저에서 접속
# 블로그: http://127.0.0.1:5000/
# 관리: http://127.0.0.1:5000/admin

# 3. 각 기능 테스트
# - 포스트 생성 후 목록에 나타나는지 확인
# - 포스트 수정 후 내용이 변경되었는지 확인
# - 포스트 삭제 후 목록에서 사라졌는지 확인
# - 파일 시스템에서 content/posts/ 폴더 확인

추가 학습 자료

Python 기본

Flask

Markdown

  • 파싱: _parse_front_matter() 함수 참고 (이미 구현됨)
  • HTML 변환: _markdown_to_html() 함수 참고 (이미 구현됨)

학생들이 마음껏 확장해볼 수 있는 아이디어들

이 블로그는 정답이 있는 과제가 아니라, 학생들의 아이디어를 얹어보는 실험 공간으로 쓰기 좋습니다. 아래 목록은 "반드시 해야 하는 과제"가 아니라, 시작점일 뿐입니다. 원하는 대로 합치고, 바꾸고, 더 멀리 확장해도 좋습니다.

쉬운 과제

  • 카테고리 추가: tags처럼 category를 하나 더 두고 글을 분류하기
  • 프로필 정보 변경: content/site.json의 이름, 소개, SNS 링크 바꾸기
  • 히어로 문구 수정: 메인 페이지 첫 화면의 문구와 버튼 바꾸기
  • 색상 테마 변경: static/css/style.css:root 변수값 바꾸기
  • footer 문구 변경: 사이트 하단 저작권/안내 문구 수정하기

보통 난이도 과제

  • 검색 기능 개선: 제목뿐 아니라 본문까지 검색하기
  • 태그 필터 페이지: 특정 태그 글만 따로 보는 페이지 추가하기
  • 미리보기 길이 조절: 홈 화면 카드에 본문 일부 미리보기 표시하기
  • 초안(draft) 기능: 게시글에 draft: true를 넣으면 목록에서 숨기기
  • 정렬 방식 선택: 최신순 / 오래된순 / 제목순 정렬 옵션 추가하기
  • 페이지네이션: 글이 많아지면 페이지를 나눠 보여주기

도전 과제

  • 이미지 업로드/삽입: 포스트 본문에 이미지 경로를 넣어 미디어 활용하기
  • 댓글 기능: 로컬 파일 기반 또는 별도 저장소를 사용한 간단한 댓글 구현
  • 좋아요/조회수: 글마다 숫자를 저장하고 화면에 표시하기
  • RSS 피드 생성: 블로그 글 목록을 RSS XML로 내보내기
  • 코드 하이라이트: Markdown 코드 블록에 구문 강조 적용하기
  • 라이트/다크 테마 토글: 버튼으로 테마를 바꾸고 localStorage에 저장하기

아이디어를 더 크게 만드는 질문

학생들이 기능을 고를 때 아래 질문에 답해보면, 자기만의 방향을 잡기 좋습니다.

  • 이 블로그가 무슨 블로그였으면 좋겠는가?
    • 개발 기록 블로그, 취미 일기, 포트폴리오, 동아리 소식, 공부 노트 등
  • 방문자가 들어왔을 때 첫 3초 안에 무엇을 느끼게 하고 싶은가?
    • 깔끔함, 개성, 신뢰감, 재미, 전문성, 감성 등
  • 글을 읽는 사람이 어떤 행동을 하게 만들고 싶은가?
    • 다른 글도 읽기, 검색하기, 태그 탐색하기, 공유하기, 댓글 남기기 등
  • 지금 있는 기능 중 무엇을 더 편하게 만들고 싶은가?
    • 검색, 글 작성, 태그 보기, 모바일 화면, 다크모드 등

자유롭게 바꿔도 되는 것

학생들은 아래 항목을 자기 스타일대로 바꿔도 됩니다.

  • 사이트 제목과 소개 문구
  • 프로필 사진, 이름, 역할, 소개글
  • 메인 히어로 문구와 버튼 이름
  • 카드 색상, 배경, 타이포그래피, 그림자
  • 글 카드 구성 방식(짧게/길게/이미지 포함)
  • 관리 페이지의 버튼 배치와 편집기 레이아웃
  • 정적 내보내기 결과물의 구조와 파일명

아이디어를 더 멀리 확장하는 예시

  • 내 블로그 정체성 만들기: 각자 다른 테마와 소개 문구로 완전히 다른 분위기 구현하기
  • 콘텐츠 중심 블로그: 카드형이 아니라 잡지 스타일, 타임라인 스타일로 바꾸기
  • 상호작용 강화: 검색, 필터, 즐겨찾기, 북마크, 공유 버튼 추가하기
  • 개인 브랜딩: 프로필, 프로젝트, 연락처, 기술 스택 섹션을 추가해 포트폴리오처럼 만들기
  • 커뮤니티 느낌: 댓글, 좋아요, 공지, 배너, 추천 글 같은 요소 넣기

실험할 때의 팁

  • 기능을 크게 만들기보다 작게 하나씩 바꿔보는 것이 좋습니다.
  • 먼저 "무슨 느낌의 블로그를 만들고 싶은지" 한 줄로 적고 시작하면 방향이 선명해집니다.
  • 기능을 추가할 때는 보통 아래 파일을 함께 수정합니다.
    • 데이터 처리: blog_site/content.py
    • 화면 표시: templates/
    • 디자인: static/css/style.css
    • 동작 로직: blog_site/app.py

구현 목표 체크리스트

  • 내가 만들고 싶은 블로그의 분위기를 먼저 정했는가?
  • 학생이 직접 수정할 수 있는 기능을 하나 선택했는가?
  • 어떤 파일을 수정해야 하는지 이해했는가?
  • 기능 추가 후 로컬에서 확인했는가?
  • 필요하면 export_site.py로 정적 HTML도 다시 생성했는가?

설치

pip install -r requirements.txt

로컬 실행

python app.py

기본 접속 주소:

  • 블로그: http://127.0.0.1:5000/
  • 관리 페이지: http://127.0.0.1:5000/admin

글 작성/관리

웹 인터페이스를 통한 CRUD (권장)

  1. http://127.0.0.1:5000/admin 접속
  2. "New Post" 클릭해서 새 글 작성
  3. Edit/Delete로 기존 글 수정/삭제

파일 기반 추가 (선택사항)

content/posts/.md 파일을 직접 추가해도 됩니다.

---
title: 새 글
slug: new-post
date: 2026-06-05
summary: 한 줄 요약
tags: flask, jinja2
---

# 본문

Markdown 내용 작성.

GitHub Pages용 HTML 생성

python export_site.py

생성 결과는 docs/ 폴더에 저장됩니다.

  • 관리 페이지(/admin, /admin/create 등)는 정적 빌드에서 제외됩니다.

GitHub Pages 업로드

  1. docs/ 폴더를 GitHub 저장소에 포함시킵니다.
  2. GitHub Pages 설정에서 배포 소스를 main branch /docs로 지정합니다.
  3. python export_site.py를 다시 실행하면 정적 페이지가 갱신됩니다.

커스터마이징

  • 사이트 설정 및 프로필: content/site.json
  • 템플릿: templates/ (기본, 관리자, 편집기 등)
  • 스타일: static/css/style.css
  • 내보내기 로직: export_site.py
  • 게시글 로직: blog_site/content.py (TODO 주석 참고)

About

포트폴리오입니다.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors