Site Generation

Chapter 10

10.1. Introduction

Successful software applications are rarely produced by a team of one. When we’re talking about any software worth writing, we’re usually dealing with teams of collaborating developers ranging anywhere in size from a handful of programmers working in a small team to hundreds or thousands of programmers working in a large distributed environment. Most open source projects (such as Maven) succeed or fail based on the presence or absence of well written documentation for a widely-distributed, ad-hoc collection of users and developers. In all environments it is important for projects to have an easy way to publish and maintain online documentation. Software development is primarily an exercise in collaboration and communication, and publishing a Maven site is one way to make sure that your project is communicating with your end-users.

A web site for an open source project is often the foundation for both the end-user and developer communities alike. End-users look to a project’s web site for tutorials, user guides, API documentation, and mailing list archives, and developers look to a project’s web site for design documents, code reports, issue tracking, and release plans. Large open-source projects may be integrated with wikis, issue trackers, and continuous integration systems which help to augment a project’s online documentation with material that reflects the current status of ongoing development. If a new open source project has an inadequate web site which fails to convey basic information to prospective users, it often is a sign that the project in question will fail to be adopted. In other words, for an open source project, the site and the documentation are as important to the formation of a community as the code itself.

Maven can be used to create a project web site to capture information which is relevant to both the end-user and the developer audience. Out of the box, Maven can generate reports on everything from unit test failures to package coupling to reports on code quality. Maven provides you with the ability to write simple web pages and render those pages against a consistent project template. Maven can publish site content in multiple formats including XHTML and PDF. Maven can be used to generate API documentation and can also be used to embed Javadoc and source code in your project’s binary release archive. Once you’ve used Maven to generate all of your project’s end-user and developer documentation, you can then use Maven to publish your web site to a remote server.

10.2. Building a Project Site with Maven

To illustrate the process of building a project website, create a sample Maven project with the archetype plugin:

$ mvn archetype:create -DgroupId=org.sonatype.mavenbook -DartifactId=sample-project

This creates the simplest possible Maven project with one Java class in src/main/java and a simple POM. You can then build a Maven site by simply running mvn site. To build the site and preview the result in a browser, you can run mvn site:run, this will build the site and start an embedded instance of Jetty.

$ cd sample-project
$ mvn site:run
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'site'.
[INFO] ------------------------------------------------------------------------
[INFO] Building sample-project
[INFO]task-segment: [site:run] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] Setting property: classpath.resource.loader.class =>
'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
[INFO] Setting property: velocimacro.messages.on => 'false'.
[INFO] Setting property: resource.loader => 'classpath'.
[INFO] Setting property: resource.manager.logwhenfound => 'false'.
[INFO] [site:run]
2008-04-26 11:52:26.981::INFO:  Logging to STDERR via org.mortbay.log.StdErrLog
[INFO] Starting Jetty on http://localhost:8080/
2008-04-26 11:52:26.046::INFO:  jetty-6.1.5
2008-04-26 11:52:26.156::INFO:  NO JSP Support for /, did not find
org.apache.jasper.servlet.JspServlet
2008-04-26 11:52:26.244::INFO:  Started SelectChannelConnector@0.0.0.0:8080

Once Jetty starts and is listening to port 8080, you can see the project’s site when you go to http://localhost:8080/ in a web browser. You can see the results in Figure 10.1, “Simple Generated Maven Site”.

figs/web/site_index.png

Figure 10.1. Simple Generated Maven Site


If you click around on this simple site, you’ll see that it isn’t very helpful as a real project site. There’s just nothing there (and it doesn’t look very good). Since the sample-project hasn’t configured any developers, mailing lists, issue tracking providers, or source code repositories, all of these pages on the project site will have no information. Even the index page of the site states, "There is currently no description associated with this project". To customize the site, you’ll have to start to add content to the project and to the project’s POM.

If you are going to use the Maven Site plugin to build your project’s site, you’ll want to customize it. You will want to populate some of the important fields in the POM that tell Maven about the people participating in the project, and you’ll want to customize the left-hand navigation menu and the links visible in the header of the page. To customize the contents of the site and affect the contents of the left-hand navigation menu, you will need to edit the site descriptor.

10.3. Customizing the Site Descriptor

When you add content to the site, you are going to want to modify the left-hand navigation menu that is generated with your site. The following site descriptor customizes the logo in the upper left-hand corner of the site. In addition to customizing the header of the site, this descriptor adds a menu section to the left-hand navigation menu under the heading "Sample Project". This menu contains a single link to an overview page.

