행복한 아빠

[Grails1.0 사용자 가이드] 6. 웹 계층 - 3 본문

Grails

[Grails1.0 사용자 가이드] 6. 웹 계층 - 3

행복한아빠 2008. 3. 6. 20:01


6. 웹 계층 - 3

6.3 태그 라이브러리

Java Server Pages(JSP)와 같이 GSP도 사용자 정의 태그 라이브러리 개념을 지원한다. JSP와는 달리 Grails 태그 라이브러리 메커니즘은 단순하고 우와하고 실행시간에 완벽하게 reload할 수 있다.

아주 간단하게도 태그 라이브러리를 만들기 위해서는 grails-app/tablib 디렉토리에 TagLib으로 끝나는 Groovy 클래스를 만들기만 하면 된다.(이것이 태그 라이브러리 생성 약속(convention)이다.)

class SimpleTagLib {
}

이제 태그를 생성하기 하기 위해 단지 태그 애트리뷰트(attribute)와 몸체 내용(body content) 두 개의 아규먼트를 가진 코드 블럭을 가진 속성을 생성하면 된다.

class SimpleTagLib {
    def simple = { attrs, body ->
    }
}

attrs 아규먼트는 태그 애트리뷰트의 간단한 맵이다. body 아규먼트는 몸체 내용을 반환하는 호출이 가능한 코드 블럭이다.

class SimpleTagLib {
    def emoticon = { attr, body ->
        out << body() << attr.happy == 'true' ? ":-)" : ":-("
    }
}

위의 데모에는 암묵적인 out 변수가 있는데 이것은 응답에 컨텐츠를 추가하는데 사용하는 출력 Writer를 참조하는 것이다. 그런 다음 import 필요없이 GSP 안에서 간단히 태그를 참조할 수 있다.

<g:emoticon happy="true">Hi John</g:emoticon>


6.3.1 간단한 태그
이전 예제에서 보여준 것은 몸체 없이 그냥 컨텐츠를 출력하는 하찮은 간단 태그를 작성하는 것이다. 또 다른 예제는 dateFormat 스타일의 태그이다.

def dateFormat = { attrs, body ->
    out << new java.text.SimpleDateFormat(attrs.format).format(attrs.date)
}

위 예제는 날짜를 포맷하기 위해 자바의 SimpleDateFormat 클래스를 사용하여 응답에 출력한다. 그리고 아래와 같이 GSP 안에서 이 태그를 사용할 수 있다.

<g:dateFormat format="dd-MM-yyyy" date="${new Date()}" />

어떤 경우 단순한 태그에서 응답에 HTML 마크업을 출력할 필요가 있다. 그 한 방법은 컨텐트을 직접 포함하는 것이다.

def formatBook = { attrs, body ->
    out << "<div id="${attrs.book.id}">"
    out << "Title : ${attrs.book.title}"
    out << "</div>"
}

이 접근방법이 끌리기는 하지만 그리 깨끗하지는 않다. 보다 나은 접근방법은 render 태그를 재사용하는 것이다.

def formatBook = { attrs, body ->
    out << render(template:"bookTemplate", model:[book:attrs.book])
}

그리고 실제 렌더링하는 GSP 템플릿을 분리하는 것이다.


6.3.2 논리 태그
어떤 조건이 만족할 때만 태그 몸체를 출력하는 논리 태그도 만들 수 있다. 보안 태그 종류가 이런 것의 예제가 될 수 있다.

def isAdmin = { attrs, body ->
    def user = attrs['user']
    if (user != null && checkUserPrivs(user)) {
        out << body()
    }
}

위 태그는 사용자가 관리자인지 체크하고 사용자가 올바른 접근 권한을 가질 때만 몸체의 내용을 출력한다.

<g:isAdmin user="${myUser}">
    // 제한된 내용
</g:isAdmin>


6.3.3 반복 태그
반복 태그도 매우 단순하다. 그냥 body를 여러 번 호출 할 수 있다.

def repeat = { attrs, body ->
    attrs.times?.toInteger().times { num ->
        out << body(num)
    }
}

이 예제에서는 times 애트리뷰트를 검사해서 있으면 숫자로 바꾸고 지정한 수만큼 반복하기 위해 Groovy의 times 메소드를 사용한다.

<g:repeat times="3">
<p>Repeat this 3 times! Current repeat = ${it}</p>
</g:repeat>

이 예제에서 현재 번호를 참조하기 위해 암묵적인 it 변수를 어떻게 사용하는지 주목하라. 우리가 body를 호출할 때 반복 내에서 현재 값을 body에 전달하기 때문에 이것이 동작하는 것이다.

out << body(num)

그런 후 이 값은 태그로 기본 변수 it으로 전달한다. 그러나 중첩되는 태그가 있다면 이것은 충돌을 일으킬 수 있다. 따라서 당신은 반드시 꼭 body가 사용하는 변수의 이름을 주어야 한다.
def repeat = { attrs, body ->
    def var = attrs.var ? attrs.var : "num"
    attrs.times?.toInteger().times { num ->
        out << body((var):num)
    }
}

여기서 우리는 var 애트리뷰트가 있는지 검사해서 있을 경우 다음 라인 같이 body 호출시 전달하는 이름으로 사용한다.

out << body((var):num)

사용자 삽입 이미지
변수 이름 주위에 괄호를 사용한 것을 유념하라. 만일 이것을 생략하면 Groovy는 문자열 키를 사용하려는 것으로 가정하여 그 변수 자체를 참조하지 않는다.

이제 다음과 같이 이 태그의 사용법을 변경할 수 있다.

<g:repeat times="3" var="j">
<p>Repeat this 3 times! Current repeat = ${j}</p>
</g:repeat>

어떻게 변수 j 이름을 정의하기 위해 var 애트리뷰트를 사용했는지 주목하라. 그런 후 태그의 몸체 안에서 그 변수를 참조할 수 있다.

6.3.4 태그 네임스페이스
기본으로 기본 Grails 네임스페이스에 태그들을 추가하고 GSP 페이지에서 g: 접두어로 사용한다. 어쨌거나 TagLib 클래스에 static 속성을 추가함으로써 다른 네임스페이스를 지정할 수 있다.

class SimpleTagLib {
    static namespace = "my"
    def example = { attrs ->
        ...
    }
}

여기서 우리는 my라는 namespace를 지정했고 따라서 이 태그 라이브러리의 태그는 GSP 페이지에서 아래와 같이 참조할 수 있다.

<my:example name="..." />

여기서의 접두어는 static namespace 속성의 값과 동일한다. 네임스페이스는 특히 플러그인에서 유용하다.

네임스페이스 안의 태그들을 메소드로 호출하기 위해 네임스페이스를 접두어로 하여 호출할 수 있다.
out << my.example(name:"foo")

이것은 GSP, 컨트롤러 또는 태그 라이브러리에서 작동한다.

---
원문: 6.3 Tag Libraries
 

0 Comments
댓글쓰기 폼