Contributing to Liferay Development

Organizing the Source

The liferay-portal repository is large, but its layout follows a few consistent patterns. Learn the patterns once and you can locate the code for almost any feature.

Top-Level Layout

The repository has two main code areas:

  • Portal Core — Legacy platform code not yet extracted into modules. The top-level directories are portal-impl (core implementation), portal-kernel (public APIs and shared utilities), and portal-web (server-rendered UI assets).

  • Modules — Feature modules under liferay-portal/modules/. Most modules follow the Liferay MVC pattern and ship as paired -api, -service, and -web modules:

    • -api — public Java interfaces a feature exposes to other modules.
    • -service — Service Builder-generated business logic and persistence.
    • -web — UI code (portlets, JSPs, configuration, asset rendering). Most bug fixes and UI changes happen here.

Worked Example: The Blogs Module

The blogs module group under liferay-portal/modules/apps/blogs/ illustrates the standard layout. It contains blogs-api, blogs-service, blogs-web, and several supporting modules (blogs-recent-bloggers-web, blogs-item-selector-web, and others).

The blogs-web module contains the bulk of the Blogs widget code and demonstrates the framework integrations a typical UI module uses. Each entry below maps a key file to the framework concept it implements.

ComponentPath under blogs-web/src/main/...Purpose
Portlet entry pointjava/com/liferay/blogs/web/internal/portlet/BlogsPortlet.javaDeclares the portlet via OSGi @Component properties. The class does not declare a view-template init param; an MVCRenderCommand handles dispatch.
View render commandjava/com/liferay/blogs/web/internal/portlet/action/ViewMVCRenderCommand.javaDispatches / and /blogs/view to the entry JSP.
Main view JSPresources/META-INF/resources/blogs/view.jspThe Blogs widget’s primary UI entry point.
Asset rendererjava/com/liferay/blogs/web/internal/asset/model/BlogsEntryAssetRenderer.javaRenders a blog entry as an asset, for display in the Asset Publisher and similar contexts.
Panel entryjava/com/liferay/blogs/web/internal/application/list/BlogsPanelApp.javaAdds the Blogs administrative entry to the Product Menu.
Portlet instance configurationjava/com/liferay/blogs/web/internal/configuration/BlogsPortletInstanceConfiguration.javaExposes configurable parameters in System Settings.
Scheduler jobjava/com/liferay/blogs/web/internal/scheduler/CheckEntrySchedulerJobConfiguration.javaConfigures a periodic check for blog entries using the scheduler-job pattern.
Friendly URL mapperjava/com/liferay/blogs/web/internal/portlet/route/BlogsFriendlyURLMapper.javaMaps render and action URLs to SEO-friendly paths.
Dynamic includejava/com/liferay/blogs/web/internal/servlet/taglib/BlogsPortletHeaderJSPDynamicInclude.javaInjects markup into the portlet header without a Fragment bundle.
Display template handlerjava/com/liferay/blogs/web/internal/portlet/display/template/BlogsPortletDisplayTemplateHandler.javaEnables Application Display Templates (ADTs), which use FreeMarker in place of the default JSP.
Sample display templateresources/com/liferay/blogs/web/portlet/display/template/dependencies/portlet_display_template_basic.ftlAn out-of-the-box ADT that lists blog entries in FreeMarker.

These are a subset of the frameworks the blogs-web module uses. The same patterns repeat across most modules under liferay-portal/modules/apps/, so studying one module’s layout gives you a map for the rest of the codebase.

See Also