An Initial Site Descriptor. 

<project name="Sample Project">
    <bannerLeft>
        <name>Sonatype</name>
        <src>images/logo.png</src>
        <href>http://www.sonatype.com</href>
    </bannerLeft>
    <body>
        <menu name="Sample Project">
            <item name="Overview" href="index.html"/>
        </menu>
        <menu ref="reports"/>
    </body>
</project>

This site descriptor references one image. This logo.png image should be placed in ${basedir}/src/site/resources/images. In addition to the change to the site descriptor, you’ll want to create a simple index.apt page in ${basedir}/src/site/apt. Put the following content in index.apt, it will be transformed to the index.html and serve as the first page a user sees when they come to your project’s Maven-generated web site.

  Welcome to the Sample Project, we hope you enjoy your time
on this project site.  We've tried to assemble some
great user documentation and developer information, and
we're really excited that you've taken the time to visit
this site.

What is Sample Project

Well, it's easy enough to explain.   This sample project is
a sample of a project with a Maven-generated site from
Maven: The Definitive   Guide.   A dedicated team of volunteers
help maintain this sample site, and so on and so forth.

To preview the site, run mvn clean site followed by mvn site:run:

$ mvn clean site
$ mvn site:run

Once you do this, load the page in a browser by going to http://localhost:8080. You should see something similar to the screenshot in Figure 10.2, “Customized Sample Project Web Site”.

figs/web/site_custom-descriptor.png

Figure 10.2. Customized Sample Project Web Site


10.3.1. Customizing the Header Graphics

To customize the graphics which appear in the upper left-hand and right-hand corners of the page, you can use the bannerLeft and bannerRight elements in a site descriptor.

Adding a Banner Left and Banner Right to Site Descriptor. 

<project name="Sample Project">

    <bannerLeft>
        <name>Left Banner</name>
        <src>images/banner-left.png</src>
        <href>http://www.google.com</href>
    </bannerLeft>

    <bannerRight>
        <name>Right Banner</name>
        <src>images/banner-right.png</src>
        <href>http://www.yahoo.com</href>
    </bannerRight>
    ...
</project>

Both the bannerLeft and bannerRight elements take name, src, and href child elements. In the site descriptor shown above, the Maven Site plugin will generate a site with banner-left.png in the left-hand corner of the page and banner-right in the right-hand corner of the page. Maven is going to look in ${basedir}/src/site/resources/images for these images.

10.3.2. Customizing the Navigation Menu

To customize the contents of the navigation menu, use the menu element with item child elements. The menu element adds a section to the left-hand navigation menu. Each item is rendered as a link in that menu.

Creating Menu Items in a Site Descriptor. 

<project name="Sample Project">
    ...
    <body>

        <menu name="Sample Project">
            <item name="Introduction" href="index.html"/>
            <item name="News" href="news.html"/>
            <item name="Features" href="features.html"/>
            <item name="Installation" href="installation.html"/>
            <item name="Configuration" href="configuration.html"/>
            <item name="FAQ" href="faq.html"/>
        </menu>
        ...
    </body>
</project>

Menu items can also be nested. If you nest items, you will be creating a collapsible menu in the left-hand navigation menu. The following example adds a link "Developer Resources" which links to /developer/index.html. When a user is looking at the Developer Resources page, the menu items below the Developer Resources menu item will be expanded.

Adding a Link to the Site Menu. 

<project name="Sample Project">
    ...
    <body>
        ...
        <menu name="Sample Project">
            ...
            <item name="Developer Resources" href="/developer/index.html"
                  collapse="true">
                <item name="System Architecture" href="/developer/architecture.html"/>
                <item name="Embedder's Guide" href="/developer/embedding.html"/>
            </item>
        </menu>
        ...
    </body>
</project>

When an item has the collapse attribute set to true, Maven will collapse the item until a user is viewing that specific page. In the previous example, when the user is not looking at the Developer Resources page, Maven will not display the System Architecture and Embedder’s Guide links; instead, it will display an arrow pointing to the Developer Resources link. When the user is viewing the Developer Resources page it will show these links with an arrow pointing down.

10.4. Site Directory Structure

