고정 페이지 HTML 문서 모드 추가 v1.5.1
This commit is contained in:
34
server/middleware/html-page-renderer.js
Normal file
34
server/middleware/html-page-renderer.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import { getMethod, getRequestURL, setResponseHeader } from 'h3'
|
||||
import { getPageBySlug } from '../repositories/content-repository'
|
||||
|
||||
/**
|
||||
* 공개 페이지가 HTML 문서 모드일 때 Nuxt 렌더링 대신 원문 HTML을 응답한다.
|
||||
* @param {import('h3').H3Event} event - 요청 이벤트
|
||||
* @returns {Promise<string | void>} HTML 문서 또는 다음 핸들러 진행
|
||||
*/
|
||||
export default defineEventHandler(async (event) => {
|
||||
const method = getMethod(event)
|
||||
|
||||
if (method !== 'GET' && method !== 'HEAD') {
|
||||
return
|
||||
}
|
||||
|
||||
const pathname = getRequestURL(event).pathname
|
||||
const match = pathname.match(/^\/pages\/([^/]+)\/?$/)
|
||||
|
||||
if (!match) {
|
||||
return
|
||||
}
|
||||
|
||||
const slug = decodeURIComponent(match[1])
|
||||
const page = await getPageBySlug(slug)
|
||||
|
||||
if (page?.renderMode !== 'html_document') {
|
||||
return
|
||||
}
|
||||
|
||||
setResponseHeader(event, 'content-type', 'text/html; charset=utf-8')
|
||||
setResponseHeader(event, 'cache-control', 'no-cache')
|
||||
|
||||
return page.content || ''
|
||||
})
|
||||
@@ -62,6 +62,7 @@ const mapPageRow = (row) => ({
|
||||
title: row.title,
|
||||
slug: row.slug,
|
||||
content: row.content,
|
||||
renderMode: row.render_mode || 'markdown',
|
||||
featuredImage: row.featured_image,
|
||||
createdAt: row.created_at.toISOString(),
|
||||
updatedAt: row.updated_at.toISOString()
|
||||
@@ -538,12 +539,14 @@ export const createAdminPage = async (input) => {
|
||||
title,
|
||||
slug,
|
||||
content,
|
||||
render_mode,
|
||||
featured_image
|
||||
)
|
||||
VALUES (
|
||||
${input.title},
|
||||
${input.slug},
|
||||
${input.content},
|
||||
${input.renderMode},
|
||||
${input.featuredImage}
|
||||
)
|
||||
RETURNING *
|
||||
@@ -571,6 +574,7 @@ export const updateAdminPage = async (id, input) => {
|
||||
title = ${input.title},
|
||||
slug = ${input.slug},
|
||||
content = ${input.content},
|
||||
render_mode = ${input.renderMode},
|
||||
featured_image = ${input.featuredImage},
|
||||
updated_at = now()
|
||||
WHERE id = ${id}
|
||||
|
||||
@@ -4,9 +4,15 @@ import { normalizeMarkdownContent } from '../../lib/markdown-content-normalizer.
|
||||
export const adminPageInputSchema = z.object({
|
||||
title: z.string().trim().min(1),
|
||||
slug: z.string().trim().min(1).regex(/^[a-z0-9가-힣]+(?:-[a-z0-9가-힣]+)*$/),
|
||||
content: z.preprocess(normalizeMarkdownContent, z.string()).default(''),
|
||||
renderMode: z.enum(['markdown', 'html_document']).default('markdown'),
|
||||
content: z.string().default(''),
|
||||
featuredImage: z.string().trim().nullable().default(null)
|
||||
})
|
||||
}).transform((input) => ({
|
||||
...input,
|
||||
content: input.renderMode === 'html_document'
|
||||
? input.content
|
||||
: normalizeMarkdownContent(input.content)
|
||||
}))
|
||||
|
||||
/**
|
||||
* 관리자 페이지 입력값 정리
|
||||
|
||||
@@ -28,6 +28,7 @@ export const pageSchema = z.object({
|
||||
title: z.string().min(1),
|
||||
slug: z.string().min(1),
|
||||
content: z.string(),
|
||||
renderMode: z.enum(['markdown', 'html_document']).default('markdown'),
|
||||
featuredImage: z.string().nullable().default(null),
|
||||
createdAt: z.string(),
|
||||
updatedAt: z.string()
|
||||
|
||||
@@ -37,6 +37,7 @@ const samplePages = [
|
||||
title: 'About',
|
||||
slug: 'about',
|
||||
content: 'sori.studio 소개 페이지입니다.',
|
||||
renderMode: 'markdown',
|
||||
featuredImage: null,
|
||||
createdAt: now,
|
||||
updatedAt: now
|
||||
|
||||
Reference in New Issue
Block a user