logo

Achieve Ultimate Excellence

Building a Static Page Generator using Thymeleaf and Spring - Part 2

Introduction

In the previous part of this blog, we discussed the benefits of using Thymeleaf and Spring for building a static page generator. Now, let's delve into the implementation details and add some code samples to demonstrate how to create the static page generator.

Setting up the Project

  1. Create a Spring Boot project using the Spring Initializr, including the Thymeleaf dependency.

  2. Organize your project structure with appropriate directories for templates, content, and output.

  3. Define your Thymeleaf templates with placeholders for dynamic content.

  4. Create content files (e.g., Markdown or JSON) that hold the data to be injected into the templates.

To get started, create a new Spring Boot project using the Spring Initializr at https://start.spring.io/. Make sure to include the Thymeleaf dependency in your project. You can add the Thymeleaf dependency to your project by including the following in your pom.xml (for Maven) or build.gradle (for Gradle):

<!-- For Maven -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Organize the Project Structure

After setting up the Spring Boot project with Thymeleaf, it's time to organize the project structure to accommodate templates, content, and output. By maintaining a well-organized project structure, you can easily manage and scale your static page generator as it grows.

Directory Structure

Create the following directories inside the src/main/resources folder:

  1. static: This directory is meant for storing static files like CSS, JavaScript, images, and other assets required by your pages. These files won't be processed by Thymeleaf, and they will be directly accessible by the clients.

  2. templates: The templates directory is where you should store your Thymeleaf templates. These templates will be used to generate the final HTML pages by merging them with dynamic data.

  3. content: The content directory will hold the content files that provide data to be injected into the templates. You can use various file formats such as Markdown or JSON to structure the content data.

After organizing the project structure, it might look something like this:

Building the Static Page Generator

Thymeleaf Template

Create a Thymeleaf template (e.g., page-template.html) inside the templates directory with placeholders for dynamic content:

<!DOCTYPE html>
<html>
<head>
    <title th:text="${title}">Page Title</title>
</head>
<body>
    <div th:utext="${content}">Page Content</div>
</body>
</html>

Configuring Thymeleaf Template Resolver and Template Engine

In this section, we'll look at the Java code to configure Thymeleaf Template Resolver and Template Engine in Spring Boot.

@Bean
@Description("Thymeleaf Html Template Resolver")
public ITemplateResolver htmlTemplateResolver() {
    ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
    resolver.setPrefix("/thymeleaf/");
    resolver.setCacheable(contentGenerationProperties.isEnableCache());
    resolver.setTemplateMode(TemplateMode.HTML);
    return resolver;
}

@Bean
@Description("Thymeleaf Template Engine")
public SpringTemplateEngine templateEngine(ResourceBundleMessageSource messageSource,
                                           @Qualifier("htmlTemplateResolver") ITemplateResolver templateResolver) {
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    templateEngine.setTemplateResolver(templateResolver);
    templateEngine.setTemplateEngineMessageSource(messageSource);
    return templateEngine;
}

Explanation of Template Resolver and Template Engine

The above Java code uses Spring's @Bean annotation to define two beans related to Thymeleaf Template Resolver and Template Engine:

  1. Thymeleaf Html Template Resolver:

  2. This method configures the Thymeleaf template resolver for HTML templates. It creates an instance of ClassLoaderTemplateResolver, which is a template resolver implementation provided by Thymeleaf. The template resolver is responsible for resolving templates, and in this case, it will look for templates inside the /thymeleaf/ directory. The setCacheable() method is used to enable or disable template caching based on the contentGenerationProperties.isEnableCache() property. The setTemplateMode() method sets the template mode to HTML, indicating that the templates are in HTML format.

  3. Thymeleaf Template Engine:

  4. This method configures the Thymeleaf template engine. It creates an instance of SpringTemplateEngine, which is the template engine implementation used by Thymeleaf in a Spring environment. The template engine needs a template resolver to work with, so we inject the htmlTemplateResolver bean that we defined earlier. Additionally, we set the templateEngineMessageSource to a ResourceBundleMessageSource, which allows us to use message properties for internationalization in Thymeleaf templates.

By configuring the Thymeleaf Template Resolver and Template Engine in this way, we enable the Spring Boot application to process Thymeleaf templates with dynamic data, which is a crucial step in generating static pages using Thymeleaf and Spring.