Maven places all site documents under src/site. Documents of similar format are placed in subdirectories of src/site. All APT documents should be in src/site/apt, all FML documents should be in src/site/fml, and XDoc documents should be in src/site/xdoc. The site descriptor should be in src/site/site.xml, and all resources should be stored under src/site/resources. When the Maven Site plugin builds a web site, it will copy everything in the resources directory to the root of the site. If you store an image in src/site/resources/images/test.png, you would refer to the image from your site documentation using the relative path images/test.png.

The following example shows the location of all files in a project which contains APT, FML, HTML, XHTML, and some XDoc. Note that the XHTML content is simply stored in the resources directory. The architecture.html file will not be processed by Doxia, it will simply be copied to the output directory. You can use this approach if you want to include unprocessed HTML content and you don’t want to take advantage of the templating and formatting capabilities of Doxia and the Maven Site plugin.

sample-project
+- src/
   +- site/
      +- apt/
      |  +- index.apt
      |  +- about.apt
      |  |
      |  +- developer/
      |  +- embedding.apt
      |
      +- fml/
      |  +- faq.fml
      |
      +- resources/
      |  +- images/
      |  |  +- banner-left.png
      |  |  +- banner-right.png
      |  |
      |  +- architecture.html
      |  +- jira-roadmap-export-2007-03-26.html
      |
      +- xdoc/
      |  +- xml-example.xml
      |
      +- site.xml

Note that the developer documentation is stored in src/site/apt/developer/embedding.apt. This extra directory below the apt directory will be reflected in the location of the resulting HTML page on the site. When the Site plugin renders the contents of the src/site/apt directory it will produce HTML output in directories relative to the site root. If a file is in the apt directory it will be in the root directory of the generated web site. If a file is in the apt/developer directory it will be generated in the developer/ directory of the web site.

10.5. Writing Project Documentation

Maven uses a documentation-processing engine called Doxia which reads multiple source formats into a common document model. Doxia can then manipulate documents and render the result into several output formats, such as PDF or XHTML. To write document for your project, you will need to write your content in a format which can be parsed by Doxia. Doxia currently has support for Almost Plain Text (APT), XDoc (a Maven 1.x documentation format), XHTML, and FML (useful for FAQ documents) formats.

This chapter has a cursory introduction to the APT format. For a deeper understand of the APT format, or for an in-depth introduction to XDoc or FML, please see the following resources:

10.5.1. APT Example

APT Document shows a simple APT document with an introductory paragraph and a simple list. Note that the list is terminated by the psuedo-element "[]".

APT Document. 

---
Introduction to Sample Project
---
Brian Fox
---
26-Mar-2008
---

Welcome to Sample Project

This is a sample project, welcome!   We're excited that you've decided to
read the index page of this Sample Project.  We hope you enjoy the simple
sample project we've assembled for you.

Here are some useful links to get you started:

* 

* 

* 

If the APT document from APT Document were placed in src/site/apt/index.apt, the Maven Site plugin will parse the APT using Doxia and produce XHTML content in index.html.

10.5.2. FML Example

Many projects maintain a Frequently Asked Questions (FAQ) page. FAQ Markup Language Document shows an example of an FML document.

FAQ Markup Language Document. 

<?xml version="1.0" encoding="UTF-8"?>
<faqs title="Frequently Asked Questions">
    <part id="General">
        <faq id="sample-project-sucks">
            <question>Sample project doesn't work.  Why does sample
                project suck?</question>
            <answer>
                <p>
                    We resent that question.  Sample wasn't designed to work, it was
                    designed to show you how to use Maven.   If you really think
                    this project sucks, then keep it to yourself.   We're not
                    interested in your pestering questions.
                </p>
            </answer>
        </faq>
        <faq id="sample-project-source">
            <question>I want to put some code in Sample Project,
                how do I do this?</question>
            <answer>
                <p>
                    If you want to add code to this project, just start putting
                    Java source in src/main/java.   If you want to put some source
                    code in this FAQ, use the source element:
                </p>
                <source>
                    for( int i = 0; i < 1234; i++ ) {
                                        // do something brilliant
                                        }
                                        </source>
            </answer>
        </faq>
    </part>
</faqs>

10.6. Deploying Your Project Website

Once your project’s documentation has been written and you’ve creates a site to be proud of, you will want to deploy it to a server. To deploy your site you’ll use the Maven Site plugin which can take care of deploying your project’s site to a remote server using a number of methods including FTP, SCP, and DAV. To deploy the site using DAV, configure the site entry of the distributionManagement section in the POM, like this:

