From 13b1d90f810dfbb13fc92fd5563776a7177e4c01 Mon Sep 17 00:00:00 2001 From: Matheus Cruz Date: Tue, 8 Oct 2024 18:34:23 -0300 Subject: [PATCH 1/9] Add aliases to FrontMatter for shorten link --- blog/site/_posts/2024-08-29-welcome-to-roq.md | 1 + .../java/io/quarkiverse/roq/it/RoqTest.java | 19 ++++++++-- .../deployment/RoqFrontMatterProcessor.java | 11 +++++- .../data/RoqFrontMatterAliasesBuildItem.java | 30 +++++++++++++++ .../data/RoqFrontMatterDataProcessor.java | 4 +- .../record/RoqFrontMatterInitProcessor.java | 24 +++++++++--- .../RoqFrontMatterRawTemplateBuildItem.java | 30 ++++++++++++--- .../scan/RoqFrontMatterScanProcessor.java | 37 +++++++++++++++---- .../runtime/RoqFrontMatterRecorder.java | 3 ++ .../frontmatter/runtime/model/PageInfo.java | 2 +- 10 files changed, 134 insertions(+), 27 deletions(-) create mode 100644 roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterAliasesBuildItem.java diff --git a/blog/site/_posts/2024-08-29-welcome-to-roq.md b/blog/site/_posts/2024-08-29-welcome-to-roq.md index f4f1e3fb..08687863 100755 --- a/blog/site/_posts/2024-08-29-welcome-to-roq.md +++ b/blog/site/_posts/2024-08-29-welcome-to-roq.md @@ -6,6 +6,7 @@ description: This is the first article ever made with Quarkus Roq img: posts/2024/08/blogging.jpg tags: blogging author: ia3andy +aliases: [first-roq-article-ever] --- Hello folks, diff --git a/blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java b/blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java index 2f61a784..d5060401 100644 --- a/blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java +++ b/blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java @@ -1,11 +1,10 @@ package io.quarkiverse.roq.it; -import static io.restassured.RestAssured.given; -import static org.hamcrest.Matchers.containsString; - +import io.quarkus.test.junit.QuarkusTest; import org.junit.jupiter.api.Test; -import io.quarkus.test.junit.QuarkusTest; +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.containsString; @QuarkusTest public class RoqTest { @@ -54,4 +53,16 @@ public void testPage() { .body(containsString("

Roq 1.0 Beta

")) .body(containsString("2024 © ROQ")); } + + @Test + public void testAlias() { + given() + .when().get("/first-roq-article-ever") + .then() + .statusCode(200) + .body(containsString("I provide you with all the tools to generate static websites out of your Quarkus web application.")) + .body(containsString("

Hello folks,

")) + .body(containsString("

Welcome to Roq!

")) + .body(containsString("2024 © ROQ")); + } } diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/RoqFrontMatterProcessor.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/RoqFrontMatterProcessor.java index 3befce7a..c78b8147 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/RoqFrontMatterProcessor.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/RoqFrontMatterProcessor.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Set; +import io.quarkiverse.roq.frontmatter.deployment.data.RoqFrontMatterAliasesBuildItem; import io.quarkiverse.roq.frontmatter.deployment.scan.RoqFrontMatterRawTemplateBuildItem; import io.quarkiverse.roq.frontmatter.runtime.RoqTemplateExtension; import io.quarkiverse.roq.frontmatter.runtime.RoqTemplateGlobal; @@ -93,10 +94,12 @@ void bindEndpoints( RoqFrontMatterConfig config, BuildProducer selectedPathProducer, BuildProducer notFoundPageDisplayableEndpointProducer, - RoqFrontMatterOutputBuildItem roqOutput) { + RoqFrontMatterOutputBuildItem roqOutput, + List aliases) { if (roqOutput == null) { return; } + // Bind Roq Generator and dev-ui endpoints if (config.generator()) { for (String path : roqOutput.allPagesByPath().keySet()) { @@ -105,6 +108,12 @@ void bindEndpoints( .produce(new NotFoundPageDisplayableEndpointBuildItem(prefixWithSlash(path))); } } + + if (!aliases.isEmpty()) { + for (RoqFrontMatterAliasesBuildItem aliasItem : aliases) { + selectedPathProducer.produce(new SelectedPathBuildItem(aliasItem.alias(), null)); + } + } } } diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterAliasesBuildItem.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterAliasesBuildItem.java new file mode 100644 index 00000000..89628fd7 --- /dev/null +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterAliasesBuildItem.java @@ -0,0 +1,30 @@ +package io.quarkiverse.roq.frontmatter.deployment.data; + +import io.quarkiverse.roq.util.PathUtils; +import io.quarkus.builder.item.MultiBuildItem; + +public final class RoqFrontMatterAliasesBuildItem extends MultiBuildItem { + + /** + * Represents an alias of a determined link. + */ + private final String alias; + + /** + * The link where the {@code aliases} are pointing to. + */ + private final String target; + + public RoqFrontMatterAliasesBuildItem(String alias, String target) { + this.alias = PathUtils.prefixWithSlash(alias); + this.target = target; + } + + public String alias() { + return alias; + } + + public String target() { + return target; + } +} diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java index 4eab9af3..d37593f2 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java @@ -2,7 +2,9 @@ import static io.quarkiverse.roq.frontmatter.deployment.Link.DEFAULT_PAGE_LINK_TEMPLATE; -import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.Stack; import java.util.function.Function; import java.util.stream.Collectors; diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/record/RoqFrontMatterInitProcessor.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/record/RoqFrontMatterInitProcessor.java index 7594490e..39d0558f 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/record/RoqFrontMatterInitProcessor.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/record/RoqFrontMatterInitProcessor.java @@ -1,7 +1,6 @@ package io.quarkiverse.roq.frontmatter.deployment.record; import static io.quarkiverse.roq.util.PathUtils.removeTrailingSlash; -import static org.aesh.readline.terminal.Key.e; import java.util.ArrayList; import java.util.HashMap; @@ -12,10 +11,9 @@ import jakarta.inject.Singleton; -import org.jboss.logging.Logger; - import io.quarkiverse.roq.frontmatter.deployment.RoqFrontMatterOutputBuildItem; import io.quarkiverse.roq.frontmatter.deployment.RoqFrontMatterRootUrlBuildItem; +import io.quarkiverse.roq.frontmatter.deployment.data.RoqFrontMatterAliasesBuildItem; import io.quarkiverse.roq.frontmatter.deployment.publish.RoqFrontMatterPublishDerivedCollectionBuildItem; import io.quarkiverse.roq.frontmatter.deployment.publish.RoqFrontMatterPublishDocumentPageBuildItem; import io.quarkiverse.roq.frontmatter.deployment.publish.RoqFrontMatterPublishPageBuildItem; @@ -25,7 +23,10 @@ import io.quarkus.arc.deployment.SyntheticBeanBuildItem; import io.quarkus.arc.deployment.SyntheticBeansRuntimeInitBuildItem; import io.quarkus.builder.BuildException; -import io.quarkus.deployment.annotations.*; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.Consume; +import io.quarkus.deployment.annotations.ExecutionTime; import io.quarkus.deployment.annotations.Record; import io.quarkus.vertx.http.deployment.HttpRootPathBuildItem; import io.quarkus.vertx.http.deployment.RouteBuildItem; @@ -33,8 +34,6 @@ class RoqFrontMatterInitProcessor { - private static final Logger LOGGER = Logger.getLogger(RoqFrontMatterInitProcessor.class); - @BuildStep @Record(ExecutionTime.STATIC_INIT) void bindCollections( @@ -154,4 +153,17 @@ public RouteBuildItem produceRoute(RoqSiteConfig config, RoqFrontMatterRecorder .build(); } + @BuildStep + @Record(ExecutionTime.RUNTIME_INIT) + public void produceRoute(List aliases, BuildProducer routes, + RoqFrontMatterRecorder recorder) { + for (var aliasItem : aliases) { + routes.produce(RouteBuildItem.builder() + .route(aliasItem.alias()) + .handler(recorder.aliasRoute( + aliasItem.target())) + .build()); + } + } + } diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterRawTemplateBuildItem.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterRawTemplateBuildItem.java index 61e88eed..be4e5e28 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterRawTemplateBuildItem.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterRawTemplateBuildItem.java @@ -1,5 +1,9 @@ package io.quarkiverse.roq.frontmatter.deployment.scan; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + import io.quarkiverse.roq.frontmatter.runtime.model.PageInfo; import io.quarkus.builder.item.MultiBuildItem; import io.vertx.core.json.JsonObject; @@ -13,41 +17,50 @@ */ public final class RoqFrontMatterRawTemplateBuildItem extends MultiBuildItem { + /** + * The page details. + */ private final PageInfo info; /** - * The layout used for this template + * The layout used for this template. */ private final String layout; /** * true if it's a page template. * or false if it's an include template. - * + *

* Include template should not be published. */ private final boolean isPage; /** - * The FrontMatter data (it is not merged with parents at this stage) + * The FrontMatter data (it is not merged with parents at this stage). */ private final JsonObject data; private final String collection; /** - * The generated template content to be passed to be passed to Qute + * The generated template content to be passed to be passed to Qute. */ private final String generatedTemplate; /** - * Should this template be published + * Should this template be published. */ private final boolean published; + /** + * List of aliases to be used for redirecting to an url. + */ + private final List aliases; + public RoqFrontMatterRawTemplateBuildItem(PageInfo info, String layout, boolean isPage, JsonObject data, String collection, String generatedTemplate, - boolean published) { + boolean published, + List aliases) { this.info = info; this.layout = layout; this.isPage = isPage; @@ -55,6 +68,7 @@ public RoqFrontMatterRawTemplateBuildItem(PageInfo info, String layout, boolean this.collection = collection; this.generatedTemplate = generatedTemplate; this.published = published; + this.aliases = Objects.requireNonNullElseGet(aliases, Collections::emptyList); } public boolean isPage() { @@ -88,4 +102,8 @@ public String generatedContent() { public boolean published() { return published; } + + public List aliases() { + return Collections.unmodifiableList(aliases); + } } diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterScanProcessor.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterScanProcessor.java index 1a888746..9e708bb5 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterScanProcessor.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterScanProcessor.java @@ -13,7 +13,9 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.temporal.ChronoField; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Consumer; @@ -34,6 +36,7 @@ import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem; +import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; public class RoqFrontMatterScanProcessor { @@ -42,6 +45,8 @@ public class RoqFrontMatterScanProcessor { public static final Pattern FRONTMATTER_PATTERN = Pattern.compile("^---\\v.*\\v---\\v", Pattern.DOTALL); private static final String DRAFT_KEY = "draft"; private static final String DATE_KEY = "date"; + private static final String LAYOUT_KEY = "layout"; + private static final String ALIASES_KEY = "aliases"; private static final Pattern FILE_NAME_DATE_PATTERN = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})"); private record QuteMarkupSection(String open, String close) { @@ -149,9 +154,8 @@ private static Consumer addBuildItem(Path root, HashSet { watch.produce(HotDeploymentWatchedFileBuildItem.builder().setLocation(file.toAbsolutePath().toString()).build()); - var relative = toUnixPath( + String relative = toUnixPath( collection != null ? collection + "/" + root.relativize(file) : root.relativize(file).toString()); - String sourcePath = relative; String templatePath = removeExtension(relative) + ".html"; final String id = removeExtension(templatePath); try { @@ -164,31 +168,48 @@ private static Consumer addBuildItem(Path root, HashSet aliases = getAliases(aliasesArr); + PageInfo info = new PageInfo(id, draft, config.imagesPath(), dateString, content, - sourcePath, templatePath); + relative, templatePath); LOGGER.debugf("Creating generated template for %s" + templatePath); final String generatedTemplate = generateTemplate(relative, layout, content); items.add( new RoqFrontMatterRawTemplateBuildItem(info, layout, isPage, fm, collection, generatedTemplate, - isPage)); + isPage, aliases)); } else { - PageInfo info = new PageInfo(id, false, config.imagesPath(), null, fullContent, sourcePath, templatePath); + PageInfo info = new PageInfo(id, false, config.imagesPath(), null, fullContent, relative, templatePath); items.add( new RoqFrontMatterRawTemplateBuildItem(info, null, isPage, new JsonObject(), collection, fullContent, - isPage)); + isPage, List.of())); } } catch (IOException e) { throw new RuntimeException("Error while reading the FrontMatter file %s" - .formatted(sourcePath), e); + .formatted(relative), e); } }; } + private static List getAliases(JsonArray aliasesArr) { + if (aliasesArr == null) { + return List.of(); + } + ArrayList aliases = new ArrayList<>(); + for (int i = 0; i < aliasesArr.size(); i++) { + String alias = aliasesArr.getString(i); + if (alias != null && !alias.isBlank()) { + aliases.add(alias); + } + } + return aliases; + } + protected static String parsePublishDate(Path file, JsonObject frontMatter, RoqFrontMatterConfig config) { String dateString; if (frontMatter.containsKey(DATE_KEY)) { diff --git a/roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/RoqFrontMatterRecorder.java b/roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/RoqFrontMatterRecorder.java index 0f75bec4..282e62a4 100644 --- a/roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/RoqFrontMatterRecorder.java +++ b/roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/RoqFrontMatterRecorder.java @@ -75,4 +75,7 @@ public Handler handler(String rootPath, return new RoqRouteHandler(rootPath, httpConfig, pageSuppliers); } + public Handler aliasRoute(String target) { + return ctx -> ctx.redirect(target); + } } diff --git a/roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/model/PageInfo.java b/roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/model/PageInfo.java index e1172525..29a9a7a4 100644 --- a/roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/model/PageInfo.java +++ b/roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/model/PageInfo.java @@ -11,7 +11,7 @@ @Vetoed public record PageInfo( /** - * The page id (e.g posts/my-favorite-beer) + * The page id (e.g. posts/my-favorite-beer) */ String id, From a3a68bc6374dce40de48abb65ea5d1417c36d427 Mon Sep 17 00:00:00 2001 From: Matheus Cruz Date: Tue, 8 Oct 2024 18:53:10 -0300 Subject: [PATCH 2/9] Change variable name --- .../deployment/scan/RoqFrontMatterScanProcessor.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterScanProcessor.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterScanProcessor.java index 9e708bb5..5339b97c 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterScanProcessor.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterScanProcessor.java @@ -154,9 +154,9 @@ private static Consumer addBuildItem(Path root, HashSet { watch.produce(HotDeploymentWatchedFileBuildItem.builder().setLocation(file.toAbsolutePath().toString()).build()); - String relative = toUnixPath( + String sourcePath = toUnixPath( collection != null ? collection + "/" + root.relativize(file) : root.relativize(file).toString()); - String templatePath = removeExtension(relative) + ".html"; + String templatePath = removeExtension(sourcePath) + ".html"; final String id = removeExtension(templatePath); try { final String fullContent = Files.readString(file, StandardCharsets.UTF_8); @@ -176,14 +176,14 @@ private static Consumer addBuildItem(Path root, HashSet aliases = getAliases(aliasesArr); PageInfo info = new PageInfo(id, draft, config.imagesPath(), dateString, content, - relative, templatePath); + sourcePath, templatePath); LOGGER.debugf("Creating generated template for %s" + templatePath); - final String generatedTemplate = generateTemplate(relative, layout, content); + final String generatedTemplate = generateTemplate(sourcePath, layout, content); items.add( new RoqFrontMatterRawTemplateBuildItem(info, layout, isPage, fm, collection, generatedTemplate, isPage, aliases)); } else { - PageInfo info = new PageInfo(id, false, config.imagesPath(), null, fullContent, relative, templatePath); + PageInfo info = new PageInfo(id, false, config.imagesPath(), null, fullContent, sourcePath, templatePath); items.add( new RoqFrontMatterRawTemplateBuildItem(info, null, isPage, new JsonObject(), collection, fullContent, @@ -191,7 +191,7 @@ private static Consumer addBuildItem(Path root, HashSet Date: Tue, 8 Oct 2024 18:57:04 -0300 Subject: [PATCH 3/9] Add empty aliases plugin --- plugin/aliases/deployment/pom.xml | 63 +++++++++++++++++++ .../deployment/RoqPluginAliasesProcessor.java | 15 +++++ plugin/aliases/pom.xml | 19 ++++++ plugin/aliases/runtime/pom.xml | 53 ++++++++++++++++ plugin/pom.xml | 1 + 5 files changed, 151 insertions(+) create mode 100644 plugin/aliases/deployment/pom.xml create mode 100644 plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/tagging/deployment/RoqPluginAliasesProcessor.java create mode 100644 plugin/aliases/pom.xml create mode 100644 plugin/aliases/runtime/pom.xml diff --git a/plugin/aliases/deployment/pom.xml b/plugin/aliases/deployment/pom.xml new file mode 100644 index 00000000..4e319eb8 --- /dev/null +++ b/plugin/aliases/deployment/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + + io.quarkiverse.roq + quarkus-roq-plugin-aliases-parent + 999-SNAPSHOT + + quarkus-roq-plugin-aliases-deployment + Quarkus Roq - Plugin - Aliases - Deployment + + + + io.quarkiverse.roq + quarkus-roq-frontmatter-deployment + ${project.version} + + + io.quarkiverse.roq + quarkus-roq-plugin-aliases + ${project.version} + + + io.quarkus + quarkus-junit5-internal + test + + + io.quarkus + quarkus-rest + test + + + io.rest-assured + rest-assured + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${quarkus.version} + + + + + + + diff --git a/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/tagging/deployment/RoqPluginAliasesProcessor.java b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/tagging/deployment/RoqPluginAliasesProcessor.java new file mode 100644 index 00000000..6e4d879f --- /dev/null +++ b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/tagging/deployment/RoqPluginAliasesProcessor.java @@ -0,0 +1,15 @@ +package io.quarkiverse.roq.plugin.tagging.deployment; + +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.builditem.FeatureBuildItem; + +public class RoqPluginAliasesProcessor { + + private static final String FEATURE = "roq-plugin-aliases"; + + @BuildStep + FeatureBuildItem feature() { + return new FeatureBuildItem(FEATURE); + } + +} diff --git a/plugin/aliases/pom.xml b/plugin/aliases/pom.xml new file mode 100644 index 00000000..e286e539 --- /dev/null +++ b/plugin/aliases/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + + + io.quarkiverse.roq + quarkus-roq-plugin-parent + 999-SNAPSHOT + ../pom.xml + + quarkus-roq-plugin-aliases-parent + pom + Quarkus Roq - Plugin - Aliases + + + deployment + runtime + + diff --git a/plugin/aliases/runtime/pom.xml b/plugin/aliases/runtime/pom.xml new file mode 100644 index 00000000..1e557357 --- /dev/null +++ b/plugin/aliases/runtime/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + + io.quarkiverse.roq + quarkus-roq-plugin-aliases-parent + 999-SNAPSHOT + + quarkus-roq-plugin-aliases + Quarkus Roq - Plugin - Aliases - Runtime + + + + io.quarkiverse.roq + quarkus-roq-frontmatter + ${project.version} + + + + + + + io.quarkus + quarkus-extension-maven-plugin + ${quarkus.version} + + + compile + + extension-descriptor + + + ${project.groupId}:${project.artifactId}-deployment:${project.version} + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${quarkus.version} + + + + + + + diff --git a/plugin/pom.xml b/plugin/pom.xml index cc51e10a..f4434898 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -14,5 +14,6 @@ tagging + aliases From 091f0481792063b3b266532f00dfb40984eca661 Mon Sep 17 00:00:00 2001 From: Matheus Cruz Date: Tue, 8 Oct 2024 22:14:47 -0300 Subject: [PATCH 4/9] Externalize to aliases plugin --- blog/pom.xml | 5 + .../deployment/RoqPluginAliasesProcessor.java | 108 ++++++++++++++++++ .../RoqFrontMatterAliasesBuildItem.java | 5 +- .../deployment/RoqPluginAliasesProcessor.java | 15 --- .../RoqFrontMatterAliasesRecorder.java | 13 +++ .../deployment/FrontMatterJsonData.java | 32 ++++++ .../deployment/RoqFrontMatterProcessor.java | 10 +- .../data/RoqFrontMatterDataProcessor.java | 3 +- .../record/RoqFrontMatterInitProcessor.java | 15 --- .../RoqFrontMatterRawTemplateBuildItem.java | 17 +-- .../scan/RoqFrontMatterScanProcessor.java | 25 +--- 11 files changed, 165 insertions(+), 83 deletions(-) create mode 100644 plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java rename {roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data => plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/items}/RoqFrontMatterAliasesBuildItem.java (78%) delete mode 100644 plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/tagging/deployment/RoqPluginAliasesProcessor.java create mode 100644 plugin/aliases/runtime/src/main/java/io/quarkiverse/roq/plugin/aliases/runtime/RoqFrontMatterAliasesRecorder.java create mode 100644 roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/FrontMatterJsonData.java diff --git a/blog/pom.xml b/blog/pom.xml index 97b56ae2..226c94ac 100644 --- a/blog/pom.xml +++ b/blog/pom.xml @@ -39,6 +39,11 @@ quarkus-roq-plugin-tagging ${quarkus-roq.version} + + io.quarkiverse.roq + quarkus-roq-plugin-aliases + ${quarkus-roq.version} + com.fasterxml.jackson.datatype jackson-datatype-jsr310 diff --git a/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java new file mode 100644 index 00000000..f6a27abc --- /dev/null +++ b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java @@ -0,0 +1,108 @@ +package io.quarkiverse.roq.plugin.aliases.deployment; + +import static io.quarkiverse.roq.frontmatter.deployment.FrontMatterJsonData.mergeParents; +import static io.quarkiverse.roq.frontmatter.deployment.Link.DEFAULT_PAGE_LINK_TEMPLATE; +import static io.quarkiverse.roq.frontmatter.deployment.data.RoqFrontMatterDataProcessor.LINK_KEY; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +import io.quarkiverse.roq.frontmatter.deployment.Link; +import io.quarkiverse.roq.frontmatter.deployment.scan.RoqFrontMatterRawTemplateBuildItem; +import io.quarkiverse.roq.frontmatter.runtime.RoqSiteConfig; +import io.quarkiverse.roq.generator.deployment.items.SelectedPathBuildItem; +import io.quarkiverse.roq.plugin.aliases.deployment.items.RoqFrontMatterAliasesBuildItem; +import io.quarkiverse.roq.plugin.aliases.runtime.RoqFrontMatterAliasesRecorder; +import io.quarkiverse.roq.util.PathUtils; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.ExecutionTime; +import io.quarkus.deployment.annotations.Record; +import io.quarkus.deployment.builditem.FeatureBuildItem; +import io.quarkus.vertx.http.deployment.RouteBuildItem; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +public class RoqPluginAliasesProcessor { + + private static final String FEATURE = "roq-plugin-aliases"; + private static final String ALIASES_KEY = "aliases"; + + @BuildStep + FeatureBuildItem feature() { + return new FeatureBuildItem(FEATURE); + } + + @BuildStep + public void consumeTemplates(RoqSiteConfig config, List rawTemplates, + BuildProducer aliasesProducer, + BuildProducer selectedPathsProducer) { + + if (rawTemplates.isEmpty()) { + return; + } + + final var byKey = rawTemplates.stream() + .collect(Collectors.toMap(RoqFrontMatterRawTemplateBuildItem::id, Function.identity())); + + HashMap aliasMap = new HashMap<>(); + for (RoqFrontMatterRawTemplateBuildItem item : rawTemplates) { + + final JsonObject data = mergeParents(item, byKey); + + Set aliasesName = getAliases(data); + if (aliasesName.isEmpty()) { + continue; + } + + Link.PageLinkData pageLinkData = new Link.PageLinkData(item.info().baseFileName(), item.info().date(), + item.collection(), data); + final String targetLink = Link.pageLink(config.rootPath(), data.getString(LINK_KEY, DEFAULT_PAGE_LINK_TEMPLATE), + pageLinkData); + + for (String alias : aliasesName) { + String aliasLink = Link.pageLink(config.rootPath(), alias, pageLinkData); + aliasMap.put(aliasLink, targetLink); + } + } + + for (Map.Entry alias : aliasMap.entrySet()) { + aliasesProducer.produce(new RoqFrontMatterAliasesBuildItem(alias.getKey(), alias.getValue())); + selectedPathsProducer.produce(new SelectedPathBuildItem( + alias.getKey(), null)); + } + } + + @BuildStep + @Record(ExecutionTime.RUNTIME_INIT) + public void createVertxRedirects(RoqFrontMatterAliasesRecorder recorder, + BuildProducer routes, + List aliases) { + for (RoqFrontMatterAliasesBuildItem item : aliases) { + routes.produce(RouteBuildItem.builder() + .route(PathUtils.prefixWithSlash(item.alias())) + .handler(recorder.addRedirect(item.target())) + .build()); + } + } + + private Set getAliases(JsonObject json) { + JsonArray array = json.getJsonArray(ALIASES_KEY); + if (array == null) { + return Set.of(); + } + Set aliases = new HashSet<>(); + for (int i = 0; i < array.size(); i++) { + String alias = array.getString(i); + if (!alias.isBlank()) { + aliases.add(alias); + } + } + return aliases; + } +} diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterAliasesBuildItem.java b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/items/RoqFrontMatterAliasesBuildItem.java similarity index 78% rename from roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterAliasesBuildItem.java rename to plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/items/RoqFrontMatterAliasesBuildItem.java index 89628fd7..17ca741a 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterAliasesBuildItem.java +++ b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/items/RoqFrontMatterAliasesBuildItem.java @@ -1,6 +1,5 @@ -package io.quarkiverse.roq.frontmatter.deployment.data; +package io.quarkiverse.roq.plugin.aliases.deployment.items; -import io.quarkiverse.roq.util.PathUtils; import io.quarkus.builder.item.MultiBuildItem; public final class RoqFrontMatterAliasesBuildItem extends MultiBuildItem { @@ -16,7 +15,7 @@ public final class RoqFrontMatterAliasesBuildItem extends MultiBuildItem { private final String target; public RoqFrontMatterAliasesBuildItem(String alias, String target) { - this.alias = PathUtils.prefixWithSlash(alias); + this.alias = alias; this.target = target; } diff --git a/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/tagging/deployment/RoqPluginAliasesProcessor.java b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/tagging/deployment/RoqPluginAliasesProcessor.java deleted file mode 100644 index 6e4d879f..00000000 --- a/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/tagging/deployment/RoqPluginAliasesProcessor.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.quarkiverse.roq.plugin.tagging.deployment; - -import io.quarkus.deployment.annotations.BuildStep; -import io.quarkus.deployment.builditem.FeatureBuildItem; - -public class RoqPluginAliasesProcessor { - - private static final String FEATURE = "roq-plugin-aliases"; - - @BuildStep - FeatureBuildItem feature() { - return new FeatureBuildItem(FEATURE); - } - -} diff --git a/plugin/aliases/runtime/src/main/java/io/quarkiverse/roq/plugin/aliases/runtime/RoqFrontMatterAliasesRecorder.java b/plugin/aliases/runtime/src/main/java/io/quarkiverse/roq/plugin/aliases/runtime/RoqFrontMatterAliasesRecorder.java new file mode 100644 index 00000000..bd6de3e0 --- /dev/null +++ b/plugin/aliases/runtime/src/main/java/io/quarkiverse/roq/plugin/aliases/runtime/RoqFrontMatterAliasesRecorder.java @@ -0,0 +1,13 @@ +package io.quarkiverse.roq.plugin.aliases.runtime; + +import io.quarkus.runtime.annotations.Recorder; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; + +@Recorder +public class RoqFrontMatterAliasesRecorder { + + public Handler addRedirect(String url) { + return ctx -> ctx.redirect(url); + } +} diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/FrontMatterJsonData.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/FrontMatterJsonData.java new file mode 100644 index 00000000..90218a06 --- /dev/null +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/FrontMatterJsonData.java @@ -0,0 +1,32 @@ +package io.quarkiverse.roq.frontmatter.deployment; + +import java.util.Map; +import java.util.Stack; + +import io.quarkiverse.roq.frontmatter.deployment.scan.RoqFrontMatterRawTemplateBuildItem; +import io.vertx.core.json.JsonObject; + +public class FrontMatterJsonData { + + public static JsonObject mergeParents(RoqFrontMatterRawTemplateBuildItem item, + Map byPath) { + Stack fms = new Stack<>(); + String parent = item.layout(); + fms.add(item.data()); + while (parent != null) { + if (byPath.containsKey(parent)) { + final RoqFrontMatterRawTemplateBuildItem parentItem = byPath.get(parent); + parent = parentItem.layout(); + fms.push(parentItem.data()); + } else { + parent = null; + } + } + + JsonObject merged = new JsonObject(); + while (!fms.empty()) { + merged.mergeIn(fms.pop()); + } + return merged; + } +} diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/RoqFrontMatterProcessor.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/RoqFrontMatterProcessor.java index c78b8147..7eda4a39 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/RoqFrontMatterProcessor.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/RoqFrontMatterProcessor.java @@ -7,7 +7,6 @@ import java.util.List; import java.util.Set; -import io.quarkiverse.roq.frontmatter.deployment.data.RoqFrontMatterAliasesBuildItem; import io.quarkiverse.roq.frontmatter.deployment.scan.RoqFrontMatterRawTemplateBuildItem; import io.quarkiverse.roq.frontmatter.runtime.RoqTemplateExtension; import io.quarkiverse.roq.frontmatter.runtime.RoqTemplateGlobal; @@ -94,8 +93,7 @@ void bindEndpoints( RoqFrontMatterConfig config, BuildProducer selectedPathProducer, BuildProducer notFoundPageDisplayableEndpointProducer, - RoqFrontMatterOutputBuildItem roqOutput, - List aliases) { + RoqFrontMatterOutputBuildItem roqOutput) { if (roqOutput == null) { return; } @@ -108,12 +106,6 @@ void bindEndpoints( .produce(new NotFoundPageDisplayableEndpointBuildItem(prefixWithSlash(path))); } } - - if (!aliases.isEmpty()) { - for (RoqFrontMatterAliasesBuildItem aliasItem : aliases) { - selectedPathProducer.produce(new SelectedPathBuildItem(aliasItem.alias(), null)); - } - } } } diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java index d37593f2..6f35c8c3 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java @@ -1,10 +1,9 @@ package io.quarkiverse.roq.frontmatter.deployment.data; +import static io.quarkiverse.roq.frontmatter.deployment.FrontMatterJsonData.*; import static io.quarkiverse.roq.frontmatter.deployment.Link.DEFAULT_PAGE_LINK_TEMPLATE; import java.util.List; -import java.util.Map; -import java.util.Stack; import java.util.function.Function; import java.util.stream.Collectors; diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/record/RoqFrontMatterInitProcessor.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/record/RoqFrontMatterInitProcessor.java index 39d0558f..7c0b0b65 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/record/RoqFrontMatterInitProcessor.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/record/RoqFrontMatterInitProcessor.java @@ -13,7 +13,6 @@ import io.quarkiverse.roq.frontmatter.deployment.RoqFrontMatterOutputBuildItem; import io.quarkiverse.roq.frontmatter.deployment.RoqFrontMatterRootUrlBuildItem; -import io.quarkiverse.roq.frontmatter.deployment.data.RoqFrontMatterAliasesBuildItem; import io.quarkiverse.roq.frontmatter.deployment.publish.RoqFrontMatterPublishDerivedCollectionBuildItem; import io.quarkiverse.roq.frontmatter.deployment.publish.RoqFrontMatterPublishDocumentPageBuildItem; import io.quarkiverse.roq.frontmatter.deployment.publish.RoqFrontMatterPublishPageBuildItem; @@ -152,18 +151,4 @@ public RouteBuildItem produceRoute(RoqSiteConfig config, RoqFrontMatterRecorder .handler(recorder.handler(httpRootPath.getRootPath(), roqFrontMatterOutput.allPagesByPath())) .build(); } - - @BuildStep - @Record(ExecutionTime.RUNTIME_INIT) - public void produceRoute(List aliases, BuildProducer routes, - RoqFrontMatterRecorder recorder) { - for (var aliasItem : aliases) { - routes.produce(RouteBuildItem.builder() - .route(aliasItem.alias()) - .handler(recorder.aliasRoute( - aliasItem.target())) - .build()); - } - } - } diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterRawTemplateBuildItem.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterRawTemplateBuildItem.java index be4e5e28..b17a5fbf 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterRawTemplateBuildItem.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterRawTemplateBuildItem.java @@ -1,9 +1,5 @@ package io.quarkiverse.roq.frontmatter.deployment.scan; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - import io.quarkiverse.roq.frontmatter.runtime.model.PageInfo; import io.quarkus.builder.item.MultiBuildItem; import io.vertx.core.json.JsonObject; @@ -52,15 +48,9 @@ public final class RoqFrontMatterRawTemplateBuildItem extends MultiBuildItem { */ private final boolean published; - /** - * List of aliases to be used for redirecting to an url. - */ - private final List aliases; - public RoqFrontMatterRawTemplateBuildItem(PageInfo info, String layout, boolean isPage, JsonObject data, String collection, String generatedTemplate, - boolean published, - List aliases) { + boolean published) { this.info = info; this.layout = layout; this.isPage = isPage; @@ -68,7 +58,6 @@ public RoqFrontMatterRawTemplateBuildItem(PageInfo info, String layout, boolean this.collection = collection; this.generatedTemplate = generatedTemplate; this.published = published; - this.aliases = Objects.requireNonNullElseGet(aliases, Collections::emptyList); } public boolean isPage() { @@ -102,8 +91,4 @@ public String generatedContent() { public boolean published() { return published; } - - public List aliases() { - return Collections.unmodifiableList(aliases); - } } diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterScanProcessor.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterScanProcessor.java index 5339b97c..11fd80af 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterScanProcessor.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterScanProcessor.java @@ -13,9 +13,7 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.temporal.ChronoField; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Consumer; @@ -36,7 +34,6 @@ import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem; -import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; public class RoqFrontMatterScanProcessor { @@ -46,7 +43,6 @@ public class RoqFrontMatterScanProcessor { private static final String DRAFT_KEY = "draft"; private static final String DATE_KEY = "date"; private static final String LAYOUT_KEY = "layout"; - private static final String ALIASES_KEY = "aliases"; private static final Pattern FILE_NAME_DATE_PATTERN = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})"); private record QuteMarkupSection(String open, String close) { @@ -172,22 +168,19 @@ private static Consumer addBuildItem(Path root, HashSet aliases = getAliases(aliasesArr); - PageInfo info = new PageInfo(id, draft, config.imagesPath(), dateString, content, sourcePath, templatePath); LOGGER.debugf("Creating generated template for %s" + templatePath); final String generatedTemplate = generateTemplate(sourcePath, layout, content); items.add( new RoqFrontMatterRawTemplateBuildItem(info, layout, isPage, fm, collection, generatedTemplate, - isPage, aliases)); + isPage)); } else { PageInfo info = new PageInfo(id, false, config.imagesPath(), null, fullContent, sourcePath, templatePath); items.add( new RoqFrontMatterRawTemplateBuildItem(info, null, isPage, new JsonObject(), collection, fullContent, - isPage, List.of())); + isPage)); } } catch (IOException e) { throw new RuntimeException("Error while reading the FrontMatter file %s" @@ -196,20 +189,6 @@ private static Consumer addBuildItem(Path root, HashSet getAliases(JsonArray aliasesArr) { - if (aliasesArr == null) { - return List.of(); - } - ArrayList aliases = new ArrayList<>(); - for (int i = 0; i < aliasesArr.size(); i++) { - String alias = aliasesArr.getString(i); - if (alias != null && !alias.isBlank()) { - aliases.add(alias); - } - } - return aliases; - } - protected static String parsePublishDate(Path file, JsonObject frontMatter, RoqFrontMatterConfig config) { String dateString; if (frontMatter.containsKey(DATE_KEY)) { From 9be6b40dd81a167be36bffa19eb91f867eaff549 Mon Sep 17 00:00:00 2001 From: Matheus Cruz Date: Tue, 8 Oct 2024 22:25:42 -0300 Subject: [PATCH 5/9] Add documentation --- .../ROOT/pages/quarkus-roq-plugins.adoc | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/docs/modules/ROOT/pages/quarkus-roq-plugins.adoc b/docs/modules/ROOT/pages/quarkus-roq-plugins.adoc index c71db686..653b142f 100644 --- a/docs/modules/ROOT/pages/quarkus-roq-plugins.adoc +++ b/docs/modules/ROOT/pages/quarkus-roq-plugins.adoc @@ -54,3 +54,40 @@ paginate: true {/for} ---- + + +== Roq Plugin Aliases + +This plugin allows referencing a page using an alias. + +To install it, add the following code to your dependencies file: + +[source,xml,subs=attributes+] +---- + + io.quarkiverse.roq + quarkus-roq-plugin-aliases + {project-version} + +---- + +For example, consider that you want to create a shortened link for your post. + +To create an alias, create a page and add `aliases: [your-alias-here, another-alias-here]` in the Front Matter (FM). As a result, you will have the possibility to access the page using a customized URL as alias. + +[source,yaml] +._posts_/2024-08-29-welcome-to-roq.md +---- +--- +layout: post +title: "Welcome to Roq!" +date: 2024-08-29 13:32:20 +0200 +description: This is the first article ever made with Quarkus Roq +img: posts/2024/08/blogging.jpg +tags: blogging +author: ia3andy +aliases: [first-roq-article-ever] +--- +---- + +Now, when you access the URL `http://localhost:8081/first-roq-article-ever`, you will be redirected to the `2024-08-29-welcome-to-roq` blog post. \ No newline at end of file From 7516d411ef304f910d9d56125ec9931d17b744ff Mon Sep 17 00:00:00 2001 From: Matheus Cruz Date: Tue, 8 Oct 2024 22:28:03 -0300 Subject: [PATCH 6/9] Apply formatter and impsort --- blog/src/main/java/Events.java | 3 +-- blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java | 6 +++--- .../roq/frontmatter/deployment/FrontMatterJsonData.java | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/blog/src/main/java/Events.java b/blog/src/main/java/Events.java index 69c7c09e..1bb2a07a 100644 --- a/blog/src/main/java/Events.java +++ b/blog/src/main/java/Events.java @@ -1,8 +1,7 @@ +import io.quarkiverse.roq.data.runtime.annotations.DataMapping; import java.time.LocalDate; import java.util.List; -import io.quarkiverse.roq.data.runtime.annotations.DataMapping; - @DataMapping(value = "events", parentArray = true) public record Events(List list) { diff --git a/blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java b/blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java index d5060401..48ef0325 100644 --- a/blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java +++ b/blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java @@ -1,11 +1,11 @@ package io.quarkiverse.roq.it; -import io.quarkus.test.junit.QuarkusTest; -import org.junit.jupiter.api.Test; - import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.containsString; +import io.quarkus.test.junit.QuarkusTest; +import org.junit.jupiter.api.Test; + @QuarkusTest public class RoqTest { diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/FrontMatterJsonData.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/FrontMatterJsonData.java index 90218a06..c1ea3ee3 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/FrontMatterJsonData.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/FrontMatterJsonData.java @@ -9,7 +9,7 @@ public class FrontMatterJsonData { public static JsonObject mergeParents(RoqFrontMatterRawTemplateBuildItem item, - Map byPath) { + Map byPath) { Stack fms = new Stack<>(); String parent = item.layout(); fms.add(item.data()); From 4ff391dc431c1663f4ec52cf306af962853090f7 Mon Sep 17 00:00:00 2001 From: Matheus Cruz Date: Tue, 8 Oct 2024 22:59:52 -0300 Subject: [PATCH 7/9] Add not found page for aliases --- .../aliases/deployment/RoqPluginAliasesProcessor.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java index f6a27abc..c0715c5c 100644 --- a/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java +++ b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java @@ -25,6 +25,7 @@ import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.FeatureBuildItem; import io.quarkus.vertx.http.deployment.RouteBuildItem; +import io.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; @@ -41,7 +42,8 @@ FeatureBuildItem feature() { @BuildStep public void consumeTemplates(RoqSiteConfig config, List rawTemplates, BuildProducer aliasesProducer, - BuildProducer selectedPathsProducer) { + BuildProducer selectedPathsProducer, + BuildProducer notFoundPageDisplayableEndpointProducer) { if (rawTemplates.isEmpty()) { return; @@ -75,6 +77,9 @@ public void consumeTemplates(RoqSiteConfig config, List Date: Wed, 9 Oct 2024 09:55:35 -0300 Subject: [PATCH 8/9] Use RoqUrl --- .../deployment/RoqPluginAliasesProcessor.java | 31 +++++-------------- .../data/RoqFrontMatterDataProcessor.java | 22 ------------- 2 files changed, 7 insertions(+), 46 deletions(-) diff --git a/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java index c0715c5c..db9a5c02 100644 --- a/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java +++ b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java @@ -1,20 +1,14 @@ package io.quarkiverse.roq.plugin.aliases.deployment; -import static io.quarkiverse.roq.frontmatter.deployment.FrontMatterJsonData.mergeParents; -import static io.quarkiverse.roq.frontmatter.deployment.Link.DEFAULT_PAGE_LINK_TEMPLATE; -import static io.quarkiverse.roq.frontmatter.deployment.data.RoqFrontMatterDataProcessor.LINK_KEY; - import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; -import io.quarkiverse.roq.frontmatter.deployment.Link; -import io.quarkiverse.roq.frontmatter.deployment.scan.RoqFrontMatterRawTemplateBuildItem; +import io.quarkiverse.roq.frontmatter.deployment.data.RoqFrontMatterTemplateBuildItem; import io.quarkiverse.roq.frontmatter.runtime.RoqSiteConfig; +import io.quarkiverse.roq.frontmatter.runtime.model.RoqUrl; import io.quarkiverse.roq.generator.deployment.items.SelectedPathBuildItem; import io.quarkiverse.roq.plugin.aliases.deployment.items.RoqFrontMatterAliasesBuildItem; import io.quarkiverse.roq.plugin.aliases.runtime.RoqFrontMatterAliasesRecorder; @@ -40,7 +34,7 @@ FeatureBuildItem feature() { } @BuildStep - public void consumeTemplates(RoqSiteConfig config, List rawTemplates, + public void consumeTemplates(RoqSiteConfig config, List rawTemplates, BuildProducer aliasesProducer, BuildProducer selectedPathsProducer, BuildProducer notFoundPageDisplayableEndpointProducer) { @@ -49,27 +43,16 @@ public void consumeTemplates(RoqSiteConfig config, List aliasMap = new HashMap<>(); - for (RoqFrontMatterRawTemplateBuildItem item : rawTemplates) { - - final JsonObject data = mergeParents(item, byKey); + for (RoqFrontMatterTemplateBuildItem item : rawTemplates) { - Set aliasesName = getAliases(data); + Set aliasesName = getAliases(item.data()); if (aliasesName.isEmpty()) { continue; } - - Link.PageLinkData pageLinkData = new Link.PageLinkData(item.info().baseFileName(), item.info().date(), - item.collection(), data); - final String targetLink = Link.pageLink(config.rootPath(), data.getString(LINK_KEY, DEFAULT_PAGE_LINK_TEMPLATE), - pageLinkData); - + RoqUrl url = item.url(); for (String alias : aliasesName) { - String aliasLink = Link.pageLink(config.rootPath(), alias, pageLinkData); - aliasMap.put(aliasLink, targetLink); + aliasMap.put(alias, url.path()); } } diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java index 6f35c8c3..a030e0fc 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java @@ -75,26 +75,4 @@ void dispatchByType(BuildProducer pagesProdu } } - - private static JsonObject mergeParents(RoqFrontMatterRawTemplateBuildItem item, - Map byPath) { - Stack fms = new Stack<>(); - String parent = item.layout(); - fms.add(item.data()); - while (parent != null) { - if (byPath.containsKey(parent)) { - final RoqFrontMatterRawTemplateBuildItem parentItem = byPath.get(parent); - parent = parentItem.layout(); - fms.push(parentItem.data()); - } else { - parent = null; - } - } - - JsonObject merged = new JsonObject(); - while (!fms.empty()) { - merged.mergeIn(fms.pop()); - } - return merged; - } } From e12fa0ee5c83743ac5ce4ea0f82a66319982449d Mon Sep 17 00:00:00 2001 From: Matheus Cruz Date: Wed, 9 Oct 2024 10:18:00 -0300 Subject: [PATCH 9/9] Cleanup --- .../java/io/quarkiverse/roq/it/RoqTest.java | 40 +++++-------------- .../deployment/RoqPluginAliasesProcessor.java | 11 +++-- .../deployment/FrontMatterJsonData.java | 32 --------------- .../data/RoqFrontMatterDataProcessor.java | 25 +++++++++++- 4 files changed, 42 insertions(+), 66 deletions(-) delete mode 100644 roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/FrontMatterJsonData.java diff --git a/blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java b/blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java index 48ef0325..dda4194e 100644 --- a/blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java +++ b/blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java @@ -11,33 +11,21 @@ public class RoqTest { @Test public void testIndex() { - given() - .when().get("/") - .then() - .statusCode(200) - .body(containsString("I provide you with all the tools to generate static websites out of your Quarkus web application.")) - .body(containsString("Hello, world! I'm Roq")) - .body(containsString("minute read")) - .body(containsString("Page 1 of")) - .body(containsString("2024 © ROQ")); + given().when().get("/").then().statusCode(200).body(containsString( + "I provide you with all the tools to generate static websites out of your Quarkus web application.")) + .body(containsString("Hello, world! I'm Roq")).body(containsString("minute read")) + .body(containsString("Page 1 of")).body(containsString("2024 © ROQ")); } @Test public void testTag() { - given() - .when().get("/posts/tag/cool-stuff") - .then() - .statusCode(200) - .body(containsString("cool-stuff")); + given().when().get("/posts/tag/cool-stuff").then().statusCode(200).body(containsString("cool-stuff")); } @Test public void testPosts() { - given() - .when().get("/posts/2024-08-29-welcome-to-roq") - .then() - .statusCode(200) - .body(containsString("I provide you with all the tools to generate static websites out of your Quarkus web application.")) + given().when().get("/posts/2024-08-29-welcome-to-roq").then().statusCode(200).body(containsString( + "I provide you with all the tools to generate static websites out of your Quarkus web application.")) .body(containsString("

Hello folks,

")) .body(containsString("

Welcome to Roq!

")) .body(containsString("2024 © ROQ")); @@ -45,22 +33,16 @@ public void testPosts() { @Test public void testPage() { - given() - .when().get("/events") - .then() - .statusCode(200) - .body(containsString("I provide you with all the tools to generate static websites out of your Quarkus web application.")) + given().when().get("/events").then().statusCode(200).body(containsString( + "I provide you with all the tools to generate static websites out of your Quarkus web application.")) .body(containsString("

Roq 1.0 Beta

")) .body(containsString("2024 © ROQ")); } @Test public void testAlias() { - given() - .when().get("/first-roq-article-ever") - .then() - .statusCode(200) - .body(containsString("I provide you with all the tools to generate static websites out of your Quarkus web application.")) + given().when().get("/first-roq-article-ever").then().statusCode(200).body(containsString( + "I provide you with all the tools to generate static websites out of your Quarkus web application.")) .body(containsString("

Hello folks,

")) .body(containsString("

Welcome to Roq!

")) .body(containsString("2024 © ROQ")); diff --git a/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java index db9a5c02..6528c74f 100644 --- a/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java +++ b/plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/RoqPluginAliasesProcessor.java @@ -7,7 +7,6 @@ import java.util.Set; import io.quarkiverse.roq.frontmatter.deployment.data.RoqFrontMatterTemplateBuildItem; -import io.quarkiverse.roq.frontmatter.runtime.RoqSiteConfig; import io.quarkiverse.roq.frontmatter.runtime.model.RoqUrl; import io.quarkiverse.roq.generator.deployment.items.SelectedPathBuildItem; import io.quarkiverse.roq.plugin.aliases.deployment.items.RoqFrontMatterAliasesBuildItem; @@ -34,17 +33,21 @@ FeatureBuildItem feature() { } @BuildStep - public void consumeTemplates(RoqSiteConfig config, List rawTemplates, + public void consumeTemplates(List templates, BuildProducer aliasesProducer, BuildProducer selectedPathsProducer, BuildProducer notFoundPageDisplayableEndpointProducer) { - if (rawTemplates.isEmpty()) { + if (templates.isEmpty()) { return; } HashMap aliasMap = new HashMap<>(); - for (RoqFrontMatterTemplateBuildItem item : rawTemplates) { + for (RoqFrontMatterTemplateBuildItem item : templates) { + + if (!item.published()) { + continue; + } Set aliasesName = getAliases(item.data()); if (aliasesName.isEmpty()) { diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/FrontMatterJsonData.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/FrontMatterJsonData.java deleted file mode 100644 index c1ea3ee3..00000000 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/FrontMatterJsonData.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.quarkiverse.roq.frontmatter.deployment; - -import java.util.Map; -import java.util.Stack; - -import io.quarkiverse.roq.frontmatter.deployment.scan.RoqFrontMatterRawTemplateBuildItem; -import io.vertx.core.json.JsonObject; - -public class FrontMatterJsonData { - - public static JsonObject mergeParents(RoqFrontMatterRawTemplateBuildItem item, - Map byPath) { - Stack fms = new Stack<>(); - String parent = item.layout(); - fms.add(item.data()); - while (parent != null) { - if (byPath.containsKey(parent)) { - final RoqFrontMatterRawTemplateBuildItem parentItem = byPath.get(parent); - parent = parentItem.layout(); - fms.push(parentItem.data()); - } else { - parent = null; - } - } - - JsonObject merged = new JsonObject(); - while (!fms.empty()) { - merged.mergeIn(fms.pop()); - } - return merged; - } -} diff --git a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java index a030e0fc..c3159958 100644 --- a/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java +++ b/roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterDataProcessor.java @@ -1,9 +1,10 @@ package io.quarkiverse.roq.frontmatter.deployment.data; -import static io.quarkiverse.roq.frontmatter.deployment.FrontMatterJsonData.*; import static io.quarkiverse.roq.frontmatter.deployment.Link.DEFAULT_PAGE_LINK_TEMPLATE; import java.util.List; +import java.util.Map; +import java.util.Stack; import java.util.function.Function; import java.util.stream.Collectors; @@ -75,4 +76,26 @@ void dispatchByType(BuildProducer pagesProdu } } + + public static JsonObject mergeParents(RoqFrontMatterRawTemplateBuildItem item, + Map byPath) { + Stack fms = new Stack<>(); + String parent = item.layout(); + fms.add(item.data()); + while (parent != null) { + if (byPath.containsKey(parent)) { + final RoqFrontMatterRawTemplateBuildItem parentItem = byPath.get(parent); + parent = parentItem.layout(); + fms.push(parentItem.data()); + } else { + parent = null; + } + } + + JsonObject merged = new JsonObject(); + while (!fms.empty()) { + merged.mergeIn(fms.pop()); + } + return merged; + } }