블로그 이미지
App 개발에 대한 내용을 다룰 예정입니다. AppleSherbet

카테고리

분류 전체보기 (39)
한국프로야구 어플 (18)
세미나 (2)
Java Development (13)
Android App소개 (3)
기타 (2)
당근마켓 (1)
Total299,563
Today15
Yesterday32
Viewing and posting comments
 
이전 튜토리얼에서 홈페이지(말그대로 index페이지)를 완성했었다. 이제 Post 상세 페이지를 작성해보자.
Post 페이지는 현재 포스트 내용, 포스트에 붙은 Comment들을 보여준다. 그리고 이번장에서 새로운 Comment를 추가 하는 것 까지 해보겠다.
 
Creating the 'show' action
 
Post 상세 페이지를 보여주기 위해서 Appliation 컨트롤러에 show() 액션을 만들자.
/yabe/app/controller/Application.java
 
public static void show(Long id) {
    Post post = Post.findById(id);
    render(post);
}
 
show() 액션은 매우 심플하다. 특정 포스트에 대한 id값을 인자로 받아서 Post.findById(id)를 이용해 Post 객체를 얻는다. 그리고 render(post) 를 호출하여 show.html을 브라우져에 렌더링 할 것을 요청한다.
 
[여기서 잠깐]
만약 show 액션에 들어온 id 파라메터가 정상적인 값이 아닌 경우 id값은 null이 되고 Play는 자동으로 validation error를 error 컨테이너에 넣게 된다. 차후 validation 값을 체크해 해당 에러를 핸들링 할 수 있다.
 
이제 브라우져에 보이게 될 show.html 을 만들자.
/yabe/app/views/Application/show.html
 
#{extends 'main.html' /}
#{set title:post.title /}
 
#{display post:post, as:'full' /}
 
우리가 이미 display tag를 만들어 놓았기 때문에 코드는 아주 간단하다. display tag를 full 모드로 호출하고 있다.
 
Adding links to the details page
 
이제 Post 상세 페이지로 이동 할 수 있는 링크를 만들자. 기존에 만들었던 display tag에 모든 링크는 '#' 로 남겨 두었다. 이 #으로 남겨놓은 링크 부분을 Application.show 액션을 호출 하게끔 해야한다. 이전에 설명 했듯이 Play에서는 @{...} 노테이션을 이용하면 쉽게 링크를 만들 수 있다. (만약 @{...} 의 기능을 눈으로 확인하고 싶다면 렌더링된 html 페이지를 '소스보기'로 한번 확인해 보면 이해가 쉬울 것이다.)
자 이제 /yabe/app/views/tags/diaplay.html 을 수정하자.
 

${_post.title}

 
홈페이지를 refresh 하고 post 의 타이틀을 클릭해보자.


잘나오는 것을 볼 수 있다. 이제 다시 홈으로 돌아갈 수 있도록 blog title 에 홈으로 가는 링크를 달아보자.
/yabe/app/views/main.html 을 열자
 
About this blog

${blogTitle}

${blogBaseline}

 
이제 홈과 Post 상세 페이지를 왔다갔다 할 수 있게 됐다.
 
Specifying a better URL
 
브라우져상에서 보면 상세 페이지의 URL이 아래와 같다.
 
/application/show?id=1
 
이렇게 나오는 이유는 Play에서 route 파일에 특별히 명시해두지 않은 URL의 요청이 오면 'catch all' route를 타기 때문이다.
 
*    /{controller}/{action}            {controller}.{action}  
 
Post 의 show액션을 위해 더 나은 URL을 명시해보자. REST Architecture에서 보면 URL 혹은 URI는 Web에 존재하는 모든 리소스를 표현하는 주소라고 이야기 한다. 그만큼 URL자체가 명확하게 표현하고자 하는바를 나타내는 것이 좋다.
/yabe/conf/routes 파일을 수정하자.
 
GET     /posts/{id}                             Application.show
 
{id} 라고 명시된 부분은 URL path에서 추출되는 것이다. URI pattern에 대해 궁금하다면 이곳을 한번 읽고 넘어가자.
 
브라우져를 refresh하고 URL이 수정한대로 잘 나오는지 보자.


Adding pagination
 
Post간의 이동을 쉽게 하기 위해 pagenation(페이지 번호)을 추가 할 것이다. view template에서 사용할 수 있게Post 클래스에 이전/다음 포스트를 리턴하는 메소드를 추가하자.
/yabe/app/models/Post.java
 
public Post previous() {
    return Post.find("postedAt < ? order by postedAt desc", postedAt).first();
}
 
public Post next() {
    return Post.find("postedAt > ? order by postedAt asc", postedAt).first();
}
 
