이번 실습은 HTML, CSS, JavaScript, Python, WordPress, 네이버 카페를 각각 따로 배우는 것이 아니라 하나의 작은 도구로 연결해보는 과정입니다.
최종 목표는 Healthcare Post Builder입니다. 오늘 배운 내용을 입력하면 WordPress용 글 HTML과 네이버 카페용 안전 HTML을 동시에 만들고, WordPress에는 자동 발행까지 연결하는 실습입니다.
최종 결과물
- 학습 내용 입력 폼
- WordPress용 HTML 템플릿 생성
- 네이버 카페용 안전 HTML 템플릿 생성
- HTML 복사 버튼
- 네이버 적용 테스트표
- Python으로 HTML 파일 자동 생성
- WP-CLI 또는 REST API 기반 WordPress 자동 발행
핵심은 WordPress는 완전 자동화, 네이버는 안전 HTML 템플릿 검증으로 역할을 나누는 것입니다.
1단계. 프로젝트 준비
체크리스트
- 프로젝트 폴더 만들기
index.html,style.css,script.js만들기data,output,templates폴더 만들기- Git 저장소 초기화하기
Code snippet: 프로젝트 폴더 만들기
mkdir healthcare-post-builder
cd healthcare-post-builder
mkdir data output templates
touch index.html style.css script.js README.md
git init
git add .
git commit -m "initial healthcare post builder setup"
2단계. HTML 입력 화면 만들기
이 단계에서는 실제 도구의 화면 뼈대를 만듭니다. 중요한 것은 예쁘게 만드는 것이 아니라, 어떤 데이터를 받아서 어떤 결과를 만들지 정하는 것입니다.
2-1. 글 제목 입력 영역 만들기
- 사용자가 오늘의 학습 글 제목을 입력할 수 있게 만든다.
- 예:
CSS 선택자는 자동화의 손잡이다
Code snippet: 제목 입력 input
<label for="post-title">글 제목</label>
<input
id="post-title"
type="text"
placeholder="예: CSS 선택자는 자동화의 손잡이다"
/>
2-2. 학습 주제 입력 영역 만들기
- 오늘 배운 핵심 주제를 짧게 입력한다.
- 예:
CSS 선택자, 박스 모델, 네이버 카페 HTML
Code snippet: 학습 주제 입력
<label for="post-topic">학습 주제</label>
<input
id="post-topic"
type="text"
placeholder="예: CSS 선택자, 박스 모델, 네이버 카페 HTML"
/>
2-3. 핵심 요약 입력 영역 만들기
- 배운 내용을 한두 문장으로 정리한다.
- WordPress와 네이버 카페 템플릿에 공통으로 들어갈 내용이다.
Code snippet: 핵심 요약 textarea
<label for="post-summary">핵심 요약</label>
<textarea
id="post-summary"
rows="4"
placeholder="오늘 배운 내용을 내 말로 정리해보세요."
></textarea>
2-4. 인용구 입력 영역 만들기
- 글에서 강조하고 싶은 문장을 입력한다.
- WordPress에서는 디자인된 인용구로, 네이버에서는 안전한 문단 구조로 변환한다.
Code snippet: 인용구 입력
<label for="post-quote">기억할 문장</label>
<textarea
id="post-quote"
rows="3"
placeholder="예: 선택자는 화면 요소를 찾는 기준점이다."
></textarea>
2-5. 오늘 배운 내용 리스트 입력 영역 만들기
- 줄바꿈 기준으로 여러 개의 학습 항목을 입력한다.
- JavaScript에서 줄 단위로 나누어
<li>목록으로 변환한다.
Code snippet: 학습 내용 리스트 입력
<label for="post-items">오늘 배운 내용</label>
<textarea
id="post-items"
rows="6"
placeholder="HTML은 글의 구조를 만든다.
CSS는 글의 표현을 조정한다.
선택자는 자동화에서 특정 요소를 찾는 기준이다."
></textarea>
2-6. WordPress용 결과 영역 만들기
- WordPress에 넣을 HTML을 보여주는 영역이다.
- CSS 클래스와 카드형 디자인을 적극적으로 사용한다.
Code snippet: WordPress 결과 영역
<section class="result-panel">
<div class="result-head">
<h2>WordPress용 HTML</h2>
<button type="button" data-copy-target="wordpress-output">복사</button>
</div>
<textarea id="wordpress-output" rows="14" readonly></textarea>
</section>
2-7. 네이버 카페용 결과 영역 만들기
- 네이버에서 깨질 수 있는 복잡한 CSS를 줄인 HTML을 보여준다.
class보다 기본 태그 중심으로 만든다.
Code snippet: 네이버 카페 결과 영역
<section class="result-panel">
<div class="result-head">
<h2>네이버 카페용 HTML</h2>
<button type="button" data-copy-target="naver-output">복사</button>
</div>
<textarea id="naver-output" rows="14" readonly></textarea>
</section>
2-8. 전체 HTML 뼈대 만들기
Code snippet: index.html 기본 구조
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Healthcare Post Builder</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<main class="app-shell">
<header class="app-header">
<p>AI Healthcare Camp</p>
<h1>Healthcare Post Builder</h1>
</header>
<section class="builder-grid">
<form id="post-form" class="input-panel">
<label for="post-title">글 제목</label>
<input id="post-title" type="text" />
<label for="post-topic">학습 주제</label>
<input id="post-topic" type="text" />
<label for="post-summary">핵심 요약</label>
<textarea id="post-summary" rows="4"></textarea>
<label for="post-quote">기억할 문장</label>
<textarea id="post-quote" rows="3"></textarea>
<label for="post-items">오늘 배운 내용</label>
<textarea id="post-items" rows="6"></textarea>
<button type="submit">HTML 생성하기</button>
</form>
<div class="output-stack">
<section class="result-panel">
<div class="result-head">
<h2>WordPress용 HTML</h2>
<button type="button" data-copy-target="wordpress-output">복사</button>
</div>
<textarea id="wordpress-output" rows="14" readonly></textarea>
</section>
<section class="result-panel">
<div class="result-head">
<h2>네이버 카페용 HTML</h2>
<button type="button" data-copy-target="naver-output">복사</button>
</div>
<textarea id="naver-output" rows="14" readonly></textarea>
</section>
</div>
</section>
</main>
<script src="./script.js"></script>
</body>
</html>
3단계. CSS로 화면과 미리보기 디자인하기
여기서 배우는 CSS는 단순 꾸미기가 아니라, WordPress용 글 카드와 네이버용 안전 HTML을 구분하기 위한 실습입니다.
3-1. 전체 레이아웃 만들기
Code snippet: 기본 레이아웃 CSS
* {
box-sizing: border-box;
}
body {
margin: 0;
background: #f4fbf9;
color: #14222c;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans KR", sans-serif;
}
.app-shell {
width: min(1120px, calc(100% - 32px));
margin: 0 auto;
padding: 40px 0;
}
.builder-grid {
display: grid;
grid-template-columns: 0.9fr 1.1fr;
gap: 20px;
align-items: start;
}
3-2. 입력 폼 스타일 만들기
Code snippet: 입력 폼 CSS
.input-panel,
.result-panel {
border: 1px solid #d8e8e7;
border-radius: 8px;
background: #ffffff;
padding: 20px;
}
.input-panel {
display: grid;
gap: 10px;
}
label {
font-weight: 700;
color: #314955;
}
input,
textarea {
width: 100%;
border: 1px solid #d8e8e7;
border-radius: 8px;
padding: 10px 12px;
font: inherit;
}
3-3. 버튼 스타일 만들기
Code snippet: 버튼 CSS
button {
min-height: 40px;
border: 0;
border-radius: 8px;
background: #087e8b;
color: #ffffff;
font: inherit;
font-weight: 800;
cursor: pointer;
}
button:hover {
background: #066c77;
}
3-4. WordPress 미리보기 카드 디자인 만들기
Code snippet: WordPress 카드 CSS
.healthcare-study-card {
border: 1px solid #d8e8e7;
border-radius: 8px;
background: #f4fbf9;
padding: 20px;
}
.healthcare-study-card .label {
color: #087e8b;
font-weight: 800;
}
.healthcare-study-card blockquote {
margin: 20px 0;
border-left: 4px solid #087e8b;
padding-left: 14px;
color: #435865;
}
3-5. 모바일 화면 대응하기
Code snippet: 반응형 CSS
@media (max-width: 760px) {
.builder-grid {
grid-template-columns: 1fr;
}
.app-shell {
width: min(100% - 20px, 1120px);
padding: 24px 0;
}
}
4단계. JavaScript로 템플릿 생성하기
4-1. 입력값 가져오기
Code snippet: 입력값 수집 함수
function valueOf(id, fallback = "") {
const element = document.getElementById(id);
const value = element ? element.value.trim() : "";
return value || fallback;
}
function collectPostData() {
return {
title: valueOf("post-title", "오늘의 학습 기록"),
topic: valueOf("post-topic", "AI Healthcare Camp 실습"),
summary: valueOf("post-summary", "오늘 배운 내용을 내 언어로 정리했다."),
quote: valueOf("post-quote", "작게 만들어보고, 결과를 보며 고친다."),
items: valueOf("post-items", "HTML 구조 만들기\nCSS 디자인하기\nJavaScript로 템플릿 생성하기")
.split("\n")
.map((item) => item.trim())
.filter(Boolean),
};
}
4-2. HTML 이스케이프 처리하기
사용자가 입력한 값에 HTML 특수문자가 있을 수 있으므로 안전하게 변환합니다.
Code snippet: escapeHtml 함수
function escapeHtml(value) {
return value
.replaceAll("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">")
.replaceAll('"', """)
.replaceAll("'", "'");
}
4-3. WordPress용 HTML 생성하기
Code snippet: WordPress 템플릿 함수
function makeWordPressTemplate(data) {
const items = data.items
.map((item) => `<li>${escapeHtml(item)}</li>`)
.join("");
return `
<div class="healthcare-study-card">
<p class="label">AI Healthcare Camp</p>
<h2>${escapeHtml(data.title)}</h2>
<p><strong>학습 주제:</strong> ${escapeHtml(data.topic)}</p>
<p>${escapeHtml(data.summary)}</p>
<blockquote>${escapeHtml(data.quote)}</blockquote>
<h3>오늘 배운 내용</h3>
<ul>${items}</ul>
</div>`.trim();
}
4-4. 네이버 카페용 안전 HTML 생성하기
네이버용은 복잡한 클래스와 외부 CSS를 줄이고 기본 태그 중심으로 만듭니다.
Code snippet: 네이버 카페 템플릿 함수
function makeNaverTemplate(data) {
const items = data.items
.map((item) => `<li>${escapeHtml(item)}</li>`)
.join("");
return `
<h2>${escapeHtml(data.title)}</h2>
<p><b>학습 주제:</b> ${escapeHtml(data.topic)}</p>
<p><b>핵심 요약:</b> ${escapeHtml(data.summary)}</p>
<hr>
<p><b>기억할 문장</b></p>
<p>${escapeHtml(data.quote)}</p>
<p><b>오늘 배운 내용</b></p>
<ul>${items}</ul>`.trim();
}
4-5. 생성 버튼 연결하기
Code snippet: 버튼 클릭 이벤트
const form = document.getElementById("post-form");
const wordpressOutput = document.getElementById("wordpress-output");
const naverOutput = document.getElementById("naver-output");
form.addEventListener("submit", (event) => {
event.preventDefault();
const data = collectPostData();
wordpressOutput.value = makeWordPressTemplate(data);
naverOutput.value = makeNaverTemplate(data);
});
4-6. 복사 버튼 만들기
Code snippet: HTML 복사 기능
document.querySelectorAll("[data-copy-target]").forEach((button) => {
button.addEventListener("click", async () => {
const target = document.getElementById(button.dataset.copyTarget);
if (!target) {
return;
}
await navigator.clipboard.writeText(target.value);
button.textContent = "복사됨";
window.setTimeout(() => {
button.textContent = "복사";
}, 1200);
});
});
5단계. 네이버 카페 안전 HTML 테스트
네이버 카페 API나 에디터에서 어떤 HTML이 유지되는지는 직접 테스트해야 합니다. 이 단계의 목표는 나만의 안전 태그 목록을 만드는 것입니다.
5-1. 테스트용 HTML 만들기
Code snippet: 네이버 적용 테스트 HTML
<p>일반 문장 테스트</p>
<p><b>b 태그 굵게 테스트</b></p>
<p><strong>strong 태그 굵게 테스트</strong></p>
<p><font color="red">font color 빨간색 테스트</font></p>
<p><span style="font-size:20px;">글자 크기 테스트</span></p>
<hr>
<blockquote>blockquote 인용구 테스트</blockquote>
<ul>
<li>목록 1</li>
<li>목록 2</li>
</ul>
5-2. 테스트 결과표 만들기
Code snippet: 테스트 결과표
<table>
<thead>
<tr>
<th>태그</th>
<th>목적</th>
<th>적용 여부</th>
<th>메모</th>
</tr>
</thead>
<tbody>
<tr><td><b></td><td>굵게</td><td></td><td></td></tr>
<tr><td><strong></td><td>굵게</td><td></td><td></td></tr>
<tr><td><hr></td><td>구분선</td><td></td><td></td></tr>
<tr><td><blockquote></td><td>인용구</td><td></td><td></td></tr>
</tbody>
</table>
6단계. WordPress 자동 발행 연결하기
WordPress는 우리가 직접 관리하는 블로그이기 때문에 자동화 범위를 넓게 잡을 수 있습니다. 먼저 WP-CLI로 발행하고, 이후 REST API로 확장하면 됩니다.
6-1. WP-CLI로 초안 발행하기
Code snippet: WP-CLI 글 발행 명령
ssh Ai_Leader_Camp '
cd /opt/bitnami/wordpress
sudo /opt/bitnami/wp-cli/bin/wp post create \
--post_type=post \
--post_status=draft \
--post_title="CSS 선택자는 자동화의 손잡이다" \
--post_content="$(cat /tmp/post.html)" \
--post_category=146 \
--tags_input="AI Healthcare Camp,CSS,WordPress,네이버카페,자동화"
'
6-2. WordPress REST API로 확장하기
Code snippet: REST API 요청 형태
async function publishToWordPress(payload) {
const response = await fetch("https://hongsik.blog/wp-json/wp/v2/posts", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer YOUR_TOKEN",
},
body: JSON.stringify({
title: payload.title,
content: payload.html,
status: "draft",
categories: [146],
}),
});
return response.json();
}
7단계. Python으로 HTML 파일 생성하기
7-1. 글 데이터 JSON 만들기
Code snippet: post_data.json
{
"title": "CSS 선택자는 자동화의 손잡이다",
"topic": "CSS 선택자와 네이버 카페 HTML 템플릿",
"summary": "CSS 선택자는 화면 요소를 찾고, 글 템플릿을 구조화하는 기준이 된다.",
"quote": "선택자는 자동화에서 화면 요소를 찾는 손잡이다.",
"items": [
"HTML은 글의 구조를 만든다.",
"CSS는 글의 표현을 조정한다.",
"네이버용 HTML은 안전 태그 중심으로 만들어야 한다."
],
"tags": ["AI Healthcare Camp", "CSS", "자동화", "WordPress", "네이버카페"]
}
7-2. Python으로 WordPress용 HTML 생성하기
Code snippet: build_post.py
import json
from html import escape
from pathlib import Path
def make_wordpress_html(data):
items = "\n".join(f"<li>{escape(item)}</li>" for item in data["items"])
return f"""
<div class="healthcare-study-card">
<p class="label">AI Healthcare Camp</p>
<h2>{escape(data["title"])}</h2>
<p><strong>학습 주제:</strong> {escape(data["topic"])}</p>
<p>{escape(data["summary"])}</p>
<blockquote>{escape(data["quote"])}</blockquote>
<h3>오늘 배운 내용</h3>
<ul>
{items}
</ul>
</div>
""".strip()
def make_naver_html(data):
items = "\n".join(f"<li>{escape(item)}</li>" for item in data["items"])
return f"""
<h2>{escape(data["title"])}</h2>
<p><b>학습 주제:</b> {escape(data["topic"])}</p>
<p><b>핵심 요약:</b> {escape(data["summary"])}</p>
<hr>
<p><b>기억할 문장</b></p>
<p>{escape(data["quote"])}</p>
<ul>
{items}
</ul>
""".strip()
data = json.loads(Path("data/post_data.json").read_text(encoding="utf-8"))
Path("output/wordpress-post.html").write_text(make_wordpress_html(data), encoding="utf-8")
Path("output/naver-post.html").write_text(make_naver_html(data), encoding="utf-8")
print("HTML files generated in output folder.")
8단계. 네이버 카페 발행 보조로 확장하기
네이버 카페는 공식 API가 허용하는 범위와 실제 에디터가 허용하는 범위를 나누어 봐야 합니다. 우선은 안전 HTML을 생성하고, 적용 여부를 확인하는 방식으로 진행합니다.
8-1. 네이버 카페용 안전 태그 규칙 만들기
Code snippet: 안전 태그 후보
const NAVER_SAFE_TAGS = [
"p",
"br",
"b",
"strong",
"ul",
"ol",
"li",
"hr",
"font",
];
const NEEDS_TEST_TAGS = [
"blockquote",
"h2",
"h3",
"span style",
];
8-2. 네이버용 템플릿을 더 단순하게 만드는 이유
- 네이버가 일부 HTML과 CSS를 제거할 수 있다.
- 외부 CSS 파일이나 JavaScript는 사용하기 어렵다.
- 따라서 복잡한 디자인보다 구조가 살아남는 템플릿이 중요하다.
Code snippet: 네이버용 단순 템플릿 예시
<h2>오늘의 학습 기록</h2>
<p><b>학습 주제:</b> CSS 선택자</p>
<p><b>핵심 요약:</b> 선택자는 자동화의 기준점이다.</p>
<hr>
<p><b>오늘 배운 내용</b></p>
<ul>
<li>선택자로 요소를 찾을 수 있다.</li>
<li>네이버는 적용 가능한 태그를 테스트해야 한다.</li>
</ul>
9단계. 실습 기록용 블로그 템플릿 만들기
실습할 때마다 같은 흐름으로 기록하면 나중에 프로젝트 로그가 됩니다.
Code snippet: 학습 기록 템플릿
# 오늘의 실습 기록
## 오늘 만든 것
-
## 왜 만들었나
-
## 막힌 부분
-
## 해결 과정
-
## 오늘 배운 것
-
## 다음 액션
-
10단계. 최종 MVP 점검표
- 입력 폼이 있다.
- WordPress용 HTML이 생성된다.
- 네이버 카페용 HTML이 생성된다.
- 복사 버튼이 작동한다.
- Python으로 HTML 파일이 생성된다.
- WordPress에 초안 또는 발행 글을 만들 수 있다.
- 네이버에서 적용되는 태그 테스트표가 있다.
- GitHub에 코드가 올라가 있다.
- hongsik.blog에 실습 기록이 올라가 있다.
Code snippet: MVP 완료 기준을 코드 주석으로 남기기
// Healthcare Post Builder MVP 기준
// 1. 사용자가 제목, 요약, 인용구, 학습 항목을 입력할 수 있다.
// 2. WordPress용 HTML과 네이버 카페용 HTML이 동시에 생성된다.
// 3. 생성된 HTML을 복사할 수 있다.
// 4. Python으로 같은 결과물을 파일로 만들 수 있다.
// 5. WordPress에는 자동 발행 또는 초안 생성이 가능하다.
// 6. 네이버 카페는 안전 HTML 적용 테스트 결과를 기준으로 템플릿을 개선한다.
이번 실습의 핵심
HTML은 글의 구조를 만들고, CSS는 표현 방식을 정리합니다. JavaScript는 입력값을 받아 템플릿을 생성하고, Python은 여러 글을 반복 생성할 수 있게 도와줍니다. WordPress는 자동 발행까지 가능하고, 네이버 카페는 안전 HTML을 검증하면서 적용 범위를 넓혀가야 합니다.
그래서 이번 트랙의 방향은 단순한 문법 암기가 아니라 네이버와 WordPress에 실제로 쓸 수 있는 글쓰기 자동화 도구를 만드는 것입니다.