Skip to content

Latest commit

 

History

History
98 lines (73 loc) · 5.31 KB

Project-Pages-Architecture.md

File metadata and controls

98 lines (73 loc) · 5.31 KB

Zanata's project pages use Seam components, JSF and RichFaces. The code that contributes to the rendering of a single page is often spread across a number of layout and code files. Most pages are based on a template, have transitions and additional parameters defined in a configuration file, and retrieve values from several Java classes (Seam components), as well as localized text strings defined in a properties file. Due to URL rewriting and nesting of page components, locating the code for a specific page can take a few steps.

The examples below are all based around the project list page at <server>/project/list, which is built from xhtml page /zanata-war/src/main/webapp/project/home.xhtml

URL Rewriting

Each project page is defined as an xhtml page, but is mapped to a URL that does not end with .xhtml. To figure out which xhtml page maps to a particular page on the website, find the rewrite rule in urlrewrite.xml as follows:

e.g. for the project list on zanata.org, the URL is https://translate.zanata.org/zanata/project/list. Remove the server prefix (https://translate.zanata.org/zanata) leaving the local path of the page, project/list. Search for the local path in urlrewrite.xml (/zanata-war/src/main/webapp/WEB-INF/urlrewrite.xml) to find the rule:

  <rule>
    <from casesensitive="true">^/project/list(.+)?$</from>
    <to last="true">/project/home.seam</to>
  </rule>

This rule is taking the /project/list path and directing it to /project/home.seam. Seam replaces the file extension of each page with .seam, so /project/home.seam correlates to /project/home.xhtml. Project pages are located in the "zanata" repository (See [[Repositories]]) under /zanata-war/src/main/webapp/, so the page is found at /zanata-war/src/main/webapp/project/home.xhtml.

Template

Zanata's project pages are based on a template found at /zanata-war/src/main/webapp/WEB-INF/layout/template.xhtml. The template is included near the top of each document in the ui:composition element, as shown here:

  <ui:composition ... template="../WEB-INF/layout/template.xhtml">

Page flow and extra parameters (pages.xml)

In Seam, page transitions, parameters, etc. are defined in pages.xml

e.g. for the project list Search "project/home" in /zanata-war/src/main/webapp/WEB-INF/pages.xml

  <page view-id="/project/home.xhtml">
    <action execute="#{breadcrumbs.clear}"/>
    <action execute="#{breadcrumbs.addLocation('', 'Projects')}"/>
  </page>

This example page is fairly simple, with just the breadcrumbs location defined in pages.xml.

Seam Components and EL

Seam components are Java classes that can be referenced in Seam pages using Expression Language (EL). A few usages of EL to refer to Seam Components are shown in the following example:

Continuing with the project list example, we can find the code in /project/home.xhtml that specifies that the project list table should be rendered and where to retrieve the data:

  <rich:dataTable id="projectList" 
                  rows="#{projectAction.pageSize}"
                  value="#{projectAction.projectPagedListDataModel}"
                  var="project">
      <rich:column width="270px" sortBy="#{project.name}">
          <f:facet name="header">#{messages['jsf.ProjectName']}</f:facet>
          <s:link id="project" styleClass="table_link"
                  value="#{project.name}" propagation="none"
                  view="/project/project.xhtml"
                  rendered="#{project.status == 'ACTIVE'}"> 
              <f:param name="slug" value="#{project.slug}"/>
          </s:link>
          ...
      </rich:column>
      <rich:column width="270px">
          <f:facet name="header">#{messages['jsf.Description']}</f:facet>
          <h:outputText value="#{project.description}" />
      </rich:column>
      ...
  </rich:dataTable> 

Notice expressions such as #{projectAction.pageSize}, #{project.name} and #{messages['jsf.Description']} which all use EL and refer to seam components. These EL expressions give the return value from ProjectAction.getPageSize(), the return value of HProject.getName() for each project shown on the page, and a text string from zanata-war/src/main/resources/messages.properties, respectively.

Seam components are Java classes that have a component name defined by a @Name annotation.

e.g. the projectAction seam component is defined in /zanata-war/src/main/java/org/zanata/action/ProjectAction.java by the annotation @Name("projectAction")

  package org.zanata.action;

  import org.jboss.seam.annotations.Name;
  ...

  @Name("projectAction")
  @Scope(ScopeType.PAGE)
  public class ProjectAction implements Serializable
  {
     ...

In Zanata, most Seam components have similar class and component names, differing only in capitalization of the first letter. There are a few exceptions, but it should always be possible to use text search to find the @Name annotation on the component.

e.g. to find projectAction I can search for @Name("projectAction") as follows:

  [damason@damason zanata]$ grep '@Name("projectAction")' **/*.java
  zanata-war/src/main/java/org/zanata/action/ProjectAction.java:@Name("projectAction")
  [damason@damason zanata]$