|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Spring-pug4j is a Spring Framework integration library for Pug4J (formerly Jade4J), providing Spring MVC view resolution for Pug templates. The library acts as a bridge between Spring's view resolution mechanism and the Pug templating engine. |
| 8 | + |
| 9 | +**Key Details:** |
| 10 | +- Current version: 3.3.2-SNAPSHOT |
| 11 | +- Requires Java 17+ |
| 12 | +- Spring Framework 6.2+ (Jakarta EE with jakarta.servlet-api 6.0) |
| 13 | +- Build tool: Maven |
| 14 | +- Testing: JUnit 4, Mockito |
| 15 | + |
| 16 | +## Build Commands |
| 17 | + |
| 18 | +```bash |
| 19 | +# Compile the project |
| 20 | +mvn compile |
| 21 | + |
| 22 | +# Run all tests |
| 23 | +mvn test |
| 24 | + |
| 25 | +# Run a specific test class |
| 26 | +mvn test -Dtest=SpringTemplateLoaderTest |
| 27 | + |
| 28 | +# Run tests with debug logging |
| 29 | +mvn --batch-mode test -D"org.slf4j.simpleLogger.defaultLogLevel"="error" -D"org.slf4j.simpleLogger.log.de.neuland.pug4j"="debug" |
| 30 | + |
| 31 | +# Full build with verification |
| 32 | +mvn --batch-mode --update-snapshots verify |
| 33 | + |
| 34 | +# Package the library |
| 35 | +mvn package |
| 36 | + |
| 37 | +# Install to local Maven repository |
| 38 | +mvn install |
| 39 | +``` |
| 40 | + |
| 41 | +## Architecture |
| 42 | + |
| 43 | +The library consists of three core components that integrate Spring MVC with Pug4J: |
| 44 | + |
| 45 | +### 1. SpringTemplateLoader (`de.neuland.pug4j.spring.template.SpringTemplateLoader`) |
| 46 | +- Implements `TemplateLoader` from pug4j and `ResourceLoaderAware` from Spring |
| 47 | +- Responsible for loading Pug template files using Spring's `ResourceLoader` abstraction |
| 48 | +- Handles path resolution, including: |
| 49 | + - Classpath resources (e.g., `classpath:/templates`) |
| 50 | + - File system paths (including Windows paths like `file:C:/templates`) |
| 51 | + - Relative and absolute paths |
| 52 | + - Path normalization (converts Windows backslashes to Unix forward slashes) |
| 53 | +- Automatically appends `.pug` suffix to template names if no extension is provided |
| 54 | +- Configurable properties: |
| 55 | + - `templateLoaderPath`: Base path for template lookup (default: "") |
| 56 | + - `basePath`: Additional base path component (default: "") |
| 57 | + - `encoding`: Character encoding (default: "UTF-8") |
| 58 | + - `suffix`: Template file extension (default: ".pug") |
| 59 | + |
| 60 | +### 2. PugViewResolver (`de.neuland.pug4j.spring.view.PugViewResolver`) |
| 61 | +- Extends Spring's `AbstractTemplateViewResolver` |
| 62 | +- Registers itself as a view resolver in Spring MVC's view resolution chain |
| 63 | +- Creates `PugView` instances for resolved view names |
| 64 | +- Configures each view with: |
| 65 | + - The shared `PugConfiguration` instance |
| 66 | + - Content type (default: "text/html;charset=UTF-8") |
| 67 | + - Exception rendering mode for development |
| 68 | + |
| 69 | +### 3. PugView (`de.neuland.pug4j.spring.view.PugView`) |
| 70 | +- Extends Spring's `AbstractTemplateView` |
| 71 | +- Executes template rendering by: |
| 72 | + - Retrieving compiled template from `PugConfiguration` |
| 73 | + - Merging Spring MVC model data with the template |
| 74 | + - Writing rendered HTML to the HTTP response |
| 75 | +- Features a development-friendly exception rendering mode (`renderExceptions`): |
| 76 | + - When enabled, catches `PugException` and renders formatted HTML error pages |
| 77 | + - When disabled, logs errors and allows Spring's standard error handling |
| 78 | + |
| 79 | +### Component Interaction Flow |
| 80 | + |
| 81 | +1. Spring MVC receives a request and determines a logical view name (e.g., "index") |
| 82 | +2. `PugViewResolver.buildView()` creates a `PugView` instance |
| 83 | +3. `PugView.renderMergedTemplateModel()` is invoked with the model data |
| 84 | +4. `PugView` retrieves the compiled template via `PugConfiguration.getTemplate()` |
| 85 | +5. `PugConfiguration` uses `SpringTemplateLoader.getReader()` to load the template source |
| 86 | +6. Template is compiled (or retrieved from cache) and rendered with the model |
| 87 | +7. Output is written to the HTTP response |
| 88 | + |
| 89 | +## Configuration Patterns |
| 90 | + |
| 91 | +The library supports both XML and Java-based Spring configuration: |
| 92 | + |
| 93 | +**XML Configuration:** |
| 94 | +```xml |
| 95 | +<bean id="templateLoader" class="de.neuland.pug4j.spring.template.SpringTemplateLoader"> |
| 96 | + <property name="templateLoaderPath" value="classpath:/templates" /> |
| 97 | +</bean> |
| 98 | + |
| 99 | +<bean id="pugConfiguration" class="de.neuland.pug4j.PugConfiguration"> |
| 100 | + <property name="caching" value="false" /> |
| 101 | + <property name="templateLoader" ref="templateLoader" /> |
| 102 | +</bean> |
| 103 | + |
| 104 | +<bean id="viewResolver" class="de.neuland.pug4j.spring.view.PugViewResolver"> |
| 105 | + <property name="configuration" ref="pugConfiguration" /> |
| 106 | + <property name="renderExceptions" value="true" /> |
| 107 | +</bean> |
| 108 | +``` |
| 109 | + |
| 110 | +**Java Configuration:** |
| 111 | +```java |
| 112 | +@Configuration |
| 113 | +public class PugConfig { |
| 114 | + @Bean |
| 115 | + public SpringTemplateLoader templateLoader() { |
| 116 | + SpringTemplateLoader loader = new SpringTemplateLoader(); |
| 117 | + loader.setTemplateLoaderPath("classpath:/templates"); |
| 118 | + loader.setEncoding("UTF-8"); |
| 119 | + loader.setSuffix(".pug"); |
| 120 | + return loader; |
| 121 | + } |
| 122 | + |
| 123 | + @Bean |
| 124 | + public PugConfiguration pugConfiguration() { |
| 125 | + PugConfiguration config = new PugConfiguration(); |
| 126 | + config.setCaching(false); |
| 127 | + config.setTemplateLoader(templateLoader()); |
| 128 | + return config; |
| 129 | + } |
| 130 | + |
| 131 | + @Bean |
| 132 | + public ViewResolver viewResolver() { |
| 133 | + PugViewResolver resolver = new PugViewResolver(); |
| 134 | + resolver.setConfiguration(pugConfiguration()); |
| 135 | + return resolver; |
| 136 | + } |
| 137 | +} |
| 138 | +``` |
| 139 | + |
| 140 | +## Release Process |
| 141 | + |
| 142 | +This project uses the Maven Release Plugin for releases: |
| 143 | + |
| 144 | +```bash |
| 145 | +# Prepare release (updates versions, creates tag) |
| 146 | +mvn release:prepare |
| 147 | + |
| 148 | +# Perform release (builds and deploys to repository) |
| 149 | +mvn release:perform |
| 150 | +``` |
| 151 | + |
| 152 | +Releases are signed with GPG when the `performRelease` property is set, and deployed to Sonatype OSS repository. |
| 153 | + |
| 154 | +## Testing Notes |
| 155 | + |
| 156 | +- Tests use JUnit 4 and Mockito for mocking |
| 157 | +- `SpringTemplateLoaderTest` focuses on path resolution edge cases: |
| 158 | + - Windows path handling (backslash to forward slash conversion) |
| 159 | + - Relative paths with `..` navigation |
| 160 | + - Empty template loader paths |
| 161 | + - Various combinations of `templateLoaderPath`, `basePath`, and template names |
| 162 | +- CI runs on both Ubuntu and Windows to ensure cross-platform compatibility |
| 163 | +- Timezone is set to "Europe/Berlin" in CI environment |
| 164 | + |
| 165 | +## Important Implementation Details |
| 166 | + |
| 167 | +- **Path Normalization**: All file paths are converted to Unix-style (forward slashes) using `FilenameUtils.separatorsToUnix()` to ensure cross-platform compatibility |
| 168 | +- **Extension Handling**: The `SpringTemplateLoader.getExtension()` method returns the suffix without the leading dot (e.g., "pug" not ".pug") |
| 169 | +- **Resource Loading**: Uses Spring's `ResourceLoader` abstraction, supporting classpath, file system, and URL-based resources |
| 170 | +- **Error Handling**: In development mode (`renderExceptions=true`), template compilation errors are rendered as formatted HTML pages; in production mode, errors are logged and handled by Spring's error handling |
0 commit comments