위 코드는 최적화된 코드는 아니나 지금은 이정도로 충분하다. 이제 show.html template에 pagination 링크를 달아보자.  (#{display /} 바로 전에 추가)
/yabe/app/views/Application/show.html 
 

 
 
자 이제 comment form 을 만들시간이다. Application controller 에 postComment() 메소드를 만드는 것으로 부터 시작해보자.
/yabe/app/controllers/Application.java
public static void postComment(Long postId, String author, String content) {
    Post post = Post.findById(postId);
    post.addComment(author, content);
    show(postId);
}

postComment()에서는 Post 클래스에 미리 만들어 놓았던 addComment()를 사용하고 있다. 그리고 곧바로 show() 액션을 호출한다. 이제, show.html에 Comment 입력할 수 있는 form을 만들자. (html의 기본을 알고 있다면 form에 대해서는 쉽게 이해할 수 있을 것이다.)

show.html (#{display /} 부분 바로앞)에 아래의 코드를 추가하자.
/yabe/app/views/Application/show.html 

Post a comment

#{form @Application.postComment(post.id)}

#{/form}

코드에서 보면 현재 #{form @Application.postComment(post.id)} 라고 호출하고 있다. 실제 postComment 메소드를 살펴보면postComment(Long postId, String author, String content) 라고 되어있고 이는 post.id 외에 나머지 인자는 form 안에 name="author" 부분과 name="content" 부분에서 유저가 입력하는 값이 전달 됨을 알 수 있다.
 

이제 Comment 를 달수 있게 됐다. 

 

Adding validation

현재로썬 Comment를 만들때 아무런 validation 체크를 하지 않고 있다. author 필드와 content 필드는 모두 필수 입력 항목이므로 validation을 추가해보자. Play validation 메카니즘을 이용해 쉽게 http 파라메터의 validation 체크를 할 수 있다.
postComment() 액션 메소드에 @Required validation을 추가해보자.
/yabe/app/controllers/Application.java
 

public static void postComment(Long postId, @Required String author, @Required String content) {
    Post post = Post.findById(postId);
    if (validation.hasErrors()) {
        render("Application/show.html", post);
    }
    post.addComment(author, content);
    show(postId);
}

위처럼 인자에 @Required 어노테이션의 추가한후 Error 가 발생했는지 여부를 확인해 간단히 validation 체크를 할 수가 있다.
validation 객체는 controller에서 사용할 수 있는 헬퍼이고 validation.hasErrors() 메소드를 통해 에러 여부를 확인한다. 즉, 둘 값중 하나라도 값이 비어있으면 hasError()메소드는 false를 리턴한다. validation error 가 있을 경우 render("Application/show.html", post) 를 호출함으로써 명시적으로 post 인자를 전달하면서 show 템플릿을 호출한다. - 사실 단순히 show(postId); 를 호출해줘도 show 템플릿이 보여질 것이다. 하지만 stateless 한 특징상 show액션이 다시 불리면 validation error 정보가 사라지게 된다. 

자 이제 show.html 을 수정해서 validation error 가 있을 경우 저장되어있는 error 정보를 표시해주자. 
/yabe/app/views/Application/show.html 
 
 

Post a comment

#{form @Application.postComment(post.id)} #{ifErrors}

All fields are required!

#{/ifErrors}

#{/form}

Play 에서는 validation error 가 발생할 경우 뷰에서 사용할 수 있는 몇가지 유용한 태그를 제공한다. 위에서 사용한 #{ifErrors} 태그는 validation error 가 발생했을 경우에만 true 가 된다. #{else} 구문과 함께 사용할 수 있으며, 관련 다른 태그로 #{errors} - 순환을 하며 에러 메세지를 출력가능, #{error '필드 이름'/} - 특정 필드의 에러 메세지 출력할때 사용 등이 있다.

또 한가지 주목할 부분은 각 필드에 ${params.author} , ${params.content} 를 사용했다는 것이다. 이것은 postComment() 액션 호출시 넘겨진 파라메터들을 기억해서 값이 있을 경우 해당 필드에 표시해주는 역할을 한다. 

이제 포스팅을 하는 사용자에게 좀 더 그럴듯한 UI 를 제공하기 위해 에러가 날 경우 자동으로 포커싱해주는 약간의 JavaScript 코드를 넣겠다. 우선 [JQuery][JQuery Tools Expose] 자바스크립트 라이브러리 두개를 다운로드 받자. 그리고 yabe/public/javascripts 폴더에 복사한다. 
이제 라이브러리를 넣기 위해 main.html 을 아래와 같이 수정하자. (</head> 바로 위에 넣자)


    


이제 이 스크립트들을 사용할 수 있게됐다. show.html 템플릿을 아래처럼 수정하자.(show.html 맨 아래에 추가한다.)




예전보다 상당히 좋아졌다. 우리는 여기에 두 가지만 더 구현해 보겠다. 첫째로 성공적으로 comment 를 달았을 경우 성공했다는 메세지를 표시해보자. 우리는 flash scope 를 이용해 구현할 것이다. flash scope 란 ruby on rails 의 flash 와 거의 동일하다. 즉, 특정 컨트롤러의 액션에서 flash 메세지를 만들고 다음 액션의 처리까지만 메세지가 유지된다. 액션 A에서 만들어진 flash 메세지는 곧 이어 호출되는 액션 B에서 까지만(액션B의 template 포함) 유효한것이다. 

이제 postComment 액션을 수정해서 flash 에 성공 메세지를 추가하자. 

public static void postComment(Long postId, @Required String author, @Required String content) {
    Post post = Post.findById(postId);
    if(validation.hasErrors()) {
        render("Application/show.html", post);
    }
    post.addComment(author, content);
    flash.success("Thanks for posting %s", author);
    show(postId);
}

이제 flash scope 동안 전달된 메세지를 표시하기위해 show.html 을 수정하자. (show.html 가장 위에 추가한다)

…
#{if flash.success}
    

${flash.success}

#{/if} #{display post:post, as:'full' /} …


이제 마지막으로 postComment 액션을 위한 깜~~끔한 URL 을 새로 정의하자. (현재는 catch all route를 사용한다.)
/conf/routes 파일을 아래 처럼 수정하자.
POST    /posts/{postId}/comments                Application.postComment
Play framework으로 블로그 개발하기 (4) - Viewing and posting comments (끝)
저작자 표시
신고
Posted by AppleSherbet

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

티스토리 툴바