DEV Community

Roshan Adhikari
Roshan Adhikari

Posted on • Updated on • Originally published at roshanadhikary.com.np

Build a Markdown-based Blog with Spring Boot - Part 3

This piece is a part of a series of blog posts regarding this topic. If you haven't read the first two, please do so: Part 1 and Part 2.

By now, we have defined POJO classes for our entities, repository interfaces for those entities, and controllers for handling various HTTP requests.

Now, we should try and work with our database. For this, we need to specify various database-specific properties in the application.properties file inside resources directory.

Defining application properties

Inside the application.properties file, we specify our database URL, username, password, and the database initialization method.

The first three property names are pretty self-explanatory, and so are their values.

The last property, spring.jpa.hibernate.ddl-auto, specifies the database schema generation method. With a value of create-drop, we instruct Hibernate to drop the database schema and recreate it afterward using the entity model as a reference. More about schema generation strategies here.

Now when we run our @SpringBootApplication class (MdBlogApplication in my case), the database should be created with the name that we specified in the database URL.

After this, we get to read and parse Markdown files for our blog posts. First, lets add CommonMark as one of our dependencies.

Adding CommonMark to POM

CommonMark will help us to parse Markdown content from our Markdown files and render HTML blog posts from said content.

Loading Maven changes after adding CommonMark

After adding the CommonMark dependency, IntelliJ IDEA will display a small icon allowing us to load Maven changes. This way, the related files will be downloaded and integrated into our classpath.

Now we are ready to parse some Markdown!

Conventions for Markdown files

From this point on, we will assume that our blog posts will be stored as Markdown files in the resources/posts/ directory.

Each Markdown file will be named with the following format in mind: 1_Hello_World!.md

Let's deconstruct the file name:

1: This is the ID for the post. It should be unique because our entity Post has a unique, auto-generating ID field.

_: We will use underscores (_) as the delimiter for separating the ID from the title of the post, and for separating the words in the title.

Hello_World!: The title of our blog post.

.md: The extension for the Markdown file.

The reasons for using these conventions will be apparent as soon as we begin reading lines from the Markdown files.

Reading lines from Markdown files

We need to write a utility class with methods that serve to read individual lines from a Markdown file, retrieve ID from a file name, and retrieve title from a file name.

For now, let us implement the method to read individual lines.

The readLinesFromMdFile method takes a file name as an argument and creates an InputStream from the ClassPathResource available under that name inside resources/posts/ directory.

We create a BufferedReader instance using the InputStream, and then collect individual lines in the file into a List instance, which is returned from the method.

Now onto retrieving the ID and title portions from the file name.

In the getTitleFromFileName method, we separate the extension (.md) from the rest of the file name, and split the remainder string excluding the ID portion.

In the getIdFromFileName method, again, we separate the extension from the rest of the file name. Then, we parse the ID portion as a long value.

Now we can finally render HTML content from a List of Markdown lines.

Rendering HTML

We need to write another utility class with a method that parses the passed List of Markdown lines and returns a String of rendered HTML content.

In the renderHtml method, we use CommonMark types like Parser to parse Markdown content, and HtmlRenderer to render the parsed Markdown content as HTML.

Finally, we return a String that represents our HTML blog post.

Code

 This is it for part 3. In the next piece, we will pick up the project from this point on.

The GitHub repository has been updated for this part, as well as other parts.

Top comments (0)