diff --git a/README.md b/README.md index 8a0a895..7e03d01 100644 --- a/README.md +++ b/README.md @@ -47,4 +47,11 @@ docker 또는 kubernetes를 이용하여 배포 합니다. * SQL_PORT='DB_SVR_portnumber' * CSRF_TRUSTED_ORIGINS=https://www.example.com,https://butler.example.com,https://butler.example.com:8000 * MM_URL=https://mm.example.com/hooks/${hash} -* (기능 미구현)MINIO_URL=https://minio.example.com/ \ No newline at end of file +* (기능 미구현)MINIO_URL=https://minio.example.com/ + +## 특이사항 +### markdown에디터에 삽입된 이미지 렌더링할때 404에러가 발생하지만, 실제 동작은 잘 되는 이유. +* MinIO와 연결하여 이미지 저장 기능을 사용 할 수 있도록 구현되어 있습니다. +* Bucket을 private로 설정하는 것을 선호하므로 Presigned URL로 호출해 오도록 설정되어 있습니다. +* 게시물에는 Presigned URL이 아닌 버킷에 저장된 이미지의 이름만 들어있으므로 get_presigned_url을 이용하여 Presigned URL을 호출하기전에 렌더링이 발생하는 에러 메세지입니다. +* 에러가 아니니 기능상 문제 없이 사용 가능합니다. \ No newline at end of file diff --git a/blog/templates/blog/create_post.html b/blog/templates/blog/create_post.html index d97db32..7e2247f 100644 --- a/blog/templates/blog/create_post.html +++ b/blog/templates/blog/create_post.html @@ -60,10 +60,38 @@ const textarea = document.getElementById("markdown-editor"); const preview = document.getElementById("preview"); - // 실시간 미리보기 업데이트 - textarea.addEventListener("input", function () { - const markdownContent = textarea.value; // textarea 내용 가져오기 - const renderedContent = md.render(markdownContent); // 마크다운 -> HTML 변환 + // 미리보기 업데이트 함수 + async function updatePreview() { + const markdownContent = textarea.value; + const lines = markdownContent.split("\n"); + + for (let i = 0; i < lines.length; i++) { + const match = lines[i].match(/!\[Image\]\((.+)\)/); + if (match) { + const objectName = match[1]; + try { + // Presigned URL 가져오기 + const response = await fetch("/obs_minio/get_presigned_url/", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({object_name: objectName}) + }); + + if (response.ok) { + const data = await response.json(); + const presignedUrl = data.presigned_url; + lines[i] = ``; // Presigned URL로 업데이트 + } + } catch (error) { + console.error("Error fetching presigned URL:", error); + } + } + } + + // 마크다운 렌더링 및 미리보기 업데이트 + const renderedContent = md.render(lines.join("\n")); preview.innerHTML = renderedContent; // Highlight.js로 코드 블록 강조 @@ -72,7 +100,10 @@ .forEach((block) => { hljs.highlightElement(block); }); - }); + } + + // 실시간 미리보기 업데이트 + textarea.addEventListener("input", updatePreview); // Ctrl+V로 이미지 붙여넣기 처리 textarea.addEventListener("paste", async function (event) { @@ -96,23 +127,18 @@ if (response.ok) { const data = await response.json(); - const imageUrl = data.url; // 업로드된 이미지 URL + const fullImageUrl = data.url; // 전체 URL + const objectName = fullImageUrl + .split("/") + .slice(-2) + .join("/"); // 마크다운 에디터에 이미지 삽입 - const markdownImage = `\n`; + const markdownImage = `\n`; textarea.value += markdownImage; // 미리보기 업데이트 - const markdownContent = textarea.value; - const renderedContent = md.render(markdownContent); - preview.innerHTML = renderedContent; - - // Highlight.js로 코드 블록 강조 - document - .querySelectorAll("#preview pre code") - .forEach((block) => { - hljs.highlightElement(block); - }); + updatePreview(); } else { alert("Image upload failed. Please try again."); } diff --git a/blog/templates/blog/create_post_url생성테스트.html b/blog/templates/blog/create_post_url생성테스트.html new file mode 100644 index 0000000..d97db32 --- /dev/null +++ b/blog/templates/blog/create_post_url생성테스트.html @@ -0,0 +1,128 @@ +{% extends "components/base.html" %} +{% block title %}Create Post{% endblock %} + +{% block main_area %} +