Configuring Site Deployment. 

<project>
    ...
    <distributionManagement>
        <site>
            <id>sample-project.website</id>
            <url>dav:https://dav.sample.com/sites/sample-project</url>
        </site>
    </distributionManagement>
    ...
</project>

The url in distribution management has a leading indicator dav which tells the Maven Site plugin to deploy the site to a URL that is able to understand WebDAV. Once you have added the distributionManagement section to our sample-project POM, we can try deploying the site:

 $ mvn clean site-deploy

If you have a server configured properly that can understand WebDAV, Maven will deploy your project’s web site to the remote server. If you are deploying this project to a site and server visible to the public, you are going to want to configure your web server to access for credentials. If your web server asks for a username and password (or other credentials, you can configure this values in your ~/.m2/settings.xml).

10.6.1. Configuring Server Authentication

To configure a username/password combination for use during the site deployment, we’ll include the following in $HOME/.m2/settings.xml:

Storing Server Authentication in User-specific Settings. 

<settings>
    ...
    <servers>
        <server>
            <id>sample-project.website</id>
            <username>jdcasey</username>
            <password>b@dp@ssw0rd</password>
        </server>
        ...
    </servers>
    ...
</settings>

The server authentication section can contain a number of authentication elements. In the event you’re using SCP for deployment, you may wish to use public-key authentication. To do this, specify the publicKey and passphrase elements, instead of the password element. You may still want to configure the username element, depending on your server’s configuration.

10.6.2. Configuring File and Directory Modes

If you are working in a large group of developers, you’ll want to make sure that your web site’s files end up with the proper user and group permissions after they are published to the remote server. To configure specific file and directory modes for use during the site deployment, include the following in $HOME/.m2/settings.xml:

Configuring File and Directory Modes on Remote Servers. 

<settings>
    ...
    <servers>
        ...
        <server>
            <id>hello-world.website</id>
            ...
            <directoryPermissions>0775</directoryPermissions>
            <filePermissions>0664</filePermissions>
        </server>
    </servers>
    ...
</settings>

The above settings will make any directories readable and writable by either the owner or members of the owner’s primary group; the anonymous users will only have access to read and list the directory. Similarly, the owner or members of the owner’s primary group will have access to read and write any files, with the rest of the world restricted to read-only access.

10.7. Customizing Site Appearance

The default Maven template leaves much to be desired. If you wish to customize your project’s website beyond simply adding content, navigational elements, and custom logos. Maven offers several mechanisms for customizing your website that offer successively deeper access to content decoration and website structure. For small, per-project tweaks, providing a custom site.css is often enough. However, if you want your customizations to be reusable across multiple projects, or if your customizations involve changing the XHTML that Maven generates, you should consider creating your own Maven website skin.

10.7.1. Customizing the Site CSS

The easiest way to affect the look and feel of your project’s web site is through the project’s site.css. Just like any images or XHTML content you provide for the website, the site.css file goes in the src/site/resources directory. Maven expects this file to be in the src/site/resources/css subdirectory. With CSS it is possible to change text styling properties, layout properties, and even add background images and custom bullet graphics. For example, if we decided that to make the menu heading stand out a little more, we might try the following style in src/site/resources/css/site.css:

#navcolumn h5 {
font-size: smaller;
border: 1px solid #aaaaaa;
background-color: #bbb;
margin-top: 7px;
margin-bottom: 2px;
padding-top: 2px;
padding-left: 2px;
color: #000;
}

When you regenerate the website, the menu headers should be framed by a gray background and separated from the rest of the menu by some extra margin space. Using this file, any structure in the Maven-generated website can be decorated with custom CSS. When you change site.css in a specific Maven project, the changes will apply to that specific project. If you are interested in making changes that will apply to more than one Maven project, you can create a custom skin for the Maven Site plugin.

Tip

There is no good reference for the structure of the default Maven site template. If you are attempting to customize the style of your Maven project, you should use a Firefox extension like Firebug as a tool to explore the DOM for your project’s pages.

10.7.2. Create a Custom Site Template

If the default Maven Site structure just doesn’t do it for you, you can always customize the Maven site template. Customizing the Maven Site template gives you complete control over the ultimate output of the Maven plugin, and it is possible to customize your project’s site template to the point where it hardly resembles the structure of a default Maven site template.

