Skip to content

Commit

Permalink
Merge pull request #83 from dd4t/feature/thymeleaf
Browse files Browse the repository at this point in the history
Added Thymeleaf support
  • Loading branch information
RaimondKempees authored Dec 27, 2016
2 parents 8d7d9c0 + ebe90a7 commit fe1d631
Show file tree
Hide file tree
Showing 7 changed files with 498 additions and 0 deletions.
167 changes: 167 additions & 0 deletions dd4t-thymeleaf-support/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.dd4t</groupId>
<artifactId>dd4t-parent</artifactId>
<version>2.0.7-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<name>${project.groupId}:${project.artifactId}</name>
<description>Provides support for Thymeleaf views.</description>
<url>https://github.com/dd4t</url>

<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>

<developers>
<developer>
<name>Quirijn Slings</name>
<email>[email protected]</email>
<organization>DD4T</organization>
<organizationUrl>https://github.com/dd4t</organizationUrl>
</developer>
<developer>
<name>Raimond Kempees</name>
<email>[email protected]</email>
<organization>DD4T</organization>
<organizationUrl>https://github.com/dd4t</organizationUrl>
</developer>
</developers>

<scm>
<connection>scm:git:[email protected]:/dd4t/dd4t-2-java.git</connection>
<developerConnection>scm:git:[email protected]:/dd4t/dd4t-2-java.git</developerConnection>
<url>[email protected]:/dd4t/dd4t-2-java.git</url>
</scm>

<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<targetPath>META-INF/tld</targetPath>
<filtering>true</filtering>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
</build>
<artifactId>dd4t-thymeleaf-support</artifactId>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.dd4t</groupId>
<artifactId>dd4t-bom</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.dd4t</groupId>
<artifactId>dd4t-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.dd4t</groupId>
<artifactId>dd4t-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.dd4t</groupId>
<artifactId>dd4t-databind</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.dd4t</groupId>
<artifactId>dd4t-mvc-support</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
<!--
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<scope>provided</scope>
</dependency>
-->
<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring4 -->


</dependencies>
</project>
17 changes: 17 additions & 0 deletions dd4t-thymeleaf-support/src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Thymeleaf is a view language for java (see http://www.thymeleaf.org/).

This library offers support for Experience Manager in Thymeleaf views.

Usage:

<xpm:page src="${page}"/>

Place this somewhere near the bottom of the HTML page. Generates the <script> tag needed for XPM. Note that the DD4T Page object must be on the request (in this example, it is called 'page' but that can be different per implementation).

<xpm:componentpresentation src="${entity}"/>

Place this tag directly inside the enclosing element of the component presentation. Note that the DD4T entity (= ViewModel) object must be on the request (in this example, it is called 'entity' but that can be different per implementation).

<xpm:field src="${entity}" fieldname="somefieldname"/>

Place this tag directly inside the enclosing element of the field. Note that the DD4T entity (= ViewModel) object must be on the request (in this example, it is called 'entity' but that can be different per implementation).
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.dd4t.thymeleaf.dialect;

import java.util.HashSet;
import java.util.Set;

import javax.annotation.Resource;

import org.dd4t.core.services.PropertiesService;
import org.dd4t.thymeleaf.dialect.processor.xpm.XpmComponentPresentationProcessor;
import org.dd4t.thymeleaf.dialect.processor.xpm.XpmFieldProcessor;
import org.dd4t.thymeleaf.dialect.processor.xpm.XpmPageInitProcessor;
import org.thymeleaf.dialect.IProcessorDialect;
import org.thymeleaf.processor.IProcessor;


public class XpmDialect implements IProcessorDialect {

@Resource
PropertiesService propertiesService;



public XpmDialect() {
}

/**
* Prefix of the dialect.
*/
@Override
public String getPrefix() {
return "xpm";
}

/**
* Available processors
*/
@Override
public Set<IProcessor> getProcessors(String dialectPrefix) {
final Set<IProcessor> processors = new HashSet<IProcessor>();
processors.add(new XpmPageInitProcessor(getPrefix(), propertiesService));
processors.add(new XpmComponentPresentationProcessor(getPrefix(), propertiesService));
processors.add(new XpmFieldProcessor(getPrefix(), propertiesService));
return processors;
}

@Override
public String getName() {
return "XPM Dialect";
}

@Override
public int getDialectProcessorPrecedence() {
return 0;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package org.dd4t.thymeleaf.dialect.processor.xpm;

import java.util.Map;
import java.util.logging.Logger;
import org.dd4t.core.services.PropertiesService;
import org.dd4t.databind.viewmodel.base.TridionViewModelBase;
import org.dd4t.mvc.utils.XPMRenderer;
import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.model.IModel;
import org.thymeleaf.model.IModelFactory;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractElementTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.standard.expression.IStandardExpression;
import org.thymeleaf.standard.expression.IStandardExpressionParser;
import org.thymeleaf.standard.expression.StandardExpressions;
import org.thymeleaf.templatemode.TemplateMode;

/**
* Custom processor that generates the Experience Manager tags on the page level
* @author Quirijn Slings
*/

public class XpmComponentPresentationProcessor extends AbstractElementTagProcessor {
private static final Logger LOG = Logger.getLogger(XpmComponentPresentationProcessor.class.getName());
private static final String TAG_NAME = "componentpresentation";
private static final String SRC_ATTR_NAME = "src";
private static final int PRECEDENCE = 10000;

public XpmComponentPresentationProcessor(final String dialectPrefix, PropertiesService propertiesService) {
super(TemplateMode.HTML,
dialectPrefix,
TAG_NAME,
true,
null,
false,
PRECEDENCE
);
String xpmEnabledAsString = propertiesService.getProperty("xpm.enabled");
if (xpmEnabledAsString != null) {
XPMRenderer.getInstance().setEnabled(Boolean.parseBoolean(xpmEnabledAsString));
}
}

/**
* Process the tag
*/

@Override
protected void doProcess(
final ITemplateContext context, final IProcessableElementTag tag,
final IElementTagStructureHandler structureHandler) {
final IEngineConfiguration configuration = context.getConfiguration();
final IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);

// check if there is a 'src' attribute on the current tag
if (! tag.hasAttribute(SRC_ATTR_NAME)) {
// TODO: log a warning message
return;
}

// retrieve the entity object from the attribute
IStandardExpression expressionComponentPresentation = parser.parseExpression(context, tag.getAttributeValue(SRC_ATTR_NAME));
TridionViewModelBase entity = (TridionViewModelBase) expressionComponentPresentation.execute(context);

Map<String,Object> props = entity.getModelProperties();



// get an XPM renderer (part of DD4T) and generate the XPM comment for this page
XPMRenderer renderer = XPMRenderer.getInstance();
String xpmMarkup = renderer.componentPresentation(entity.getTcmUri().toString(), entity.getLastModified(), entity.getTemplateUri().toString(), false);

// create a model with the returned markup
final IModelFactory modelFactory = context.getModelFactory();
final IModel model = modelFactory.parse(context.getTemplateData(), xpmMarkup);

// instruct the engine to replace this entire element with the specified model
structureHandler.replaceWith(model, false);
}
}
Loading

0 comments on commit fe1d631

Please sign in to comment.