DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Best GitHub-Like Alternatives for Machine Learning Projects
  • Deploy MuleSoft App to CloudHub2 Using GitHub Actions CI/CD Pipeline
  • Continuous Integration for iOS and macOS
  • GraalVM Features and Future

Trending

  • OneStream Fast Data Extracts APIs
  • How to Migrate Vector Data from PostgreSQL to MyScale
  • DevOps Uses a Capability Model, Not a Maturity Model
  • Machine Learning Libraries For Any Project
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Github Flavored Markdown + OSGi + dotCMS

Github Flavored Markdown + OSGi + dotCMS

Learn how to choose a Java markdown library and use OSGi with dotCMS.

Will Ezell user avatar by
Will Ezell
·
Nov. 04, 15 · Tutorial
Like (6)
Save
Tweet
Share
7.90K Views

Join the DZone community and get the full member experience.

Join For Free

As a Java based CMS, dotCMS handles a lot of different use cases for managing and delivering content. Recently, we were asked if dotCMS can deliver Github flavored markdown content. We thought that this would be a great example of how easy it is to extend dotCMS with OSGi plugins. (As a side note, this blog - as seen on dotcms.com -  is actually written using the plugin).

  • Just take me to the source code

Markdown

Some background for developers stuck in 2008, Markdown is a text to html parser originally written by John Gruber. It provides a user a simple, small set of markup tags that is parsed and rendered as standard HTML for consumption by browsers or even less capable views or viewports. Github Flavored Markdown, or GFM, offers a few extensions for further formatting, including support for strikethrough, url auto-linking, syntax highlighting and tables, Because of the ubiquity of github as a coding resource, GFM has become a de facto standard for commenting, documentation and other online authoring tools that needs support for formatting, but want to limit, uh, “creativity”.

Choosing a Java Markdown Parsing Library

There are number of different Java markdown libraries to out there, including:

  • Pegdown - Larger footprint, dependencies, slower, can hang in corner cases
  • Markdown4j - nice, though seems abandoned
  • TxtMark - small, fast though does not support GFM extensions

dotCMS decided to leverage TxtMark, by René Jeschke, which offers a fast, self contained Markdown implementation without external dependencies. Because TxtMark only supports “standard” Markdown, we also implemented the additions suggested by Bogdan Stefanescu for further Github markdown flavoring. We also added the ability to do code syntax highlighting by adding a class attribute to the <code> code block (and by using highlight.js)

Creating the OSGi Plugin

Most content rendered in dotCMS is parsed by Apache Velocity. dotCMS provides an OSGi extension point for developers to hook into Velocity and provide custom Velocity “Viewtools”, which are pure Java and can be used when rendering content, pages, a template or a widget (Viewtools can be thought of as the Velocity equivalent of a jsp taglib).

To get started, we copied the Viewtool OSGi example provided in the dotCMS source code. This gave us the foundation on which to build our plugin. We then copied the txtmark java files to our plugins src directory ./src/main/java and added our our own package and Viewtool implementation called MarkdownTool.java. This class implements theorg.apache.velocity.tools.view.tools.ViewTool interface and exposes public methods for web developers to use when displaying content. The important method is parse(String markdown), and takes a String of markdown, gets a Markdown Processor and returns our String as marked up html.

Our final MarkdownTool code could literally be as simple as this.

    /**
     * Parse a String for markdown
     * @param parse
     * @return
     * @throws Throwable
     */
    public String parse(String parse) throws Throwable {
        return Processor.process(parse, Configuration.builder().forceExtentedProfile().build());
    }

In order to register the Viewtool via OSGi for use by dotCMS, we need to create two additional classes, the MarkdownToolInfo and the OSGi Activator. The MarkdownToolInfo declares the Velocity variable used to bind our Viewtool and the scope of the tool. Thescope of a Viewtool dictates when a Viewtool is instantiated and can be one of three values:

  • application - loads on startup as a Singleton
  • request - instantiated every visitor request, which gives you a handle on the request object
  • session - once per visitor, added to the visitor session (not sure why someone would want to do this)

Our MarkdownToolInfo class looks looks like

    public String getKey() {
        return "markdown";
    }

    public String getScope() {
        return "request";
    }

    public Object getInstance(Object initData) {
        MarkdownTool viewTool = new MarkdownTool();
        viewTool.init(initData);
        return viewTool;
    }

The second additional class we need to create is a standard OSGi Activator class that is called when an OSGi plugin is initially loaded. This class extends dotCMS's GenericBundleActivator which provides convenience methods to enable or register OSGi plugins in various parts of the dotCMS system. In this case, we register the Viewtool like so:

initializeServices(bundleContext);
registerViewToolService(bundleContext, new MarkdownToolInfo());

Building the plugin

Finally, in order to build our plugin, we need to futz with the ./build.gradle file, which will build our OSGi manifest. Here we add our plugin name and point to the Bundle-Activator that we created in the above step. The important code looks like this:

jar {
    manifest {
        name = 'Markdown Viewtool'
        instruction 'Bundle-Vendor', 'dotcms'
        instruction 'Bundle-Description', 'dotCMS - Markdown'
        instruction 'Bundle-DocURL', 'http://www.dotcms.com'
        instruction 'Bundle-Activator', 'com.dotcms.osgi.markdown.Activator'
        instruction 'DynamicImport-Package', '*'
        instruction 'Import-Package', '*;version=0'
    }
}

To build, we then run the Gradle wrapper

./gradlew clean jar

which builds and jars our osgi plugin. Once it is build, we upload the OSGi jar to your running dotCMS instance via the System > Dynamic Plugins screen. There you should then see the plugin register and become active

Using the Markdown Plugin

The nice thing about Velocity is that it makes easy things easy. So once our plugin is registered and active, using our new plugin on a template or page is easy and understandable for your web developers, e.g.

$markdown.parse("**Parse** *this* ~~string~~") 

will result in

**Parse** *this* ~~string~~

Or when rendering a piece of content with a text field called “body”, something like :

$markdown.parse($content.body)

will parse the content object's body value and return the results.

Get the code

The code for the Markdown OSGi plugin can be found on dotCMS's github repos here:

https://github.com/dotCMS/plugin-viewtool-markdown

DotCMS GitHub

Published at DZone with permission of Will Ezell, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Best GitHub-Like Alternatives for Machine Learning Projects
  • Deploy MuleSoft App to CloudHub2 Using GitHub Actions CI/CD Pipeline
  • Continuous Integration for iOS and macOS
  • GraalVM Features and Future

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: