-
Notifications
You must be signed in to change notification settings - Fork 2
리팩토링
글(Post)과 댓글(Comment)을 보여주는 코드를 하나의 html 파일에 작성해 나가면 파일이 너무 길어지고 가독성이 떨어진다. 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을 통해서 출력될 것이다.
새로운 댓글을 작성하는 부분도 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" .}}
각 기능별로 뷰 파일이 분리가 되어 전반적으로 코드가 훨씬 깔끔해졌다.
포스트 작성 폼이 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" .}}
뷰를 기능에 따라 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 적용