Closes #8 Signed-off-by: Minecon724 <git@m724.eu>
This commit is contained in:
parent
25cdedfe2b
commit
c57ae37666
4 changed files with 78 additions and 11 deletions
|
@ -152,7 +152,7 @@ public class BlogBuilder {
|
|||
articles.sort(Comparator.comparing(Article::createdAt).reversed());
|
||||
|
||||
LOGGER.debug("Rendering pages...");
|
||||
renderIndexPages(articles);
|
||||
renderIndexAndPages(articles);
|
||||
|
||||
Files.writeString(outputDirectory.resolve("articles.rss"), Feed.generateRss(site, articles));
|
||||
|
||||
|
@ -172,21 +172,27 @@ public class BlogBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
private void renderIndexPages(List<Article> articles) throws IOException {
|
||||
private void renderIndexAndPages(List<Article> articles) throws IOException {
|
||||
int lastPage = Math.max(Math.ceilDiv(articles.size(), site.articlesPerPage()), 1);
|
||||
Files.writeString(outputDirectory.resolve("index.html"), template.renderIndexPage(PageNumbers.create(1, lastPage), articles.subList(0, site.articlesPerPage())));
|
||||
|
||||
var pageDirectory = outputDirectory.resolve("page");
|
||||
Files.createDirectory(pageDirectory);
|
||||
|
||||
// yes we do render page 1 twice, because https://git.m724.eu/Minecon724/blog-software-java/issues/8
|
||||
for (int page=1; page<=lastPage; page++) {
|
||||
var startIndex = (page - 1) * site.articlesPerPage();
|
||||
var endIndex = Math.min(startIndex + site.articlesPerPage(), articles.size());
|
||||
var pageArticles = articles.subList(startIndex, endIndex);
|
||||
|
||||
var renderedPage = template.renderIndexPage(PageNumbers.create(page, lastPage), pageArticles);
|
||||
var pageNumbers = PageNumbers.create(page, lastPage);
|
||||
|
||||
if (page == 1) {
|
||||
var renderedIndex = template.renderIndex(pageNumbers, pageArticles);
|
||||
Files.writeString(outputDirectory.resolve("index.html"), renderedIndex);
|
||||
|
||||
if (!site.separateFirstPage()) continue;
|
||||
}
|
||||
|
||||
var renderedPage = template.renderPage(pageNumbers, pageArticles);
|
||||
Files.writeString(pageDirectory.resolve(page + ".html"), renderedPage);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ public record Site(
|
|||
int articlesPerPage,
|
||||
|
||||
boolean templateArticles,
|
||||
boolean separateFirstPage,
|
||||
|
||||
Map<String, Object> custom
|
||||
) {
|
||||
|
@ -39,6 +40,7 @@ public record Site(
|
|||
"/",
|
||||
10,
|
||||
false,
|
||||
false,
|
||||
Map.of()
|
||||
);
|
||||
|
||||
|
@ -57,6 +59,7 @@ public record Site(
|
|||
String baseUrl = (String) yaml.getOrDefault("baseUrl", DEFAULT.baseUrl());
|
||||
var articlesPerPage = (int) yaml.getOrDefault("articlesPerPage", DEFAULT.articlesPerPage());
|
||||
var templateArticles = (boolean) yaml.getOrDefault("templateArticles", DEFAULT.templateArticles());
|
||||
var separateFirstPage = (boolean) yaml.getOrDefault("separateFirstPage", DEFAULT.separateFirstPage());
|
||||
|
||||
String directory = DEFAULT.directory();
|
||||
if (baseUrl != null) {
|
||||
|
@ -68,7 +71,7 @@ public record Site(
|
|||
}
|
||||
|
||||
return new Site(
|
||||
name, baseUrl, directory, articlesPerPage, templateArticles, yaml
|
||||
name, baseUrl, directory, articlesPerPage, templateArticles, separateFirstPage, yaml
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,30 @@ public class TemplateExtension extends AbstractExtension {
|
|||
|
||||
return site.directory() + path;
|
||||
}
|
||||
},
|
||||
"url_to_page", new Function() {
|
||||
@Override
|
||||
public List<String> getArgumentNames() {
|
||||
return List.of("page");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
|
||||
var pageObj = args.get("page");
|
||||
int page;
|
||||
|
||||
if (pageObj instanceof Number pageNumber) {
|
||||
page = pageNumber.intValue();
|
||||
} else {
|
||||
throw new IllegalArgumentException("\"page\" must be Number");
|
||||
}
|
||||
|
||||
if (page == 1 && !site.separateFirstPage()) {
|
||||
return site.directory();
|
||||
} else {
|
||||
return site.directory() + "page/" + page + ".html";
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,8 +11,11 @@ import eu.m724.blog.object.Article;
|
|||
import eu.m724.blog.object.PageNumbers;
|
||||
import eu.m724.blog.object.Site;
|
||||
import io.pebbletemplates.pebble.PebbleEngine;
|
||||
import io.pebbletemplates.pebble.error.LoaderException;
|
||||
import io.pebbletemplates.pebble.loader.FileLoader;
|
||||
import io.pebbletemplates.pebble.template.PebbleTemplate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
@ -25,11 +28,13 @@ import java.util.Map;
|
|||
* using the Pebble templating engine.
|
||||
*/
|
||||
public class TemplateRenderer {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TemplateRenderer.class);
|
||||
|
||||
private final Site site;
|
||||
private final Minifier minifier;
|
||||
|
||||
private final PebbleEngine pebbleEngine;
|
||||
private final PebbleTemplate indexTemplate, articleTemplate;
|
||||
private final PebbleTemplate indexTemplate, articleTemplate, pageTemplate;
|
||||
|
||||
/**
|
||||
* Constructs a TemplateRenderer instance for rendering templates from the specified directory.
|
||||
|
@ -54,20 +59,49 @@ public class TemplateRenderer {
|
|||
|
||||
this.indexTemplate = pebbleEngine.getTemplate("index_template");
|
||||
this.articleTemplate = pebbleEngine.getTemplate("article_template");
|
||||
|
||||
var pageTemplate = indexTemplate;
|
||||
|
||||
try {
|
||||
pageTemplate = pebbleEngine.getTemplate("page_template");
|
||||
} catch (LoaderException e) {
|
||||
LOGGER.debug("Template has no page template, using index_template instead");
|
||||
}
|
||||
|
||||
this.pageTemplate = pageTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the index page using this template.
|
||||
* Renders a page using this template.<br>
|
||||
* This is different from index, as this uses page template.
|
||||
*
|
||||
* @param articles the {@link Article}s to be included in the <strong>CURRENT</strong> page
|
||||
* @param pageArticles the {@link Article}s to be included in the <strong>CURRENT</strong> page
|
||||
* @param pageNumbers a {@link PageNumbers} instance for the current page
|
||||
* @return the rendered index HTML page as a string
|
||||
* @throws IOException if an error occurs during the template evaluation
|
||||
*/
|
||||
public String renderIndexPage(PageNumbers pageNumbers, List<Article> articles) throws IOException {
|
||||
public String renderPage(PageNumbers pageNumbers, List<Article> pageArticles) throws IOException {
|
||||
var context = Map.of(
|
||||
"page", pageNumbers,
|
||||
"articles", articles
|
||||
"articles", pageArticles
|
||||
);
|
||||
|
||||
return renderTemplate(pageTemplate, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the index page using this template.<br>
|
||||
* This is different from rendering page 1, as this uses index template.
|
||||
*
|
||||
* @param pageArticles the {@link Article}s to be included in the <strong>CURRENT</strong> page
|
||||
* @param pageNumbers a {@link PageNumbers} instance for the current page
|
||||
* @return the rendered index HTML page as a string
|
||||
* @throws IOException if an error occurs during the template evaluation
|
||||
*/
|
||||
public String renderIndex(PageNumbers pageNumbers, List<Article> pageArticles) throws IOException {
|
||||
var context = Map.of(
|
||||
"page", pageNumbers,
|
||||
"articles", pageArticles
|
||||
);
|
||||
|
||||
return renderTemplate(indexTemplate, context);
|
||||
|
|
Loading…
Add table
Reference in a new issue