[24/24] incubator-freemarker git commit: Merge remote-tracking branch 'origin/2.3-gae' into 2.3
Merge remote-tracking branch 'origin/2.3-gae' into 2.3 Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/44201a6d Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/44201a6d Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/44201a6d Branch: refs/heads/2.3 Commit: 44201a6d1701ac66c2dfec8eb98e3f374a47496f Parents: dd7a2aa 4b989f8 Author: ddekany Authored: Tue Dec 6 23:27:36 2016 +0100 Committer: ddekany Committed: Tue Dec 6 23:27:36 2016 +0100 -- .../freemarker/core/AddConcatExpression.java| 58 ++- .../freemarker/core/BuiltInsForSequences.java | 33 +- src/main/java/freemarker/core/EvalUtil.java | 26 +- src/main/java/freemarker/core/NewBI.java| 8 +- .../debug/impl/RmiDebuggedEnvironmentImpl.java | 2 +- .../freemarker/ext/beans/ArgumentTypes.java | 75 ++- .../java/freemarker/ext/beans/BeanModel.java| 94 ++-- .../java/freemarker/ext/beans/BeansWrapper.java | 89 ++-- .../ext/beans/BeansWrapperBuilder.java | 17 +- .../freemarker/ext/beans/ClassIntrospector.java | 157 --- .../ext/beans/MethodAppearanceFineTuner.java| 3 +- .../java/freemarker/ext/beans/_BeansAPI.java| 70 +-- .../freemarker/ext/util/IdentityHashMap.java| 9 +- .../java/freemarker/ext/util/ModelCache.java| 19 +- .../template/AdapterTemplateModel.java | 2 +- .../java/freemarker/template/Configuration.java | 3 + .../template/DefaultObjectWrapper.java | 23 +- .../template/DefaultObjectWrapperBuilder.java | 18 +- .../template/ObjectWrapperAndUnwrapper.java | 2 +- .../freemarker/template/SimpleSequence.java | 2 +- .../template/TemplateCollectionModelEx.java | 2 +- .../java/freemarker/template/_TemplateAPI.java | 3 +- .../resources/freemarker/version.properties | 8 +- src/manual/en_US/book.xml | 459 +++ src/manual/en_US/docgen.cjson | 2 +- src/test/java/freemarker/core/ASTTest.java | 2 +- .../ext/beans/BeansAPINewInstanceTest.java | 6 +- .../ext/beans/BeansWrapperSingletonsTest.java | 3 +- .../template/DefaultObjectWrapperTest.java | 1 + .../template/TemplateLanguageVersionTest.java | 3 +- .../CopyrightCommentRemoverTemplateLoader.java | 1 + src/test/java/freemarker/test/TemplateTest.java | 1 + src/test/java/freemarker/test/TestUtil.java | 115 - .../freemarker/test/servlet/WebAppTestCase.java | 2 +- .../test/templatesuite/TemplateTestCase.java| 46 +- .../test/templatesuite/TemplateTestSuite.java | 2 +- .../models/OverloadedMethods2.java | 144 +++--- .../freemarker/test/utility/FileTestCase.java | 1 - .../java/freemarker/test/utility/Helpers.java | 164 --- .../java/freemarker/test/utility/TestUtil.java | 266 +++ .../expected/sequence-builtins.txt | 7 + .../templates/sequence-builtins.ftl | 8 +- 42 files changed, 1078 insertions(+), 878 deletions(-) -- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/44201a6d/src/main/resources/freemarker/version.properties --
[03/24] incubator-freemarker git commit: grammar fix
grammar fix Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/f83161be Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/f83161be Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/f83161be Branch: refs/heads/2.3 Commit: f83161be9472e493fd21dd6a0c1dd458cf111cab Parents: 6032411 Author: ratherblue Authored: Mon Jul 25 22:49:47 2016 -0700 Committer: ratherblue Committed: Mon Jul 25 22:49:47 2016 -0700 -- src/manual/en_US/book.xml | 216 - 1 file changed, 108 insertions(+), 108 deletions(-) -- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f83161be/src/manual/en_US/book.xml -- diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml index 14732b5..b46e1ea 100644 --- a/src/manual/en_US/book.xml +++ b/src/manual/en_US/book.xml @@ -7,9 +7,9 @@ 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 @@ -44,7 +44,7 @@ Templates are written in the FreeMarker Template Language (FTL). It's a simple, specialized language, not a full-blown -programming language like PHP. You meant to prepare the data to display in +programming language like PHP. You are meant to prepare the data to display in a real programming language, like issue database queries and do business calculations, and then the template displays that already prepared data. In the template you are focusing on how to present the data, and outside @@ -220,21 +220,21 @@ +- animals | | | +- mouse - | | | + | | | | | +- size = "small" - | | | + | | | | | +- price = 50 | | | +- elephant - | | | + | | | | | +- size = "large" - | | | + | | | | | +- price = 5000 | | | +- python - | | + | | | +- size = "medium" - | | + | | | +- price = 4999 | +- message = "It is a test" @@ -5867,7 +5867,7 @@ To prove that "s" didn't contain the value in escaped form: [BR] [BR] [BR] - [BR] + [BR]Julia[BR] [BR] @@ -6508,10 +6508,10 @@ import java.io.*; public class Test { public static void main(String[] args) throws Exception { - -/* */ -/* You should do this ONLY ONCE in the whole application life-cycle: */ - + +/* */ +/* You should do this ONLY ONCE in the whole application life-cycle: */ + /* Create and adjust the configuration singleton */ Configuration cfg = new Configuration(Configuration.VERSION_2_3_25); cfg.setDirectoryForTemplateLoading(new File("/where/you/store/templates")); @@ -6519,8 +6519,8 @@ public class Test { cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); cfg.setLogTemplateExceptions(false); -/* */ -/* You usually do these for MULTIPLE TIMES in the application life-cycle: */ +/* */ +/* You usually do these for MULTIPLE TIMES in the application life-cycle: */ /* Create a data-model */ Map root = new HashMap(); @@ -6966,7 +6966,7 @@ public class Product { the second string doesn't contains the first. public class IndexOfMethod implements TemplateMethodModel { - + public TemplateModel exec(List args) throws TemplateModelException { if (args.size() != 2) { throw new TemplateModelException("Wrong arguments"); @@ -7060,16 +7060,16 @@ import freemarker.template.TemplateModelException; /** * FreeMarker user-defined directive that progressively transforms * the output of its nested content to upper-case. - * - * + * + * * Directive info
- * + * *Directive parameters: None *
Loop variables: None *
Directive nested content: Yes */ public class UpperDirective implements TemplateDirectiveModel { - + public void execute(Environment env, Map params, TemplateMo
[20/24] incubator-freemarker git commit: Utilizing Java 5 generics at some places where it doesn't break backward compatibility. Some code cleanup.
Utilizing Java 5 generics at some places where it doesn't break backward compatibility. Some code cleanup. Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/c253e33d Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/c253e33d Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/c253e33d Branch: refs/heads/2.3 Commit: c253e33d22db9365e3c134f59110bf20c0872670 Parents: 277956d Author: ddekany Authored: Sun Dec 4 17:55:56 2016 +0100 Committer: ddekany Committed: Sun Dec 4 21:31:17 2016 +0100 -- .../java/freemarker/ext/beans/BeanModel.java| 88 +--- .../freemarker/ext/beans/ClassIntrospector.java | 1 - .../template/AdapterTemplateModel.java | 2 +- .../freemarker/template/SimpleSequence.java | 2 +- 4 files changed, 42 insertions(+), 51 deletions(-) -- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/c253e33d/src/main/java/freemarker/ext/beans/BeanModel.java -- diff --git a/src/main/java/freemarker/ext/beans/BeanModel.java b/src/main/java/freemarker/ext/beans/BeanModel.java index ba3dc62..24f8590 100644 --- a/src/main/java/freemarker/ext/beans/BeanModel.java +++ b/src/main/java/freemarker/ext/beans/BeanModel.java @@ -80,10 +80,9 @@ implements } }; -// Cached template models that implement member properties and methods for this -// instance. Keys are FeatureDescriptor instances (from classCache values), -// values are either ReflectionMethodModels/ReflectionScalarModels -private HashMap memberMap; +// I've tried to use a volatile ConcurrentHashMap field instead of HashMap + synchronized(this), but oddly it was +// a bit slower, at least on Java 8 u66. +private HashMap memberCache; /** * Creates a new model that wraps the specified object. Note that there are @@ -192,7 +191,7 @@ implements } } -private void logNoSuchKey(String key, Map keyMap) { +private void logNoSuchKey(String key, Map keyMap) { LOG.debug("Key " + StringUtil.jQuoteNoXSS(key) + " was not found on instance of " + object.getClass().getName() + ". Introspection information for " + "the class is: " + keyMap); @@ -207,71 +206,64 @@ implements } private TemplateModel invokeThroughDescriptor(Object desc, Map classInfo) -throws IllegalAccessException, -InvocationTargetException, -TemplateModelException { -// See if this particular instance has a cached implementation -// for the requested feature descriptor -TemplateModel member; +throws IllegalAccessException, InvocationTargetException, TemplateModelException { +// See if this particular instance has a cached implementation for the requested feature descriptor +TemplateModel cachedModel; synchronized (this) { -if (memberMap != null) { -member = (TemplateModel) memberMap.get(desc); -} else { -member = null; -} +cachedModel = memberCache != null ? memberCache.get(desc) : null; } -if (member != null) -return member; +if (cachedModel != null) { +return cachedModel; +} -TemplateModel retval = UNKNOWN; +TemplateModel resultModel = UNKNOWN; if (desc instanceof IndexedPropertyDescriptor) { -Method readMethod = -((IndexedPropertyDescriptor) desc).getIndexedReadMethod(); -retval = member = +Method readMethod = ((IndexedPropertyDescriptor) desc).getIndexedReadMethod(); +resultModel = cachedModel = new SimpleMethodModel(object, readMethod, ClassIntrospector.getArgTypes(classInfo, readMethod), wrapper); } else if (desc instanceof PropertyDescriptor) { PropertyDescriptor pd = (PropertyDescriptor) desc; -retval = wrapper.invokeMethod(object, pd.getReadMethod(), null); -// (member == null) condition remains, as we don't cache these +resultModel = wrapper.invokeMethod(object, pd.getReadMethod(), null); +// cachedModel remains null, as we don't cache these } else if (desc instanceof Field) { -retval = wrapper.wrap(((Field) desc).get(object)); -// (member == null) condition remains, as we don't cache these +resultModel = wrapper.wrap(((Field) desc).get(object)); +// cachedModel remains null, as we don't cache these } else if (desc instanceof Method) { Method method = (Metho
[21/24] incubator-freemarker git commit: Utilizing Java 5 generics at some places where it doesn't break backward compatibility.
Utilizing Java 5 generics at some places where it doesn't break backward compatibility. Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/ed403c83 Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/ed403c83 Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/ed403c83 Branch: refs/heads/2.3 Commit: ed403c83cb0acd0b221ecc6a1daa1ccd3597c291 Parents: c253e33 Author: ddekany Authored: Sun Dec 4 21:48:42 2016 +0100 Committer: ddekany Committed: Sun Dec 4 21:57:29 2016 +0100 -- .../test/templatesuite/TemplateTestCase.java| 45 +++- .../test/templatesuite/TemplateTestSuite.java | 2 +- 2 files changed, 25 insertions(+), 22 deletions(-) -- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ed403c83/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java -- diff --git a/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java b/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java index 9e9b4ff..dfac6b3 100644 --- a/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java +++ b/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java @@ -52,6 +52,7 @@ import com.google.common.collect.ImmutableSet; import freemarker.cache.FileTemplateLoader; import freemarker.core.ASTPrinter; import freemarker.ext.beans.BeansWrapper; +import freemarker.ext.beans.BeansWrapperBuilder; import freemarker.ext.beans.BooleanModel; import freemarker.ext.beans.Java7MembersOnlyBeansWrapper; import freemarker.ext.beans.ResourceBundleModel; @@ -117,7 +118,7 @@ public class TemplateTestCase extends FileTestCase { private final boolean noOutput; private final Configuration conf; -private final HashMap dataModel = new HashMap(); +private final HashMap dataModel = new HashMap(); public TemplateTestCase(String testName, String simpleTestName, String templateName, String expectedFileName, boolean noOutput, Version incompatibleImprovements) { @@ -181,6 +182,8 @@ public class TemplateTestCase extends FileTestCase { conf.setTemplateLoader(new CopyrightCommentRemoverTemplateLoader( new FileTemplateLoader(new File(getTestClassDirectory(), "templates"; +BeansWrapper beansWrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_0).build(); + dataModel.put(ASSERT_VAR_NAME, AssertDirective.INSTANCE); dataModel.put(ASSERT_EQUALS_VAR_NAME, AssertEqualsDirective.INSTANCE); dataModel.put(ASSERT_FAILS_VAR_NAME, AssertFailsDirective.INSTANCE); @@ -239,7 +242,7 @@ public class TemplateTestCase extends FileTestCase { } else if (simpleTestName.equals("beans")) { dataModel.put("array", new String[] { "array-0", "array-1"}); dataModel.put("list", Arrays.asList(new String[] { "list-0", "list-1", "list-2"})); -Map tmap = new HashMap(); +Map tmap = new HashMap(); tmap.put("key", "value"); Object objKey = new Object(); tmap.put(objKey, "objValue"); @@ -248,8 +251,8 @@ public class TemplateTestCase extends FileTestCase { dataModel.put("obj", new freemarker.test.templatesuite.models.BeanTestClass()); dataModel.put("resourceBundle", new ResourceBundleModel(ResourceBundle.getBundle("freemarker.test.templatesuite.models.BeansTestResources"), BeansWrapper.getDefaultInstance())); dataModel.put("date", new GregorianCalendar(1974, 10, 14).getTime()); -dataModel.put("statics", BeansWrapper.getDefaultInstance().getStaticModels()); -dataModel.put("enums", BeansWrapper.getDefaultInstance().getEnumModels()); +dataModel.put("statics", beansWrapper.getStaticModels()); +dataModel.put("enums", beansWrapper.getEnumModels()); } else if (simpleTestName.equals("boolean")) { dataModel.put( "boolean1", TemplateBooleanModel.FALSE); dataModel.put( "boolean2", TemplateBooleanModel.TRUE); @@ -290,23 +293,23 @@ public class TemplateTestCase extends FileTestCase { dataModel.put("bigDecimal", new SimpleNumber(java.math.BigDecimal.valueOf(1))); dataModel.put("bigDecimal2", new SimpleNumber(java.math.BigDecimal.valueOf(1, 16))); } else if (simpleTestName.equals("simplehash-char-key")) { -HashMap mStringC = new HashMap(); +HashMap mStringC = new HashMap(); mStringC.put("c", "string"); dataModel.put("mStringC", mStringC); -HashMap mStringCNull = new HashMap(); +HashMap mStringCNull = new Hash
[16/24] incubator-freemarker git commit: (JavaDoc typo)
(JavaDoc typo) Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/ad4d7268 Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/ad4d7268 Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/ad4d7268 Branch: refs/heads/2.3 Commit: ad4d7268e727aed954b8af7c7365aca013e0b264 Parents: d70e8da Author: ddekany Authored: Sat Dec 3 15:14:42 2016 +0100 Committer: ddekany Committed: Sat Dec 3 15:14:42 2016 +0100 -- src/main/java/freemarker/template/TemplateCollectionModelEx.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ad4d7268/src/main/java/freemarker/template/TemplateCollectionModelEx.java -- diff --git a/src/main/java/freemarker/template/TemplateCollectionModelEx.java b/src/main/java/freemarker/template/TemplateCollectionModelEx.java index 604eebc..8101f2b 100644 --- a/src/main/java/freemarker/template/TemplateCollectionModelEx.java +++ b/src/main/java/freemarker/template/TemplateCollectionModelEx.java @@ -47,7 +47,7 @@ public interface TemplateCollectionModelEx extends TemplateCollectionModel { boolean isEmpty() throws TemplateModelException; /** - * Tells if a given value occurs in the collection, accodring the rules of the wrapped collection. As of 2.3.22, + * Tells if a given value occurs in the collection, according the rules of the wrapped collection. As of 2.3.22, * this interface is not yet utilized by FTL, and certainly it won't be earlier than 2.4.0. The usefulness of this * method is questionable, as the equality rules of Java differs from that of FTL, hence, calling this won't be * equivalent with {@code ?seq_contains(e)}.
[22/24] incubator-freemarker git commit: FREEMARKER-42: ?first now works with FTL collections (things that can be listed but doesn't support getting items by index), not only with sequences. The pract
FREEMARKER-42: ?first now works with FTL collections (things that can be listed but doesn't support getting items by index), not only with sequences. The practical importance of this is that ?first now always works on Java Set-s (which is useful for Set-s with well defined ordering), while earlier it has failed depending on the object_wrapper configuration setting. Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/496ddfbc Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/496ddfbc Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/496ddfbc Branch: refs/heads/2.3 Commit: 496ddfbc08c6d3242ab5c31694db152d9c1e4c58 Parents: ed403c8 Author: ddekany Authored: Mon Dec 5 00:49:38 2016 +0100 Committer: ddekany Committed: Mon Dec 5 00:49:38 2016 +0100 -- .../freemarker/core/BuiltInsForSequences.java | 33 ++-- src/manual/en_US/book.xml | 57 ++-- .../test/templatesuite/TemplateTestCase.java| 1 + .../expected/sequence-builtins.txt | 7 +++ .../templates/sequence-builtins.ftl | 8 ++- 5 files changed, 98 insertions(+), 8 deletions(-) -- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/496ddfbc/src/main/java/freemarker/core/BuiltInsForSequences.java -- diff --git a/src/main/java/freemarker/core/BuiltInsForSequences.java b/src/main/java/freemarker/core/BuiltInsForSequences.java index a12d274..d56a95f 100644 --- a/src/main/java/freemarker/core/BuiltInsForSequences.java +++ b/src/main/java/freemarker/core/BuiltInsForSequences.java @@ -138,15 +138,40 @@ class BuiltInsForSequences { } -static class firstBI extends BuiltInForSequence { +static class firstBI extends BuiltIn { + @Override -TemplateModel calculateResult(TemplateSequenceModel tsm) +TemplateModel _eval(Environment env) +throws TemplateException { +TemplateModel model = target.eval(env); +// In 2.3.x only, we prefer TemplateSequenceModel for +// backward compatibility. In 2.4.x, we prefer TemplateCollectionModel. +if (model instanceof TemplateSequenceModel && !isBuggySeqButGoodCollection(model)) { +return calculateResultForSequence((TemplateSequenceModel) model); +} else if (model instanceof TemplateCollectionModel) { +return calculateResultForColletion((TemplateCollectionModel) model); +} else { +throw new NonSequenceOrCollectionException(target, model, env); +} +} + +private TemplateModel calculateResultForSequence(TemplateSequenceModel seq) throws TemplateModelException { -if (tsm.size() == 0) { +if (seq.size() == 0) { +return null; +} +return seq.get(0); +} + +private TemplateModel calculateResultForColletion(TemplateCollectionModel coll) +throws TemplateModelException { +TemplateModelIterator iter = coll.iterator(); +if (!iter.hasNext()) { return null; } -return tsm.get(0); +return iter.next(); } + } static class joinBI extends BuiltIn { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/496ddfbc/src/manual/en_US/book.xml -- diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml index e592d47..4adf154 100644 --- a/src/manual/en_US/book.xml +++ b/src/manual/en_US/book.xml @@ -30,7 +30,7 @@ Manual -Freemarker 2.3.25 +Freemarker 2.3.26 @@ -16416,8 +16416,19 @@ N first built-in - The first subvariable of the sequence. Template processing - will die with error if the sequence is empty. + Returns the first item of the sequence. Thus + value?first is the + same as value[0], + except that, since FreeMarker 2.3.26, + value?first also works + if value doesn't + support getting items with numerical index, but still supports to be + listed (i.e., with FTL collection values). + + If the sequence or collection is empty, the result will be a + missing value (as in + empty?first!'No item was + found'). @@ -26603,6 +26614,46 @@ TemplateModel x = env.getVariable("x"); // get variable x Version history + +2.3.26 (incubating at Apache) + +Release date
[04/24] incubator-freemarker git commit: couple grammar fixes, rephrase some things
couple grammar fixes, rephrase some things Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/a3fa4d2f Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/a3fa4d2f Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/a3fa4d2f Branch: refs/heads/2.3 Commit: a3fa4d2f631e1e9d15e8587034413e779dc52c07 Parents: f83161b Author: ratherblue Authored: Mon Jul 25 22:57:30 2016 -0700 Committer: ratherblue Committed: Mon Jul 25 22:57:30 2016 -0700 -- src/manual/en_US/book.xml | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) -- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a3fa4d2f/src/manual/en_US/book.xml -- diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml index b46e1ea..18c486d 100644 --- a/src/manual/en_US/book.xml +++ b/src/manual/en_US/book.xml @@ -58,15 +58,15 @@ This approach is often referred to as the MVC (Model View Controller) pattern, and is -particularly popular for dynamic Web pages. It helps in separating the Web -page designers (HTML authors) from the developers (Java programmers +particularly popular for dynamic web pages. It helps in separating web +page designers (HTML authors) from developers (Java programmers usually). Designers won't face complicated logic in templates, and can change the appearance of a page without programmers having to change or recompile code. While FreeMarker was originally created for generating HTML pages in MVC web application frameworks, it isn't bound to servlets or HTML or -anything Web-related. It's used in non-web application environments as +anything web-related. It's used in non-web application environments as well. FreeMarker is Template + data-model = output -Let's assume that you need a HTML page in a Web shop, similar to +Let's assume that you need a HTML page on a website, similar to this: @@ -114,10 +114,9 @@