TIL_220801_강의용 게시판 프로젝트 6

창고·2022년 8월 2일
0

들어가기에 앞서
실제 프로젝트 진행했던 코드 내용 및 세부 내용은 일부만 업로드하였습니다.

10. 뷰 구축

(2) html 테스트

  • resource > templates > new directory 'articles' > new HTML 'index.html'
  • semantic tag 사용, 초기 뼈대 구상
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>게시판 페이지</title>
</head>

<body>

  <header>
    header 삽입부
    <hr>
  </header>

  <main>
    검색창

    테이블

    내비게이션 바
  </main>

  <footer>
    <hr>
    footer 삽입부
  </footer>

</body>
</html>
  • 번외 : ctrl + d 한줄 복사
  • 검색창 1차 구현
  • 테스트 구현을 위해 ArticleController 메소드 추가
@RequestMapping("/articles")
@Controller
public class ArticleController {

    @GetMapping
    public String articles(ModelMap map) {
        map.addAttribute("articles", List.of());
        return "articles/index";
    }
}
  • 테스트 메소드 contentType > contentTypeCompatibleWith로 변경 (호환되는 타입도 포함)
    • contentType은 완전히 일치해야 통과를 시키는데, 테스트 페이지가 UTF-8이 포함되어 있어 HTML과 완전히 일치하지 않는다고 판단함.
      따라서 어느 정도 호환되는 타입까지 지원되는 contentTypeCompatibleWith로 변경
 @DisplayName("[VIEW][GET] 게시글 리스트 (게시판 페이지 - 정상 호출")
    @Test
    public void givenNothing_whenRequestingArticlesView_thenReturnsArticlesView() throws Exception {
        // Given

        // When & Then
        mvc.perform(get("/articles"))
                .andExpect(status().isOk()) // 정상 호출인지
                .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_HTML)) // HTML 파일의 컨텐츠인지 (호환되는 컨텐츠 포함)
                .andExpect(view().name("articles/index")) // 뷰 이름 검사
                .andExpect(model().attributeExists("articles")); // 내부에 값이 있는지 (이름을 articles로 지정)
    }

(3) 게시판 페이지 작성

  • 테스트 통과 후 application 실행, articles 접근
  • 테이블 1차 구현 및 확인
  • 번외 : ctrl+shift+f9 로 변경된 내용 바로 반영
  • ctrl+shift+f9와 구글 LiveReload 활용 시 변경된 내용이 새로고침을 하지 않아도 실시간으로 반영됨
  • 내비게이션 1차 구현 및 확인
    <nav>
      <table>
        <tr>
          <td>previous</td>
          <td>1</td>
          <td>2</td>
          <td>3</td>
          <td>4</td>
          <td>next</td>
        </tr>
      </table>
    </nav>

  • 특정 구역을 하나의 컴포넌트로 구성해보기 (템플릿 엔진 대부분 지원)
    • header, footer와 같이 어느 페이지에서든 반복되는 요소의 경우 별도의 파일로 분리, 개개의 페이지에서 삽입할 수 있게 지원
  • html 파일 내 Thymeleaf 템플릿임을 명시
  <html lang="ko" xmlns:th="http://www.thymeleaf.org">
  • header 부분 변경
  <header th:replace="header :: header"></header>
  • footer 부분 변경
  <footer>  <header th:replace="footer :: footer"></header></footer>
  • header, footer, main index html 제작
    • 아래 설정 부분에서 tree appearance 에서 compact middle package 해제 후 제작
  • header 템플릿, footer 템플릿 예시
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Header template</title>
</head>
<body>
  <header>
    header 삽입부
    <hr>
  </header>
</body>
</html>
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Footer template</title>
</head>
<body>
  <footer>
    <hr>
    footer 삽입부
  </footer>
</body>
</html>

(4) Decoupled Template Logic

  • Thymeleaf 기능과 HTML5를 완전히 분리 (HTML5 기반의 정적 페이지 + 분리된 Thymeleaf 기능)
  • 그러나 기본 properties에는 아직 없어 javaconfig로 수동으로 해야 함
  • 미리 만들어둔 파일 https://gist.github.com/djkeh/6e1d557ce8c466135b1541d342b1c25c
  • config 폴더에 클래스로 생성, 메인 어플리케이션 클래스에 @ConfigurationPropertiesScan 추가
  • 코드 일부 수정
    @RequiredArgsConstructor
    @Getter
    @ConstructorBinding
    @ConfigurationProperties("spring.thymeleaf3")
    public static class Thymeleaf3Properties {
        private final boolean decoupledLogic;
  • application.yml 수정
  thymeleaf3.decoupled-logic: true
  • spring initializr > spring configuration processor
  • clean, build 진행
  • index에서 헤더/푸터 부분의 th 문법 지우고 다음과 같이 수정
  <header id="header"></header>
  <footer id="footer"></footer>
  • index.th.xml 생성
<?xml version="1.0"?>
<thlogic>
    <attr sel="#header" th:replace="header :: header" />
    <attr sel="#footer" th:replace="footer :: footer" />
</thlogic>

(5) 게시글 페이지 작성

  • ArticleController 메소드 추가
    @GetMapping("/{articleId}")
    public String article(@PathVariable Long articleId, ModelMap map) {
        map.addAttribute("article", "article"); // TODO : 실제 데이터 구현할 때 여기에 넣어야 함
        map.addAttribute("articleComments", List.of());
        return "articles/detail";
    }
  • detail.th.xml 추가 (index.th.xml 복붙)
<?xml version="1.0"?>
<thlogic>
    <attr sel="#header" th:replace="header :: header" />
    <attr sel="#footer" th:replace="footer :: footer" />
</thlogic>
  • detail 추가 및 내용 수정 (index 복붙)
profile
공부했던 내용들을 모아둔 창고입니다.

0개의 댓글