Markdown XPages UIControl

Often when I’m designing an xpage, there might be a section of the page in which I want to explain some instructions to the user. Some options here are to:

  1. write the Instructions using html and embed directly in the xpage markup
  2. write the Instructions directly in the design pane and format using designer’s ui e.g. bold, color, size etc
  3. use some native xpage controls to achieve the desired result.
  4. Write the instructions in a richtext field on a notes document that is loaded to display the info.

Option 1 works good but is annoying to type html opening and closing all those tags. Option 2 is quick to use but creates ugly html with hardcoded styles / colours etc. Option 3 is doable but still a little clunky, Option 4 is not a great move because it is very hard to include the instructions within source control.

A better option needed

Lightweight markup languages are a great way to let formatting ‘get out of the way’ and just let you focus on writing the content. There are many lightweight languages to choose from. Markdown is a popular one so I thought that would be great to be able to quickly write some markdown and let the formatting take care of itself.

If you aren’t familiar with the concept, it is basically a system of writing some plaintext content that can automatically be converted to html. For example the following text is plain text but easy to see the intended structure:

This will processed by Markdown into the following html

Side note: Asciidoctor is good too

I have also created a similar control for AsciiDoctor which is another lightweight format. I actually prefer to use Asciidoctor now, however since Markdown seems to be more common I thought I would share the markdown control first.

If you are interested in AsciiDoctor control let me know. It is a bit more intense though because it starts up a JRuby instance and maybe that is not something you’d like to do (because AsciiDoctor is ruby based).

Overview

A few years ago Martin Rolph from Oval UK shared a solution of a Markdown Custom Control. You can find the project on github at OvalUK/XPagesDemos. The solution used markdown4j which is a java-based markdown processor. I decided to build on Martin’s work and convert it from a custom control into an XspLibrary Control with a few extra options of where to retrieve the markdown from.

The markdown control allows you bind to a dynamic data source such as a NotesDocument / scoped variable etc. but also provides some options to load the source text from some static locations. You can have the source text:

  • Bound to a String Field in a Datasource or Scope variable
  • Supplied from a text file in the WEB-INF directory (read only)
  • Supplied from a text file from within a plugin (read only)
  • Supplied from a File in the ‘Resources’ Design Element (read only)
  • Written directly within the control’s start and end tags (passthrough text) but this has some gotchas. (read only)

The control is an extension of the normal ‘inputTextArea’ control. When the control is in edit mode it just works exactly like a plain text area.

In Read-only mode, the supplied plaintext will be converted to html for display using the Markdown Processor.

Simple Example

In this simple example, I am binding the text to a viewScope variable ‘sampleText’
I have 2 markdown controls, one on the left in edit mode, and one on the right in read mode, showing a live preview of the markup using the onKeyUp event to refresh the preview control. Here is the markup for the page

And here is an example of how it looks

Examples of the different methods of supplying the text

You should be able to find the control in the Controls palette under Gregorbyte Library. Drag it onto the page.

Bound to a Datasource / Managed Bean

You can bind it to any text field just like you would normally. In this example it is bound to a document and in edit mode acts just like a normal text area.

Then in edit mode:

In Read only mode:

Supplied from WEB-INF

To read a file from WEB-INF the ‘value’ should be the path to the file

  • It must start with ‘/WEB-INF’
  • It must finish with ‘.md’
  • readonly property should be ‘true’

e.g.

Supplied from a File in the Resources Design element

To supply the text from a File in the Resources Design element, give your file should the .md extension, and then supply ‘value’ as ‘/<yourfilename>.md’, also set readonly=”true” e.g.

Supplied from a TextFile in a plugin

To supply the text from a file in a plugin, make sure your file has .md extension. Right click on the file in eclipse and ‘Copy Qualified Name’. Paste this as the ‘value’ and set readonly = true.
You may run into some trouble if your file is not included in the build process, or it is built to a different location than it is in the source code, but basically the format should be ‘/com.your.plugin/your/classpath/to/resource/file.md’

Written directly within start and end tag

This is a quick and dirty method but it is a bit buggy. If you sometimes format your xsp markup with Ctrl + Shift + F then it will ruin your markdown with indents etc. The markdown text must be placed flush with the margin of the code editor

Installation

To install you do one of the following:

  • install my GregorbyteXspLibrary to your designer + server
  • Scavenge necessary files from the Github repo

Method 1: Install my library

Go to the latest releases of camac/GregorbyteXspLibrary, download the zip file and install the update site using your favourite methods (same method as you would install IBM Extension Library)

Method 2: Scavenge Necessary files from github repo

You will need These java files

  • /com.gregorbyte.xsp.controls/src/com/gregorbyte/xsp/component/markdown/UIMarkdown.java
  • /com.gregorbyte.xsp.controls/src/com/gregorbyte/xsp/renderkit/markdown/MarkdownRenderer.java

You will need this JAR

  • /com.gregorbyte.lib.markdown4j/lib/markdown4j-2.2.jar

You will need this xsp-config (place in your WEB-INF

  • /com.gregorbyte.xsp.controls/src/com/gregorbyte/xsp/config/gregorbyte-markdown.xsp-config

You will need to include the contents of this file in your WEB-INF/faces-config.xml file

  • /com.gregorbyte.xsp.controls/src/com/gregorbyte/xsp/config/gregorbyte-markdown-faces-config.xml

I am pretty sure that is all that is needed, let me know if you have any trouble.

Conclusion

Once again thanks to Martin Rolph for providing the markdown custom control in the first place, I have simply added a few more ways to supply the source and wrapped it in a control.

I’d love to hear what you think if this is useful to you or not. Personally I have been using it mainly to supply markdown from within a plugin. Mainly help/instructions/code examples in our demo database.

You may also like...

2 Responses

  1. Paul Withers says:

    Great work, it’s something I’ve wanted to do in customer applications for a while, to avoid rich text formatting. But this goes way beyond what I had planned, in terms of where the markdown is stored. This sounds like an excellent addition to Extension Library. I’m sure you’ve got the environment already set up, but I blogged about it on OpenNTF a while ago https://www.openntf.org/main.nsf/blog.xsp?permaLink=PWIS-9QZTH2.

    • camerongregor says:

      Thanks for the comment Paul! I have a few controls which are candidates for Extension Library submission.
      Unfortunately the lack of activity on my existing pull requests has discouraged me from submitting anything else at the moment. But I see this has been acknowledged at IBM Connect so hopefully it will pick up.
      Also when I asked in #extensionlibrary channel in OpenNTF slack, nobody seemed to be able to clarify for me the issues regarding licensing. e.g. When bootstrap was absorbed into extlib, Select2 was deliberately excluded due to licencing (I believe), but I’d like to know what the guidelines are on that?
      Some of the controls I’ve developed require some 3rd party libraries. this Markdown control for example relies on Markdown4J. So I’d like to be able to figure out which controls I shouldn’t even bother submitting due to this licensing issue.
      I still plan on making further pull-requests to the extension library, but for now I plan on releasing a few through my ‘GregorbyteXspLibrary’ and blogging here so at least people can grab it an use it straight away, (or suggest better options/features) and then if I get comments like yours I know that it is something that people would like to use, and then when I get around to making some pull requests I know which controls to start with first

Leave a Reply

Your email address will not be published. Required fields are marked *