notion을 CMS로 이용하는 방법
(작성자: 정경호)
WP 테크 글을 발행할 수 있게 만들었는데,
동료의 요구 사항은 글을 더 쉽게 쓸 수 있도록 해달라는 것. Jekyll에 글을 쓰기 위해선 VS code를 열고 글을 작성하고 빌드하는 과정이 어렵다고 피드백을 해줬다.
또한 이미지를 붙여넣기가 너무 힘들다는 피드백도 있었다. 이미지는 포스트할 때 이미지 쉽게 업로드하기 글에서 설명한 것 처럼 raycast 와 extension을 이용하면 쉽게 가능한데. (이는 나한테만 쉬운거였음 ㅋㅋㅋ..) 나는 vim에 익숙하고 raycast에 익숙해서 쉽게 조합해서 사용하지만 이 도구에 익숙하지 않으면 다 장애물이 된다는 것을 알게 됐다.
그래서 notion을 CMS로 이용하기로 했다
처음부터 notion을 염두한건 아니었다. 다양한 후보군들이 존재하고 jekyll-admin 같은 전용 CMS도 존재한다. 하지만 notion 만큼 완성도를 가진건 아니었고 또 새로운 도구를 도입하는 것에 대한 내 부담도 있었다.
다행히도 우리 회사는 Notion을 많이 사용하고 구성원들도 익숙하므로 Notion을 CMS로 사용하면 다양한 이점을 가질 수 있을것 같았다.
그리고 jekyll-notion 프로젝트를 발견했다.
아래 이미지에서 보이듯 다양한 방식으로 notion 문서를 jekyll에 배포할 수 있으며 심지어 video도 임베딩 할 수 있는 방법을 제공한다.
사용방법을 여기서 자세히 말하진 않겠지만
- Notion connections를 만들고
- jekyll 프로젝트에 환경 설정을 하면
jekyll 을 빌드할때 notion 페이지를 가져와서 글을 렌더링할 수 있다.
사실 이 글은 Notion에서 쓰고 발행하는 첫 글이다
아래 이미지는 발행할 글을 갖고있는 테이블인데. 이 테이블에 글을 추가하고 Published = true
로 설정하면 새 글 발행이 가능하다.
노션을 쓰니 vim에 비해 느껴지는 장단점이 있는데. 노션이 이미지를 붙여넣기가 너무 쉽다는 것을 빼면 나머지 장점은 잘 모르겠다. vim은 아무래도 커스텀이 가능하니까 나에게 맞춰서 정말 편하게 할 수 있는데 Notion은 그게 안되니까.
아무튼 이렇게 notion - jekyll 연동은 잘 되었고 조금 부족하지만(더 필요한 부분은 jekyll을 확장하면 되니) 만족스러운 결과물이다.
💡 여기에서 글을 작성할 수 있다. 👉 https://www.notion.so/fnf-digital/3134312cba1f4feb95ca2593a515aeb0?v=a7935f8070a2403584339a791366a941
🚨 글 작성 후 배포를 해야하는데, README.md 를 참고하면된다.
이미지가 안뜬다
며칠이 지나고 다시 글을 읽어보니 이미지가 안뜬다는 사실을 발견했다. Notion의 AWS SignedUrl API가 관련있을거란 생각이 들었다. 첫날에는 잘 보였는데, 다음날 쯤 보니 이미지가 안보이기 시작했기 때문이다.
AWS SignedUrl
https://prod-files-secure.s3.us-west-2.amazonaws.com/d1e171ff-e12d-422d-b387-ee69736aa2cc/422a090d-8410-402f-82b6-7a193e481a85/image.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240828%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240828T065908Z&X-Amz-Expires=3600&X-Amz-Signature=2741632ffd686499e46ce91588f40b69bd90664a80b5a36df907c847ae1feaa8&X-Amz-SignedHeaders=host&x-id=GetObject
GetObject 할 수 있는 시간이 지정되있는 쿼리
X-Amz-Date=20240828T065908Z&X-Amz-Expires=3600
image url을 뽑아보니 위와같이 생겼고 시간에 대한 query param이 포함된걸 확인할 수 있었다.
이미지 다운로드, 교체 코드가 필요함
- 이미지가 안뜨는 문제를 해결하기 위해 아래와 같이 Notion의 s3 파일을 다운로드 받는 코드를 작성했다.
#!/bin/bash
# 1. _site 디렉토리에서 prod-files-secure.s3 내용을 포함하는 모든 파일 목록 만들기
echo "Searching for files containing 'https://prod-files-secure.s3.us-west-2.amazonaws.com/'..."
file_list=$(grep -rl 'https://prod-files-secure.s3.us-west-2.amazonaws.com/' ./_site --include=\*.html)
# 2. 위 파일 목록에서 https://prod-files-secure.s3/ 파일을 읽어와 asset/images 에 다운로드
echo "Downloading images to asset/images..."
mkdir -p ./assets/images
IFS=$'\n'
for file in $file_list;
do
# Extract URLs from the file
urls=$(grep -o 'https://prod-files-secure.s3.us-west-2.amazonaws.com/[^"]*\.\(png\|jpg\|jpeg\|gif\)[^"]*' "$file")
echo "Processing file: $file"
for url in $urls;
do
# 쿼리 파라미터 제거
clean_url=$(echo "$url" | sed 's/[?&].*//')
# URL에서 파일 경로 추출 (호스트 부분 이후)
filename=$(echo "$clean_url" | sed 's|https://prod-files-secure.s3.us-west-2.amazonaws.com/||')
# 파일이 이미 존재하는지 확인
if [ -f "./assets/images/$filename" ]; then
echo "File already exists, skipping: ./assets/images/$filename"
else
# 디렉토리가 존재하지 않으면 생성
mkdir -p "./assets/images/$(dirname "$filename")"
# amp; 삭제
removed_amp_url=$(echo "$url" | sed 's/amp;//g')
# 파일 다운로드
echo "Downloading: $url to ./assets/images/$filename"
curl -s "$removed_amp_url" -o "./assets/images/$filename"
fi
done
done
- 페이지가 로드 될 때, Notion s3 파일을 다운로드 받은 파일을 가르키도록 javascript 코드를
post.html
추가했다.
<script>
document.addEventListener("DOMContentLoaded", function() {
// 모든 img 태그와 배경 이미지 스타일을 검색
const images = document.querySelectorAll("img, [style*='background-image']");
images.forEach(image => {
let src = image.src || image.style.backgroundImage;
if (src.includes("https://prod-files-secure.s3.us-west-2.amazonaws.com/")) {
// 쿼리 파라미터를 제거하고, URL을 상대 경로로 변경
const cleanUrl = src.replace(/^https:\/\/prod-files-secure\.s3\.us-west-2\.amazonaws\.com\//, "/").split("?")[0];
const replacedUrl = `/assets/images/${cleanUrl}`;
if (image.src) {
// img 태그인 경우 src 속성 수정
image.src = replacedUrl;
} else if (image.style.backgroundImage) {
// background-image 스타일인 경우 수정
image.style.backgroundImage = `url('${replacedUrl}')`;
}
}
});
});
</script>
이미지가 잘 뜬다.