Page Generator Service

Create a service that reads content from any data source (e.g., a database, API, or JSON files), processes the Thymeleaf template, and generates the final HTML pages:

import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

@Service
public class StaticPageGeneratorService {

    private final TemplateEngine templateEngine;

    public StaticPageGeneratorService(TemplateEngine templateEngine) {
        this.templateEngine = templateEngine;
    }

    public void generateStaticPages() throws IOException {
        Map<String, String> pages = readContentFromDataSource(); // Replace this method with actual data retrieval from your data source
        for (Map.Entry<String, String> entry : pages.entrySet()) {
            String filename = entry.getKey();
            String content = entry.getValue();
            String output = processTemplate(content);

            // Write the generated HTML page to the output directory
            String outputPath = "output/" + filename + ".html";
            Files.write(Paths.get(outputPath), output.getBytes());
        }
    }

    private Map<String, String> readContentFromDataSource() {
        // Implement your code to read content from a data source (e.g., database, API, JSON files)
        // Replace this method with actual data retrieval logic from your data source
        Map<String, String> pages = new HashMap<>();
        pages.put("page1", "Welcome to Page 1\\n\\nThis is the content for Page 1.");
        pages.put("page2", "Greetings from Page 2\\n\\nThis is the content for Page 2.");
        return pages;
    }

    private String processTemplate(String content) {
        // Use Thymeleaf to process the template
        Context context = new Context();
        context.setVariable("title", getTitle(content));
        context.setVariable("content", getContent(content));
        return templateEngine.process("page-template", context);
    }

    private String getTitle(String content) {
        // Parse the content and extract the title
        // For simplicity, we split the content using '\\n' and take the first line as the title.
        return content.split("\\n")[0];
    }

    private String getContent(String content) {
        // Parse the content and extract the main content
        // For simplicity, we split the content using '\\n\\n' and take the second part as the content.
        String[] parts = content.split("\\n\\n");
        return parts.length > 1 ? parts[1] : "";
    }
}

Deploying the Generated Static Pages

Once the static pages are generated, you can deploy them to a web server, CDN, or any hosting service of your choice. Since they are purely HTML files, you can simply upload them using FTP, SFTP, or any other deployment method. Here are the general steps to deploy the generated static pages:

  1. Prepare the Static Pages: Ensure that the output directory contains all the generated HTML pages along with any other static assets like CSS, JavaScript, and images that your pages might require.

  2. Choose a Hosting Service: Decide where you want to host your static pages. You can use traditional web hosting services, cloud storage services like Amazon S3, or specialized static site hosting platforms like Netlify, GitHub Pages, or Vercel.

  3. Upload the Pages: Use the deployment method supported by your chosen hosting service to upload the static pages. For example, if you are using Amazon S3, you can use their AWS Management Console or CLI tools to upload the files. If you are using Netlify or GitHub Pages, you can simply push your code repository to trigger automatic deployments.

  4. Set Up Custom Domain (Optional): If you want to use a custom domain for your static site, configure the DNS settings of your domain to point to the hosting service's servers. Most hosting services provide instructions for setting up custom domains.

  5. Test the Deployment: After the deployment, access your static pages using the provided hosting URL or custom domain. Ensure that all the pages load correctly and any links or assets work as expected.

Conclusion

With the implementation details and code samples provided in this blog, you can now successfully create a static page generator using Thymeleaf and Spring. The combination of Thymeleaf's powerful templating capabilities and Spring's flexibility enables you to generate dynamic content-driven static pages efficiently. Deploying these generated static pages is a breeze, allowing you to host your website on various platforms without the need for complex server-side processing.

Static site generation has become increasingly popular due to its performance, security, and simplicity advantages. By generating static pages, you can provide a fast and reliable browsing experience to your users, especially for content-heavy websites and blogs.

As you explore and enhance your static page generator, consider adding more features like support for different data sources, content caching, or integration with a CI/CD pipeline to automate deployments. The flexibility of Thymeleaf and Spring makes it possible to customize and expand your static page generation process to suit your specific requirements.

Happy coding and happy generating static pages!

avatar
Article By,
Create by
Browse Articles by Related Categories
Browse Articles by Related Tags
Share Article on:

Related posts