Nov 10, 2021 2:52:02 PM Thomas Dumont avatar

Extend plugin features integration into a plugin

Introduction

The plugin-extend allows to associate generic extensions (add comments, ratings, views count ...) to resources (site pages, documents, ...).

Resources that can accept extensions must meet certain technical requirements in order to be "extendable".

The plugin offers a back office interface to dynamically combine all resource types found with all installed extensions and available on the system. An extension can be associated with all the resources of a given type or to a particular instance defined by its identifier (for example you can enable comments on a particular page of the website and display the count of views on all pages).

Integrate Extend into a resource

In order to facilitate the understanding of the guide, the extension will be integrated from an example: integration of extend on the plugin-document.

Implementing the IExtendableResource interface

Implement the IExtendableResource interface to the representative class of the Document resource. The class in question Document must then implement the following methods :

public class Document implements Localizable, IExtendableResource
{
    ...

    /**
     * {@inheritDoc}
     */
    @Override
    public String getIdExtendableResource( )
    {
        return Integer.toString( _nIdDocument );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getExtendableResourceType( )
    {
        return PROPERTY_RESOURCE_TYPE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getExtendableResourceName( )
    {
        return _strTitle;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getExtendableResourceDescription( )
    {
        return _strDescription;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getExtendableResourceImageUrl( )
    {
        return _strImageUrl;
    }

    ...
}

Implementing the Service DocumentExtendableResourceService

This service allows you to recover the resource from a resource type and its ID. It also allows to declare the type of resource "Document" with the plugin extend:

public class DocumentExtendableResourceService implements IExtendableResourceService
{
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isInvoked( String strResourceType )
    {
        return Document.PROPERTY_RESOURCE_TYPE.equals( strResourceType );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IExtendableResource getResource( String strIdResource, String strResourceType )
    {
        if ( StringUtils.isNotBlank( strIdResource ) && StringUtils.isNumeric( strIdResource ) )
        {
            int nIdDocument = Integer.parseInt( strIdResource );
            return DocumentHome.findByPrimaryKey( nIdDocument );
        }
        return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getResourceType( )
    {
        return Document.PROPERTY_RESOURCE_TYPE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getResourceTypeDescription( Locale locale )
    {
        return I18nService.getLocalizedString( MESSAGE_DOCUMENT_RESOURCE_TYPE_DESCRIPTION, locale );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getResourceUrl( String strIdResource, String strResourceType )
    {
        String strUrl ;

        ...

        return strUrl;
    }
}

This service is instantiated by Spring. It must then be declared at the level of the document_context.xml file:

<bean id="[plugin].[resource_type]ExtendableResourceService" class="fr.paris.lutece.plugins.[plugin].service.resource.[Resource_type]ExtendableResourceService" />

for example :

<bean id = "document.documentExtendableResourceService" class = "en.paris.lutece.plugins.document.service.resource.DocumentExtendableResourceService" />

Be careful, if the plugin is disabled, then the resource will not be available from the extend plugin!

Add buttons to BO to interact with extend

Changing the JSPBean

In the getModifyDocument method, add the following line:

public String getModifyDocument( HttpServletRequest request )
{
    ...
    ExtendableResourcePluginActionManager.fillModel( request, getUser( ), model, strDocumentId, Document.PROPERTY_RESOURCE_TYPE );
    ...
}

This call will add in the model the buttons.

Modification of the template

Modify the template modify_document.html and add the following line:

$ {extendableResourceActionsHtml!}

Display of contents in FO

To display a particular front-office content, you have to configure in the backoffice menu "Content Extension Management" (.../jsp/admin/plugins/extend/ManageResourceExtendersByResource.jsp ) a rule that activates the extensions for these resources (you can choose a particular resource, or all the resources of a type). Then you have to add the following marker in a template:

@ Extender [<idExtendableResource>, <resourceType>, <extenderType>, <parameters>] @

where :

  • <idExtendableResource> is the ID of the resource (ex: 1)
  • <resourceType> is the type of resource (be careful, the type is case-sensitive). For example :
  • PAGE for classic pages of a portal Lutèce
    • document for documents from the plugin-document
  • <extenderType> is the type of the extension (be careful, the type is case-sensitive). For examples :
    • comment to comment on resources
    • hit for the number of views on the resource
    • rating to vote resources
    • feedback to give feedback on resources
  • <parameters> is the additional parameters to add for extensions (eg: {show: true})

Some examples :

MarkeurDescription
@ Extender [1, document, comment] @ Displays comments for the document with ID 1.
@ Extender [1, document, hit, {show: true}] @] @ Displays the number of views on the document with ID 1.
@ Extender [1, document, hit, {show: false}] @ Does not display the number of views for the document with ID 1, but increments the counter.
@ Extender [1, document, hit, {increment: true}] @ increments counter
@ Extender [1, document, hit, {increment: false}] @ does not increment counter
@ Extender [1, document, rating, {show: "vote"}] @ Displays the note of the document with ID 1 @
@ Extender [1, document, rating, {show: "voteAction"}] @ Displays links to cast the document with ID 1
@ Extender [1, document, rating, {show: "all"}] @ Display the note and links of the document with ID 1
@ Extender [2, PAGE, feedback] @ Display a form to give feedback on the page with ID 2

Markers with configurable IDs

In the case where the processing of extentions is done on the server side, it is possible to use parameterizable resource IDs. In this case, the ID must always be defined in an HTML template, but can be set anywhere. This allows for example to put a marker in the header (which is managed by the core Lutèce), and to define the ID of the resource in the body (for example in a template managed by a plugin).

To do this, instead of putting the identifier, just put ExtendParameteredId.

The id must then be defined in a marker:

@ ExtenderParameter [<idExtendableResource>, <resourceType>, <extenderType>] @

If the ID is not specified by an ExtenderParameter markup, then the original markers are ignored.

Example:

In order to add in the header meta data related to Open graph, we add in the <head> tag of the file page_framset.html the marker:

@ Extender [ExtendParameteredId, document, opengraph, {header: true}] @

For example, in the template page_template_document1.html of the Document plugin, add the following parameter editor:

@ ExtenderParameter [1, document, opengraph] @

Thus, if the content of the template page_template_document1.html is included in the final page, then the first marker will be replaced the meta data relative to the document of id 1, and will be placed in the <head> tag.

Deleting resource

When an extencible resource (in our example, a document) is deleted, you must notify the various extensions of the deletion of this resource. To do this, just call the method fr.paris.lutece.portal.service.resource.ExtendableResourceRemovalListenerService.doRemoveResourceExtentions (String strExtendableResourceType, String strExtendableResourceId). This method will take care of deleting all the data contained in the base relative to the deleted resource.

The first parameter of this method is the type of the deleted resource (for example "document" in our case) The second parameter is the identifier of the resource.

View information about an extension in an XPage

Some of the Extend Plugin modules allow you to view information about the extension (ex: the extend comment module allows you to view the comments of a resource in the extension's information management page). This information page of the extension can be integrated into an XPage of a plugin. For that, it is enough to recover the contents of the page of information thanks to ResourceExtenderComponent of this module.

For example, the following method allows the information page of the extend comment module to be displayed independently:

public String getPage (HttpServletRequest request)
{
    ResourceExtenderDTO resourceExtender = new ResourceExtenderDTO ();
    String strIdExtendableResource = request.getParameter (MARK_ID_EXTENDABLE_RESOURCE); // Your marker to get the identifier of the resource
    String strExtendableResourceType = request.getParameter (MARK_EXTENDABLE_RESOURCE_TYPE); // Your marker to get the type of the resource
    resourceExtender.setIdExtendableResource (strIdExtendableResource);
    resourceExtender.setExtendableResourceType (strExtendableResourceType);
    resourceExtender.setExtenderType (EXTENDER_TYPE_COMMENT); // The type of extension you want to display (here how)

    // We then get the ResourceExtenderComponent from the desired module
    IResourceExtenderComponentManager extenderComponentManager = SpringContextService.getBean (ResourceExtenderComponentManager.BEAN_MANAGER);
    IResourceExtenderComponent resourceExtendercomponent = extenderComponentManager.getResourceExtenderComponent (EXTENDER_TYPE_COMMENT);

    // We recover the HTML content of the information page
    String strHtml = resourceExtendComponent.getInfoHtml (resourceExtender, AdminUserService.getLocale (request), request);

    return getAdminPage (strHtml);
}