Skip to content

Commit

Permalink
Merge pull request #124 from mcruzdev/issue-77
Browse files Browse the repository at this point in the history
Add support for redirect with aliases
  • Loading branch information
mcruzdev authored Oct 9, 2024
2 parents 5cc7067 + 3c0f5ba commit 434c5de
Show file tree
Hide file tree
Showing 19 changed files with 366 additions and 48 deletions.
5 changes: 5 additions & 0 deletions blog/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
<artifactId>quarkus-roq-plugin-tagging</artifactId>
<version>${quarkus-roq.version}</version>
</dependency>
<dependency>
<groupId>io.quarkiverse.roq</groupId>
<artifactId>quarkus-roq-plugin-aliases</artifactId>
<version>${quarkus-roq.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
Expand Down
1 change: 1 addition & 0 deletions blog/site/_posts/2024-08-29-welcome-to-roq.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 1 addition & 2 deletions blog/src/main/java/Events.java
Original file line number Diff line number Diff line change
@@ -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<Event> list) {

Expand Down
45 changes: 19 additions & 26 deletions blog/src/test/java/io/quarkiverse/roq/it/RoqTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,48 @@
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.containsString;

import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

@QuarkusTest
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&#39;m Roq"))
.body(containsString("minute read"))
.body(containsString("Page 1 of"))
.body(containsString("2024 &copy; 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&#39;m Roq")).body(containsString("minute read"))
.body(containsString("Page 1 of")).body(containsString("2024 &copy; 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("<p>Hello folks,</p>"))
.body(containsString("<h1 class=\"page-title\">Welcome to Roq!</h1>"))
.body(containsString("2024 &copy; ROQ"));
}

@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("<h2 class=\"event-title\">Roq 1.0 Beta</h2>"))
.body(containsString("2024 &copy; 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("<p>Hello folks,</p>"))
.body(containsString("<h1 class=\"page-title\">Welcome to Roq!</h1>"))
.body(containsString("2024 &copy; ROQ"));
}
}
37 changes: 37 additions & 0 deletions docs/modules/ROOT/pages/quarkus-roq-plugins.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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+]
----
<dependency>
<groupId>io.quarkiverse.roq</groupId>
<artifactId>quarkus-roq-plugin-aliases</artifactId>
<version>{project-version}</version>
</dependency>
----

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.
63 changes: 63 additions & 0 deletions plugin/aliases/deployment/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.quarkiverse.roq</groupId>
<artifactId>quarkus-roq-plugin-aliases-parent</artifactId>
<version>999-SNAPSHOT</version>
</parent>
<artifactId>quarkus-roq-plugin-aliases-deployment</artifactId>
<name>Quarkus Roq - Plugin - Aliases - Deployment</name>

<dependencies>
<dependency>
<groupId>io.quarkiverse.roq</groupId>
<artifactId>quarkus-roq-frontmatter-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkiverse.roq</groupId>
<artifactId>quarkus-roq-plugin-aliases</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-internal</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-processor</artifactId>
<version>${quarkus.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package io.quarkiverse.roq.plugin.aliases.deployment;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import io.quarkiverse.roq.frontmatter.deployment.data.RoqFrontMatterTemplateBuildItem;
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;
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.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem;
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(List<RoqFrontMatterTemplateBuildItem> templates,
BuildProducer<RoqFrontMatterAliasesBuildItem> aliasesProducer,
BuildProducer<SelectedPathBuildItem> selectedPathsProducer,
BuildProducer<NotFoundPageDisplayableEndpointBuildItem> notFoundPageDisplayableEndpointProducer) {

if (templates.isEmpty()) {
return;
}

HashMap<String, String> aliasMap = new HashMap<>();
for (RoqFrontMatterTemplateBuildItem item : templates) {

if (!item.published()) {
continue;
}

Set<String> aliasesName = getAliases(item.data());
if (aliasesName.isEmpty()) {
continue;
}
RoqUrl url = item.url();
for (String alias : aliasesName) {
aliasMap.put(alias, url.path());
}
}

for (Map.Entry<String, String> alias : aliasMap.entrySet()) {
aliasesProducer.produce(new RoqFrontMatterAliasesBuildItem(alias.getKey(), alias.getValue()));
selectedPathsProducer.produce(new SelectedPathBuildItem(
alias.getKey(), null));
notFoundPageDisplayableEndpointProducer.produce(
new NotFoundPageDisplayableEndpointBuildItem(alias.getKey(),
"Roq URL alias for " + alias.getValue() + " URL."));
}
}

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
public void createVertxRedirects(RoqFrontMatterAliasesRecorder recorder,
BuildProducer<RouteBuildItem> routes,
List<RoqFrontMatterAliasesBuildItem> aliases) {
for (RoqFrontMatterAliasesBuildItem item : aliases) {
routes.produce(RouteBuildItem.builder()
.route(PathUtils.prefixWithSlash(item.alias()))
.handler(recorder.addRedirect(item.target()))
.build());
}
}

private Set<String> getAliases(JsonObject json) {
JsonArray array = json.getJsonArray(ALIASES_KEY);
if (array == null) {
return Set.of();
}
Set<String> aliases = new HashSet<>();
for (int i = 0; i < array.size(); i++) {
String alias = array.getString(i);
if (!alias.isBlank()) {
aliases.add(alias);
}
}
return aliases;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.quarkiverse.roq.plugin.aliases.deployment.items;

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 = alias;
this.target = target;
}

public String alias() {
return alias;
}

public String target() {
return target;
}
}
19 changes: 19 additions & 0 deletions plugin/aliases/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.quarkiverse.roq</groupId>
<artifactId>quarkus-roq-plugin-parent</artifactId>
<version>999-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>quarkus-roq-plugin-aliases-parent</artifactId>
<packaging>pom</packaging>
<name>Quarkus Roq - Plugin - Aliases</name>

<modules>
<module>deployment</module>
<module>runtime</module>
</modules>
</project>
Loading

0 comments on commit 434c5de

Please sign in to comment.