Nov 4, 2021 4:02:31 PM Thomas Dumont avatar

XPage

Definition

An XPage is a special page that is not part of the page tree built with portlets. It is autonomous and is called using the page parameter as follows :

jsp/site/Portal.jsp?Page=my_page

This component is typically intended to implement applications operating within the portal.

Basic implementation

Creating an XPage requires only two actions:

  • Creating a Java class that implements the XPageApplication interface
  • the declaration of the XPage in the xml file of the plugin

In XPage sample: An HelloWorld Plugin, several implementations are presented as part of a HelloWorld plugin.

Implementing the XPageApplication interface

The implementation of the XPageApplication interface needs to define the method :

XPage getPage( HttpServletRequest request, int nMode, plugin plugin )

Declaration in the plugin's XML file

The declaration must be as follows:

<!-- Applications -->
<applications>
    ...
    <application> 
        <application-id>mypage</application-id> 
        <application-class>fr.paris.lutece.plugins.myplugin.web.MyApp</application-class> 
    </application>
    ...
</applications>

General introduction to the MVC framework

The MVC framework is available to develop XPages using the paradigm Model-View-Controller from version 4.1 of Lutece.

Lutece 4.1 library-mvc independent of the core

Lutece 4.2 - 4..4 library-mvc depending on the core

Lutece 5.0 core built-in framework

This framework offers:

  • Dispatching queries by the controller for processing actions and displaying views
  • The identification of actions and views by annotations
  • Population and validation of beans (JSR 303)
  • Management of validation errors directly included in the template of the template (marker "errors")
  • The management of the notifications or informative messages included in the model of the template (marker "infos")
  • HTTP redirection of requests to views avoiding the use of JSPs

Important! The plugin PluginWizard was rewritten in version 3.1 with this framework. It generates on the one hand plugins using this framework and on the other hand is an advanced example of its implementation in complex cases.

Principle of implementation of the MVC model

The MVC library offers a MVCApplication implementation of the XPageApplication interface that provides mechanisms for splitting functions according to the Pattern-View-Controller pattern, which is as follows:

schema MVC

The entry point of the XPage acts as a controller. This is the MVCApplication class that supports this function by implementing the interface's getPage method.

Actions and views are designated by @Action and @View annotations.

The controller dispatches the processes on the annotated methods according to the parameters of the request.

The annotation @Controller to be defined on the class derived from MVCApplication is used to define parameters of the class.

The XPage home page should set the defaultView setting of the @View annotation to true.

The views

The MVC framework brings a notion of views and actions.

Views are used to display content to the user. A view is a method of a controller with @View annotation. This annotation takes as parameter the unique key of the view that will be used by the framework to define it. Once the content of a view has been generated, it must return its result in a XPage object. The view that corresponds to the application home page must have the defaultView setting of the @View to true annotation. When a request is made on an application, and no view or action is specified, then the home page is displayed.

The URL of a view is generated on the following template :

jsp/site/Portal.jsp?page=appname&view=viewname

where :

  • appname is the name of the application (defined in the @Controller annotation parameter)
  • viewname is the name of the view to display (defined in the @View annotation parameter).

The view keyword is therefore a reserved keyword and should not be used as an HTML parameter name for any other reason.

The actions

Actions are used to perform treatments. Actions must not generate content to display to the user.

An action is a method of a controller with the @Action annotation. This annotation takes as parameter the unique key of the action that will be used by the framework to define it. When an action ends its processing, it must carry out a redirection towards a view thanks to the methods of redirection of the library (see the following paragraph). An action must return an object of type XPage. When performing a redirect, it must return the XPage created by the redirect method.

The URL of a view is generated on the following template :

jsp/site/Portal.jsp?page=appname&action=actionname

where :

  • appname is the name of the application (defined in the @Controller annotation parameter)
  • actionname is the name of the action to be performed (defined as a parameter of the @Action annotation).

The action keyword is therefore a reserved keyword and should not be used as an HTML parameter name for some other reason.

Redirections

When a view or action wants to redirect to another view or a defined URL, it must call one of the redirect( ) methods of the MVCApplication class.

These methods allow you to make referrals to application views by specifying only the name of the view to display, or to a fully defined URL manually. When redirecting to an application view, parameters can be specified by adding them to a Map.

