Skip to end of metadata
Go to start of metadata

Descriptor configuration 

 In this part, we will create the first controller that will return a simple view. We will be able to preview the view by clicking on the appropriate link in the system menu (the plugin will add the appropriate link).

Required modules:

 

Declaration of these modules takes place in the plug-in descriptor:

suncode-plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<plugin key="com.suncode.plugin-tutorial" name="Tutorial Plugin">
	<plugin-details>
		<description>
			<localized language="en">Description</localized>
			<localized language="pl">Opis</localized>
		</description>
		<author>Suncode</author>
	</plugin-details>
	
	<!-- I18N -->	
	<i18n key="i18n-bundle" location="locale/messages" />
	
	<!-- Web MVC -->
	<web-mvc key="mvc" />
</plugin>

Page creation

The controller is responsible for accepting the HTTP requestand returning the view or other response (e.g., json).

Our controller will display the view in response to the request / hello and respond to thejsonobject in response to /api/hello.

package com.suncode.plugin.tutorial;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController
{
    @RequestMapping( value = "/hello", method = RequestMethod.GET )
    public String showHelloView( Model model )
    {
        // we add the attribute to the model "date"
        model.addAttribute( "date", new Date() );

        // we display the view "/views/hello.ftl"
        return "hello";
    }

    @RequestMapping( value = "/api/hello", method = RequestMethod.GET, produces = "application/json" )
    @ResponseBody
    public Map<String, Object> sayHello()
    {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put( "say", "hello" );
        result.put( "date", new Date() );

        // we return a map that will be processed into an object json
        return result;
    }
}

 

The view will display a simple text and the date sent from the controller:

hello.ftl
<p>Hello World</p>
<p>Current date: ${date?datetime}</p>

Views must be made in Freemarker technology. All views must be in the /views directory and have the .ftl extension (the directory and extension are automatically added to the name of the returned view).

By default, Eclipse does not have a built-in Freemarker template editor. This editor is part of jBoss Tools.

The project structure is as follows:

After installing/updating the plugin, we can try out our controller. To do this, send a request to the appropriate URL:

All URLs of the plugin are preceded by a prefix consisting of /plugin/{plugin ID}/(eg. /plugin/com.suncode.plugin-tutorial/)

 

  1. /plugin/com.suncode.plugin-tutorial/hello

     

    All views returned by the plugin aredecorated by default (except for requests with the X-Requested-With header: XMLHTTPREQUEST).

    If we do not want to decorate our site, we need to add the parameter: decorator = none(eg.: /plugin/com.suncode.plugin-tutorial/hello?decorator=none) so that we get a clean page:

    All available decorators are described in Creating Freemarker Views - View decorators .

  2. /plugin/com.suncode.plugin-tutorial/api/hello

    json
    {"say":"hello","date":1399446110308}

Serving static resources 

Plug-ins can serve any static resources (scripts, photos etc.). Such resources must be located in the /resourcesdirectory:

 

 

 

 

 

 

 

Static resources can be downloaded using 2 URLs(differing in the cache policy):

  • /plugin/{id}/resources/{resource} - resources read in this way are not cached:
    • (np. plugin/com.suncode.plugin-tutorial/resources/data.js)
  • /plugin/{id}/resources/{lastUpdate}/{resource} - the resources read in this way are cached(to update the plugin when the link to the resource also changes):
    •  (np. plugin/com.suncode.plugin-tutorial/resources/1399542968944/data.js)

where:

  • id– plugin identificator
  • resource- resource address inside the plug relative to/resources
  • lastUpdate - date of the last update of the plugin

 

For performance reasons, always try to use the URL with the last update date due to the cache policy.

 

Serving static resources for anonymous users

 

By default serving static resources requires the requesting user to authenticate first. To allow access for anonymous users they have to be put in /public folder, inside the /resources folder (/resources/public/<resource>).

 

The resources is then available via URL's (cached and non-cached):

 

  • /plugin/{id}/resources/public/{resource} - (i.e. plugin/com.suncode.plugin-tutorial/resources/public/data.js)
  • /plugin/{id}/resources/{lastUpdate}/public/{resource} -  (i.e. plugin/com.suncode.plugin-tutorial/resources/1399542968944/public/data.js)

Dynamic link to resources to Freemarker views 

A dynamic link to resources is created by adding the date of the last update to the URL. In the Freemarker views, you can make it easier to download a link:

The following object and macro are described in documentation for creating Freemarker views.

view.ftl
<!-- Pomocnicze makro -->
<#import "/plugin.ftl" as plugin/>
 
<!-- Wykorzystując obiekt pluginContext -->
<script src="${pluginContext.pluginResourcesPath}/data.js"></script>
 
<!-- Wykorzystując pomocnicze makro -->
<script src="<@plugin.resourceUrl 'data.js'/>"></script>
 

 

  • No labels