Sites and Inheritence

Maven's support for sites that span multiple projects has generally been limited to date. The following are some features that will assist in this.

Requirements

  • Inherited navigational elements
  • Using submenus
  • Ability to generate within the subproject, or at the top level and get the same results (with the exception of aggregated reports)
  • No strict requirements on filesystem layout other than those that already exist for Maven projects
  • Ability to aggregate reports (individual report technique out of scope here)
  • Breadcrumbing
  • Skinning
  • Separation of user and developer documentation
  • Separation of different releases in documentation

Proposed Solutions

Inherited Navigational Elements

The site descriptor will be deployed to the repository whenever the artifact is (through the deploy phase) or the site is (through the site-deploy phase). It will also be discoverable via the parent POM using ${basedir}/src/site/site.xml using the normal workspace location. When deployed to the repository, it will be located at /groupId/artifactId/version/artifactId-version-site.xml.

We can add inherit="top|bottom|none" to the menu element, with none as the default.

<menu name="Commons Common">
  <item ... />
</menu>

<menu name="Commons Specifics" inherit="bottom">
  <item ... />
</menu>

Including Generated Content

Currently there are elements like ${reports} and ${modules} in the site descriptor. These will be deprecated in favour of:

  <!-- Include all info and reports -->
  <menu ref="reports" />

  <menu ref="modules" />

~~TODO: not happy with this yet

Symmetric generation

When generating within the top level, content will be generated into the target/site location of the subproject, using the difference between the top level URL and the subproject's URL as the relative path to use. It will not be possible to navigate between the sites on the filesystem - you must push to staging to achieve this.

When generated within the subproject, it is only generated into the subproject. The site will appear correctly, but navigating to upper levels will not be possible when previewing. However, it can be deployed from there directly into the right subdirectory on the site.

Filesystem layout constraints

The location of site.xml relative to a project is determined by plugin configuration as normal, and defaults to src/site. When locating a parent project, this is done using the normal workspaces/USD technique (using relativePath in the POM, falling back to the repository. Parent project documents are not needed - only the site descriptor.

Report aggregation

Most of the work of this is covered in the individual plugins and the Maven Dashboard discussion, and is out of scope for this document. While the site mojo itself will not be an @aggregator, individual reports are free to do so and should behave correctly.

Breadcrumbing

Breadcrumbs will be stored in the <breadcrumbs /> element.

<body>
  <breadcrumbs>
    <item href="http://www.apache.org/" name="Apache" />
    <item name="Maven"/> <!-- href is derived from project.url -->
  </breadcrumbs>

Note: Generally you'll only specify one breadcrumb, but it is a list to facilitate the root to have additional breadcrumbs that navigate back beyond the Maven hierachy.

By default, the name element of the project will be used as the breadcrumb.

Skinning

Skinning support will provided by a separate artifact that contains CSS, images and is unpacked over a site. It can optionally contain a replacement /META-INF/maven/site.vm velocity template for generating the final XHTML.

It is built as a normal JAR. To configure the skin in the client, add it to the site descriptor:

<project>
...
  <skin>
    <groupId>org.apache.maven.skins</groupId>
    <artifactId>maven-default-skin</artifactId>
    <version>1.0</version> <!-- optional -->
  </skin>
...

Separation of different releases in documentation

see http://jira.codehaus.org/browse/MNG-41

  • No labels

7 Comments

  1. Unknown User (skaze)

    I have struggled with maven and its multiproject site support and have discussed this quite a bit with with vincent. The key observation is that a project that is a module of another project (and therefore semantically a child) is not necessarily related to the web/deployment location of its parent (or siblings, or children). Each project can provide its own project.distributionManagement.site.url and project.url independent to its location within the multiproject graph and therefore the assumption that one can use the same address space for URL linking as is used in the file system is wrong. There is an implicit relationship between a project's project.url and its project.distributionManager.site.url (i.e. if they do not resolve to the same web location then the developer is doing something pretty strange) and therefore the only way to know how to address a project (be it a child or parent) is via a project's project.url, after all the only address space that is valid for a project site and therefore the URL to link to it is the project's public location.

    Things are further compounded when trying to write an intelligent Mojo to build links to modules and parents due to the current maven multiproject handling. In theory one should be able to relate to ones parent and child projects without having to be in a reactor build (i.e. when -N has been passed in on command line) but there is no valid graph of interpolated projects unless is in a reactor build. Note that not even project.getParent() is interpolated meaning that you will find unevaluated expressions in the parent model. Then theres the whole module problem with modules not refering to projects but filesystem locations (something IMHO that breaks the whole repo based project location independence). We need a way to parse the interpolated model of a project's children and parent, if we had this fully interpolated graph of the multiproject ancestry then we can get a lot smarter with what Mojos can do in this world of peeking into parents and siblings.

    See MNG-661 for more discussion.

    1. I've read MNG-661. This aims to resolve the issues you're talking about. Perhaps I didn't explain it properly, but is there something you think this doesn't address?

      1. Unknown User (skaze)

        oops, i should have hit reply (new to this confluence thingy)

  2. Unknown User (skaze)

    Sorry Brett i should have been more specific in terms of this proposal.

    Under 'Symmetric generation':

    'When generating within the top level, content will be generated into the target/site location of the subproject, then copied into the right place within the target/site of the top level project, using the difference between the top level URL and the subproject's URL as the relative path to use (which will default to artifactId).'

    'When generated within the subproject, it is only generated into the subproject. The site will appear correctly, but navigating to upper levels will not be possible when previewing...'

    My first paragraph attempted to highlight why I don't think you can relate a project's filesystem location in respect to where it resides in relation to its parent and child projects and the URLs required to address those parent and child projects; thus I can not see the point of copying a module project's target/site into its parent's target/site when those files are independent of each other (i.e they may not even be residing on the same web server)

    My second paragraph just highlighted some of the things i came across when trying to build a mojo that peeked up and down the project ancestry when not in a reactor environment (i.e. the lack of an cooked multiproject graph).

    1. ok, so the first one needs to be more explicit - if the subproject URL is not related to the parent, then it won't be copied, and URLs will be used instead of relative paths.

      For the second one, I don't know that we can do anything about the local preview, but it will behave correctly without a reactor context as it can discover the parent POM and site descriptor from the repository/local file system using the current discovery rules used for a parent POM.

      Is that sufficient?

      1. Unknown User (skaze)

        The question i would still ask is why are you looking perform this copy at all? I cant understand what you get out of combining site files in this manner. What is the reason for pulling all the module site files into a directory structure with a shared root when they will deployed by their own deploy processing?

        Re the second part, as far as i know (which admittedly is not a lot re mojo dev) in the current mojo env you get hold of your parent by declaring that you want the project in your mojo via a @parameter expression="${project} and then query this project object for its parent. This parent object will not have been interpolated and will therefore contain unevaluated expressions (including say its URL which is something that I use property expression to populate). Is there another way of getting hold of the parent such that its model has been properly evaluated that i don't know about?

        1. The copy is done from the top level so it can run as an aggregator and the subprojects can be viewed as a single site and deployed as one. However, I see that if any of the subprojects have a different URL this won't work, so it may need to be reconsidered.

          The parent project should be a complete project - if it isn't interpolated then that is a bug I think.

          Perhaps if you have any further responses they can be posted to dev@maven.apache.org, as this isn't a great forum for discussion, thanks!