minio 테스트 인증정보 삭제, 변수 처리 완료
All checks were successful
Build And Test / build-and-push (push) Successful in 4m25s

This commit is contained in:
2025-01-26 01:16:26 +09:00
parent d8111f6070
commit 1d38fe26bd
9 changed files with 381 additions and 52 deletions

View File

@ -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] = `![Image](${presignedUrl})`; // 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 = `![Image](${imageUrl})\n`;
const markdownImage = `![Image](${objectName})\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.");
}

View File

@ -0,0 +1,128 @@
{% extends "components/base.html" %}
{% block title %}Create Post{% endblock %}
{% block main_area %}
<h1 class="pt-3">Create New Post</h1>
<div class="container">
<div class="row">
<div class="col-md-6">
<form method="POST" id="post-form">
{% csrf_token %}
<div class="mb-3">
{{ form.title.label_tag }}
{{ form.title }}
</div>
<div class="mb-3">
{{ form.summary.label_tag }}
{{ form.summary }}
</div>
<div class="mb-3">
{{ form.tags.label_tag }}
{{ form.tags }}
</div>
<!-- 마크다운 에디터 -->
<h2>Contents</h2>
<textarea id="markdown-editor" name="contents" class="form-control" rows="10"></textarea>
<!-- 버튼 -->
<div class="d-flex justify-content-end mt-4">
<button type="submit" class="btn btn-primary me-2">Create Post</button>
<a href="{% url 'blog:post_list' %}" class="btn btn-secondary">Cancel</a>
</div>
</form>
</div>
<div class="col-md-6">
<div id="preview" class="border p-3 bg-light h-100 overflow-auto"></div>
</div>
</div>
<!-- 마크다운 파서 및 스크립트 -->
<script src="https://cdn.jsdelivr.net/npm/markdown-it/dist/markdown-it.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
<script>
// 마크다운 파서 초기화
const md = window.markdownit({
highlight: function (str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs
.highlight(str, {language: lang})
.value;
} catch (__) {}
}
return ''; // 기본 HTML 이스케이프 처리
}
});
// content 필드와 미리보기 연결
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 변환
preview.innerHTML = renderedContent;
// Highlight.js로 코드 블록 강조
document
.querySelectorAll("#preview pre code")
.forEach((block) => {
hljs.highlightElement(block);
});
});
// Ctrl+V로 이미지 붙여넣기 처리
textarea.addEventListener("paste", async function (event) {
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
for (const item of items) {
if (item.type.startsWith("image/")) {
const file = item.getAsFile();
if (!file)
return;
const formData = new FormData();
formData.append("image", file);
try {
// 이미지 업로드 API 호출
const response = await fetch("/obs_minio/upload/", {
method: "POST",
body: formData
});
if (response.ok) {
const data = await response.json();
const imageUrl = data.url; // 업로드된 이미지 URL
// 마크다운 에디터에 이미지 삽입
const markdownImage = `![Image](${imageUrl})\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);
});
} else {
alert("Image upload failed. Please try again.");
}
} catch (error) {
console.error("Error uploading image:", error);
alert("An error occurred during image upload.");
}
}
}
});
</script>
</div>
{% endblock %}

View File

@ -13,7 +13,7 @@
by.
{{ post.author | upper }}</div>
<!-- Rendered Markdown Content -->
<div>
<div id="post-content">
{{ post.render_markdown|safe }}
</div>
<hr>
@ -50,9 +50,50 @@
hljs.highlightElement(block);
});
});
</script>
<!-- Delete post -->
<script>
// Function to update images with presigned URLs
async function updateImagesWithPresignedUrls() {
const contentDiv = document.getElementById("post-content");
const contentHtml = contentDiv.innerHTML;
const parser = new DOMParser();
const doc = parser.parseFromString(contentHtml, "text/html");
const images = doc.querySelectorAll("img");
for (const img of images) {
const objectName = img.getAttribute("src"); // src에 저장된 object_name
try {
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();
img.setAttribute("src", data.presigned_url); // Presigned URL로 src 업데이트
}
} catch (error) {
console.error("Error fetching presigned URL:", error);
}
}
// 업데이트된 HTML을 다시 삽입
contentDiv.innerHTML = doc.body.innerHTML;
// Reapply syntax highlighting
document
.querySelectorAll("pre code")
.forEach((block) => {
hljs.highlightElement(block);
});
}
// Call the function when the page loads
document.addEventListener("DOMContentLoaded", updateImagesWithPresignedUrls);
// Delete post
document
.getElementById("delete-button")
.addEventListener("click", function () {
@ -64,4 +105,4 @@
}
});
</script>
{% endblock %}
{% endblock %}

View File

@ -3,8 +3,9 @@
{% block main_area %}
<h1 class="pt-3">Update Post</h1>
<div class="container">
<div class="row">
<div class="container mt-3">
<h5 class="text-danger">&#9671;마크다운 미리보기는 Contents 편집 내용 입력시 동작합니다.</h5>
<div class="row mt-3">
<div class="col-md-6">
<form method="POST" id="post-form">
{% csrf_token %}
@ -40,18 +41,113 @@
<!-- 마크다운 파서 및 스크립트 -->
<script src="https://cdn.jsdelivr.net/npm/markdown-it/dist/markdown-it.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
<script>
// 마크다운 파서 초기화
const md = window.markdownit();
const md = window.markdownit({
highlight: function (str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs
.highlight(str, {language: lang})
.value;
} catch (__) {}
}
return ''; // 기본 HTML 이스케이프 처리
}
});
// content 필드와 미리보기 연결
const textarea = document.getElementById("markdown-editor");
const preview = document.getElementById("preview");
// 미리보기 업데이트 함수
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 {
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] = `![Image](${presignedUrl})`;
}
} catch (error) {
console.error("Error fetching presigned URL:", error);
}
}
}
const renderedContent = md.render(lines.join("\n"));
preview.innerHTML = renderedContent;
// Highlight.js로 코드 블록 강조
document
.querySelectorAll("#preview pre code")
.forEach((block) => {
hljs.highlightElement(block);
});
}
// 실시간 미리보기 업데이트
textarea.addEventListener("input", function () {
const markdownContent = textarea.value; // textarea 내용 가져오기
preview.innerHTML = md.render(markdownContent); // 마크다운 -> HTML 변환
textarea.addEventListener("input", updatePreview);
// Ctrl+V로 이미지 붙여넣기 처리
textarea.addEventListener("paste", async function (event) {
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
for (const item of items) {
if (item.type.startsWith("image/")) {
const file = item.getAsFile();
if (!file)
return;
const formData = new FormData();
formData.append("image", file);
try {
// 이미지 업로드 API 호출
const response = await fetch("/obs_minio/upload/", {
method: "POST",
body: formData
});
if (response.ok) {
const data = await response.json();
const fullImageUrl = data.url; // 전체 URL
const objectName = fullImageUrl
.split("/")
.slice(-2)
.join("/");
// 마크다운 에디터에 이미지 삽입
const markdownImage = `![Image](${objectName})\n`;
textarea.value += markdownImage;
// 미리보기 업데이트
updatePreview();
} else {
alert("Image upload failed. Please try again.");
}
} catch (error) {
console.error("Error uploading image:", error);
alert("An error occurred during image upload.");
}
}
}
});
</script>
</div>