Adjustments for Freemarker, especially template laoding

Jens Pelzetter 2019-12-20 17:38:39 +01:00
parent d55f96ae39
commit 2ef2de7d50
9 changed files with 191 additions and 21 deletions

View File

@ -38,6 +38,11 @@
<artifactId>ccm-theme-foundry</artifactId> <artifactId>ccm-theme-foundry</artifactId>
<version>${project.parent.version}</version> <version>${project.parent.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.librecms</groupId>
<artifactId>ccm-theme-ftllibs-devel</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency> <dependency>
<groupId>net.sf.saxon</groupId> <groupId>net.sf.saxon</groupId>

View File

@ -86,23 +86,25 @@
Get the URL of the root category of the navigation with the provided id. Get the URL of the root category of the navigation with the provided id.
@param navigationId The ID of the navigation system to use. @param navigationId The ID of the navigation system to use.
@param containerId Container of the category menu
@return The URL of the root category of the navigation system with the @return The URL of the root category of the navigation system with the
provided ID. provided ID.
--> -->
<#function getNavigationRootUrl navigationId="categoryMenu"> <#function getNavigationRootUrl navigationId="categoryMenu" containerId="container">
<#return [navigationId].url> <#return [container][navigationId].url>
</#function> </#function>
<#--doc <#--doc
Get title of the navigation with the provided id. Get title of the navigation with the provided id.
@param navigationId The ID of the navigation system to use. @param navigationId The ID of the navigation system to use.
@param containerId Container of the category menu
@return The title of the navigation. @return The title of the navigation.
--> -->
<#function getNavigationTitle navigationId="categoryMenu"> <#function getNavigationTitle navigationId="categoryMenu" containerId="container">
<#return [navigationId].categoryTitle> <#return [containerId][navigationId].categoryTitle>
</#function> </#function>
<#--doc <#--doc
@ -110,11 +112,12 @@
provided ID. If no id is provided 'categoryNav' is used. provided ID. If no id is provided 'categoryNav' is used.
@param hierarchyId The ID of the category hierachy to use. @param hierarchyId The ID of the category hierachy to use.
@param containerId Container of the category hierarchy
@return The first level of categories in the hierarchy. @return The first level of categories in the hierarchy.
--> -->
<#function getCategoryHierarchy hierarchyId="categoryNav"> <#function getCategoryHierarchy hierarchyId="categoryNav" containerId="container">
<#return [hierarchyId].subCategories> <#return [containerId][hierarchyId].subCategories>
</#function> </#function>
<#--doc <#--doc
@ -129,22 +132,24 @@
</#function> </#function>
<#--doc <#--doc
Gets the subcategories of the category with the provided id. Not longer supported
@param categoryId The ID of the category to use. @param categoryId The ID of the category to use.
@return The sub categories of the category with the provided ID. @return Nothing
--> -->
<#function getSubCategoriesOfCategoryWithId categoryId> <#function getSubCategoriesOfCategoryWithId categoryId>
<#return model["/bebop:page/nav:categoryMenu//nav:category[@id=${categoryId}]/nav:category"]> <#return "">
</#function> </#function>
<#--doc <#--doc
Gets the greeting/index item of the current navigation page. The returned Gets the greeting/index item of the current navigation page. The returned
model can be processed with usual functions for processing content items. model can be processed with usual functions for processing content items.
@param containerId Container of the index item.
@return The model of the index item. @return The model of the index item.
--> -->
<#function getGreetingItem path="greetingItem"> <#function getGreetingItem containerId="container">
<#return eval(path)> <#return [container].greetingItem>
</#function> </#function>

View File

@ -18,8 +18,10 @@
*/ */
package org.libreccm.theming.freemarker; package org.libreccm.theming.freemarker;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader; import freemarker.cache.TemplateLoader;
import freemarker.cache.TemplateLookupStrategy; import freemarker.cache.WebappTemplateLoader;
import freemarker.template.Configuration; import freemarker.template.Configuration;
import freemarker.template.TemplateExceptionHandler; import freemarker.template.TemplateExceptionHandler;
import org.libreccm.core.UnexpectedErrorException; import org.libreccm.core.UnexpectedErrorException;
@ -32,9 +34,11 @@ import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject; import javax.inject.Inject;
import javax.servlet.ServletContext;
/** /**
* *
@ -43,6 +47,9 @@ import javax.inject.Inject;
@ApplicationScoped @ApplicationScoped
class FreemarkerConfigurationProvider { class FreemarkerConfigurationProvider {
@Inject
private ServletContext servletContext;
@Inject @Inject
private Themes themes; private Themes themes;
@ -64,7 +71,18 @@ class FreemarkerConfigurationProvider {
configuration.setLogTemplateExceptions(false); configuration.setLogTemplateExceptions(false);
configuration.setWrapUncheckedExceptions(false); configuration.setWrapUncheckedExceptions(false);
configuration.setLocalizedLookup(false); configuration.setLocalizedLookup(false);
configuration.setTemplateLoader(new CcmTemplateLoader(forTheme));
configuration.setTemplateLoader(
new MultiTemplateLoader(new TemplateLoader[]{
// For for files from themes
new CcmTemplateLoader(forTheme),
// Loader for MacroLibs provided by CCM modules
new WebappTemplateLoader(
servletContext, "/themes/freemarker"
),
new ClassTemplateLoader(getClass(), "/themes/freemarker")
})
);
configurations.put(forTheme, configuration); configurations.put(forTheme, configuration);
@ -83,13 +101,12 @@ class FreemarkerConfigurationProvider {
@Override @Override
public Object findTemplateSource(final String name) throws IOException { public Object findTemplateSource(final String name) throws IOException {
return themes final Optional<InputStream> source = themes.getFileFromTheme(fromTheme, name);
.getFileFromTheme(fromTheme, name) if (source.isPresent()) {
.orElseThrow(() -> new UnexpectedErrorException(String return source.get();
.format("Failed to open Freemarker Template \"%s\" from " } else {
+ "theme \"%s\".", return null;
name, }
fromTheme.getName())));
} }
@Override @Override

View File

@ -72,22 +72,47 @@
Retrieves the link to the login form. Only available if the current user Retrieves the link to the login form. Only available if the current user
is not logged in. is not logged in.
@depcrecated Use getLoginUrl() instead
@return The link to the login form. @return The link to the login form.
--> -->
<#function getLoginLink> <#function getLoginLink>
<#return currentUser.loginLink> <#return getLoginUrl()>
</#function>
<#--doc
Retrieves the URL of the login form. Only available if the current user
is not logged in.
@return The link to the login form.
-->
<#function getLoginUrl>
<#return currentUser.loginUrl>
</#function> </#function>
<#--doc <#--doc
Retrieves the link for logging out. Only available if the current user Retrieves the link for logging out. Only available if the current user
is logged in. is logged in.
@depcreated Use getLogoutUrl instead
@return The link for logging out. @return The link for logging out.
--> -->
<#function getLogoutLink> <#function getLogoutLink>
<#return getLogoutUrl()>
</#function>
<#--doc
Retrieves the URL for logging out. Only available if the current user
is logged in.
@return The link for logging out.
-->
<#function getLogoutUrl>
<#return currentUser.logoutUrl> <#return currentUser.logoutUrl>
</#function> </#function>
<#--doc <#--doc
Retrieves the screen name (user name) of the current user. Only available Retrieves the screen name (user name) of the current user. Only available
if the current user is logged in. if the current user is logged in.

View File

@ -0,0 +1 @@
target

View File

@ -0,0 +1,52 @@
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>libreccm-parent</artifactId>
<groupId>org.libreccm</groupId>
<version>7.0.0-SNAPSHOT</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'Z</maven.build.timestamp.format>
</properties>
<groupId>org.librecms</groupId>
<artifactId>ccm-theme-ftllibs-devel</artifactId>
<name>FTL Libs Devel theme</name>
<licenses>
<license>
<name>Lesser GPL 2.1</name>
<url>http://www.gnu.org/licenses/old-licenses/lgpl-2.1</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>org.libreccm</groupId>
<artifactId>ccm-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.librecms</groupId>
<artifactId>ccm-cms</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
<build>
</build>
<reporting>
</reporting>
</project>

View File

@ -0,0 +1,58 @@
<#import "/ccm-core/user-banner.ftl" as UserBanner>
<!DOCTYPE html>
<html>
<head>
<title>FTL Libs Devel</title>
</head>
<body>
<h1>FTL Libs Test</h1>
<h2>user-banner.ftl</h2>
<dl>
<div>
<dt>UserBanner.getGreeting</dt>
<dd>${UserBanner.getGreeting()}</dd>
</div>
<div>
<dt>UserBanner.isLoggedIn</dt>
<dd>${UserBanner.isLoggedIn()?c}</dd>
</div>
<div>
<dt>UserBanner.isAuthenticated</dt>
<dd>${UserBanner.isAuthenticated()?c}</dd>
</div>
<div>
<dt>UserBanner.isNotLoggedIn</dt>
<dd>${UserBanner.isNotLoggedIn()?c}</dd>
</div>
<div>
<dt>UserBanner.isNotAuthenticated</dt>
<dd>${UserBanner.isNotAuthenticated()?c}</dd>
</div>
<div>
<dt>UserBanner.getChangePasswordUrl</dt>
<dd>${UserBanner.getChangePasswordUrl()}</dd>
</div>
<div>
<dt>UserBanner.getLoginLink</dt>
<dd>${UserBanner.getLoginLink()}</dd>
</div>
<div>
<dt>UserBanner.getLogoutLink</dt>
<dd>${UserBanner.getLogoutLink()}</dd>
</div>
<div>
<dt>UserBanner.getScreenName</dt>
<dd>${UserBanner.getScreenName()}</dd>
</div>
<div>
<dt>UserBanner.getUserGivenName</dt>
<dd>${UserBanner.getUserGivenName()}</dd>
</div>
<div>
<dt>UserBanner.getUserFamilyName</dt>
<dd>${UserBanner.getUserFamilyName()}</dd>
</div>
</dl>
</body>
</html>

View File

@ -0,0 +1,6 @@
{
"name": "ftllibs-devel",
"type": "freemarker",
"default-template": "page.html.ftl"
}

View File

@ -79,6 +79,7 @@
<!-- Modules providing themes --> <!-- Modules providing themes -->
<module>ccm-theme-foundry</module> <module>ccm-theme-foundry</module>
<module>ccm-theme-ftllibs-devel</module>
<!-- Bundle modules --> <!-- Bundle modules -->
<module>ccm-bundle-devel</module> <module>ccm-bundle-devel</module>