What has happened?
Two things happened.
- Many developers store all their custom views, models and related logic in a web application.
- 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
-
In DXA we use a dxa-builder (starting from 1.6.0) which is publicly available. This requires you to create a gradle project without sources. For an example you can take a look at DXA project. https://github.com/sdl/dxa-web-application-java/blob/master/build.gradle