วันพฤหัสบดีที่ 16 มิถุนายน พ.ศ. 2554

JSF2 and Internationalization

ขอรวบรัดนิดนึงครับ ว่าจะเอา ตัวอย่างมาจากบทก่อน เพื่อแก้เพิ่มเนื่องจากเวลาจำกัด
ให้ดูตัวอย่างเริ่มต้นจากด้านล่างนี้ครับ แล้วเราจะมาเพิ่มเติมกันเลย

JSF 2.0 and Spring Framework annotation example

เริ่มแรกให้เราไปเพิ่ม locale และ path file properties ให้ app เรารู้จักก่อน โดยไปเพิ่มที่ file
faces-config.xml
<application>
 <locale-config>
  <default-locale>en</default-locale>
  <supported-locale>th</supported-locale>
 </locale-config>
 <resource-bundle>
  <base-name>message</base-name>
  <var>msg</var>
 </resource-bundle>
</application>

จากตัวอย่าง code ก็จะอธิบายสั้น ๆ ว่า เรากำหนด msg เพื่อให้สะดวกเรียกใช้บนหน้า jsf โดยเวลาเราเรียกใช้จะได้ดังนี้
#{msg['label.username']}

เราจะเพิ่ม file ที่ชื่อ message.properties (มี default locale เป็น en) และ file ที่ชื่อ message_th.properties ทั้ง 2 file นี้จะสร้างไว้ที่ classpath
โดยจะกำหนดค่าในแต่ละ file ดังนี้

message.properties
label.username=User Name
label.password=Password

message_th.properties
label.username=ชื่อผู้ใช้
label.password=รหัสผ่าน

ส่วนต่อมาคือ code ส่วนที่นำไปแปะไว้ที่หน้า web jsf file เพื่อกด click แล้วให้ทำการสลับ ภาษาในหน้านั้น
<h:form>
 <h:commandLink actionListener="#{localizationBean.changeLanguage('th')}" >
  <h:graphicImage value="/images/icon_flag/th.png" styleClass="pic" />
 </h:commandLink>
 / 
 <h:commandLink actionListener="#{localizationBean.changeLanguage('en')}" >
  <h:graphicImage value="/images/icon_flag/en.png" styleClass="pic" />
 </h:commandLink>
</h:form>

ในที่นี้มี h:form เพื่อทำการ refresh ค่าในหน้า page
ตัวอย่างจาก code ก็คือ มีธงชาติ 2 ประเทศ กดอันใหน ก็เป็นภาษานั้น เข้าใจง่ายดี รู้ไม่มีจินตนาการเอาเอง
โดยปกติ แล้วก็ควรจะวางไว้บน header เพื่อที่จะได้ reuse ได้

ส่วนต่อมาคือ class ที่เป็น bean ทำหน้าที่ set locale อยู่เบื้องหลัง code ค่อนข้างจะน้อย ที่สำคัญคือ
ให้ set bean scope เป็น session ไม่งั้น ค่ามันจะหลุดจากการ set locale ครั้งล่าสุด ไปเป็นค่า defaultตลอด
package x.y.z.project.web.jsf.bean;

import java.io.Serializable;
import java.util.Locale;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import org.springframework.context.annotation.Scope;

@Named("localizationBean")
@Scope("session")
public class LocalizationBean implements Serializable {
    
    private Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();

    public void changeLanguage(String language) {
        locale = new Locale(language);
        FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
    }

    public Locale getLocale() {
        return locale;
    }

    public String getLanguage() {
        return locale.getLanguage();
    }
}

ต่อไปก็เป็นส่วนที่ใช้งานบนหน้า web จริง คือส่วนที่ถูกเปลี่ยนแปลง ดูตัวอย่างเลยดีกว่า
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:a4j="http://richfaces.org/a4j"
      xmlns:rich="http://richfaces.org/rich"
      xmlns:ui="http://java.sun.com/jsf/facelets">
    <f:view locale="#{localizationBean.locale}">
  <h:head>
   <title>Project</title>
  </h:head>
  <h:body>
   <f:facet name="header">
    <ui:include src="header.xhtml" />
   </f:facet>

   <rich:panel>
   <h:panelGrid columns="2" styleClass="formhilightlefttable">
    <h:outputLabel value="#{msg['label.username']}" />
    <h:inputText value="#{loginBean.username}"/>
    
    <h:outputLabel value="#{msg['label.password']}" />
    <h:inputText value="#{loginBean.password}"/>
   </h:panelGrid>
   </rich:panel>
  </h:body>
 </f:view>
</html>

ในส่วนนี้ที่สำคัญคือ
ที่ไว้ใช้กำหนด เก็บค่า locale ไว้สำหรับทั้งหน้า

#{msg['label.username']} เป็นตัวอย่างค่าที่ดึงจาก file message.properties ในส่วนนี้จะถูกเปลี่ยน ค่าไป จาก ไทย เป็น อังกฤษ เมื่อมีการคลิ๊กที่ธงชาติ

#{loginBean.username} ตรงนี้เป็นในส่วนติดต่อ กับ bean หลังบ้าน เพื่อใช้เก็บค่า และดำเนินการต่อไป

ui:include src="header.xhtml" ในส่วนนี้ได้ทำการ include file header มาส่วนใหญ่แล้ว ก็จะวางในส่วน menu ต่าง ๆ ไว้ รวมถึง locale ที่เป็นรูปธงไว้ใช้ สลับภาษาไว้บน file นี้ด้วย

ไม่มีความคิดเห็น: