Skip to content
Jaehue Jang edited this page Jan 11, 2015 · 4 revisions

글(Post)과 댓글(Comment)을 보여주는 코드를 하나의 html 파일에 작성해 나가면 파일이 너무 길어지고 가독성이 떨어진다. Partial을 통해 기능별로 코드를 분리해보자.

1. 댓글 목록을 Partial 뷰로 만들기

포스트의 댓글을 보여주는 부분을 Partial 뷰로 추출한다. app/views/Comment 경로에 _comment.html 파일을 생성하고 다음과 같이 코드를 작성한다.

{{range .post.Comments}}
  <p>
    <mark>
      <b>{{.Commenter}}:</b>
    </mark>
    {{.Body}}
    <small>
      ({{formatDate .CreatedAt}})
    </small>
  </p>
{{end}}

이 후에는 댓글을 보여주는 부분을 {{template "Comment/_comment.html" .}}로 대체할 수 있다. 아래는 Show 뷰에 Partial 뷰를 적용한 코드이다.

{{set . "title" "Show Post"}}
{{template "header.html" .}}

<p>
  <b>Title: </b>
  {{ .post.Title}}
</p>

<p>
  <b>Body: </b>
  {{ .post.Body}}
</p>

<h4>Comments: </h4>
{{template "Comment/_comment.html" .}}

<h4>Add a comment:</h4>
<form method="POST" action="{{url "Comment.Create" .post.Id}}">  
  <div>
    {{with $field := field "commenter" .}}
      <label for="commenter">Name</label>
      <input type="text" id="commenter" name="{{$field.Name}}" placeholder="Commenter"/>
    {{end}}
  </div>
  <div>
    {{with $field := field "body" .}}
      <label for="body">Body</label>
      <input type="text" id="body" name="{{$field.Name}}" placeholder="Body"/>
    {{end}}
  </div>
  <button type="submit">Add comment</button>
</form>

<a href="{{url "Post.Edit" .post.Id}}">Edit</a>
<a href="{{url "Post.Index"}}">Back</a>

{{template "footer.html" .}}

이제 .post.Comments 내의 각 댓글은 app/views/Post/_comment.html을 통해서 출력될 것이다.

2. 댓글 작성 폼을 Partial 뷰로 만들기

새로운 댓글을 작성하는 부분도 Partial 뷰로 옮겨보자. app/views/Comment 경로에 _form.html 파일을 생성하고 다음과 같이 코드를 작성한다.

<form method="POST" action="{{url "Comment.Create" .post.Id}}">  
  <div>
    {{with $field := field "commenter" .}}
      <label for="commenter">Name</label>
      <input type="text" id="commenter" name="{{$field.Name}}" placeholder="Commenter"/>
    {{end}}
  </div>
  <div>
    {{with $field := field "body" .}}
      <label for="body">Body</label>
      <input type="text" id="body" name="{{$field.Name}}" placeholder="Body"/>
    {{end}}
  </div>
  <button type="submit">Add comment</button>
</form>

그 후에 아래 코드로 app/views/Post/Show.html을 수정한다.

{{set . "title" "Show Post"}}
{{template "header.html" .}}

<p>
  <b>Title: </b>
  {{ .post.Title}}
</p>

<p>
  <b>Body: </b>
  {{ .post.Body}}
</p>

<h4>Comments: </h4>
{{template "Comment/_comment.html" .}}

<h4>Add a comment:</h4>
{{template "Comment/_form.html" .}}

<a href="{{url "Post.Edit" .post.Id}}">Edit</a>
<a href="{{url "Post.Index"}}">Back</a>

{{template "footer.html" .}}

각 기능별로 뷰 파일이 분리가 되어 전반적으로 코드가 훨씬 깔끔해졌다.

3. 포스트 작성 폼을 Partial 뷰로 만들기

포스트 작성 폼이 Edit.html과 New.html에 중복으로 작성되어 있다. 이 부분도 Partial 뷰로 추출해보자.

