RSS 피드 썸네일 정보 추가

This commit is contained in:
2026-06-04 10:46:17 +09:00
parent 24611af8b6
commit accd933e99
9 changed files with 67 additions and 7 deletions

View File

@@ -22,6 +22,34 @@ const escapeXml = (value) => String(value || '')
*/
const normalizeSiteUrl = (value) => String(value || '').trim().replace(/\/+$/, '')
/**
* URL을 절대 URL로 변환한다.
* @param {unknown} value - 원본 URL
* @param {string} siteUrl - 사이트 URL
* @returns {string} 절대 URL
*/
const toAbsoluteUrl = (value, siteUrl) => {
const url = String(value || '').trim()
if (!url) {
return ''
}
if (/^https?:\/\//i.test(url)) {
return url
}
if (url.startsWith('//')) {
return `https:${url}`
}
if (url.startsWith('/')) {
return `${siteUrl}${url}`
}
return `${siteUrl}/${url.replace(/^\/+/, '')}`
}
/**
* RSS 날짜 문자열을 만든다.
* @param {unknown} value - ISO 날짜 문자열
@@ -45,6 +73,14 @@ const formatRssDate = (value) => {
*/
const getPostUrl = (post, siteUrl) => `${siteUrl}/post/${encodeURIComponent(post.slug)}`
/**
* 게시물 RSS 썸네일 URL을 반환한다.
* @param {Object} post - 게시물
* @param {string} siteUrl - 사이트 URL
* @returns {string} 썸네일 절대 URL
*/
const getPostThumbnailUrl = (post, siteUrl) => toAbsoluteUrl(post.ogImage || post.featuredImage, siteUrl)
/**
* RSS item XML을 만든다.
* @param {Object} post - 게시물
@@ -53,6 +89,7 @@ const getPostUrl = (post, siteUrl) => `${siteUrl}/post/${encodeURIComponent(post
*/
const buildRssItem = (post, siteUrl) => {
const postUrl = getPostUrl(post, siteUrl)
const thumbnailUrl = getPostThumbnailUrl(post, siteUrl)
const description = createPostSummary(post.excerpt, post.content, {
maxLength: 280,
appendEllipsis: true
@@ -65,6 +102,8 @@ const buildRssItem = (post, siteUrl) => {
` <link>${escapeXml(postUrl)}</link>`,
` <guid isPermaLink="true">${escapeXml(postUrl)}</guid>`,
` <pubDate>${escapeXml(formatRssDate(publishedAt))}</pubDate>`,
thumbnailUrl ? ` <media:thumbnail url="${escapeXml(thumbnailUrl)}" />` : '',
thumbnailUrl ? ` <media:content url="${escapeXml(thumbnailUrl)}" medium="image" />` : '',
description ? ` <description>${escapeXml(description)}</description>` : '',
' </item>'
].filter(Boolean).join('\n')
@@ -89,7 +128,7 @@ export const buildRssFeed = async (selfPath = '/rss.xml', fallbackSiteUrl = '')
return [
'<?xml version="1.0" encoding="UTF-8"?>',
'<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">',
'<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">',
' <channel>',
` <title>${escapeXml(settings.title)}</title>`,
` <link>${escapeXml(siteUrl)}</link>`,