The Site plugin uses a rendering engine called Doxia, which in turn uses a Velocity template to render the XHTML for each page. To change the page structure that is rendered by default, we can configure the site plugin in our POM to use a custom page template. The site template is fairly complex, and you’ll need to have a good starting point for your customization. Start by copying the default Velocity template from Doxia’s Subversion repository default-site.vm to src/site/site.vm. This template is written in a templating language called Velocity. Velocity is a simple templating language which supports simple macro definition and allows you to access an object’s methods and properties using simple notation. A full introduction is beyond the scope of this book, for more information about Velocity and a full introduction please go to the Velocity project site at http://velocity.apache.org.

The default-site.xml template is fairly involved, but the change required to customize the left-hand menu is relatively straightforward. If you are trying to change the appearance of a menuItem, locate the menuItem macro. It resides in a section that looks like this:

#macro ( menuItem $item )

...

#end

If you replace the macro definition with the macro definition listed below, you will injects Javascript references into each menu item which will allow the reader to expand or collapse the menu tree without suffering through a full page reload:

#macro ( menuItem $item $listCount )
#set ( $collapse = "none" )
#set ( $currentItemHref = $PathTool.calculateLink( $item.href,
$relativePath ) )
#set ( $currentItemHref = $currentItemHref.replaceAll( "\\", "/" ) )

#if ( $item && $item.items && $item.items.size() > 0 )
#if ( $item.collapse == false )
#set ( $collapse = "collapsed" )
#else
## By default collapsed
#set ( $collapse = "collapsed" )
#end

#set ( $display = false )
#displayTree( $display $item )

#if ( $alignedFileName == $currentItemHref || $display )
#set ( $collapse = "expanded" )
#end
#end
<li class="$collapse">
#if ( $item.img )
#if ( ! ( $item.img.toLowerCase().startsWith("http") ||
$item.img.toLowerCase().startsWith("https") ) )
#set ( $src = $PathTool.calculateLink( $item.img, $relativePath ) )
#set ( $src = $item.img.replaceAll( "\\", "/" ) )
<img src="$src"/>
#else
<img src="$item.img" align="absbottom" style="border-width: 0"/>
#end
#end
#if ( $alignedFileName == $currentItemHref )
<strong>$item.name</strong>
#else
#if ( $item && $item.items && $item.items.size() > 0 )
<a onclick="expand('list$listCount')"
style="cursor:pointer">$item.name</a>
#else
<a href="$currentItemHref">$item.name</a>
#end
#end
#if ( $item && $item.items && $item.items.size() > 0 )
#if ( $collapse == "expanded" )
<ul id="list$listCount" style="display:block">
#else
<ul id="list$listCount" style="display:none">
#end
#foreach( $subitem in $item.items )
#set ( $listCounter = $listCounter + 1 )
#menuItem( $subitem $listCounter )
#end
</ul>
#end
</li>
#end

This change adds a new parameter to the menuItem macro. For the new functionality to work, you will need to change references to this macro, or the resulting template may produce unwanted or internally inconsistent XHTML. To finish changing these references, make a similar replacement in the mainMenu macro. Find this macro by looking for something similar to the following template snippet:

#macro ( mainMenu $menus )
...
#end

Replace the mainMenu macro with the following implementation:

#macro ( mainMenu $menus )
#set ( $counter = 0 )
#set ( $listCounter = 0 )
#foreach( $menu in $menus )
#if ( $menu.name )
<h5 onclick="expand('menu$counter')">$menu.name</h5>
#end
<ul id="menu$counter" style="display:block">
#foreach( $item in $menu.items )
#menuItem( $item $listCounter )
#set ( $listCounter = $listCounter + 1 )
#end
</ul>
#set ( $counter = $counter + 1 )
#end
#end

This new mainMenu macro is compatible with the new menuItem macro above, and also provides support for a Javascript-enabled top-level menu. Clicking on a top-level menu item with children will expand the menu and allow users to see the entire tree without waiting for a page to load.

The change to the menuItem macro introduced an expand() Javascript function. This method needs to be added to the main XHTML template at the bottom of this template file. Find the section that looks similar to the following:

<head>
    ...
    <meta http-equiv="Content-Type"
          content="text/html; charset=${outputEncoding}" />
    ...
</head>

and replace it with this:

<head>
    ...
    <meta http-equiv="Content-Type"
          content="text/html; charset=${outputEncoding}" />
    <script type="text/javascript">
        function expand( item ) {
        var expandIt = document.getElementById( item );
        if( expandIt.style.display == "block" ) {
        expandIt.style.display = "none";
        expandIt.parentNode.className = "collapsed";
        } else {
        expandIt.style.display = "block";
        expandIt.parentNode.className = "expanded";
        }
        }
    </script>
    #if ( $decoration.body.head )
    #foreach( $item in $decoration.body.head.getChildren() )
    #if ( $item.name == "script" )
    $item.toUnescapedString()
    #else
    $item.toString()
    #end
    #end
    #end
</head>

After modifying the default site template, you’ll need to configure your project’s POM to reference this new site template. To customize the site template, you’ll need to use the templateDirectory and template configuration properties of the Maven Site plugin.

Customizing the Page Template in a Project’s POM. 

<project>
    ...
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-site-plugin</artifactId>
                <configuration>
                    <templateDirectory>src/site</templateDirectory>
                    <template>site.vm</template>
                </configuration>
            </plugin>
        </plugins>
    </build>
    ...
</project>

Now, you should be able to regenerate your project website. When you do so you may notice that the resources and CSS for the maven site are missing. When a Maven project customizes the site template, the Site plugin expects the project to supply all of the default images and CSS. To seed your project’s resources, you may want to copy the resources from the default Doxia site renderer project to your own project’s resources directory by executing the following commands:

$ svn co \
      http://svn.apache.org/repos/asf/maven/doxia/doxia-sitetools/\
      trunk/doxia-site-renderer
$ rm \
      doxia-site-renderer/src/main/resources/org/apache/maven/\
      doxia/siterenderer/resources/css/maven-theme.cs+