app/views/Post 경로에 _form.html 파일을 생성하고 폼 작성 코드를 추출하여 다음과 같이 작성한다.

<form method="POST" action="{{if .post.Id}}{{url "Post.Update" .post.Id}}{{else}}{{url "Post.Create"}}{{end}}">
  {{$post := .post}}
  {{with $field := field "title" .}}
    <div>
      <label for="title">Title</label>
      <input type="text" id="title" name="{{$field.Name}}" placeholder="Enter title" value="{{if $field.Flash}}{{$field.Flash}}{{else}}{{$post.Title}}{{end}}"/>
    </div>
  {{end}}

  {{with $field := field "body" .}}
    <div>
      <label for="title">Body</label>
      <textarea id="body" name="{{$field.Name}}">
        {{if $field.Flash}}{{$field.Flash}}{{else}}{{$post.Body}}{{end}}
      </textarea>
    </div>
  {{end}}
  <button type="submit">Create Post</button>
</form>

여기서 주의해야 할 부분은 폼의 action url 부분이다. 새글 작성 폼과 글 수정 폼은 action의 url이 서로 다르기 때문에 폼의 action url을 {{if .post.Id}}{{url "Post.Update" .post.Id}}{{else}}{{url "Post.Create"}}{{end}}와 같이 작성해주었다. .post.Id가 존재하는 경우는 이미 존재하는 글을 수정하는 경우이므로 {{url "Post.Update" .post.Id}}를 출력하도록 했고, .post.Id가 존재하지 않는 경우는 새글을 작성하는 경우이므로 {{url "Post.Create"}}를 출력하도록 했다.

이제 app/views/Post/New.html을 아래와 같이 수정해보자.

{{set . "title" "New Post"}}
{{template "header.html" .}}

{{template "Post/_form.html" .}}

<a href="{{url "Post.Index"}}">Back</a>

{{template "footer.html" .}}

app/views/Post/Edit.html도 수정한다.

{{set . "title" "Edit Post"}}
{{template "header.html" .}}

{{template "Post/_form.html" .}}

<a href="{{url "Post.Show" .post.Id}}">Show</a>
<a href="{{url "Post.Index"}}">Back</a>

{{template "footer.html" .}}

4. Partial 뷰 작업 - 댓글 지우기

뷰를 기능에 따라 Partial 뷰로 분리하는 작업을 완료하였다. 이제는 Partial 뷰에 새로운 기능을 추가해 볼 것이다. _comment.html 파일에 댓글을 삭제하는 기능을 추가해보자.

먼저 app/controller/comment.go 파일에 다음과 같이 Destroy 액션을 작성한다.

func (c Comment) Destroy(postId, id int) revel.Result {
  if _, err := c.Txn.Exec("delete from comments where id=?", id); err != nil {
    panic(err)
  }
  return c.Redirect(routes.Post.Show(postId))
}

다음으로는 라우트에 Destroy 액션을 정의해주자. /posts/:postId/comments/:id로 DELETE 방식으로 요청을 보내거나 /posts/:postId/comments/:id/delete url로 GET으로 요청을 보냈을때 Comment 컨트롤러의 Destroy 액션으로 전달되도록 conf/routes 파일에 다음을 추가한다.

GET     /posts/:postId/comments/:id/delete      Comment.Destroy
DELETE  /posts/:postId/comments/:id             Comment.Destroy

마지막으로 app/views/Comment/_comment.html 뷰에 댓글 삭제 버튼을 추가하자.

{{$post := .post}}
{{range .post.Comments}}
  <p>
    <mark>
      <b>{{.Commenter}}:</b>
    </mark>
    {{.Body}}
    <small>
      ({{formatDate .CreatedAt}})
    </small>
    <a href="{{url "Comment.Destroy" $post.Id .Id}}">Destroy</a>
  </p>
{{end}}

이제 기본 기능을 모두 갖춘 블로그가 완성되었다.

PREV: 댓글 기능 만들기
NEXT: 데이타 처리에 ORM 적용