Thursday, January 1, 2009

Configure site plugin for Maven multi-project

Sometimes we want to configure look-and-feel for the product site generated by Maven. There is no need to describe how to do that for a single project - Maven documentation quite clearly describes it on Creating Content page. On the other hand there is no need to repeat the same configuration for each sub-module's POM in multi-module project. Here is a short description what steps need to be performed to reduce code/markup duplication to add custom logo and make changes to CSS for every site to be generated, both root module one's and sub-modules'.
  1. The first step is creating src/site/resources directory that will contain our images and CSS files, in the root module. As it is described on the site plugin documentation page, we need to configure src/site/site.xml descriptor for our sites:
    <?xml version="1.0" encoding="UTF-8"?>
    <project name="My project">
    <bannerLeft>
    <name>myproject</name>
    <src>images/logo.jpg</src>
    <href>http://en.wikipedia.org/wiki/My_Science_Project</href>
    </bannerLeft>
    <skin>
    <groupId>org.apache.maven.skins</groupId>
    <artifactId>maven-classic-skin</artifactId>
    <version>1.0</version>
    </skin>
    <body>
    <links>
    <item name="${project.name}" href="${project.url}"/>
    </links>

    <menu ref="parent"/>
    <menu ref="modules"/>
    <menu ref="reports"/>
    <menu name="Links">
    <item name="Wiki page" href="http://en.wikipedia.org/wiki/My_Science_Project"/>
    </menu>
    </body>
    </project>
    Here we declared that index page will have banner on top left and click on it will lead to My Science Project movie Wiki page (as example). We use Maven classic skin (some styling we will change later). In <body> element we configure default parent, modules and reports menu items, and provide one more link to Wiki page as part of Links menu. Nothing special yet.

  2. Following plugin documentation, create two sub-directories - css and images. We use the first one to keep all our CSS files - for that we create site.css file that will contain content similar to
    h2 {
    background-color: #5587B7;
    }

    By default site.css generated (and used) by site plugin is empty, and providing this we change styling for HTML element specified in maven-theme.css.
    Next, we copy our site logo image logo.jpg into images sub-directory.

  3. The last but not the least is configuring our POMs. It is predictable that all changes should be done to the root POM - that's the aim of our configuration and the post itself:) Main difference between parent and children POMs is difference in path to site descriptor file and resources. So we need to divide configuration used by the root and child POMs. Here how we do this:
    <build>
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-site-plugin</artifactId>
    <inherited>false</inherited>
    <configuration>
    <siteDirectory>${project.basedir}/src/site</siteDirectory>
    </configuration>
    </plugin>
    </plugins>

    <pluginManagement>
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-site-plugin</artifactId>
    <configuration>
    <siteDirectory>${project.parent.basedir}/src/site</siteDirectory>
    </configuration>
    </plugin>
    </plugins>
    </pluginManagement>
    </build>
    Plugin configuration in pligins element overrides configuration of the one in pluginManagement, it also has inherited attribute set to false so the changes are not propagated to child modules and their POMs. So, configuration of in pluginManagement element specifies correct path for sub-modules - they access site resources through their parent.
Sample multi project can be found here: myproject.zip
That's it!

4 comments:

  1. Works like a charm, thanks!

    ReplyDelete
    Replies
    1. Will this work with just 'mvn site' or do we need to also use 'mvn site:stage' as described at http://maven.apache.org/plugins/maven-site-plugin/examples/multimodule.html ?

      Delete
    2. You need to execute site:stage in case you need to copy site to the staging location. In this case element should be configured for the project, as the plugin documentation specifies. The article does not cover this.

      Delete
  2. Inheriting a parent site descriptor seems to work (maven-site-plugin 3.2) only if you use absolute URLs or the ref-Attribute in the menu elements of the parent site descriptor.
    This could be related to bug MSITE-135 (jira.codehaus.org/browse/MSITE-135).

    ReplyDelete