SiteMesh는 Decorator Tag, Page Tag 2개의 tag 라이브러리를 제공한다. Decorator Tag는 decorator page를 생성할 때 사용되는 tag이고, Page Tag는 decorator 페이지 내에서 다른 decorator를 포함할 때 사용된다.
Decorator Tags
<decorator:head />
원래 웹페이지의 HTML <head> 태그의 내용을 추가한다. 속성은 없다.
<decorator:body />
원래 웹페이지의 HTML <body> 태그의 내용을 추가한다. body의 onload, onunload 이벤트의 바디 속성은 body.onload 와 body.onunload decorator에 의해 포함되어 쓰일 수 있다.
<body onload="<decorator:getProperty property="body.onload" />">
<body onload="alert('1');" bottommargin=5>
좀더 자세히 알기 위해서는 getProperty를 참조할 것. 속성은 없다.
<decorator:title [ default=”…” ] />
Insert title of 원래 HTML 페이지의 title 태그로부터 얻은 title을 추가한다. title을 찾을 수 없다면, value값을 default로 지정할 수 있다.
<decorator:getProperty property=”…” [ default=”…” ] [ writeEntireProperty=”…” ]/>
원래 페이지의 속성을 추가한다. HTMLPage interface를 이용하여 해당 페이지의 속성들을 얻어낼 수 있다.
property : 추가할 속성의 이름 (key)
default : 속성을 발견하지 못헀을 때, default로 지정되는 값
writeEntireProperty : 1, yes, true, t, y 로 지정했을 때, 이름을 포함한 속성값(propertyName=”propertyValue”)이 그대로 쓰여진다.
예)
decorator: <body bgcolor="White"<decorator:getProperty property="body.
onload" writeEntireProperty="true" />> undecorated page: <body onload="document.someform.somefield.focus();"> decorated page: <body bgcolor="White" onload="document.someform.
somefield.focus();">
<decorator:usePage id=”…” />
decorator jsp에서 사용할 수 있는 Page Object id를 지정한다.
id : 지정할 ID
예1)
<decorator:usePage id="myPage" /> <% if ( myPage.getIntProperty("rating") == 10 ) { %> <b>10 out of 10!</b> <% } %>
예2)
<decorator:usePage id="p" /> <% HttpServletRequest req = p.getRequest(); StringBuffer printUrl = new StringBuffer(); printUrl.append( req.getRequestURI() ); printUrl.append("?printable=true"); if (request.getQueryString()!=null) { printUrl.append('&'); printUrl.append(request.getQueryString()); } %> <p align="right">[ <a href="<%= printUrl %>">printable version</a> ]</p>
Page 태그
page 태그는 현재 페이지
The page tags, are used to apply decorators to inline or external content from within the current page.
<page:applyDecorator name=”…” [ page=”…” title=”…” ] > …..body…. </page:applyDecorator>
특정 컨텐츠에 decorator를 적용한다. 해당 컨텐츠는 tag를 통해 body를 지정함으로서, 또는 page 속성을 지정하여 다른 page의 결과를 사용함으로서 인라인(inline)되게 할 수 있다.
name : 포함될 페이지에 적용될 decorator
page : 전체 page에서 쓸 수 있는 외부 자원을 상대적(relative), 절대적(absolute) 패쓰를 이용하여 지정한다.
title : Page.getTitle() 메소드 또는 decorator안에서 <decorator:title/> 를 사용하여 page의 title을 다시 지정(override)할 수 있다. <page:param name=”title”>…<page:param>에서 지정하여 식별이 가능하도록 한다.
Body : decorator가 적용될 내용.
<page:param name=”…”> … </page:param>
파라미터를 decorator로 넘긴다. 이 값은 Page.getProperty() 또는 <decorator:getProperty/>로부터 얻어온 값을 오버라이드할 수 있다.
name : 오버라이드될 파라미터의 이름
Body: 파라미터의 값.
DecoratorMappers
어떤 한 웹 페이지가 파싱이 될 때, 그것은 decorator에 매핑이 된다. 이 매핑은 DecoratorMappers의 체인에 의해 수행된다.
각 요청이 들어올 때마다 체인의 가장 첫번째 mapper는 어느 decorator가 쓰여져야 하는 지를 물어본다. 그래서 Page Object와 HttpServletRequest 객체를 reference로 받고, 해당 decorator가 쓰여지는지 알게 되면 그 decorator를 리턴하고, 모르면 null을 리턴한다.. 만약 null이 리턴 되면, 체인의 다음번 mapper에게 또다시 decorator 찾는 쿼리를 하게 된다.
이런 전체적인 프로세스는 체인에 더이상 mapper이 없거나, 체인에 있는 decorator가 valid한 decorator를 리턴할 때까지 반복된다. 만약 어떠한 mapper가 decorator를 리턴할 수 없는 상태면, 그 page는 전혀 장식이 되지 않고, 원래상태에 따라 화면이 표출될 것이다.
이런 체인의 mapper 호출 방식은 Chain of Responsibility 패턴으로 유명하다.
mapper의 예
- 요청된 페이지의 path를 바탕으로 decorator를 결정한다.
- 로케일, 시간 또는 브라우져에 따라 다른 decroator를 사용한다.
- 검색 엔진 로봇에 맞은 간단한 decorator를 사용한다.
- URL 파라미터, Request 속성 또는 meta-tag에 따라 decorator를 달리 사용한다.
- 미리 저장된 사용자의 셋팅에 맞게 커스트마이즈된 decorator를 사용한다.
DecoratorMapper의 주요 구현은 ConfigDecoratorMapper이다. 이 클래스는 /WEB-INF/decorators.xml 파일을 읽어 mapping과 decorator를 읽는다. 적절한 decorator는 URL 패턴에 따라 적용되어 진다.
Mapper의 종류
Mapper 종류 | 내용 |
---|---|
AgentDecoratorMapper | browser에 따른 decorator를 선택할 수 있도록 한다. browser 타입은 일반적인 경우와 같이 request.getHeader(“User-Agent”)를 통해 구해온다. 다른 mapper들이 특정 decorator를 지칭하여 반환하는 것과 달리 AgentDecoratorMapper는 적용될 decorator의 decorator page이름을 browser에 따라 수정한다. 예를 들어 decorator mapper가 main decorator를 선정했다면 decorator 페이지는 /decorators/main.jsp가 적용될 것이다. 하지만 http 클라이언트가 익스플러라면 main decorator에 /decorators/main-ie.jsp 장식자 페이지를 적용하게 된다. 모질라 기반 browser라면 /decorators/main-ns.jsp가 decorator page로 결정된다. 만약 선정된 decorator page를 찾는데 실패하면 기본 decorator page인 main.jsp가 적용될 것이다. <mapper class="com.opensymphony.module.sitemesh. |
ConfigDecoratorMapper | DecoratorMapper의 디폴트 구현으로서, decorators.xml 파일을 읽어 decorator와 mapping된 데이터들을 읽는다. <mapper class="com.opensymphony.module. |
CookieDecoratorMapper | 쿠키값을 바탕으로 하는 decorator를 선정할 수 있다. |
EnvEntryDecoratorMapper | decorator 이름으로 web-app 환경 entry에 대한 레퍼런스를 허락한다. |
FileDecoratorMapper | 파일 이름을 주어 decorator의 이름을 취급한다.
<mapper class="com.opensymphony.module. |
FrameSetDecoratorMapper | page가 HTMLPage나 isFrameSet()의 리턴값이 true일 때, 특정 decorator를 선정할 수 있도록 해준다. 그 decorator의 이름은 주어진 property에서 지정할 수 있다. <mapper class="com.opensymphony.module. |
InlineDecoratorMapper | inline decorator를 사용할 때, 올바른 decoraotor가 무엇인지 사용할 때 선정할 수 있다. |
LanguageDecoratorMapper | browser에서 page 요청에 대해 “Accept-Language” HTTP 헤더를 이용하여 language 페이지를 결정할 때 선정할 수 있다. locale에 따라서 decorator의 파일의 이름에 ‘-en’에 붙여져서 사용될 수 있도록 지정할 수 있다. <mapper class="com.opensymphony.module. |
PageDecoratorMapper | 메타 태그에 decorator 항목이 있을 때 장식자를 리턴한다. PageDecoratorMapper는 여러 파라미터를 받는다. 밑의 예를 보면, PageDecoratorMapper는 첫번째 파라미터로 meta.decorator 프로퍼티를 받는다. 이 의미는 decorator의 META 프로퍼티의 값이 decorator 이름으로 쓰여질 수 있다는 것을 의미한다. decorator_test라는 이름의 장식자를 특정페이지에 적용하고 싶다면 <META name=”decorator” content=”decorator_test”> 와 같이 페이지에 메타 태그를 추가하거나 또는 <HTML decorator=”decorator_test”>와 같이 <HTML> 태그를 수정하여 사용한다. <mapper class="com.opensymphony.module. decorators.xml에서 decorator_test decoration을
미리 정의 <decorator name="decorator" page="tv.jsp"> </decorator> |
ParameterDecoratorMapper | 설정에 정의된 파라미터와 동일한 스트링이 URL 쿼리 스트링에 존재할 때 정의해 놓은 decorator를 선정하도록 되어 있다. <mapper class="com.opensymphony.module. 이 mapper는 3개의 parameter가 존재한다. help.jsp
help.jsp?decorator=test&confirm=true |
SessionDecoratorMapper | session 어트리부트에서 지정한 decorator를 선정하도록 되어 있다. 디폴트로 decorator를 session 속성에서 찾지만, decorator.parameter 속성을 통해서 오버라이드 될 수 있다. |
PrintableDecoratorMapper | URL 쿼리 스트링의 printable=true라는 문자열에 반응한다. decorators.xml에 정의된 decorator중 printable decorator를 리턴할 것이다. 아래의 예는 다음을 의미한다. printable로 정의된 decoraotr는 printable=true 라는 리쿼스트가 들어올 때 해당 jsp가 적용된다. <mapper class="com.opensymphony.module. |
RobotDecoratorMapper | 검색엔진 로봇에서 식별되어 지는 특정 decorator를 선정하도록 되어 있다. <mapper class="com.opensymphony.module. |
사용자 정의 mapper 환경 설정
sitemesh.xml
요청에 따라 적용될수 있는 mapper를 정의하기 위해서는 sitemesh.xml파일을 생성한다.
<sitemesh> <property name="decorators-file" value="/WEB-INF/decorators.xml" /> <excludes file="${decorators-file}" /> <page-parsers> <parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.
HTMLPageParser" /> <parser content-type="text/html;charset=ISO-8859-1" class="com.opensymphony.module.sitemesh.parser.
HTMLPageParser" /> </page-parsers> <decorator-mappers> <mapper class="com.opensymphony.module.sitemesh.mapper.
ConfigDecoratorMapper"> <param name="config" value="${decorators-file}" /> </mapper> </decorator-mappers> </sitemesh>
이 예에서 유일하게 적용된 mapper는 ConfigDecoratorMapper이다. 이 mapper는 웹페이지의 content-type이 text/html 이거나 text/html;charset=ISO-8859-1인 경우일때만 적용될 것이다. 다른 content-type(예, image/gif)의 page는 적용되지 않는다.
decorators.xml
부가적으로 패턴 매치를 이용하여 특정 파일들을 exclude하여 Sitemesh가 처리하지 않게 할 수 있다.
<excludes /> block을 이용하여 exlcude해야할 파일을 설정할 수 있다.
<decorators> <excludes> <pattern>/plainPage.jsp</pattern> <pattern>/plain/*.jsp</pattern> </excludes> </decorators>
/plainPage.jps와 /plain 디렉토리의 jsp 페이지는 장식이 전혀 되지 않는다. (패턴 매칭은 ConfigDecoratorMapper에서 사용되는 decorator 매핑처럼 정확하게 같은 룰을 따른다. )
일반적으로 <excludes /> 블럭은 decorators.xml 파일의 시작에서 추가되지만, 다른 XML 파일에서 정의할 수 있다.
디폴트 mapper 환경설정
만약 WEB-INF 디렉토리에서 sitemesh.xml이 발견되지 않으면, 디폴트 mapper 설정 화일이 사용되어 질 수 있다. 디폴트 mapper 환경설정파일의 정의는 sitemesh.jar안에 있는 sitemesh-default.xml의 설정파일이 적용된다. 그리고, 다음의 mapper들로 구성되어 진다.
- PageDecoratorMapper
- FrameSetDecoratorMapper
- PrintableDecoratorMapper
- FileDecoratorMapper
- ConfigDecoratorMapper
디폴트로 오직 text/html 컨텐트 타입만 Sitemesh에 의해 decoration된다.
Freemarker 예제
Freemarker와 연동하여 decoration을 사용할 수 있다.
Freemarker lib
Freemarker lib을 사용한다.
web.xml 수정
WEB-INF/web.xml에 <web-app> 태그에 다음의 코드를 추가한다.
<servlet> <servlet-name>sitemesh-freemarker</servlet-name> <servlet-class>com.opensymphony.module.sitemesh.freemarker.
FreemarkerDecoratorServlet</servlet-class> <init-param> <param-name>TemplatePath</param-name> <param-value>/</param-value> </init-param> <init-param> <param-name>default_encoding</param-name> <param-value>ISO-8859-1</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>sitemesh-freemarker</servlet-name> <url-pattern>*.dec</url-pattern> </servlet-mapping>
decorators.xml 수정
\.dec 파일을 레퍼런스하여 decorators.xml을 수정한다.
<#include "/includes/decorators/header.dec"> <h2>${title}</h2> ${head} <img src="${base}/images/logo.gif" border="0"> <td valign="top" class="body"> <div class="header"> <span class="pagetitle">${title}</span> </div> ${body} </td> <#include "/includes/decorators/footer.dec">
Context
FreemarkerDecoratorServlet은 당신이 필요로 하게될 정보, 즉 Context object들을 저장한다.
기본 context 속성
모든 리쿼스트, 리쿼스트 파라미터, 세션, 서블릿 context 속성 그리고 어플리케이션 변수를 얻을 수 있다.
예)
${Session["user"]}
어플리케이션안에서, 세션안에서, 리쿼스트안에서 변수를 찾아낼 수 있고, 지정할 수 있다.
<#assign ww=JspTaglibs["/WEB-INF/webwork.tld"]>
JspTaglibs라고 하는 변수를 생성하고, JSP 태그 라이브러리에서 로드할 수 있도록 쓸 수 있다.
<#assign ww=JspTaglibs["/WEB-INF/webwork.tld"]> ... <@ww.property value="myVar"/>
Sitemesh context 속성
base | request.getContextPath() |
title | page title을 파싱한다. (<title>…<title>) |
head | page head를 파싱한다. |
body | page body를 파싱한다. |
page | SiteMesh의 내부 Page object |