Creating a DXA module

What has happened?

Two things happened.

  1. Many developers store all their custom views, models and related logic in a web application.
  2. When developer want to implement a custom module, they often have no idea what should they do.

Why can’t I just store it all in a webapp?

You definitely can.

But whilst this is more than acceptable or even recommended for small projects, it may become a mess when a project grows. That time it’s a good idea to move the stuff into a custom DXA module.

Ok, let’s give it a try. How?

Creating a new module is simple but of course requires some effort.

  • Create a new Maven project by executing

mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart

NOTE: you can create a Maven project manually without using archetypes

NOTE: you can use any other system that works with Maven infrastructure, of course

  • Fill a created pom.xml file with your information.
  • Add a <dependencyManagement/> section with dxa-dom

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>com.sdl.dxa</groupId>
			<artifactId>dxa-bom</artifactId>
			<version>${dxa-bom.version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement> 
  • Add a dependency on dxa-common-impl

<dependency>
	<groupId>com.sdl.dxa</groupId>
	<artifactId>dxa-common-impl</artifactId>
</dependency> 
  • Extend a AbstractInitializer class. This is a class to register your views and models.

Set all necessary annotations on it like in the code below.

// you can do multiple registration at once
@RegisteredViewModels({
        @RegisteredViewModel(viewName = "MySecondView", model = MySecondModel.class),
        @RegisteredViewModel(viewName = "MySecondView", model = MyAlternativeSecondModel.class),
        @RegisteredViewModel(model = MyModelWithoutView.class)
})
// or use a single registration annotation if you have just 1 view
@RegisteredViewModel(viewName = "MyView", model = MyModel.class)
// @ModuleInfo is not mandatory but will give you better experience when debugging
@ModuleInfo(name = "My module", areaName = "MyModule", description = "My module implements my feature")
// you have to declare this as a Spring bean
@Component
public class MyModuleInitializer extends AbstractInitializer {
    @Override
    public String getAreaName() {
        return "MyModule"; // this is a name of folder where you store your views
    }
} 
  • Now initialize your Spring context for the module.

@Configuration
@ComponentScan("my.package.mymodule")
public class SpringContext {
} 
  • Move your views to src/main/resources/META-INF/resources/WEB-INF/Views/…
  • Move your models and classes with business logic to src/main/java
  • Add the module to dependencies of your web application.
  • Register your module Spring Context in your application.
  • Now you have a module.

Now I have two projects and build them separately :(

Indeed, this is less convenient.

Three of million ways to solve it are:

  • Create a parent Maven project and declare your webapp and module as subprojects.

http://books.sonatype.com/mvnex-book/reference/multimodule.html 

  • Create a cmd/shell script that will build your projects

call mvn clean install -f mymodule/pom.xml
call mvn clean install -f mywebapp/pom.xml