Posts Tagged ‘wordpress

13
Feb
13

Create Custom Maven Plugin

This page describes how to create a custom maven plugin.

Full downloadable source for this page is available here. Corrections and enhancements are welcome, fork, change and push back to GitHub.

Problem Statement

This site contains hundreds pages with small demo java projects embedded in its pages.

While working on this site I came across a few problems.

  1. How to reduce typo errors on the pages source code.
  2. How to keep the blog page up to date after code fixes.

The solution: Have a custom maven plugin generate the blog page with source code automatically. The plugin uses velocity template that contain the text of the blog page along with “#include” velocity directives that bring in the source code from the project.

Implementation

Follow these steps to create a custom plugin to generate HTML content from velocity templates.

Start by editing the pom.xml file to look like this.

vi pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>github.numberformat</groupId>
	<artifactId>blog-plugin</artifactId>
	<version>1.0-SNAPSHOT</version>
	<packaging>maven-plugin</packaging>

	<properties>
		<mavenVersion>2.0.6</mavenVersion>
	</properties>

	<pluginRepositories>
	  <pluginRepository>
	    <id>numberformat-releases</id>
	    <url>https://raw.github.com/numberformat/20130213/master/repo</url>
	  </pluginRepository>
	</pluginRepositories>

	<dependencies>
		<dependency>
			<groupId>org.apache.maven</groupId>
			<artifactId>maven-plugin-api</artifactId>
			<version>2.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.velocity</groupId>
			<artifactId>velocity</artifactId>
			<version>1.7</version>
		</dependency>
		<dependency>
			<groupId>org.apache.maven</groupId>
			<artifactId>maven-model</artifactId>
			<version>${mavenVersion}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.maven</groupId>
			<artifactId>maven-artifact</artifactId>
			<version>${mavenVersion}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.maven</groupId>
			<artifactId>maven-project</artifactId>
			<version>${mavenVersion}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.maven</groupId>
			<artifactId>maven-core</artifactId>
			<version>${mavenVersion}</version>
		</dependency>
	</dependencies>
	<name>Wordpress Page Generation Plugin</name>
	<description>Generates a wordpress page for the project.</description>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.0.2</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
	 		<plugin> 			
	 			<groupId>github.numberformat</groupId>
	 			<artifactId>blog-plugin</artifactId>
	 			<version>1.0-SNAPSHOT</version>
	 			<configuration>
				<gitUrl>https://github.com/numberformat/20130213</gitUrl>
	 			</configuration>
	        <executions>
	          <execution>
	            <id>1</id>
	            <phase>site</phase>
	            <goals>
	              <goal>generate</goal>
	            </goals>	            
	          </execution>
	        </executions>
	 		</plugin>
		</plugins>
	</build>
</project>

The following file is the plugin implementation class.

BlogMojo.java

package github.numberformat.plugin;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

/**
 * This is a simple plug-in that generates a blog page from a velocity
 * template. This allows developers to create very simple project documentation
 * pages for their projects. Developers would typically create a blog entry by
 * copying and pasting the HTML directly into the blog site.
 * 
 * @goal generate
 */
public class BlogMojo extends AbstractMojo {
	/**
	 * @parameter default-value="${basedir}"
	 * @required
	 * @readonly
	 */
	private File basedir;

	/**
	 * Represents the date first published.
	 * 
	 * @parameter default-value="https://github.com/numberformat"
	 * @required
	 * @readonly
	 */
	private String gitUrl;
	
	
	public void execute() throws MojoExecutionException {
		
		final File templateDir = basedir;
		final File targetBlog = new File(basedir, "target/blog");

		if(new File(templateDir, "src/blog/wordpress.vm").canRead()) {
			if(!targetBlog.exists()) {
				targetBlog.mkdirs();
			} else if(!targetBlog.isDirectory()) {
				throw new MojoExecutionException("Must be a directory: " + targetBlog.getAbsolutePath());
			}
	
	        VelocityEngine ve = new VelocityEngine();
	        ve.setProperty("file.resource.loader.path", templateDir.getAbsolutePath());
	        ve.init();
        
	        Template t = ve.getTemplate( "src/blog/wordpress.vm" );
	        VelocityContext context = new VelocityContext();
	        context.put("blog_header", getHeader());
	        context.put("blog_footer", getFooter());
	        context.put("blog_git_url", gitUrl);
	        
	        FileWriter writer = null;
			try {
				writer = new FileWriter(new File(targetBlog, "wordpress.html"));
		        t.merge( context, writer );				
			} catch (IOException e) {
				throw new MojoExecutionException(e.getMessage());
			} finally {
				try{writer.close();}catch(Exception e){}				
			}
		}
	}


	private Object getFooter() {
		return "<div style=\"font-size:13px;border:1px solid gray; " +
				"padding:5px;line-height:120%\">Full downloadable source for " +
				"this page is <a href=\""+gitUrl+"\">available here</a>. " +
				"</div>";
	}

	private Object getHeader() {
		return "<div style=\"font-size:13px;border:1px solid gray; " +
				"padding:5px;line-height:120%\">Full downloadable source for " +
				"this page is <a href=\""+gitUrl+"\">available here</a>. " +
				"Corrections and enhancements are welcome, fork, change and push " +
				"back to GitHub.</div>";
	}
}

Publish to Nexus or Website

You may deploy the plugin into a nexus repository a simple website.

Example Usage

For demonstration purposes I have published the plugin to the following URL, you may use it in your project by including it in your pom.xml.

vi pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.test</groupId>
  <artifactId>testProject</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <pluginRepositories>
    <pluginRepository>
      <id>numberformat-releases</id>
      <url>https://raw.github.com/numberformat/20130213/master/repo</url>
    </pluginRepository>
  </pluginRepositories>
  
  <build>
  	<plugins>
  		<plugin> 			
  			<groupId>github.numberformat</groupId>
  			<artifactId>blog-plugin</artifactId>
  			<version>1.0-SNAPSHOT</version>
	        <executions>
	          <execution>
	            <id>1</id>
	            <phase>site</phase>
	            <goals>
	              <goal>generate</goal>
	            </goals>	            
	          </execution>
	        </executions>
  		</plugin>
  	</plugins>
  </build>
</project>

As you can see from the above the plugin to generate the wordpress page is hooked into the “site” phase of the build lifecycle.

Velocity Template

Save the file into:

src/blog/wordpress.vm

#set( $foo = "Velocity" )
Hello $foo World!

(include sourcecode tag in square brackets around the include line below)
#include("src/main/java/App.java")
(include /sourcecode tag in square brackets around the include line above)

Run the Plugin

To run the plugin and you have specified the executions tag above just type

mvn site

As an alternative if you don’t want to hook it into the maven lifecycle then just delete the “executions” tag above and run the plugin by typing:

To run the plugin just type

mvn blog:generate

If you get a WARNING about plexus ignore it.

Upon successful build you can view the generated wordpress page in the target/blog folder of the project.

Next Steps

blog-plugin improvements:

  1. Enhance the plugin to generate pages in formats other than wordpress.
  2. Have plugin insert headers or footers on the generated pages. (done)
  3. Enhance the plugin to have blog pages contain a link to GitHub where visitors can simply checkout the project instead of copying and pasting source from the page. (done)
Full downloadable source for this page is available here.



Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 74 other followers

March 2017
S M T W T F S
« Mar    
 1234
567891011
12131415161718
19202122232425
262728293031  

Blog Stats

  • 801,397 hits