通过XPages中的属性文件定义日期模式

通过XPages中的属性文件定义日期模式,xpages,Xpages,我想在全局级别上定义应用程序中的日期模式。因此,我想使用一个属性文件。由于我已经在使用一个,例如设置重复控件的默认行数,我添加了一个ne wkey值对: date_format_date_only=yyyy-MM-dd 在我的应用程序中,我通过转换器设置了日期格式,例如: <xp:this.converter> <xp:convertDateTime pattern="yyyy-MM-dd" type="date" /> </xp:this.convert

我想在全局级别上定义应用程序中的日期模式。因此,我想使用一个属性文件。由于我已经在使用一个,例如设置重复控件的默认行数,我添加了一个ne wkey值对:

date_format_date_only=yyyy-MM-dd
在我的应用程序中,我通过转换器设置了日期格式,例如:

<xp:this.converter>
    <xp:convertDateTime pattern="yyyy-MM-dd" type="date" />
</xp:this.converter>

但是当我把它设置为

<xp:this.converter>
    <xp:convertDateTime pattern="${application.date_format_date_only}" />
</xp:this.converter>

它不起作用。日期显示为2018年2月26日。Application是我通过主题设计元素设置的变量:

<resources>
<bundle src="/application.properties" var="application" />
</resources>

我是不是忽略了什么


我注意到,当我将捆绑包直接添加到XPage时,模式可以工作,但是主题设计元素有什么用呢?

我通过主题定义做某些事情,但不是全部。对主题属性求值应用读取计时有一些限制

我认为您需要避免在您使用的每个页面中声明资源包。我说得对吗

在这种情况下,我的建议是更多地利用JSF机制。 我个人设置了一个请求范围的bean,我称之为
MessageBean

public class MessageBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private ApplicationEx application;
    private Locale locale;

    private ResourceBundle app;
    private ResourceBundle error;
    private ResourceBundle log;

    public void setApplication(Application application) {
        this.application = (ApplicationEx) application;
    }

    public void setLanguage(String language) {
        locale = new Locale(language);
    }

    public ResourceBundle getApp() {
        if (app == null) {
            app = getResourceBundle("app");
        }

        return app;
    }

    public ResourceBundle getError() {
        if (error == null) {
            error = getResourceBundle("error");
        }

        return error;
    }

    public ResourceBundle getLog() {
        if (log == null) {
            log = getResourceBundle("log");
        }

        return log;
    }

    private ResourceBundle getResourceBundle(String name) {
        try {
            return application.getResourceBundle("/WEB-INF/i18n/" + name + ".properties", locale);
        } catch (IOException e) {
            throw new FacesException(e);
        }
    }

}
faces config.xml
中:

<managed-bean>
    <managed-bean-name>msg</managed-bean-name>
    <managed-bean-class>mypackage.MessageBean
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
        <property-name>application</property-name>
        <value>#{facesContext.application}</value>
    </managed-property>
    <managed-property>
        <property-name>language</property-name>
        <value>#{facesContext.viewRoot.locale.language}</value>
    </managed-property>
</managed-bean>

味精
mypackage.MessageBean
要求
应用
#{facesContext.application}
语言
#{facesContext.viewRoot.locale.language}
这个bean为我做的是连接不同的属性文件——它们位于/WEB-INF/i18n/-(我根据它们的权限“app”=一般app messages、“error”=error messages等进行划分),并将它们很好地安排在一个根目录下:
msg

换句话说,我可以在页面的任何位置声明应用程序资源包的
${msg.app.hello}
,或错误资源包的
${msg.error.sorry}


我不必在页面上声明任何资源,这就是bean的魔力。您不使用它们,它们不是创建的。如果您想使用它们,框架会自动创建它们并将它们提供给您。

我通过主题定义做某些事情,但不是全部。对主题属性求值应用读取计时有一些限制

我认为您需要避免在您使用的每个页面中声明资源包。我说得对吗

在这种情况下,我的建议是更多地利用JSF机制。 我个人设置了一个请求范围的bean,我称之为
MessageBean

public class MessageBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private ApplicationEx application;
    private Locale locale;

    private ResourceBundle app;
    private ResourceBundle error;
    private ResourceBundle log;

    public void setApplication(Application application) {
        this.application = (ApplicationEx) application;
    }

    public void setLanguage(String language) {
        locale = new Locale(language);
    }

    public ResourceBundle getApp() {
        if (app == null) {
            app = getResourceBundle("app");
        }

        return app;
    }

    public ResourceBundle getError() {
        if (error == null) {
            error = getResourceBundle("error");
        }

        return error;
    }

    public ResourceBundle getLog() {
        if (log == null) {
            log = getResourceBundle("log");
        }

        return log;
    }

    private ResourceBundle getResourceBundle(String name) {
        try {
            return application.getResourceBundle("/WEB-INF/i18n/" + name + ".properties", locale);
        } catch (IOException e) {
            throw new FacesException(e);
        }
    }

}
faces config.xml
中:

<managed-bean>
    <managed-bean-name>msg</managed-bean-name>
    <managed-bean-class>mypackage.MessageBean
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
        <property-name>application</property-name>
        <value>#{facesContext.application}</value>
    </managed-property>
    <managed-property>
        <property-name>language</property-name>
        <value>#{facesContext.viewRoot.locale.language}</value>
    </managed-property>
</managed-bean>

味精
mypackage.MessageBean
要求
应用
#{facesContext.application}
语言
#{facesContext.viewRoot.locale.language}
这个bean为我做的是连接不同的属性文件——它们位于/WEB-INF/i18n/-(我根据它们的权限“app”=一般app messages、“error”=error messages等进行划分),并将它们很好地安排在一个根目录下:
msg

换句话说,我可以在页面的任何位置声明应用程序资源包的
${msg.app.hello}
,或错误资源包的
${msg.error.sorry}

我不必在页面上声明任何资源,这就是bean的魔力。您不使用它们,它们不是创建的。如果您想要使用它们,框架会自动创建它们并将它们提供给您

我注意到,当我将捆绑包直接添加到XPage时,模式可以工作,但是主题设计元素有什么用呢

我相信主题背后的意图是“定义应用程序的外观”(define the look and feel of a application),我认为这反映在这样一个事实上,即在主题文件上定义的资源束只在beforeRenderResponse阶段对XPage可用。因此,正如您所发现的,您希望使用在主题上声明的捆绑包访问的任何属性只能通过运行时绑定而不能在页面加载上访问,而且转换器不能使用运行时绑定

为避免将捆绑包直接添加到您构建的每个XPage,有两个快速简单的SSJS解决方案:

  • 将属性放在
    xsp.properties
    中,并使用
    context.getProperty('foo')
    访问它,或者,如果您站在不愿意将自己的键值对添加到xsp.properties的辩论的一边,则使用
    context.getProperty('foo')
    访问它
  • 改用
    context.bundle(“application.properties”).getString(“foo”)
  • @shillem关于用Java编写并使用bean的回答可能更优雅、更好,尤其是在应用程序中使用控制器框架的情况下,但是上面的方法可以奏效

    我注意到,当我将捆绑包直接添加到XPage时,模式可以工作,但是主题设计元素有什么用呢

    我相信主题背后的意图是“定义应用程序的外观”(define the look and feel of a application),我认为这反映在这样一个事实上,即在主题文件上定义的资源束只在beforeRenderResponse阶段对XPage可用。因此,正如您所发现的,您希望使用在主题上声明的捆绑包访问的任何属性只能通过运行时绑定而不能在页面加载上访问,而且转换器不能使用运行时绑定

    为避免将捆绑包直接添加到您构建的每个XPage,有两个快速简单的SSJS解决方案:

  • 将属性放在
    xsp.properties
    中,并使用
    context.getProperty('foo')
    访问它,或者,如果您站在不愿意将自己的键值对添加到xsp.properties的辩论的一边,则使用
    context.getProperty('foo')
    访问它
  • 改用
    context.bundle(“application.properties”).getString(“foo”)
  • @shillem关于用Java编写并使用bean的回答可能更优雅、更好,尤其是在应用程序中使用控制器框架的情况下