Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fe1d631

Browse files
Merge pull request #83 from dd4t/feature/thymeleaf
Added Thymeleaf support
2 parents 8d7d9c0 + ebe90a7 commit fe1d631

File tree

7 files changed

+498
-0
lines changed

7 files changed

+498
-0
lines changed

dd4t-thymeleaf-support/pom.xml

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<groupId>org.dd4t</groupId>
7+
<artifactId>dd4t-parent</artifactId>
8+
<version>2.0.7-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<name>${project.groupId}:${project.artifactId}</name>
13+
<description>Provides support for Thymeleaf views.</description>
14+
<url>https://github.com/dd4t</url>
15+
16+
<licenses>
17+
<license>
18+
<name>The Apache License, Version 2.0</name>
19+
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
20+
</license>
21+
</licenses>
22+
23+
<developers>
24+
<developer>
25+
<name>Quirijn Slings</name>
26+
<email>[email protected]</email>
27+
<organization>DD4T</organization>
28+
<organizationUrl>https://github.com/dd4t</organizationUrl>
29+
</developer>
30+
<developer>
31+
<name>Raimond Kempees</name>
32+
<email>[email protected]</email>
33+
<organization>DD4T</organization>
34+
<organizationUrl>https://github.com/dd4t</organizationUrl>
35+
</developer>
36+
</developers>
37+
38+
<scm>
39+
<connection>scm:git:[email protected]:/dd4t/dd4t-2-java.git</connection>
40+
<developerConnection>scm:git:[email protected]:/dd4t/dd4t-2-java.git</developerConnection>
41+
<url>[email protected]:/dd4t/dd4t-2-java.git</url>
42+
</scm>
43+
44+
<packaging>jar</packaging>
45+
<properties>
46+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
47+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
48+
</properties>
49+
<build>
50+
<resources>
51+
<resource>
52+
<directory>src/main/resources</directory>
53+
<targetPath>META-INF/tld</targetPath>
54+
<filtering>true</filtering>
55+
<includes>
56+
<include>**/**</include>
57+
</includes>
58+
</resource>
59+
</resources>
60+
</build>
61+
<artifactId>dd4t-thymeleaf-support</artifactId>
62+
63+
<dependencyManagement>
64+
<dependencies>
65+
<dependency>
66+
<groupId>org.dd4t</groupId>
67+
<artifactId>dd4t-bom</artifactId>
68+
<version>${project.version}</version>
69+
<type>pom</type>
70+
<scope>import</scope>
71+
</dependency>
72+
</dependencies>
73+
</dependencyManagement>
74+
75+
<dependencies>
76+
<dependency>
77+
<groupId>org.dd4t</groupId>
78+
<artifactId>dd4t-api</artifactId>
79+
<version>${project.version}</version>
80+
</dependency>
81+
<dependency>
82+
<groupId>org.dd4t</groupId>
83+
<artifactId>dd4t-core</artifactId>
84+
<version>${project.version}</version>
85+
</dependency>
86+
<dependency>
87+
<groupId>org.dd4t</groupId>
88+
<artifactId>dd4t-databind</artifactId>
89+
<version>${project.version}</version>
90+
</dependency>
91+
<dependency>
92+
<groupId>org.dd4t</groupId>
93+
<artifactId>dd4t-mvc-support</artifactId>
94+
<version>${project.version}</version>
95+
</dependency>
96+
<dependency>
97+
<groupId>org.thymeleaf</groupId>
98+
<artifactId>thymeleaf-spring4</artifactId>
99+
<version>3.0.2.RELEASE</version>
100+
</dependency>
101+
<dependency>
102+
<groupId>org.slf4j</groupId>
103+
<artifactId>slf4j-api</artifactId>
104+
<scope>provided</scope>
105+
</dependency>
106+
<!--
107+
<dependency>
108+
<groupId>commons-io</groupId>
109+
<artifactId>commons-io</artifactId>
110+
<scope>provided</scope>
111+
</dependency>
112+
<dependency>
113+
<groupId>org.springframework</groupId>
114+
<artifactId>spring-beans</artifactId>
115+
<scope>provided</scope>
116+
</dependency>
117+
<dependency>
118+
<groupId>org.springframework</groupId>
119+
<artifactId>spring-context-support</artifactId>
120+
<scope>provided</scope>
121+
</dependency>
122+
<dependency>
123+
<groupId>org.springframework</groupId>
124+
<artifactId>spring-jms</artifactId>
125+
<scope>provided</scope>
126+
</dependency>
127+
<dependency>
128+
<groupId>org.springframework</groupId>
129+
<artifactId>spring-web</artifactId>
130+
<scope>provided</scope>
131+
</dependency>
132+
<dependency>
133+
<groupId>org.springframework</groupId>
134+
<artifactId>spring-webmvc</artifactId>
135+
<scope>provided</scope>
136+
</dependency>
137+
<dependency>
138+
<groupId>org.apache.commons</groupId>
139+
<artifactId>commons-lang3</artifactId>
140+
<scope>provided</scope>
141+
</dependency>
142+
<dependency>
143+
<groupId>org.apache.httpcomponents</groupId>
144+
<artifactId>httpclient</artifactId>
145+
<scope>provided</scope>
146+
</dependency>
147+
<dependency>
148+
<groupId>javax.servlet.jsp</groupId>
149+
<artifactId>jsp-api</artifactId>
150+
<scope>provided</scope>
151+
</dependency>
152+
<dependency>
153+
<groupId>javax.servlet</groupId>
154+
<artifactId>javax.servlet-api</artifactId>
155+
<scope>provided</scope>
156+
</dependency>
157+
<dependency>
158+
<groupId>joda-time</groupId>
159+
<artifactId>joda-time</artifactId>
160+
<scope>provided</scope>
161+
</dependency>
162+
-->
163+
<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring4 -->
164+
165+
166+
</dependencies>
167+
</project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Thymeleaf is a view language for java (see http://www.thymeleaf.org/).
2+
3+
This library offers support for Experience Manager in Thymeleaf views.
4+
5+
Usage:
6+
7+
<xpm:page src="${page}"/>
8+
9+
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).
10+
11+
<xpm:componentpresentation src="${entity}"/>
12+
13+
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).
14+
15+
<xpm:field src="${entity}" fieldname="somefieldname"/>
16+
17+
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).
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package org.dd4t.thymeleaf.dialect;
2+
3+
import java.util.HashSet;
4+
import java.util.Set;
5+
6+
import javax.annotation.Resource;
7+
8+
import org.dd4t.core.services.PropertiesService;
9+
import org.dd4t.thymeleaf.dialect.processor.xpm.XpmComponentPresentationProcessor;
10+
import org.dd4t.thymeleaf.dialect.processor.xpm.XpmFieldProcessor;
11+
import org.dd4t.thymeleaf.dialect.processor.xpm.XpmPageInitProcessor;
12+
import org.thymeleaf.dialect.IProcessorDialect;
13+
import org.thymeleaf.processor.IProcessor;
14+
15+
16+
public class XpmDialect implements IProcessorDialect {
17+
18+
@Resource
19+
PropertiesService propertiesService;
20+
21+
22+
23+
public XpmDialect() {
24+
}
25+
26+
/**
27+
* Prefix of the dialect.
28+
*/
29+
@Override
30+
public String getPrefix() {
31+
return "xpm";
32+
}
33+
34+
/**
35+
* Available processors
36+
*/
37+
@Override
38+
public Set<IProcessor> getProcessors(String dialectPrefix) {
39+
final Set<IProcessor> processors = new HashSet<IProcessor>();
40+
processors.add(new XpmPageInitProcessor(getPrefix(), propertiesService));
41+
processors.add(new XpmComponentPresentationProcessor(getPrefix(), propertiesService));
42+
processors.add(new XpmFieldProcessor(getPrefix(), propertiesService));
43+
return processors;
44+
}
45+
46+
@Override
47+
public String getName() {
48+
return "XPM Dialect";
49+
}
50+
51+
@Override
52+
public int getDialectProcessorPrecedence() {
53+
return 0;
54+
}
55+
56+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package org.dd4t.thymeleaf.dialect.processor.xpm;
2+
3+
import java.util.Map;
4+
import java.util.logging.Logger;
5+
import org.dd4t.core.services.PropertiesService;
6+
import org.dd4t.databind.viewmodel.base.TridionViewModelBase;
7+
import org.dd4t.mvc.utils.XPMRenderer;
8+
import org.thymeleaf.IEngineConfiguration;
9+
import org.thymeleaf.context.ITemplateContext;
10+
import org.thymeleaf.model.IModel;
11+
import org.thymeleaf.model.IModelFactory;
12+
import org.thymeleaf.model.IProcessableElementTag;
13+
import org.thymeleaf.processor.element.AbstractElementTagProcessor;
14+
import org.thymeleaf.processor.element.IElementTagStructureHandler;
15+
import org.thymeleaf.standard.expression.IStandardExpression;
16+
import org.thymeleaf.standard.expression.IStandardExpressionParser;
17+
import org.thymeleaf.standard.expression.StandardExpressions;
18+
import org.thymeleaf.templatemode.TemplateMode;
19+
20+
/**
21+
* Custom processor that generates the Experience Manager tags on the page level
22+
* @author Quirijn Slings
23+
*/
24+
25+
public class XpmComponentPresentationProcessor extends AbstractElementTagProcessor {
26+
private static final Logger LOG = Logger.getLogger(XpmComponentPresentationProcessor.class.getName());
27+
private static final String TAG_NAME = "componentpresentation";
28+
private static final String SRC_ATTR_NAME = "src";
29+
private static final int PRECEDENCE = 10000;
30+
31+
public XpmComponentPresentationProcessor(final String dialectPrefix, PropertiesService propertiesService) {
32+
super(TemplateMode.HTML,
33+
dialectPrefix,
34+
TAG_NAME,
35+
true,
36+
null,
37+
false,
38+
PRECEDENCE
39+
);
40+
String xpmEnabledAsString = propertiesService.getProperty("xpm.enabled");
41+
if (xpmEnabledAsString != null) {
42+
XPMRenderer.getInstance().setEnabled(Boolean.parseBoolean(xpmEnabledAsString));
43+
}
44+
}
45+
46+
/**
47+
* Process the tag
48+
*/
49+
50+
@Override
51+
protected void doProcess(
52+
final ITemplateContext context, final IProcessableElementTag tag,
53+
final IElementTagStructureHandler structureHandler) {
54+
final IEngineConfiguration configuration = context.getConfiguration();
55+
final IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);
56+
57+
// check if there is a 'src' attribute on the current tag
58+
if (! tag.hasAttribute(SRC_ATTR_NAME)) {
59+
// TODO: log a warning message
60+
return;
61+
}
62+
63+
// retrieve the entity object from the attribute
64+
IStandardExpression expressionComponentPresentation = parser.parseExpression(context, tag.getAttributeValue(SRC_ATTR_NAME));
65+
TridionViewModelBase entity = (TridionViewModelBase) expressionComponentPresentation.execute(context);
66+
67+
Map<String,Object> props = entity.getModelProperties();
68+
69+
70+
71+
// get an XPM renderer (part of DD4T) and generate the XPM comment for this page
72+
XPMRenderer renderer = XPMRenderer.getInstance();
73+
String xpmMarkup = renderer.componentPresentation(entity.getTcmUri().toString(), entity.getLastModified(), entity.getTemplateUri().toString(), false);
74+
75+
// create a model with the returned markup
76+
final IModelFactory modelFactory = context.getModelFactory();
77+
final IModel model = modelFactory.parse(context.getTemplateData(), xpmMarkup);
78+
79+
// instruct the engine to replace this entire element with the specified model
80+
structureHandler.replaceWith(model, false);
81+
}
82+
}

0 commit comments

Comments
 (0)