Use tabs for indentation
This commit is contained in:
163
README.adoc
163
README.adoc
@@ -154,7 +154,7 @@ import org.springframework.boot.runApplication
|
|||||||
class BlogApplication
|
class BlogApplication
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
runApplication<BlogApplication>(*args)
|
runApplication<BlogApplication>(*args)
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ We also need to create the associated Mustache templates.
|
|||||||
----
|
----
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>{{title}}</title>
|
<title>{{title}}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
----
|
----
|
||||||
@@ -454,19 +454,19 @@ fun LocalDateTime.format() = this.format(englishDateFormatter)
|
|||||||
private val daysLookup = (1..31).associate { it.toLong() to getOrdinal(it) }
|
private val daysLookup = (1..31).associate { it.toLong() to getOrdinal(it) }
|
||||||
|
|
||||||
private val englishDateFormatter = DateTimeFormatterBuilder()
|
private val englishDateFormatter = DateTimeFormatterBuilder()
|
||||||
.appendPattern("MMMM")
|
.appendPattern("MMMM")
|
||||||
.appendLiteral(" ")
|
.appendLiteral(" ")
|
||||||
.appendText(ChronoField.DAY_OF_MONTH, daysLookup)
|
.appendText(ChronoField.DAY_OF_MONTH, daysLookup)
|
||||||
.appendLiteral(" ")
|
.appendLiteral(" ")
|
||||||
.appendPattern("yyyy")
|
.appendPattern("yyyy")
|
||||||
.toFormatter(Locale.ENGLISH)
|
.toFormatter(Locale.ENGLISH)
|
||||||
|
|
||||||
private fun getOrdinal(n: Int) = when {
|
private fun getOrdinal(n: Int) = when {
|
||||||
n in 11..13 -> "${n}th"
|
n in 11..13 -> "${n}th"
|
||||||
n % 10 == 1 -> "${n}st"
|
n % 10 == 1 -> "${n}st"
|
||||||
n % 10 == 2 -> "${n}nd"
|
n % 10 == 2 -> "${n}nd"
|
||||||
n % 10 == 3 -> "${n}rd"
|
n % 10 == 3 -> "${n}rd"
|
||||||
else -> "${n}th"
|
else -> "${n}th"
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
@@ -493,15 +493,15 @@ We introduce a `MarkdownConverter` bean, which leverages https://kotlinlang.org/
|
|||||||
@Service
|
@Service
|
||||||
class MarkdownConverter : (String?) -> String {
|
class MarkdownConverter : (String?) -> String {
|
||||||
|
|
||||||
private val parser = Parser.builder().extensions(Arrays.asList(AutolinkExtension.create())).build()
|
private val parser = Parser.builder().extensions(Arrays.asList(AutolinkExtension.create())).build()
|
||||||
private val renderer = HtmlRenderer.builder().build()
|
private val renderer = HtmlRenderer.builder().build()
|
||||||
|
|
||||||
override fun invoke(input: String?): String {
|
override fun invoke(input: String?): String {
|
||||||
if (input == null || input == "") {
|
if (input == null || input == "") {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return renderer.render(parser.parse(input))
|
return renderer.render(parser.parse(input))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
@@ -516,7 +516,6 @@ class BlogApplication {
|
|||||||
@Bean
|
@Bean
|
||||||
fun mustacheCompiler(loader: Mustache.TemplateLoader?) =
|
fun mustacheCompiler(loader: Mustache.TemplateLoader?) =
|
||||||
Mustache.compiler().escapeHTML(false).withLoader(loader)
|
Mustache.compiler().escapeHTML(false).withLoader(loader)
|
||||||
|
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
@@ -531,17 +530,17 @@ We update the "blog" Mustache templates.
|
|||||||
|
|
||||||
<div class="articles">
|
<div class="articles">
|
||||||
|
|
||||||
{{#articles}}
|
{{#articles}}
|
||||||
<section>
|
<section>
|
||||||
<header class="article-header">
|
<header class="article-header">
|
||||||
<h2 class="article-title"><a href="/article/{{id}}">{{title}}</a></h2>
|
<h2 class="article-title"><a href="/article/{{id}}">{{title}}</a></h2>
|
||||||
<div class="article-meta">By <strong>{{author.firstname}}</strong>, on <strong>{{addedAt}}</strong></div>
|
<div class="article-meta">By <strong>{{author.firstname}}</strong>, on <strong>{{addedAt}}</strong></div>
|
||||||
</header>
|
</header>
|
||||||
<div class="article-description">
|
<div class="article-description">
|
||||||
{{headline}}
|
{{headline}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{{/articles}}
|
{{/articles}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{> footer}}
|
{{> footer}}
|
||||||
@@ -555,16 +554,16 @@ And we create an "article new one".
|
|||||||
{{> header}}
|
{{> header}}
|
||||||
|
|
||||||
<section class="article">
|
<section class="article">
|
||||||
<header class="article-header">
|
<header class="article-header">
|
||||||
<h1 class="article-title">{{article.title}}</h1>
|
<h1 class="article-title">{{article.title}}</h1>
|
||||||
<p class="article-meta">By <strong>{{article.author.firstname}}</strong>, on <strong>{{article.addedAt}}</strong></p>
|
<p class="article-meta">By <strong>{{article.author.firstname}}</strong>, on <strong>{{article.addedAt}}</strong></p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="article-description">
|
<div class="article-description">
|
||||||
{{article.headline}}
|
{{article.headline}}
|
||||||
|
|
||||||
{{article.content}}
|
{{article.content}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{{> footer}}
|
{{> footer}}
|
||||||
@@ -580,40 +579,40 @@ class HtmlController(private val repository: ArticleRepository,
|
|||||||
private val markdownConverter: MarkdownConverter) {
|
private val markdownConverter: MarkdownConverter) {
|
||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
fun blog(model: Model): String {
|
fun blog(model: Model): String {
|
||||||
model["title"] = properties.title
|
model["title"] = properties.title
|
||||||
model["banner"] = properties.banner
|
model["banner"] = properties.banner
|
||||||
model["articles"] = repository.findAllByOrderByAddedAtDesc().map { it.render() }
|
model["articles"] = repository.findAllByOrderByAddedAtDesc().map { it.render() }
|
||||||
return "blog"
|
return "blog"
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/article/{id}")
|
@GetMapping("/article/{id}")
|
||||||
fun article(@PathVariable id: Long, model: Model): String {
|
fun article(@PathVariable id: Long, model: Model): String {
|
||||||
val article = repository
|
val article = repository
|
||||||
.findById(id)
|
.findById(id)
|
||||||
.orElseThrow { IllegalArgumentException("Wrong article id provided") }
|
.orElseThrow { IllegalArgumentException("Wrong article id provided") }
|
||||||
.render()
|
.render()
|
||||||
model["title"] = article.title
|
model["title"] = article.title
|
||||||
model["article"] = article
|
model["article"] = article
|
||||||
return "article"
|
return "article"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Article.render() = RenderedArticle(
|
fun Article.render() = RenderedArticle(
|
||||||
title,
|
title,
|
||||||
markdownConverter.invoke(headline),
|
markdownConverter.invoke(headline),
|
||||||
markdownConverter.invoke(content),
|
markdownConverter.invoke(content),
|
||||||
author,
|
author,
|
||||||
id,
|
id,
|
||||||
addedAt.format()
|
addedAt.format()
|
||||||
)
|
)
|
||||||
|
|
||||||
data class RenderedArticle(
|
data class RenderedArticle(
|
||||||
val title: String,
|
val title: String,
|
||||||
val headline: String,
|
val headline: String,
|
||||||
val content: String,
|
val content: String,
|
||||||
val author: User,
|
val author: User,
|
||||||
val id: Long?,
|
val id: Long?,
|
||||||
val addedAt: String)
|
val addedAt: String)
|
||||||
|
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
@@ -855,16 +854,16 @@ Edit the template and the controller accordingly.
|
|||||||
|
|
||||||
<div class="articles">
|
<div class="articles">
|
||||||
|
|
||||||
{{#banner.title}}
|
{{#banner.title}}
|
||||||
<section>
|
<section>
|
||||||
<header class="banner">
|
<header class="banner">
|
||||||
<h2 class="banner-title">{{banner.title}}</h2>
|
<h2 class="banner-title">{{banner.title}}</h2>
|
||||||
</header>
|
</header>
|
||||||
<div class="banner-content">
|
<div class="banner-content">
|
||||||
{{banner.content}}
|
{{banner.content}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{{/banner.title}}
|
{{/banner.title}}
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|||||||
@@ -40,5 +40,5 @@ class BlogApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
runApplication<BlogApplication>(*args)
|
runApplication<BlogApplication>(*args)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ import org.springframework.stereotype.Service
|
|||||||
@Service
|
@Service
|
||||||
class MarkdownConverter : (String?) -> String {
|
class MarkdownConverter : (String?) -> String {
|
||||||
|
|
||||||
private val parser = Parser.builder().extensions(listOf(AutolinkExtension.create())).build()
|
private val parser = Parser.builder().extensions(listOf(AutolinkExtension.create())).build()
|
||||||
private val renderer = HtmlRenderer.builder().build()
|
private val renderer = HtmlRenderer.builder().build()
|
||||||
|
|
||||||
override fun invoke(input: String?): String {
|
override fun invoke(input: String?): String {
|
||||||
if (input == null || input == "") {
|
if (input == null || input == "") {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return renderer.render(parser.parse(input))
|
return renderer.render(parser.parse(input))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
{{> header}}
|
{{> header}}
|
||||||
|
|
||||||
<section class="article">
|
<section class="article">
|
||||||
<header class="article-header">
|
<header class="article-header">
|
||||||
<h1 class="article-title">{{article.title}}</h1>
|
<h1 class="article-title">{{article.title}}</h1>
|
||||||
<p class="article-meta">By <strong>{{article.author.firstname}}</strong>, on <strong>{{article.addedAt}}</strong></p>
|
<p class="article-meta">By <strong>{{article.author.firstname}}</strong>, on <strong>{{article.addedAt}}</strong></p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="article-description">
|
<div class="article-description">
|
||||||
{{article.headline}}
|
{{article.headline}}
|
||||||
|
|
||||||
{{article.content}}
|
{{article.content}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{{> footer}}
|
{{> footer}}
|
||||||
@@ -2,28 +2,28 @@
|
|||||||
|
|
||||||
<div class="articles">
|
<div class="articles">
|
||||||
|
|
||||||
{{#banner.title}}
|
{{#banner.title}}
|
||||||
<section>
|
<section>
|
||||||
<header class="banner">
|
<header class="banner">
|
||||||
<h2 class="banner-title">{{banner.title}}</h2>
|
<h2 class="banner-title">{{banner.title}}</h2>
|
||||||
</header>
|
</header>
|
||||||
<div class="banner-content">
|
<div class="banner-content">
|
||||||
{{banner.content}}
|
{{banner.content}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{{/banner.title}}
|
{{/banner.title}}
|
||||||
|
|
||||||
{{#articles}}
|
{{#articles}}
|
||||||
<section>
|
<section>
|
||||||
<header class="article-header">
|
<header class="article-header">
|
||||||
<h2 class="article-title"><a href="/article/{{id}}">{{title}}</a></h2>
|
<h2 class="article-title"><a href="/article/{{id}}">{{title}}</a></h2>
|
||||||
<div class="article-meta">By <strong>{{author.firstname}}</strong>, on <strong>{{addedAt}}</strong></div>
|
<div class="article-meta">By <strong>{{author.firstname}}</strong>, on <strong>{{addedAt}}</strong></div>
|
||||||
</header>
|
</header>
|
||||||
<div class="article-headline">
|
<div class="article-headline">
|
||||||
{{headline}}
|
{{headline}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{{/articles}}
|
{{/articles}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{> footer}}
|
{{> footer}}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>{{title}}</title>
|
<title>{{title}}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>{{title}}</h1>
|
<h1>{{title}}</h1>
|
||||||
|
|||||||
Reference in New Issue
Block a user