5.4.5. Wiki macro

eXo Platform uses XWiki as a Wiki engine, so you can develop and use macros in eXo Wiki completely following the XWiki approach.

If you have never tried using a macro before, you can quickly try eXo video-wiki-macro. Follow the project's README and it will help you build, deploy and use the macro.

As said, the macro completely follows XWiki approach, so you can refer to their documentation for a start. In this tutorial, you write a new macro called "mailto". When a user inserts the macro, he inputs a username from that your macro that retrieves an email contact and adds it inline. The source code can be found here.

Create a Maven project with the structure like this:

Alternatively, you can generate a project and modify it using the XWiki's macro-archetype 5.4.2.

In pom.xml, you need dependencies of XWiki (version 5.4.2 for strong compatibility) and eXo Social:


<dependency>
    <groupId>org.xwiki.rendering</groupId>
    <artifactId>xwiki-rendering-syntax-xwiki21</artifactId>
</dependency>
<dependency>
    <groupId>org.xwiki.rendering</groupId>
    <artifactId>xwiki-rendering-syntax-xhtml</artifactId>
</dependency>
<dependency>
    <groupId>org.xwiki.rendering</groupId>
    <artifactId>xwiki-rendering-transformation-macro</artifactId>
</dependency>
<dependency>
    <groupId>org.exoplatform.social</groupId>
    <artifactId>social-component-core</artifactId>
</dependency>

The macro class should extend org.xwiki.rendering.macro.AbstractMacro and implement the execute method. It must declare a parameter type so that XWiki takes care the interface with users to get a username and passes it to your method.

@Component("mailto")

public class MailtoMacro extends AbstractMacro<MailtoMacroParams> {
  public MailtoMacro() {
    super("mailto", "Add an email contact inline.", MailtoMacroParams.class);
  }
  public boolean supportsInlineMode() {
    return true;
  }
  public List<Block> execute(MailtoMacroParams parameters,
                             String content,
                             MacroTransformationContext context) throws MacroExecutionException {
    IdentityManager identityManager = (IdentityManager) PortalContainer.getInstance().getComponentInstanceOfType(IdentityManager.class);
    try {
      // Get user info.
      Identity identity = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME, parameters.getUsername(), false);
      Profile profile = identity.getProfile();
      String displayName = profile.getFullName(); //to be displayed.
      String email = profile.getEmail(); //to be linked.
      
      // Build the blocks.
      RawBlock rawblock = new RawBlock(displayName, Syntax.XHTML_1_0);
      LinkBlock linkblock = new LinkBlock(Arrays.<Block>asList(rawblock), new ResourceReference(email, ResourceType.MAILTO), true);
      return Arrays.<Block>asList(linkblock);
    } catch (Exception e) {
      
      // In case the parameter is not a valid user id.
      RawBlock rawblock = new RawBlock(parameters.getUsername()+"(?)", Syntax.XHTML_1_0);
      return Arrays.<Block>asList(rawblock);
    }
  }
}

You provide the macro name, a description (users will see it) by the annotation and the constructor. You can also categorize your macro, see a code sample in the video-macro's source code.

You need only one parameter - username that is mandatory. In the execute method, you use it to get a user profile (if it is invalid, the macro simply shows its raw value with a question (?) sign).

Pay attention to the annotations:

public class MailtoMacroParams {

  
  /**
   * The MailtoMacro expects a user name. If the user name is not valid, it appends a question sign to the user name.
   */
  
  private String username;
  public String getUsername() {
    return username;
  }
  @PropertyDescription("Somebody's ID. His email will be added inline.")
  @PropertyMandatory
  public void setUsername(String username) {
    this.username = username;
  }
}

Finally, you declare the macro's class name in src/main/resources/META-INF/components.txt, just with one line:

org.exoplatform.samples.xwiki.macro.MailtoMacro

Here is the picture of a Wiki page that uses the macros:

Copyright ©. All rights reserved. eXo Platform SAS
blog comments powered byDisqus