$ cp -rf \
      doxia-site-renderer/src/main/resources/org/apache/maven/\
      doxia/siterenderer/resources/* \
      sample-project/src/site/resources

Check out the doxia-site-renderer project, remove the default maven-theme.css file and then copy all the resources to your project’s src/site/resources directory.

When you regenerate the site, you’ll notice that a few menu items look like regular unstyled text. This is caused by a quirky interaction between the site’s CSS and our new custom page template. It can be fixed by modifying our site.css to restore the proper link color for these menus. Simply add this:

li.collapsed, li.expanded, a:link {
    color:#36a;
}

After regenerating the site, the menu’s link color should be corrected. If you applied the new site template to the same sample-project from this chapter, you’ll notice that the menu now consists of a tree. Clicking on "Developer Resources" no longer takes you to the "Developer Resources" page; in stead, it expands the sub-menu. Since you’ve turned the Developer Resources menu-item into a dynamically-folding sub-menu, you have lost the ability to reach the developer/index.apt page. To address this change, you should add an Overview link to the sub-menu which references the same page:

Adding a Menu Item to a Site Descriptor. 

<project name="Hello World">
    ...
    <menu name="Main Menu">
        ...
        <item name="Developer Resources" collapse="true">
            <item name="Overview" href="/developer/index.html"/>
            <item name="System Architecture" href="/developer/architecture.html"/>
            <item name="Embedder's Guide" href="/developer/embedding.html"/>
        </item>
    </menu>
    ...
</project>

10.7.3. Reusable Website Skins

If your organization is creating many Maven project sites, you will likely want to reuse site template and CSS customizations throughout an organization. If you want thirty projects to share the same CSS and site template, you can use Maven’s support for skinning. Maven Site skins allow you to package up resources and templates which can be reused by other projects in lieu of duplicating your site template for each project which needs to be customized.

While you can define your own skin, you may want to consider using one of Maven’s alternate skins. You can choose from several skins. These each provide their own layout for navigation, content, logos, and templates:

  • Maven Classic Skin - org.apache.maven.skins:maven-classic-skin:1.0
  • Maven Default Skin - org.apache.maven.skins:maven-default-skin:1.0
  • Maven Stylus Skin - org.apache.maven.skins:maven-stylus-skin:1.0.1

You can find an up-to-date and comprehensive listing in the Maven repository: https://repo1.maven.org/maven2/org/apache/maven/skins/.

Creating a custom skin is a simple matter of wrapping your customized maven-theme.css in a Maven project, so that it can be referenced by groupId, artifactId, and version. It can also include resources such as images, and a replacement website template (written in Velocity) that can generate a completely different XHTML page structure. In most cases, custom CSS can manage the changes you desire. To demonstrate, let’s create a designer skin for the sample-project project, starting with a custom maven-theme.css.

Before we can start writing our custom CSS, we need to create a separate Maven project to allow the sample-project site descriptor to reference it. First, use Maven’s archetype plugin to create a basic project. Issue the following command from the directory above the sample-project project’s root directory:

$ mvn archetype:create -DartifactId=sample-site-skin
      -DgroupId=org.sonatype.mavenbook

This will create a project (and a directory) called sample-site-skin. Change directories to the new sample-site-skin directory, remove all of the source code and tests, and create a directory to store your skin’s resources:

$ cd sample-site-skin
$ rm -rf src/main/java src/test
$ mkdir src/main/resources

10.7.4. Creating a Custom Theme CSS

Next, write a custom CSS for the custom skin. A custom CSS stylesheet in a Maven site skin should be placed in src/main/resources/css/maven-theme.css. Unlike the site.css file, which goes in the site-specific source directory for a project, the maven-theme.css will be bundled in a JAR artifact in your local Maven repository. In order for the maven-theme.css file to be included in the skin’s JAR file, it must reside in the main project-resources directory, src/main/resources.

As with the default the default site template, you will want to start customizing your new skin’s CSS from a good starting point. Copy the CSS file used by the default Maven skin to your project’s maven-theme.css. To get a copy of this theme file, save the contents of maven-theme.css from the maven-default-skin project to src/main/resources/css/maven-theme.css in our new skin project.

Now that we have the base theme file in place, customize it using the CSS from our old site.css file. Replace the #navcolumn h5 CSS block with the following:

#navcolumn h5 {
font-size: smaller;
border: 1px solid #aaaaaa;
background-color: #bbb;
margin-top: 7px;
margin-bottom: 2px;
padding-top: 2px;
padding-left: 2px;
color: #000;
}

Once you’ve customized the maven-theme.css, build and install the sample-site-skin JAR artifact to your local Maven repository by running:

$ mvn clean install

Once the installation is complete, switch back to the sample-project project directory, if you already customized the site.css earlier in this chapter, move site.css to site.css.bak so it no longer affects the output of the Maven Site plugin:

$ mv src/site/resources/css/site.css src/site/resources/css/site.css.bak

To use the sample-site-skin in the sample-project site, you’ll need to add a reference to the sample-site-skin artifact in the sample-project's site descriptor. A site references a skin in the site descriptor using the skin element:

Configuring a Custom Site Skin in Site Descriptor. 

<project name="Sample Project">
    ...
    <skin>
        <groupId>org.sonatype.mavenbook</groupId>
        <artifactId>sample-site-skin</artifactId>
    </skin>
    ...
</project>

You can think of a Maven Site skin as a site dependency. Site skins are referenced as artifacts with a groupId and an artifactId. Using a site skin allows you to consolidate site customizations to a single project, and makes reusing custom CSS and site templates as easy as reusing build logic through a custom Maven plugin.

10.8. Tips and Tricks

This section lists some useful tips and tricks you can use when creating a Maven site.

10.8.1. Inject XHTML into HEAD

To inject XHTML into the HEAD element, add a head element to the body element in your project’s Site descriptor. The following example adds a feed link to every page in the sample-project web site.

Injecting HTML into the HEAD element. 

<project name="Hello World">
    ...
    <body>
        <head>
            <link href="http://sample.com/sites/sample-project/feeds/blog"
                  type="application/atom+xml"
                  id="auto-discovery"
                  rel="alternate"
                  title="Sample Project Blog" />
        </head>
        ...
    </body>
</project>

10.8.2. Add Links under Your Site Logo

If you are working on a project which is being developed by an organization, you may want to add links under your project’s logo. Assume that your project is a part of the Apache Software Foundation, you might want to add a link to the Apache Software Foundation web site right below your logo, and you might want to add a link to a parent project as well. To add links below your site logo, just add a links element to the body element in the Site descriptor. Each item element in the links element will be rendered as a link in a bar directly below your project’s logo. The following example would add a link to the Apache Software Foundation followed by a link to the Apache Maven project.

Adding Links Under Your Site Logo. 

<project name="Hello World">
    ...
    <body>
        ...
        <links>
            <item name="Apache" href="http://www.apache.org"/>
            <item name="Maven" href="http://maven.apache.org"/>
        </links>
        ...
    </body>
</project>

10.8.3. Add Breadcrumbs to Your Site

If your hierarchy exists within a logical hierarchy, you may want to place a series of breadcrumbs to give the user a sense of context and give them a way to navigate up the tree to projects which might contain the current project as a subproject. To configure breadcrumbs, add a breadcrumbs element to the body element in the site descriptor. Each item element will render a link, and the items in the breadcrumbs element will be rendered in order. The breadcrumb items should be listed from highest level to lowest level. In the following site descriptor, the Codehaus item would be seen to contain the Mojo item.

Configuring the Site’s Breadcrumbs. 

<project name="Sample Project">
    ...
    <body>
        ...
        <breadcrumbs>
            <item name="Codehaus" href="http://www.codehaus.org"/>
            <item name="Mojo" href="http://mojo.codehaus.org"/>
        </breadcrumbs>
        ...
    </body>
</project>

10.8.4. Add the Project Version

When you are documenting a project that has multiple versions, it is often very helpful to list the project’s version number on every page. To display your project’s version on the website, simply add the version element to your site descriptor:

Positioning the Version Information. 

<project name="Sample Project">
    ...
    <version position="left"/>
    ...
</project>

This will position the version (in the case of the sample-project project, it will say "Version: 1.0-SNAPSHOT") in the upper left-hand corner of the site, right next to the default "Last Published" date. Valid positions for the project version are:

left

Left side of the bar just below the site logo

right

Right side of the bar just below the site logo

navigation-top

Top of the menu

navigation-bottom

Bottom of the menu

none

Suppress the version entirely

10.8.5. Modify the Publication Date Format and Location

In some cases, you may wish to reformat or reposition the "Last Published" date for your project website. Just like the project version tip above, you can specify the position of the publication date by using one of the following:

left

Left side of the bar just below the site logo

right

Right side of the bar just below the site logo

navigation-top

Top of the menu

navigation-bottom

Bottom of the menu

none

Suppress the publication entirely

Positioning the Publish Date. 

<project name="Sample Project">
    ...
    <publishDate position="navigation-bottom"/>
    ...
</project>

By default, the publication date will be formatted using the date format string MM/dd/yyyy. You can change this format by using the standard notation found in the JavaDocs for SimpleDateFormat (see JavaDoc for SimpleDateFormat for more information). To reformat the date using yyyy-MM-dd, use the following publishDate element.

Configuring the Publish Date Format. 

<project name="Sample Project">
    ...
    <publishDate position="navigation-bottom" format="yyyy-MM-dd"/>
    ...
</project>

10.8.6. Using Doxia Macros

In addition to its advanced document rendering features, Doxia also provides a macro engine that allows each input format to trigger injection of dynamic content. An excellent example of this is the snippet macro, which allows a document to pull a code snippet out of a source file that’s available via HTTP. Using this macro, a small fragment of APT can be rendered into XHTML. The following APT code calls out to the snippet macro. Please note that this code should be on a single continuous line, the black slash character is inserted to denote a line break so that this code will fit on the printed page.

%{snippet|id=modello-model|url=http://svn.apache.org/repos/asf/maven/\
archetype/trunk/maven-archetype/maven-archetype-model/src/main/\
mdo/archetype.mdo}

Output of the Snippet Macro in XHTML. 

<div class="source"><pre>

        <model>
            <id>archetype</id>
            <name>Archetype</name>
            <description><![CDATA[Maven's model for the archetype descriptor.
]]></description>
            <defaults>
                <default>
                    <key>package</key>
                    <value>org.apache.maven.archetype.model</value>
                </default>
            </defaults>
            <classes>
                <class rootElement="true" xml.tagName="archetype">
                    <name>ArchetypeModel</name>
                    <description>Describes the assembly layout and packaging.</description>
                    <version>1.0.0</version>
                    <fields>
                        <field>
                            <name>id</name>
                            <version>1.0.0</version>
                            <required>true</required>
                            <type>String</type>
                        </field>
                        ...
                    </fields>
                </class>
            </classes>
        </model>

</pre></div>
Warning

Doxia macros MUST NOT be indented in APT source documents. Doing so will result in the APT parser skipping the macro altogether.

For more information about defining snippets in your code for reference by the snippet macro, see the Guide to the Snippet Macro on the Maven website, at http://maven.apache.org/guides/mini/guide-snippet-macro.html.