This commit is contained in:
80
modules/core/runtime/pom.xml
Normal file
80
modules/core/runtime/pom.xml
Normal file
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
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>fr.cnd.compositor</groupId>
|
||||
<artifactId>core-parent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>core</artifactId>
|
||||
<name>Core - Runtime</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>fr.cnd.compositor</groupId>
|
||||
<artifactId>compositor</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-arc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-rest-jackson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.pebbletemplates</groupId>
|
||||
<artifactId>pebble</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-extension-maven-plugin</artifactId>
|
||||
<version>${quarkus.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>extension-descriptor</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<deployment>${project.groupId}:${project.artifactId}-deployment:${project.version}</deployment>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-compile</id>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-extension-processor</artifactId>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<annotationProcessorPathsUseDepMgmt>true</annotationProcessorPathsUseDepMgmt>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,60 @@
|
||||
package fr.cnd.compositor.blocks;
|
||||
|
||||
import fr.cnd.compositor.models.BlockRenderRequest;
|
||||
import fr.cnd.compositor.models.BlockRenderResult;
|
||||
import fr.cnd.compositor.blocks.services.BlockService;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Path("/blocks")
|
||||
public class BlockResource {
|
||||
|
||||
@Inject
|
||||
BlockService blockService;
|
||||
|
||||
@POST
|
||||
@Path("template/render")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Uni<BlockRenderResult> render(BlockRenderRequest request) {
|
||||
final Map<String, List<String>> result = new HashMap<>();
|
||||
Uni<Void> chain = Uni.createFrom().voidItem();
|
||||
for (final String definitionId : request.getDefinitions().keySet()) {
|
||||
final List<String> definitionResults = new ArrayList<>();
|
||||
result.put(definitionId, definitionResults);
|
||||
chain = chain.chain(() -> blockService.renderTemplate(request.getDefinitions().get(definitionId))
|
||||
.invoke(definitionResults::add))
|
||||
.replaceWithVoid();
|
||||
}
|
||||
|
||||
return chain.map(x -> BlockRenderResult.builder().result(result).build());
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("configuration/render")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Uni<BlockRenderResult> renderConfiguration(BlockRenderRequest request) {
|
||||
final Map<String, List<String>> result = new HashMap<>();
|
||||
Uni<Void> chain = Uni.createFrom().voidItem();
|
||||
for (final String definitionId : request.getDefinitions().keySet()) {
|
||||
final List<String> definitionResults = new ArrayList<>();
|
||||
result.put(definitionId, definitionResults);
|
||||
chain = chain.chain(() -> blockService.renderBlockConfiguration(request.getDefinitions().get(definitionId))
|
||||
.invoke(definitionResults::add))
|
||||
.replaceWithVoid();
|
||||
}
|
||||
|
||||
return chain.map(x -> BlockRenderResult.builder().result(result).build());
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package fr.cnd.compositor.blocks.models;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BlockRenderDefinition {
|
||||
String name;
|
||||
Map<String, Object> inputs;
|
||||
Map<String, List<BlockRenderDefinition>> slots;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package fr.cnd.compositor.blocks.models;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BlockRenderRequest {
|
||||
Map<String, List<BlockRenderDefinition>> definitions;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package fr.cnd.compositor.blocks.models;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BlockRenderResult {
|
||||
Map<String, List<String>> result;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package fr.cnd.compositor.blocks.pebble;
|
||||
|
||||
import fr.cnd.compositor.blocks.models.BlockRenderDefinition;
|
||||
import fr.cnd.compositor.models.BlockRenderDefinition;
|
||||
import fr.cnd.compositor.blocks.specs.BlockTemplate;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package fr.cnd.compositor.blocks.pebble;
|
||||
|
||||
import fr.cnd.compositor.blocks.specs.BlockEngine;
|
||||
import io.pebbletemplates.pebble.PebbleEngine;
|
||||
import io.pebbletemplates.pebble.template.PebbleTemplate;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import io.smallrye.mutiny.unchecked.Unchecked;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.util.Map;
|
||||
|
||||
@ApplicationScoped
|
||||
public class PebbleBlockEngine implements BlockEngine {
|
||||
|
||||
@Inject
|
||||
PebbleEngine pebbleEngine;
|
||||
|
||||
@Override
|
||||
public Uni<String> render(String content, Map<String, Object> context) {
|
||||
return Uni.createFrom().item(Unchecked.supplier(() -> {
|
||||
try {
|
||||
PebbleTemplate template = pebbleEngine.getTemplate(content);
|
||||
StringWriter writer = new StringWriter();
|
||||
template.evaluate(writer, context);
|
||||
return writer.toString();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to render template content", e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package fr.cnd.compositor.blocks.pebble;
|
||||
|
||||
import io.pebbletemplates.pebble.PebbleEngine;
|
||||
import io.pebbletemplates.pebble.loader.StringLoader;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
public class PebbleProvider {
|
||||
@Inject
|
||||
PebbleBlocksExtension pebbleBlocksExtension;
|
||||
|
||||
@ApplicationScoped
|
||||
PebbleEngine createPebbleEngine() {
|
||||
return new PebbleEngine.Builder()
|
||||
.loader(new StringLoader())
|
||||
.extension(pebbleBlocksExtension)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package fr.cnd.compositor.blocks.resolvers;
|
||||
|
||||
import fr.cnd.compositor.blocks.specs.BlockConfiguration;
|
||||
import fr.cnd.compositor.blocks.specs.BlockConfigurationResolver;
|
||||
import io.smallrye.common.annotation.Identifier;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.enterprise.inject.Any;
|
||||
import jakarta.enterprise.inject.Instance;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
@ApplicationScoped
|
||||
public class CDIBlockConfigurationResolver implements BlockConfigurationResolver {
|
||||
|
||||
@Inject
|
||||
@Any
|
||||
Instance<BlockConfiguration> blockConfigurations;
|
||||
|
||||
@Override
|
||||
public Uni<BlockConfiguration> resolveConfiguration(String blockIdentifier) {
|
||||
Instance<BlockConfiguration> selected = blockConfigurations.select(Identifier.Literal.of(blockIdentifier));
|
||||
if (selected.isResolvable()) {
|
||||
return Uni.createFrom().item(selected.get());
|
||||
}
|
||||
return Uni.createFrom().nullItem();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package fr.cnd.compositor.blocks.resolvers;
|
||||
|
||||
import fr.cnd.compositor.blocks.specs.BlockTemplate;
|
||||
import fr.cnd.compositor.blocks.specs.BlockTemplateResolver;
|
||||
import io.smallrye.common.annotation.Identifier;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.enterprise.inject.Any;
|
||||
import jakarta.enterprise.inject.Instance;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
@ApplicationScoped
|
||||
public class CDIBlockTemplateResolver implements BlockTemplateResolver {
|
||||
|
||||
@Inject
|
||||
@Any
|
||||
Instance<BlockTemplate> blockTemplates;
|
||||
|
||||
@Override
|
||||
public Uni<BlockTemplate> resolveTemplate(String blockIdentifier) {
|
||||
Instance<BlockTemplate> selected = blockTemplates.select(Identifier.Literal.of(blockIdentifier));
|
||||
if (selected.isResolvable()) {
|
||||
return Uni.createFrom().item(selected.get());
|
||||
}
|
||||
return Uni.createFrom().nullItem();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package fr.cnd.compositor.blocks.resolvers;
|
||||
|
||||
import fr.cnd.compositor.blocks.specs.ContextMapping;
|
||||
import fr.cnd.compositor.blocks.specs.ContextMappingResolver;
|
||||
import io.smallrye.common.annotation.Identifier;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.enterprise.inject.Any;
|
||||
import jakarta.enterprise.inject.Instance;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
@ApplicationScoped
|
||||
public class CDIContextMappingResolver implements ContextMappingResolver {
|
||||
|
||||
@Inject
|
||||
@Any
|
||||
Instance<ContextMapping> contextMappings;
|
||||
|
||||
@Override
|
||||
public Uni<ContextMapping> resolveContextMapping(String contextMappingIdentifier) {
|
||||
Instance<ContextMapping> selected = contextMappings.select(Identifier.Literal.of(contextMappingIdentifier));
|
||||
if (selected.isResolvable()) {
|
||||
return Uni.createFrom().item(selected.get());
|
||||
}
|
||||
return Uni.createFrom().nullItem();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package fr.cnd.compositor.blocks.services;
|
||||
|
||||
import fr.cnd.compositor.models.BlockRenderDefinition;
|
||||
import fr.cnd.compositor.blocks.specs.BlockConfiguration;
|
||||
import fr.cnd.compositor.blocks.specs.BlockConfigurationResolver;
|
||||
import fr.cnd.compositor.blocks.specs.BlockTemplate;
|
||||
import fr.cnd.compositor.blocks.specs.BlockTemplateResolver;
|
||||
import io.quarkus.arc.All;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Service responsible for resolving block templates by name.
|
||||
* <p>
|
||||
* This service aggregates all available {@link BlockTemplateResolver} implementations
|
||||
* and queries them sequentially until one returns a non-null template. This allows
|
||||
* multiple template sources (e.g., file-based, database-backed, remote) to coexist
|
||||
* with a chain-of-responsibility pattern.
|
||||
*/
|
||||
@ApplicationScoped
|
||||
public class BlockService {
|
||||
|
||||
@Inject
|
||||
@All
|
||||
List<BlockTemplateResolver> resolvers;
|
||||
|
||||
@Inject
|
||||
@All
|
||||
List<BlockConfigurationResolver> blockConfigurationResolvers;
|
||||
|
||||
/**
|
||||
* Resolves a block template by its name.
|
||||
* <p>
|
||||
* Iterates through all registered {@link BlockTemplateResolver} instances and returns
|
||||
* the first non-null {@link BlockTemplate} found. If no resolver can handle the template,
|
||||
* returns {@code null}.
|
||||
*
|
||||
* @param templateName the identifier of the template to resolve
|
||||
* @return a {@link Uni} emitting the resolved {@link BlockTemplate}, or {@code null} if not found
|
||||
*/
|
||||
public Uni<BlockTemplate> resolveTemplate(String templateName) {
|
||||
Uni<BlockTemplate> result = Uni.createFrom().nullItem();
|
||||
|
||||
for (BlockTemplateResolver resolver : resolvers) {
|
||||
result = result.chain(template -> {
|
||||
if (template != null) {
|
||||
return Uni.createFrom().item(template);
|
||||
}
|
||||
return resolver.resolveTemplate(templateName);
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a block configuration by its identifier.
|
||||
* <p>
|
||||
* Iterates through all registered {@link BlockConfigurationResolver} instances and returns
|
||||
* the first non-null {@link BlockConfiguration} found. If no resolver can handle the identifier,
|
||||
* returns {@code null}.
|
||||
*
|
||||
* @param blockIdentifier the identifier of the block configuration to resolve
|
||||
* @return a {@link Uni} emitting the resolved {@link BlockConfiguration}, or {@code null} if not found
|
||||
*/
|
||||
public Uni<BlockConfiguration> resolveBlockConfiguration(String blockIdentifier) {
|
||||
Uni<BlockConfiguration> result = Uni.createFrom().nullItem();
|
||||
|
||||
for (BlockConfigurationResolver resolver : blockConfigurationResolvers) {
|
||||
result = result.chain(configuration -> {
|
||||
if (configuration != null) {
|
||||
return Uni.createFrom().item(configuration);
|
||||
}
|
||||
return resolver.resolveConfiguration(blockIdentifier);
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public Uni<String> renderTemplate(List<BlockRenderDefinition> definitions) {
|
||||
final List<String> results = new ArrayList<>();
|
||||
Uni<Void> chain = Uni.createFrom().voidItem();
|
||||
for (BlockRenderDefinition definition : definitions) {
|
||||
chain = chain.chain(() -> renderTemplate(definition))
|
||||
.invoke(results::add)
|
||||
.replaceWithVoid();
|
||||
}
|
||||
|
||||
return chain.map(x -> String.join(" ", results));
|
||||
}
|
||||
|
||||
public Uni<String> renderTemplate(BlockRenderDefinition definition) {
|
||||
final Map<String, String> slotsContent = new HashMap<>();
|
||||
Uni<Void> slotChain = Uni.createFrom().voidItem();
|
||||
for (String slotName : Optional.ofNullable(definition.getSlots()).map(Map::keySet).orElse(new HashSet<>())) {
|
||||
slotChain = slotChain.chain(() -> renderTemplate(definition.getSlots().get(slotName)))
|
||||
.invoke(slotContent -> slotsContent.put(slotName, slotContent))
|
||||
.replaceWithVoid();
|
||||
}
|
||||
|
||||
return slotChain.chain(() -> resolveTemplate(definition.getName()))
|
||||
.chain(blockTemplate -> {
|
||||
final Map<String, Object> context = new HashMap<>(Optional.ofNullable(definition.getInputs()).orElse(new HashMap<>()));
|
||||
context.put("__slots__", slotsContent);
|
||||
return blockTemplate.render(BlockRenderDefinition.builder()
|
||||
.name(definition.getName())
|
||||
.inputs(context)
|
||||
.build());
|
||||
});
|
||||
}
|
||||
|
||||
public Uni<String> renderBlockConfiguration(List<BlockRenderDefinition> definitions) {
|
||||
return mapDefinition(definitions)
|
||||
.chain(this::renderTemplate);
|
||||
}
|
||||
|
||||
private Uni<List<BlockRenderDefinition>> mapDefinition(List<BlockRenderDefinition> definitions) {
|
||||
final List<BlockRenderDefinition> results = new ArrayList<>();
|
||||
Uni<Void> chain = Uni.createFrom().voidItem();
|
||||
for (BlockRenderDefinition definition : definitions) {
|
||||
chain = chain.chain(() -> mapDefinition(definition))
|
||||
.invoke(results::add)
|
||||
.replaceWithVoid();
|
||||
}
|
||||
|
||||
return chain.map(x -> results);
|
||||
}
|
||||
|
||||
private Uni<BlockRenderDefinition> mapDefinition(BlockRenderDefinition definition) {
|
||||
final Map<String, List<BlockRenderDefinition>> slotMapping = new HashMap<>();
|
||||
Uni<Void> slotChain = Uni.createFrom().voidItem();
|
||||
for (String slotName : Optional.ofNullable(definition.getSlots()).map(Map::keySet).orElse(new HashSet<>())) {
|
||||
final List<BlockRenderDefinition> slotDefinitions = new ArrayList<>();
|
||||
slotMapping.put(slotName, slotDefinitions);
|
||||
for (BlockRenderDefinition blockDefinition : definition.getSlots().get(slotName)) {
|
||||
slotChain = slotChain.chain(() -> mapDefinition(blockDefinition))
|
||||
.invoke(slotDefinitions::add)
|
||||
.replaceWithVoid();
|
||||
}
|
||||
}
|
||||
|
||||
final BlockRenderDefinition mappedDefinition = BlockRenderDefinition.builder()
|
||||
.slots(slotMapping)
|
||||
.build();
|
||||
|
||||
return slotChain.chain(() -> resolveBlockConfiguration(definition.getName())
|
||||
.call(blockConfiguration -> blockConfiguration
|
||||
.getBlockTemplateName()
|
||||
.invoke(mappedDefinition::setName))
|
||||
.call(blockConfiguration -> blockConfiguration
|
||||
.mapInputs(definition.getInputs())
|
||||
.invoke(mappedDefinition::setInputs))
|
||||
.map(x -> mappedDefinition));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package fr.cnd.compositor.blocks.specs;
|
||||
|
||||
import io.smallrye.mutiny.Uni;
|
||||
|
||||
public interface BlockConfigurationResolver {
|
||||
Uni<BlockConfiguration> resolveConfiguration(String blockIdentifier);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package fr.cnd.compositor.blocks.specs;
|
||||
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import fr.cnd.compositor.blocks.pebble.PebbleBlockEngine;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Interface définissant un moteur de rendu de templates pour les blocs.
|
||||
* <p>
|
||||
* Un {@code BlockEngine} est responsable de transformer un contenu template
|
||||
* en chaîne de caractères finale, en utilisant un contexte de données fourni.
|
||||
* Le rendu est effectué de manière asynchrone via {@link Uni}.
|
||||
* <p>
|
||||
* Les implémentations peuvent utiliser différents moteurs de templates
|
||||
* (Pebble, Freemarker, Thymeleaf, etc.) selon les besoins.
|
||||
*
|
||||
* <h2>Exemple d'implémentation</h2>
|
||||
* <pre>{@code
|
||||
* @ApplicationScoped
|
||||
* public class MyBlockEngine implements BlockEngine {
|
||||
*
|
||||
* @Override
|
||||
* public Uni<String> render(String content, Map<String, Object> context) {
|
||||
* return Uni.createFrom().item(() -> {
|
||||
* // Logique de rendu du template
|
||||
* return renderedContent;
|
||||
* });
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @see PebbleBlockEngine
|
||||
*/
|
||||
public interface BlockEngine {
|
||||
|
||||
/**
|
||||
* Effectue le rendu d'un contenu template avec le contexte fourni.
|
||||
* <p>
|
||||
* Cette méthode prend un template sous forme de chaîne de caractères
|
||||
* et le combine avec les données du contexte pour produire le résultat final.
|
||||
*
|
||||
* @param content le contenu du template à rendre, utilisant la syntaxe
|
||||
* spécifique au moteur de template implémenté
|
||||
* @param context une Map contenant les variables disponibles pour le template,
|
||||
* où les clés sont les noms des variables et les valeurs leurs données
|
||||
* @return un {@link Uni} émettant la chaîne de caractères résultant du rendu,
|
||||
* ou une erreur si le rendu échoue (template invalide, erreur d'évaluation, etc.)
|
||||
*/
|
||||
Uni<String> render(String content, Map<String, Object> context);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package fr.cnd.compositor.blocks.specs;
|
||||
|
||||
import fr.cnd.compositor.models.BlockRenderDefinition;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
|
||||
public interface BlockTemplate {
|
||||
Uni<String> render(BlockRenderDefinition definition);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package fr.cnd.compositor.blocks.specs;
|
||||
|
||||
import io.smallrye.mutiny.Uni;
|
||||
|
||||
public interface BlockTemplateResolver {
|
||||
Uni<BlockTemplate> resolveTemplate(String blockIdentifier);
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package fr.cnd.compositor.blocks.templates;
|
||||
|
||||
import fr.cnd.compositor.blocks.pebble.AbstractPebbleBlockTemplate;
|
||||
import io.smallrye.common.annotation.Identifier;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
|
||||
@Identifier("html")
|
||||
@ApplicationScoped
|
||||
public class HtmlBlockTemplate extends AbstractPebbleBlockTemplate {
|
||||
@Override
|
||||
public Uni<String> getTemplate() {
|
||||
return Uni.createFrom().item("""
|
||||
<html>
|
||||
<head>
|
||||
<title>{{title}}</title>
|
||||
</head>
|
||||
<body>
|
||||
{{content}}
|
||||
</body>
|
||||
</html>
|
||||
""");
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package fr.cnd.compositor.blocks.templates;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import fr.cnd.compositor.blocks.specs.BlockConfiguration;
|
||||
import io.smallrye.common.annotation.Identifier;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Identifier("product")
|
||||
@ApplicationScoped
|
||||
public class HtmlProductConfiguration implements BlockConfiguration {
|
||||
|
||||
@Inject
|
||||
ObjectMapper objectMapper;
|
||||
|
||||
@Override
|
||||
public Uni<String> getBlockTemplateName() {
|
||||
return Uni.createFrom().item("html");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uni<Map<String, Object>> mapInputs(Map<String, Object> inputs) {
|
||||
Map<String, String> product = objectMapper.convertValue(inputs.getOrDefault("product", new HashMap<>()), new TypeReference<>() {});
|
||||
|
||||
return Uni.createFrom().item(Map.of(
|
||||
"title", product.getOrDefault("title", ""),
|
||||
"content", product.getOrDefault("name", "")
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
name: Core
|
||||
#description: Do something useful.
|
||||
metadata:
|
||||
# keywords:
|
||||
# - core
|
||||
# guide: ... # To create and publish this guide, see https://github.com/quarkiverse/quarkiverse/wiki#documenting-your-extension
|
||||
# categories:
|
||||
# - "miscellaneous"
|
||||
# status: "preview"
|
||||
Reference in New Issue
Block a user