사이먼's 코딩노트

[SpringBoot] 앵커 이동 / 마크다운 적용 본문

Java/SpringBoot

[SpringBoot] 앵커 이동 / 마크다운 적용

simonpark817 2024. 5. 16. 22:48

[앵커 이동 기능 추가]

  • 현재까지 구현된 SBB 프로그램에서 답변을 작성하거나 수정하면 자동으로 페이지 상단으로 스크롤이 이동해서 자신이 작성한 답변을 확인하려면 다시 스크롤을 내려서 확인해야 되는 문제점이 있다.
  • 해당 문제는 답변을 추천한 경우에도 발생하는데, 우리는 a태그를 활용하여 답변 등록, 수정, 추천 시 앵커 태그를 이용하여 원하는 위치로 이동시킬 수 있다.
  • 먼저 question_detaill.html 템플릿에서 아래와 같이 답변이 반복되는 구간에서 반복문이 들어간 div태그의 코드를 수정한다.
<!-- 답변 반복 시작 -->
<div th:id="|answer_${answer.id}" class="card my-3" th:each="answer : ${question.answerList}">
  • 앵커 태그의 id 속성은 반드시 유일한 값이어야 하므로 답변의 id값을 사용했다.
  • 앵커 태그의 id 속성이 유일하지 않고 중복된 값이 존재한다면 맨 처음 한 개를 제외한 나머지 앵커는 제대로 동작하지 않게된다.

 

[리다이렉트 수정]

  • 답변을 등록하거나 수정할 때 위에서 지정한 앵커 태그를 사용해 원하는 화면 위치로 이동할 수 있도록 코드를 수정해봅시다.
  • AnswerController.java 클래스에서 createAnswer(), answerModify(), answerVote() 메서드의 return 값을 아래 코드와 같이 수정해준다.
return "redirect:/question/detail/%d#answer_%d".formatted(answer.getQuestion().getId(), id);
  • 리다이렉트되는 질문 상세 페이지 URL에 #answer_%s와 같이 앵커 태그에의 id값을 넣어준다.
  • 위 코드를 모두 적용하고 로컬 서버를 다시 실행하면 질문 상세 페이지에서 답변 내용을 작성하고 '답변등록' 버튼을 클릭했을 때, 페이지의 가장 상단으로 가지 않고 새로 남긴 답변이 있는 섹션의 위치로 화면이 이동하게 되는 것을 확인할 수 있다.
  • 해당 기능을 '좋아요' 버튼을 클릭했을 때와 답변을 수정을 마쳤을 때도 동일하게 적용된다. 

 

[마크다운 적용하기]

  • Github나 Notion과 같이 자주 사용하는 서비스에서는 글을 작성할 때 마크다운이라는 도구를 사용한다.
  • 마크다운은 텍스트기반의 마크업 언어로, HTML과 달리 쉽고 간단한 문법을 사용하며 텍스트 편집기를 통해 웹상에서 글자를 강조하거나 제목, 목록, 이미지, 링크 등을 추가할 때도 유용하게 활용할 수 있다.
  • 그렇기 때문에 SBB 프로그램에도 질문이나 답변 등의 글쓰기 작성 도구로 마크다운을 적용해봅시다.

 

[마크다운 설치]

  • 마운다운 기능을 구현하기 위해선 먼저 마크다운 라이브러리를 설치해야 한다.
  • 아래와 같이 build.gradle에서 dependencies 안에 코드를 추가하여 마크다운을 설치해봅시다.
// 마크다운
implementation 'org.commonmark:commonmark:0.22.0'

 

[마크다운 컴포넌트 작성]

  • 라이브러리 설치를 마쳤다면 질문이나 답변의 '내용' 부분에 마크다운을 작성해봅시다.
  • 컨트롤러에서 질문이나 답변을 조회한 후에 마크다운 라이브러리를 적용하면 반환된 HTML을 얻을 수 있다.
  • 하지만 여기서는 개별적으로 사용하기보다 좀 더 범용적으로 사용할 수 있는 마크다운 컴포넌트를 만들고 타임리프 템플릿에서 작성한 마크다운 컴포넌트를 사용하는 방법을 이용해봅시다.
  • 먼저 CommonUtil.java 클래스를 생성하고 아래와 같이 코드를 작성해봅시다.
package com.sbs.sbb;

import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;
import org.springframework.stereotype.Component;

@Component
public class CommonUtil {
    public String markdown(String markdown) {
        Parser parser = Parser.builder().build();
        Node document = parser.parse(markdown);
        HtmlRenderer renderer = HtmlRenderer.builder().build();
        return renderer.render(document);
    }
}
  • @Component 어노테이션을 사용하여 CommonUtil.java 클래스를 생성하였다.
  • CommonUtil.java 클래스는 스프링 부트가 관리하는 빈으로 등록되고, 빈으로 등록된 컴포넌트는 템플릿에서 사용할 수 있게된다.
  • 지금과 같이 클래스의 이름을 CommonUtil로 지었을 경우 타임리프에서 접근할 때는 소문자를 사용하여 @commonUtil 과 같이 접근해야 한다.
  • CommonUtil.java 클래스에는 markdown() 메서드는 마크다운 텍스트를 HTML 문서로 변환하여 리턴한다.
  • 즉, 마크다운 문법이 적용된 일반 텍스트를 변환된 HTML로 리턴한다는 뜻이다.

 

[question_detail.html 템플릿 수정]

  • 마지막으로 질문 상세 페이지인 question_detail.html 템플릿에서 질문과 답변 영역에 아래와 같은 태그를 추가해봅시다.
<div class="card-text" th:utext="${@commonUtil.markdown(question.content)}"></div>
<div class="card-text" th:utext="${@commonUtil.markdown(answer.content)}"></div>
  • ${@commonUtil.markdown(question/answer.content)}와 같이 마크다운 컴포넌트를 적용하였다.
  • 여기서 주의할 점은 th:text가 아닌 th:utext를 사용했다는 점이다.
  • 만약 th:utext 대신 th:text를 사용할 경우 HTML의 태그들이 이스케이프 처리되어 화면에 그대로 보이게된다.
  • 마크다운으로 변환된 HTML 문서를 제대로 표시하려면 이스케이프 처리를 하지 않고 출력하는 th:utext를 사용해야 한다.
  • 위 코드를 모두 작성하고 로컬 서버를 다시 실행하면 질문이나 답변의 내용을 입력할 때 마크다운 형식의 문법을 통해서 작성하면 해당 문법이 변환되어 HTML에 표시되는 것을 확인할 수 있다.

질문 내용 작성 시 마크다운 문법 사용

 

마크다운이 적용된 질문 내용

 

반응형