When the redirection method is finished processing, the HTTP response is sent. It is therefore not possible to display HTML content or to make another redirection to ignore the first one.

Redirection methods return objects of type XPage. These objects must be returned by the views or actions that called the redirection method.

Code sample

Here is the code of an XPage offering 2 views:

  • the home page displaying a list of contacts
  • the contact creation page

as well as 2 actions:

  • create a contact
  • delete a contact
// MVCDemoApp.java

@Controller( xpageName = "mvcdemo" , pageTitle = "mvcdemo.pageTitle" , pagePath = "mvcdemo.pagePathLabel" )
public class MVCDemoApp extends MVCApplication
{
    private static final String TEMPLATE_HOME = "/skin/plugins/mvcdemo/home.html";
    private static final String TEMPLATE_FORM = "/skin/plugins/mvcdemo/form.html";
    private static final String VIEW_HOME = "home";
    private static final String VIEW_ADD_CONTACT = "addContact";
    private static final String ACTION_ADD_CONTACT = "addContact";
    private static final String ACTION_REMOVE_CONTACT = "removeContact";
    private static final String MARK_CONTACTS_LIST = "contacts_list";
    private static final String PARAMETER_ID = "id";


    @View( value = VIEW_HOME , defaultView = true )
    public XPage viewHome(HttpServletRequest request)
    {
        Map<String,Object> model = getModel();
        model.put( MARK_CONTACTS_LIST , ContactService.getContacts() );
        return getXPage( TEMPLATE_HOME, request.getLocale(  ) , model );
    }

    @View( VIEW_ADD_CONTACT )
    public XPage viewAddContact(HttpServletRequest request)
    {
        return getXPage( TEMPLATE_FORM, request.getLocale(  ) );
    }

    @Action( ACTION_ADD_CONTACT )
    public XPage addContact(HttpServletRequest request)
    {
        Contact contact = new Contact();
        populate(contact, request);

        if ( !validateBean(contact))
        {
            return redirectView( request , VIEW_ADD_CONTACT );
        }
        ContactService.addContact(contact);
        return redirectView( request , VIEW_HOME );
    }

    @Action( ACTION_REMOVE_CONTACT )
    public XPage removeContact(HttpServletRequest request)
    {
        String strContact = request.getParameter( PARAMETER_ID );
        ContactService.removeContact( strContact );
        return redirectView( request , VIEW_HOME );
    }

Advanced features

Multi-action forms

Example of a single action form:

<form action="jsp/site/Portal.jsp">
    <input type="hidden" name="page" value="myplugin" />
    <input type="hidden" name="action" value="action1" />
    ...
    <button type="submit" value="Action 1" />
</form>

Example of multi-action form:

<form action="jsp/site/Portal.jsp">
    <input type="hidden" name="page" value="myplugin" />
    ...
    <button type="submit" name=action_action1 value="Action 1" />
    <button type="submit" name=action_action2 value="Action 2" />
    <button type="submit" name=view_view1 value="Action 3" />
</form>

The prefix action_ and view_ in the button names are interpreted as calls to actions or views. The other part of the name is interpreted as the value of the action or view.

Returns JSON or XML streams by XPage

From Lutece 5.0

This feature can be useful for making some part of the page in Ajax while keeping the server part code in the same class.

For that, two methods have been added to the framework in the MVCApplication class:

  • XPage responseJSON( HttpServletRequest request )
  • XPage responseXML( HttpServletRequest request )

Here is an example that returns a list of images in JSON format:

@View( VIEW_LIST_IMAGES )
public XPage viewListImages( HttpServletRequest request )
{
    String strTopicId = request.getParameter( Constants.PARAMETER_TOPIC_ID );
    JSONArray array = new JSONArray();

    if( strTopicId != null )
    {
        int nTopicId = Integer.parseInt(strTopicId);
        List<Image> list = ImageHome.findByTopic( nTopicId , _plugin );
        for( Image image : list )
        {
            JSONObject jsonImage = new JSONObject();
            jsonImage.accumulate( "id", image.getId() );
            jsonImage.accumulate( "name", image.getName() );
            array.add( jsonImage );
        }
    }

    return responseJSON( array.toString() ); 
}