Repository: incubator-freemarker Updated Branches: refs/heads/3 f48c81368 -> 0b02af638
Forward ported from 2.3-gae: Added ?absoulte_template_name. Necessary additions to the Environment and TemplateNameFormat. Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/0b02af63 Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/0b02af63 Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/0b02af63 Branch: refs/heads/3 Commit: 0b02af638982907ff8ca0fc3d0d77bd0c41c4535 Parents: f48c813 Author: ddekany <ddek...@apache.org> Authored: Sat Mar 10 21:00:09 2018 +0100 Committer: ddekany <ddek...@apache.org> Committed: Sat Mar 10 21:00:09 2018 +0100 ---------------------------------------------------------------------- .../core/AbsoluteTemplateNameBITest.java | 62 ++++++++++++++++++++ .../core/CustomTemplateResolverTest.java | 5 ++ .../TemplateNameFormatTest.java | 15 ++++- .../apache/freemarker/core/ASTExpBuiltIn.java | 3 +- .../freemarker/core/BuiltInsForStringsMisc.java | 52 ++++++++++++++++ .../org/apache/freemarker/core/Environment.java | 27 ++++++++- .../templateresolver/TemplateNameFormat.java | 5 ++ .../core/templateresolver/TemplateResolver.java | 12 +++- .../impl/DefaultTemplateNameFormat.java | 15 ++++- .../impl/DefaultTemplateResolver.java | 5 ++ .../examples/AbsoluteTemplateNameBIExample.java | 42 +++++++++++++ .../AbsoluteTemplateNameBIExample-foo.ftl | 19 ++++++ .../AbsoluteTemplateNameBIExample-lib.ftl | 38 ++++++++++++ .../dir/AbsoluteTemplateNameBIExample-foo.ftl | 19 ++++++ .../dir/AbsoluteTemplateNameBIExample-main.ftl | 24 ++++++++ .../AbsoluteTemplateNameBIExample-main.ftl.out | 26 ++++++++ .../apache/freemarker/test/TemplateTest.java | 2 +- 17 files changed, 362 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-core-test/src/test/java/org/apache/freemarker/core/AbsoluteTemplateNameBITest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/AbsoluteTemplateNameBITest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/AbsoluteTemplateNameBITest.java new file mode 100644 index 0000000..f674047 --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/AbsoluteTemplateNameBITest.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.freemarker.core; + +import java.io.IOException; + +import org.apache.freemarker.test.TemplateTest; +import org.junit.Test; + +public class AbsoluteTemplateNameBITest extends TemplateTest { + + @Test + public void basicsTest() throws Exception { + assertOutput("${'a/b'?absoluteTemplateName}", "/a/b"); + assertOutput("${'a/b/'?absoluteTemplateName}", "/a/b/"); + assertOutput("${'foo://a/b'?absoluteTemplateName}", "foo://a/b"); + assertOutput("${'/a/b'?absoluteTemplateName}", "/a/b"); + + assertOutputOfDirPerF("${'a/b'?absoluteTemplateName}", "/dir/a/b"); + assertOutputOfDirPerF("${'a/b/'?absoluteTemplateName}", "/dir/a/b/"); + assertOutputOfDirPerF("${'foo://a/b'?absoluteTemplateName}", "foo://a/b"); + assertOutputOfDirPerF("${'/a/b'?absoluteTemplateName}", "/a/b"); + + for (String baseName : new String[] { "dir/f", "/dir/f", "dir/", "/dir/" }) { + assertOutput("${'a/b'?absoluteTemplateName('" + baseName + "')}", "/dir/a/b"); + assertOutput("${'a/b/'?absoluteTemplateName('" + baseName + "')}", "/dir/a/b/"); + assertOutput("${'foo://a/b'?absoluteTemplateName('" + baseName + "')}", "foo://a/b"); + assertOutput("${'/a/b'?absoluteTemplateName('" + baseName + "')}", "/a/b"); + } + + assertOutput("${'a/b'?absoluteTemplateName('schema://dir/f')}", "schema://dir/a/b"); + assertOutput("${'a/b/'?absoluteTemplateName('schema://dir/f')}", "schema://dir/a/b/"); + assertOutput("${'foo://a/b'?absoluteTemplateName('schema://dir/f')}", "foo://a/b"); + assertOutput("${'/a/b'?absoluteTemplateName('schema://dir/f')}", "schema://a/b"); + } + + private void assertOutputOfDirPerF(String ftl, String expectedOut) + throws IOException, TemplateException { + addTemplate("dir/f", ftl); + Configuration cfg = getConfiguration(); + cfg.removeTemplateFromCache("dir/f", getConfiguration().getLocale(), null); + assertOutputForNamed("dir/f", expectedOut); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomTemplateResolverTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomTemplateResolverTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomTemplateResolverTest.java index 426a96b..d44e999 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomTemplateResolverTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomTemplateResolverTest.java @@ -351,6 +351,11 @@ public class CustomTemplateResolverTest { } @Override + public String rootBasedNameToAbsoluteName(String name) throws MalformedTemplateNameException { + return name.startsWith(":") ? name : ":" + name; + } + + @Override public boolean supportsTemplateLoaderSetting() { return TEMPLATE_LOADER_KEY.equals(supportedSetting); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java index 50a4120..edbe98d 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/TemplateNameFormatTest.java @@ -198,9 +198,22 @@ public class TemplateNameFormatTest { assertNormRBNameThrowsColonException("a/b:c/d", tnf); assertNormRBNameThrowsColonException("a/b:/..", tnf); } + + @Test + public void testRootBasedNameToAbsoluteName() throws MalformedTemplateNameException { + final TemplateNameFormat tnf = DefaultTemplateNameFormat.INSTANCE; + + assertEquals("/foo/bar", tnf.rootBasedNameToAbsoluteName("foo/bar")); + assertEquals("scheme://foo/bar", tnf.rootBasedNameToAbsoluteName("scheme://foo/bar")); + assertEquals("/foo/bar", tnf.rootBasedNameToAbsoluteName("/foo/bar")); + // Lenient handling of malformed rootBasedName: + assertEquals("/a/b://c/d", tnf.rootBasedNameToAbsoluteName("a/b://c/d")); + assertEquals("b:/c/d", tnf.rootBasedNameToAbsoluteName("b:/c/d")); + assertEquals("b:c/d", tnf.rootBasedNameToAbsoluteName("b:c/d")); + } @Test - public void assertBackslashNotAllowed() throws IOException { + public void testBackslashNotAllowed() throws IOException { Configuration cfg = new TestConfigurationBuilder() .templateLoader(new ByteArrayTemplateLoader()) .templateNameFormat(DefaultTemplateNameFormat.INSTANCE) http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpBuiltIn.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpBuiltIn.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpBuiltIn.java index 8151568..37163da 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpBuiltIn.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpBuiltIn.java @@ -75,13 +75,14 @@ abstract class ASTExpBuiltIn extends ASTExpression implements Cloneable { protected ASTExpression target; protected String key; - static final int NUMBER_OF_BIS = 262; + static final int NUMBER_OF_BIS = 263; static final HashMap<String, ASTExpBuiltIn> BUILT_INS_BY_NAME = new HashMap(NUMBER_OF_BIS * 3 / 2 + 1, 1f); static { // Note that you must update NUMBER_OF_BIS if you add new items here! putBI("abs", new absBI()); + putBI("absoluteTemplateName", new BuiltInsForStringsMisc.absolute_template_nameBI()); putBI("ancestors", new ancestorsBI()); putBI("api", new BuiltInsForMultipleTypes.apiBI()); putBI("boolean", new BuiltInsForStringsMisc.booleanBI()); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java index be95c94..9c401cd 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java @@ -34,6 +34,9 @@ import org.apache.freemarker.core.model.TemplateStringModel; import org.apache.freemarker.core.model.impl.BeanModel; import org.apache.freemarker.core.model.impl.DefaultObjectWrapper; import org.apache.freemarker.core.model.impl.SimpleNumber; +import org.apache.freemarker.core.model.impl.SimpleString; +import org.apache.freemarker.core.templateresolver.MalformedTemplateNameException; +import org.apache.freemarker.core.util.CallableUtils; class BuiltInsForStringsMisc { @@ -302,5 +305,54 @@ class BuiltInsForStringsMisc { } } + + static class absolute_template_nameBI extends BuiltInForString { + @Override + TemplateModel calculateResult(String s, Environment env) throws TemplateException { + return new AbsoluteTemplateNameResult(s, env); + } + + private class AbsoluteTemplateNameResult implements TemplateStringModel, TemplateFunctionModel { + private final String pathToResolve; + private final Environment env; + + public AbsoluteTemplateNameResult(String pathToResolve, Environment env) { + this.pathToResolve = pathToResolve; + this.env = env; + } + + @Override + public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env) + throws TemplateException { + return new SimpleString(resolvePath(CallableUtils.getStringArgument(args, 0, this))); + } + + @Override + public ArgumentArrayLayout getFunctionArgumentArrayLayout() { + return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER; + } + + @Override + public String getAsString() throws TemplateException { + return resolvePath(getTemplate().getLookupName()); + } + + /** + * @param basePath Maybe {@code null} + */ + private String resolvePath(String basePath) throws TemplateException { + try { + return env.rootBasedToAbsoluteTemplateName(env.toFullTemplateName(basePath, pathToResolve)); + } catch (MalformedTemplateNameException e) { + throw new TemplateException(e, + "Can't resolve ", new _DelayedJQuote(pathToResolve), + "to absolute template name using base ", new _DelayedJQuote(basePath), + "; see cause exception"); + } + } + + } + + } } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java b/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java index 9434990..4800a5b 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java @@ -2629,9 +2629,13 @@ public final class Environment extends MutableProcessingConfiguration<Environmen /** * Resolves a reference to a template (like the one used in {@code #include} or {@code #import}), assuming a base - * name. This gives a full (that is, absolute), even if non-normalized template name, that could be used for - * {@link Configuration#getTemplate(String)}. This is mostly used when a template refers to another template. - * + * name. This gives a root based, even if non-normalized and possibly non-absolute (but then relative to the root) + * template name, that could be used for {@link Configuration#getTemplate(String)}. This is mostly used when a + * template refers to another template. + * <p> + * If you need to guarantee that the result is also an absolute path, then apply + * {@link #rootBasedToAbsoluteTemplateName(String)} on it. + * * @param baseName * The name to which relative {@code targetName}-s are relative to. Maybe {@code null} (happens when * resolving names in nameless templates), which means that the base is the root "directory", and so @@ -2659,6 +2663,23 @@ public final class Environment extends MutableProcessingConfiguration<Environmen return configuration.getTemplateResolver().toRootBasedName(baseName, targetName); } + /** + * Converts a root based name (a name that's either relative to the root, or is absolute), which are typically used + * by the API (such as for {@link Configuration#getTemplate(String)}), to an absolute name, which can be safely + * passed to {@code <#include path>} and such, as it won't be misinterpreted to be relative to the directory of the + * template. For example, {@code "foo/bar.ftl"} is converted to {@code "/foo/bar.ftl"}, while {@code "/foo/bar"} or + * {@code "foo://bar/baz"} remains as is, as they are already absolute names (see {@link DefaultTemplateNameFormat} + * for more about the format of names). + * + * <p> + * You only need this if the template name will be passed to {@code <#include name>}, {@code <#import name>}, + * {@code .getOptionalTemplate(name)} or a similar construct in a template, otherwise using non-absolute root + * based names is fine. + */ + public String rootBasedToAbsoluteTemplateName(String rootBasedName) throws MalformedTemplateNameException { + return configuration.getTemplateResolver().rootBasedNameToAbsoluteName(rootBasedName); + } + void importMacros(Template template) { for (Object macro : template.getMacros().values()) { visitMacroOrFunctionDefinition((ASTDirMacroOrFunction) macro); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/TemplateNameFormat.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/TemplateNameFormat.java b/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/TemplateNameFormat.java index 57773f4..22b5c5e 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/TemplateNameFormat.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/TemplateNameFormat.java @@ -39,6 +39,11 @@ public abstract class TemplateNameFormat { */ public abstract String normalizeRootBasedName(String name) throws MalformedTemplateNameException; + /** + * Implements {@link TemplateResolver#rootBasedNameToAbsoluteName(String)}; see more there. + */ + public abstract String rootBasedNameToAbsoluteName(String name) throws MalformedTemplateNameException; + protected void checkNameHasNoNullCharacter(final String name) throws MalformedTemplateNameException { if (name.indexOf(0) != -1) { throw new MalformedTemplateNameException(name, http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java b/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java index debc42d..8a86b20 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java @@ -199,13 +199,23 @@ public abstract class TemplateResolver { * returned), for example, "/foo.ftl" becomes to "foo.ftl". * * @param name - * The root based name. Not {@code null}. + * The root based name (a name that's either absolute or relative to the root). Not {@code null}. * * @return The normalized root based name. Not {@code null}. */ public abstract String normalizeRootBasedName(String name) throws MalformedTemplateNameException; /** + * Converts a root based name to an absolute name, which is useful if you need to pass a name to something that + * doesn't necessary resolve relative paths relative to the root (like the {@code #include} directive). + * + * @param name + * The root based name (a name that's either absolute or relative to the root). Not {@code null}. + */ + // TODO [FM3] This is the kind of complication why normalized template names should just be absolute paths. + public abstract String rootBasedNameToAbsoluteName(String name) throws MalformedTemplateNameException; + + /** * Tells whether the {@link TemplateResolver} implementation depends on the * {@link Configuration#getTemplateLoader() templateLoader} {@link Configuration}. If it returns {@code false} * then this {@link TemplateResolver} must not call {@link TemplateResolverDependencies#getTemplateLoader()}, or http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateNameFormat.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateNameFormat.java b/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateNameFormat.java index ff2049d..5d07159 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateNameFormat.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateNameFormat.java @@ -39,8 +39,8 @@ import org.apache.freemarker.core.util._StringUtils; * "example.com/foo.ftl"). The scheme name before the {@code ":"} (colon) can't contain {@code "/"}, and {@code ":"} * can only be used for denoting the scheme, or else {@link MalformedTemplateNameException} is thrown. * The scheme part can be separated either with {@code "://"} or just with {@code ":"} from the path, hence, {@code - * myschme:/x} is normalized to {@code myschme:x}, while {@code myschme:///x} is normalized to {@code myschme://x}, - * but {@code myschme://x} or {@code myschme:/x} aren't changed by normalization. It's up the {@link TemplateLoader} + * myscheme:/x} is normalized to {@code myscheme:x}, while {@code myscheme:///x} is normalized to {@code myscheme://x}, + * but {@code myscheme://x} or {@code myscheme:/x} aren't changed by normalization. It's up the {@link TemplateLoader} * (to which the normalized names are passed) to decide which of these scheme separation conventions are accepted. * <p> * Template names might end with {@code /}, like {@code "foo/"}, and the presence or lack of the terminating {@code @@ -131,6 +131,17 @@ public final class DefaultTemplateNameFormat extends TemplateNameFormat { return scheme == null ? path : scheme + path; } + + @Override + public String rootBasedNameToAbsoluteName(String name) throws MalformedTemplateNameException { + if (findSchemeSectionEnd(name) != 0) { + return name; + } + if (!name.startsWith("/")) { + return "/" + name; + } + return name; + } private int findSchemeSectionEnd(String name) { int schemeColonIdx = name.indexOf(":"); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java b/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java index aaf09bc..5f277d3 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java @@ -189,6 +189,11 @@ public class DefaultTemplateResolver extends TemplateResolver { } @Override + public String rootBasedNameToAbsoluteName(String name) throws MalformedTemplateNameException { + return templateNameFormat.rootBasedNameToAbsoluteName(name); + } + + @Override public boolean supportsTemplateLoaderSetting() { return true; } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-manual/src/test/java/org/apache/freemarker/manual/examples/AbsoluteTemplateNameBIExample.java ---------------------------------------------------------------------- diff --git a/freemarker-manual/src/test/java/org/apache/freemarker/manual/examples/AbsoluteTemplateNameBIExample.java b/freemarker-manual/src/test/java/org/apache/freemarker/manual/examples/AbsoluteTemplateNameBIExample.java new file mode 100644 index 0000000..2a1dcc3 --- /dev/null +++ b/freemarker-manual/src/test/java/org/apache/freemarker/manual/examples/AbsoluteTemplateNameBIExample.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.freemarker.manual.examples; + +import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.templateresolver.impl.ClassTemplateLoader; +import org.apache.freemarker.test.TemplateTest; +import org.apache.freemarker.test.TestConfigurationBuilder; +import org.junit.Test; + +public class AbsoluteTemplateNameBIExample extends TemplateTest { + + @Override + protected Configuration createDefaultConfiguration() throws Exception { + return new TestConfigurationBuilder() + .templateLoader(new ClassTemplateLoader(AbsoluteTemplateNameBIExample.class, "")) + .build(); + } + + @Test + public void test() throws Exception { + assertOutputForNamed("dir/AbsoluteTemplateNameBIExample-main.ftl"); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/AbsoluteTemplateNameBIExample-foo.ftl ---------------------------------------------------------------------- diff --git a/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/AbsoluteTemplateNameBIExample-foo.ftl b/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/AbsoluteTemplateNameBIExample-foo.ftl new file mode 100644 index 0000000..b588cb3 --- /dev/null +++ b/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/AbsoluteTemplateNameBIExample-foo.ftl @@ -0,0 +1,19 @@ +<#-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +/foo http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/AbsoluteTemplateNameBIExample-lib.ftl ---------------------------------------------------------------------- diff --git a/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/AbsoluteTemplateNameBIExample-lib.ftl b/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/AbsoluteTemplateNameBIExample-lib.ftl new file mode 100644 index 0000000..13d724b --- /dev/null +++ b/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/AbsoluteTemplateNameBIExample-lib.ftl @@ -0,0 +1,38 @@ +<#-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<#-- + <@smileyInclude name /> behaves like <#include name>, but prints a "(:" before the + template, or prints "):" instead if the template is missing. + + Note that just like with #include, if name is relative, it's resolved based on the + directory of the caller template, not of the template that defines this macro. As + .get_optional_template resolves relative names based on the current template, we + had to convert the name to an absolute name based on the caller template before + passing it to it. +--> +<#macro smileyInclude name{positional}> + <#local t = .getOptionalTemplate( + name?absoluteTemplateName(.callerTemplateName))> + <#if t.exists> + (: + <@t.include /> + <#else> + ): + </#if> +</#macro> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/dir/AbsoluteTemplateNameBIExample-foo.ftl ---------------------------------------------------------------------- diff --git a/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/dir/AbsoluteTemplateNameBIExample-foo.ftl b/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/dir/AbsoluteTemplateNameBIExample-foo.ftl new file mode 100644 index 0000000..e68993c --- /dev/null +++ b/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/dir/AbsoluteTemplateNameBIExample-foo.ftl @@ -0,0 +1,19 @@ +<#-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +/dir/foo http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/dir/AbsoluteTemplateNameBIExample-main.ftl ---------------------------------------------------------------------- diff --git a/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/dir/AbsoluteTemplateNameBIExample-main.ftl b/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/dir/AbsoluteTemplateNameBIExample-main.ftl new file mode 100644 index 0000000..311bb9a --- /dev/null +++ b/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/dir/AbsoluteTemplateNameBIExample-main.ftl @@ -0,0 +1,24 @@ +<#-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<#import '/AbsoluteTemplateNameBIExample-lib.ftl' as lib> + +<@lib.smileyInclude 'AbsoluteTemplateNameBIExample-foo.ftl' /> +<@lib.smileyInclude '../AbsoluteTemplateNameBIExample-foo.ftl' /> +<@lib.smileyInclude '/AbsoluteTemplateNameBIExample-foo.ftl' /> +<@lib.smileyInclude 'AbsoluteTemplateNameBIExample-missing.ftl' /> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/dir/AbsoluteTemplateNameBIExample-main.ftl.out ---------------------------------------------------------------------- diff --git a/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/dir/AbsoluteTemplateNameBIExample-main.ftl.out b/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/dir/AbsoluteTemplateNameBIExample-main.ftl.out new file mode 100644 index 0000000..9e9f175 --- /dev/null +++ b/freemarker-manual/src/test/resources/org/apache/freemarker/manual/examples/dir/AbsoluteTemplateNameBIExample-main.ftl.out @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + (: +/dir/foo + (: +/foo + (: +/foo + ): http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0b02af63/freemarker-test-utils/src/main/java/org/apache/freemarker/test/TemplateTest.java ---------------------------------------------------------------------- diff --git a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/TemplateTest.java b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/TemplateTest.java index 00d9306..a7d31f4 100644 --- a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/TemplateTest.java +++ b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/TemplateTest.java @@ -242,7 +242,7 @@ public abstract class TemplateTest { throw new IllegalStateException("The templateLoader was null in the configuration"); } else { throw new IllegalStateException( - "The template loader was already set to a non-ByteArrayTemplateLoader non-MultiTemplateLoader: " + "The template loader was set to a non-ByteArrayTemplateLoader non-MultiTemplateLoader: " + tl); } }