[ofbiz-framework] branch trunk updated: Improved: <script-template> widget tag (OFBIZ-11686)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[ofbiz-framework] branch trunk updated: Improved: <script-template> widget tag (OFBIZ-11686)

James Yong-2
This is an automated email from the ASF dual-hosted git repository.

jamesyong pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 60c78d2  Improved: <script-template> widget tag (OFBIZ-11686)
60c78d2 is described below

commit 60c78d24be4ab2b4f8aa2f6603968863c12b9b92
Author: James Yong <[hidden email]>
AuthorDate: Fri May 15 11:16:15 2020 +0800

    Improved: <script-template> widget tag (OFBIZ-11686)
   
    Removed script-template tag.
    Use multi-block=true on html-template tag instead.
---
 applications/order/template/order/FindOrders.ftl   |  72 +++++++++++-
 .../order/template/order/FindOrders.js.ftl         |  86 --------------
 .../order/widget/ordermgr/OrderViewScreens.xml     |   3 +-
 .../webapp/ftl/ScriptTemplateListTransform.java    |   5 +-
 framework/widget/dtd/widget-screen.xsd             |   9 +-
 .../widget/artifact/ArtifactInfoGatherer.java      |   5 -
 .../org/apache/ofbiz/widget/model/HtmlWidget.java  | 124 +++++++++------------
 .../ofbiz/widget/model/ModelWidgetVisitor.java     |   2 -
 .../ofbiz/widget/model/ScriptTemplateUtil.java     |  43 ++++---
 .../ofbiz/widget/model/XmlWidgetVisitor.java       |  10 +-
 .../ofbiz/widget/renderer/ScreenRenderer.java      |   7 +-
 11 files changed, 160 insertions(+), 206 deletions(-)

diff --git a/applications/order/template/order/FindOrders.ftl b/applications/order/template/order/FindOrders.ftl
index 0d1923d..6eaff5b 100644
--- a/applications/order/template/order/FindOrders.ftl
+++ b/applications/order/template/order/FindOrders.ftl
@@ -17,6 +17,76 @@ specific language governing permissions and limitations
 under the License.
 -->
 
+<script>
+function lookupOrders(click) {
+    orderIdValue = document.lookuporder.orderId.value;
+    if (orderIdValue.length > 1) {
+        document.lookuporder.action = "<@ofbizUrl>orderview</@ofbizUrl>";
+        document.lookuporder.method = "get";
+    } else {
+        document.lookuporder.action = "<@ofbizUrl>searchorders</@ofbizUrl>";
+    }
+
+    if (click) {
+        document.lookuporder.submit();
+    }
+    return true;
+}
+function toggleOrderId(master) {
+    var form = document.massOrderChangeForm;
+    var orders = form.elements.length;
+    for (var i = 0; i < orders; i++) {
+        var element = form.elements[i];
+        if ("orderIdList" == element.name) {
+            element.checked = master.checked;
+        }
+    }
+    toggleOrderIdList();
+}
+function setServiceName(selection) {
+    document.massOrderChangeForm.action = selection.value;
+}
+function runAction() {
+    var form = document.massOrderChangeForm;
+    form.submit();
+}
+
+function toggleOrderIdList() {
+    var form = document.massOrderChangeForm;
+    var orders = form.elements.length;
+    var isAllSelected = true;
+    var isSingle = true;
+    for (var i = 0; i < orders; i++) {
+        var element = form.elements[i];
+        if ("orderIdList" == element.name) {
+            if (element.checked) {
+                isSingle = false;
+            } else {
+                isAllSelected = false;
+            }
+        }
+    }
+    if (isAllSelected) {
+        jQuery('#checkAllOrders').attr('checked', true);
+    } else {
+        jQuery('#checkAllOrders').attr('checked', false);
+    }
+    jQuery('#checkAllOrders').attr("checked", isAllSelected);
+    if (!isSingle && jQuery('#serviceName').val() != "") {
+        jQuery('#submitButton').removeAttr("disabled");
+    } else {
+        jQuery('#submitButton').attr('disabled', true);
+    }
+}
+
+function paginateOrderList(viewSize, viewIndex, hideFields) {
+    document.paginationForm.viewSize.value = viewSize;
+    document.paginationForm.viewIndex.value = viewIndex;
+    document.paginationForm.hideFields.value = hideFields;
+    document.paginationForm.submit();
+}
+</script>
+
 <#if security.hasEntityPermission("ORDERMGR", "_VIEW", session)>
 <#if parameters.hideFields?has_content>
 <form name='lookupandhidefields${requestParameters.hideFields?default("Y")}' method="post" action="<@ofbizUrl>searchorders</@ofbizUrl>">
@@ -404,9 +474,7 @@ under the License.
 </form>
 <#if requestParameters.hideFields?default("N") != "Y">
 <script type="application/javascript">
-<!--//
 document.lookuporder.orderId.focus();
-//-->
 </script>
 </#if>
 
diff --git a/applications/order/template/order/FindOrders.js.ftl b/applications/order/template/order/FindOrders.js.ftl
deleted file mode 100644
index 0b98270..0000000
--- a/applications/order/template/order/FindOrders.js.ftl
+++ /dev/null
@@ -1,86 +0,0 @@
-/***********************************************
-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.
-***********************************************/
-
-function lookupOrders(click) {
-    orderIdValue = document.lookuporder.orderId.value;
-    if (orderIdValue.length > 1) {
-        document.lookuporder.action = "<@ofbizUrl>orderview</@ofbizUrl>";
-        document.lookuporder.method = "get";
-    } else {
-        document.lookuporder.action = "<@ofbizUrl>searchorders</@ofbizUrl>";
-    }
-
-    if (click) {
-        document.lookuporder.submit();
-    }
-    return true;
-}
-function toggleOrderId(master) {
-    var form = document.massOrderChangeForm;
-    var orders = form.elements.length;
-    for (var i = 0; i < orders; i++) {
-        var element = form.elements[i];
-        if ("orderIdList" == element.name) {
-            element.checked = master.checked;
-        }
-    }
-    toggleOrderIdList();
-}
-function setServiceName(selection) {
-    document.massOrderChangeForm.action = selection.value;
-}
-function runAction() {
-    var form = document.massOrderChangeForm;
-    form.submit();
-}
-
-function toggleOrderIdList() {
-    var form = document.massOrderChangeForm;
-    var orders = form.elements.length;
-    var isAllSelected = true;
-    var isSingle = true;
-    for (var i = 0; i < orders; i++) {
-        var element = form.elements[i];
-        if ("orderIdList" == element.name) {
-            if (element.checked) {
-                isSingle = false;
-            } else {
-                isAllSelected = false;
-            }
-        }
-    }
-    if (isAllSelected) {
-        jQuery('#checkAllOrders').attr('checked', true);
-    } else {
-        jQuery('#checkAllOrders').attr('checked', false);
-    }
-    jQuery('#checkAllOrders').attr("checked", isAllSelected);
-    if (!isSingle && jQuery('#serviceName').val() != "") {
-        jQuery('#submitButton').removeAttr("disabled");
-    } else {
-        jQuery('#submitButton').attr('disabled', true);
-    }
-}
-
-function paginateOrderList(viewSize, viewIndex, hideFields) {
-    document.paginationForm.viewSize.value = viewSize;
-    document.paginationForm.viewIndex.value = viewIndex;
-    document.paginationForm.hideFields.value = hideFields;
-    document.paginationForm.submit();
-}
\ No newline at end of file
diff --git a/applications/order/widget/ordermgr/OrderViewScreens.xml b/applications/order/widget/ordermgr/OrderViewScreens.xml
index 7d0667c..04b84ce 100644
--- a/applications/order/widget/ordermgr/OrderViewScreens.xml
+++ b/applications/order/widget/ordermgr/OrderViewScreens.xml
@@ -267,8 +267,7 @@ under the License.
                         <platform-specific><html><html-template location="component://common-theme/template/includes/SetMultipleSelectJs.ftl"/></html></platform-specific>
                         <platform-specific>
                             <html>
-                                <script-template location="component://order/template/order/FindOrders.js.ftl"/>
-                                <html-template location="component://order/template/order/FindOrders.ftl"/>
+                                <html-template multi-block="true" location="component://order/template/order/FindOrders.ftl"/>
                             </html>
                         </platform-specific>
                     </decorator-section>
diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/ScriptTemplateListTransform.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/ScriptTemplateListTransform.java
index 6b3f385..7c9bf4d 100644
--- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/ScriptTemplateListTransform.java
+++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/ScriptTemplateListTransform.java
@@ -22,7 +22,6 @@ import java.io.IOException;
 import java.io.Writer;
 import java.util.Map;
 import java.util.Set;
-
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.ofbiz.widget.model.ScriptTemplateUtil;
@@ -53,7 +52,7 @@ public class ScriptTemplateListTransform implements TemplateTransformModel {
                     if (req != null) {
                         HttpServletRequest request = (HttpServletRequest) req.getWrappedObject();
                         Set<String> scriptSrcSet = ScriptTemplateUtil.getScriptSrcLinksFromRequest(request);
-                        if (scriptSrcSet!=null) {
+                        if (scriptSrcSet != null) {
                             String srcList = "";
                             for (String scriptSrc : scriptSrcSet) {
                                 srcList += ("<script src=\"" + scriptSrc + "\" type=\"application/javascript\"></script>\n");
@@ -73,7 +72,7 @@ public class ScriptTemplateListTransform implements TemplateTransformModel {
             }
 
             @Override
-            public void write(char cbuf[], int off, int len) {
+            public void write(char[] cbuf, int off, int len) {
             }
         };
 
diff --git a/framework/widget/dtd/widget-screen.xsd b/framework/widget/dtd/widget-screen.xsd
index 62ffc03..087809b 100644
--- a/framework/widget/dtd/widget-screen.xsd
+++ b/framework/widget/dtd/widget-screen.xsd
@@ -519,6 +519,7 @@ under the License.
     </xs:element>
     <xs:attributeGroup name="attlist.html-template">
         <xs:attribute type="xs:string" name="location" use="required" />
+        <xs:attribute type="xs:boolean" name="multi-block" use="optional" default="false" />
     </xs:attributeGroup>
     <xs:element name="html-template-decorator" substitutionGroup="HtmlWidgets">
         <xs:annotation>
@@ -544,14 +545,6 @@ under the License.
             <xs:attribute type="xs:string" name="name" use="required" />
         </xs:complexType>
     </xs:element>
-    <xs:element name="script-template" substitutionGroup="HtmlWidgets">
-        <xs:complexType>
-            <xs:attributeGroup ref="attlist.script-template" />
-        </xs:complexType>
-    </xs:element>
-    <xs:attributeGroup name="attlist.script-template">
-        <xs:attribute type="xs:string" name="location" use="required" />
-    </xs:attributeGroup>
     <!-- ============== Swing Specific Elements =============== -->
     <xs:element name="swing">
         <xs:complexType />
diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/artifact/ArtifactInfoGatherer.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/artifact/ArtifactInfoGatherer.java
index 3c96f1e..0ea3393 100644
--- a/framework/widget/src/main/java/org/apache/ofbiz/widget/artifact/ArtifactInfoGatherer.java
+++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/artifact/ArtifactInfoGatherer.java
@@ -38,7 +38,6 @@ import org.apache.ofbiz.widget.model.HtmlWidget;
 import org.apache.ofbiz.widget.model.HtmlWidget.HtmlTemplate;
 import org.apache.ofbiz.widget.model.HtmlWidget.HtmlTemplateDecorator;
 import org.apache.ofbiz.widget.model.HtmlWidget.HtmlTemplateDecoratorSection;
-import org.apache.ofbiz.widget.model.HtmlWidget.ScriptTemplate;
 import org.apache.ofbiz.widget.model.IterateSectionWidget;
 import org.apache.ofbiz.widget.model.ModelAction;
 import org.apache.ofbiz.widget.model.ModelActionVisitor;
@@ -357,10 +356,6 @@ public final class ArtifactInfoGatherer implements ModelWidgetVisitor, ModelActi
     }
 
     @Override
-    public void visit(ScriptTemplate scriptTemplate) throws Exception {
-    }
-
-    @Override
     public void visit(Section section) throws Exception {
         for (ModelAction action : section.getActions()) {
             action.accept(this);
diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/HtmlWidget.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/HtmlWidget.java
index b5afc68..acb850c 100644
--- a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/HtmlWidget.java
+++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/HtmlWidget.java
@@ -40,6 +40,9 @@ import org.apache.ofbiz.base.util.template.FreeMarkerWorker;
 import org.apache.ofbiz.widget.renderer.ScreenRenderer;
 import org.apache.ofbiz.widget.renderer.ScreenStringRenderer;
 import org.apache.ofbiz.widget.renderer.html.HtmlWidgetRenderer;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.select.Elements;
 import org.w3c.dom.Element;
 
 import freemarker.ext.beans.BeansWrapper;
@@ -121,8 +124,6 @@ public class HtmlWidget extends ModelScreenWidget {
                     subWidgets.add(new HtmlTemplate(modelScreen, childElement));
                 } else if ("html-template-decorator".equals(childElement.getNodeName())) {
                     subWidgets.add(new HtmlTemplateDecorator(modelScreen, childElement));
-                } else if ("script-template".equals(childElement.getNodeName())) {
-                    subWidgets.add(new ScriptTemplate(modelScreen, childElement));
                 } else {
                     throw new IllegalArgumentException("Tag not supported under the platform-specific -> html tag with name: "
                             + childElement.getNodeName());
@@ -178,36 +179,6 @@ public class HtmlWidget extends ModelScreenWidget {
         }
     }
 
-    public static void renderScriptTemplate(Appendable writer, FlexibleStringExpander locationExdr, Map<String, Object> context) {
-        String location = locationExdr.expandString(context);
-
-        if (UtilValidate.isEmpty(location)) {
-            throw new IllegalArgumentException("Template location is empty with search string location " + locationExdr.getOriginal());
-        }
-
-        if (location.endsWith(".ftl")) {
-            try {
-                boolean insertWidgetBoundaryComments = ModelWidget.widgetBoundaryCommentsEnabled(context);
-                if (insertWidgetBoundaryComments) {
-                    writer.append(HtmlWidgetRenderer.formatBoundaryJsComment("Begin", "Template", location));
-                }
-
-                Template template = FreeMarkerWorker.getTemplate(location, specialTemplateCache, specialConfig);
-                FreeMarkerWorker.renderTemplate(template, context, writer);
-
-                if (insertWidgetBoundaryComments) {
-                    writer.append(HtmlWidgetRenderer.formatBoundaryJsComment("End", "Template", location));
-                }
-            } catch (IllegalArgumentException | TemplateException | IOException e) {
-                String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString();
-                Debug.logError(e, errMsg, MODULE);
-                writeError(writer, errMsg);
-            }
-        } else {
-            throw new IllegalArgumentException("Rendering not yet supported for the template at location: " + location);
-        }
-    }
-
     // TODO: We can make this more fancy, but for now this is very functional
     public static void writeError(Appendable writer, String message) {
         try {
@@ -218,19 +189,65 @@ public class HtmlWidget extends ModelScreenWidget {
 
     public static class HtmlTemplate extends ModelScreenWidget {
         protected FlexibleStringExpander locationExdr;
+        protected boolean multiBlock;
 
         public HtmlTemplate(ModelScreen modelScreen, Element htmlTemplateElement) {
             super(modelScreen, htmlTemplateElement);
             this.locationExdr = FlexibleStringExpander.getInstance(htmlTemplateElement.getAttribute("location"));
+            this.multiBlock = !"false".equals(htmlTemplateElement.getAttribute("multi-block"));
         }
 
         public String getLocation(Map<String, Object> context) {
             return locationExdr.expandString(context);
         }
 
+        public boolean isMultiBlock() {
+            return this.multiBlock;
+        }
+
         @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
-            renderHtmlTemplate(writer, this.locationExdr, context);
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws IOException {
+
+            if (isMultiBlock()) {
+
+                StringWriter stringWriter = new StringWriter();
+                context.put("MultiBlockWriter", stringWriter);
+                renderHtmlTemplate(stringWriter, this.locationExdr, context);
+                context.remove("MultiBlockWriter");
+                String data = stringWriter.toString();
+                stringWriter.close();
+
+                Document doc = Jsoup.parse(data);
+
+                // extract scripts
+                Elements scriptElements = doc.select("script").remove();
+                if (scriptElements != null) {
+                    StringBuilder scripts = new StringBuilder();
+
+                    for (org.jsoup.nodes.Element script : scriptElements) {
+                        scripts.append(script.data());
+                    }
+
+                    // store script for retrieval by the browser
+                    String fileName = this.getLocation(context);
+                    fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
+                    if (fileName.endsWith(".ftl")) {
+                        fileName = fileName.substring(0, fileName.length() - 4);
+                    }
+                    ScriptTemplateUtil.putScriptInSession(context, fileName, scripts.toString());
+
+                    // store value to be used by ScriptTemplateList freemarker macro
+                    String webappName = (String) context.get("webappName");
+                    ScriptTemplateUtil.addScriptSrcToRequest(context, "/" + webappName + "/control/getJs?name="
+                            + fileName);
+                }
+
+                // the 'template' block
+                String body = doc.body().html();
+                writer.append(body);
+            } else {
+                renderHtmlTemplate(writer, this.locationExdr, context);
+            }
         }
 
         @Override
@@ -321,45 +338,6 @@ public class HtmlWidget extends ModelScreenWidget {
         }
     }
 
-    public static class ScriptTemplate extends ModelScreenWidget {
-        protected FlexibleStringExpander locationExdr;
-
-        public ScriptTemplate(ModelScreen modelScreen, Element htmlTemplateElement) {
-            super(modelScreen, htmlTemplateElement);
-            this.locationExdr = FlexibleStringExpander.getInstance(htmlTemplateElement.getAttribute("location"));
-        }
-
-        public String getLocation(Map<String, Object> context) {
-            return locationExdr.expandString(context);
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws IOException {
-            StringWriter stringWriter = new StringWriter();
-            renderScriptTemplate(stringWriter, this.locationExdr, context);
-            String data = stringWriter.toString();
-            stringWriter.close();
-
-            String fileName = this.getLocation(context);
-            fileName = fileName.substring(fileName.lastIndexOf("/")+1);
-            // remove ".ftl"
-            fileName = fileName.substring(0, fileName.length()-4);
-            ScriptTemplateUtil.putScriptInSession(context, fileName, data);
-
-            String webappName = (String)context.get("webappName");
-            ScriptTemplateUtil.addScriptSrcToRequest(context, "/"+webappName+"/control/getJs?name="+fileName);
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getLocationExdr() {
-            return locationExdr;
-        }
-    }
-
     @Override
     public void accept(ModelWidgetVisitor visitor) throws Exception {
         visitor.visit(this);
diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelWidgetVisitor.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelWidgetVisitor.java
index a1f89bb..f081f98 100644
--- a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelWidgetVisitor.java
+++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelWidgetVisitor.java
@@ -32,8 +32,6 @@ public interface ModelWidgetVisitor {
 
     void visit(HtmlWidget.HtmlTemplateDecoratorSection htmlTemplateDecoratorSection) throws Exception;
 
-    void visit(HtmlWidget.ScriptTemplate scriptTemplate) throws Exception;
-
     void visit(IterateSectionWidget iterateSectionWidget) throws Exception;
 
     void visit(ModelSingleForm modelForm) throws Exception;
diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ScriptTemplateUtil.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ScriptTemplateUtil.java
index 9d3417c..7bce317 100644
--- a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ScriptTemplateUtil.java
+++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ScriptTemplateUtil.java
@@ -27,7 +27,6 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 
 import org.apache.ofbiz.base.util.UtilGenerics;
-import org.apache.ofbiz.webapp.ftl.ScriptTemplateListTransform;
 
 public class ScriptTemplateUtil {
 
@@ -35,15 +34,17 @@ public class ScriptTemplateUtil {
     private static String requestKey = "ScriptTemplateList";
     private static int maxNumOfScriptInCache = 10;
 
+    private ScriptTemplateUtil() { }
+
     /**
-     * add script src link for use by @see {@link ScriptTemplateListTransform}
+     * add script src link for use by @see {@link org.apache.ofbiz.webapp.ftl.ScriptTemplateListTransform}
      * @param context
      * @param filePath
      */
-    public static void addScriptSrcToRequest(Map<String, Object> context, String filePath){
-        HttpServletRequest request = (HttpServletRequest)context.get("request");
+    public static void addScriptSrcToRequest(final Map<String, Object> context, final String filePath) {
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
         Set<String> scriptTemplates = UtilGenerics.cast(request.getAttribute(requestKey));
-        if (scriptTemplates==null){
+        if (scriptTemplates == null) {
             // use of LinkedHashSet to maintain insertion order
             scriptTemplates = new LinkedHashSet<String>();
             request.setAttribute(requestKey, scriptTemplates);
@@ -52,22 +53,28 @@ public class ScriptTemplateUtil {
     }
 
     /**
-     * get the script src links collected from the "script-template" tags
+     * get the script src links collected from the html-template tags where multi-block=true.
      * @param request
      * @return
      */
-    public static Set<String> getScriptSrcLinksFromRequest(HttpServletRequest request){
+    public static Set<String> getScriptSrcLinksFromRequest(HttpServletRequest request) {
         Set<String> scriptTemplates = UtilGenerics.cast(request.getAttribute(requestKey));
         return scriptTemplates;
     }
 
-    public static void putScriptInSession(Map<String, Object> context, String fileName, String fileContent){
-        HttpSession session = (HttpSession)context.get("session");
-        Map<String,String> scriptTemplateMap = UtilGenerics.cast(session.getAttribute(sessionKey));
-        if (scriptTemplateMap==null){
+    /**
+     * put script in user session for retrieval by the browser
+     * @param context
+     * @param fileName
+     * @param fileContent
+     */
+    public static void putScriptInSession(Map<String, Object> context, String fileName, String fileContent) {
+        HttpSession session = (HttpSession) context.get("session");
+        Map<String, String> scriptTemplateMap = UtilGenerics.cast(session.getAttribute(sessionKey));
+        if (scriptTemplateMap == null) {
             synchronized (session) {
                 scriptTemplateMap = UtilGenerics.cast(session.getAttribute(sessionKey));
-                if (scriptTemplateMap==null){
+                if (scriptTemplateMap == null) {
                     // use of LinkedHashMap to limit size of the map
                     scriptTemplateMap = new LinkedHashMap<String, String>() {
                         private static final long serialVersionUID = 1L;
@@ -82,9 +89,15 @@ public class ScriptTemplateUtil {
         scriptTemplateMap.put(fileName, fileContent);
     }
 
-    public static String getScriptFromSession(HttpSession session, String fileName){
-        Map<String,String> scriptTemplateMap = UtilGenerics.cast(session.getAttribute(sessionKey));
-        if (scriptTemplateMap!=null){
+    /**
+     * Get the script stored in user session.
+     * @param session
+     * @param fileName
+     * @return script to be sent back to browser
+     */
+    public static String getScriptFromSession(HttpSession session, final String fileName) {
+        Map<String, String> scriptTemplateMap = UtilGenerics.cast(session.getAttribute(sessionKey));
+        if (scriptTemplateMap != null) {
             return scriptTemplateMap.get(fileName);
         }
         return null;
diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/XmlWidgetVisitor.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/XmlWidgetVisitor.java
index 737ced1..0777a70 100644
--- a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/XmlWidgetVisitor.java
+++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/XmlWidgetVisitor.java
@@ -24,7 +24,6 @@ import java.util.Map;
 import org.apache.ofbiz.widget.model.HtmlWidget.HtmlTemplate;
 import org.apache.ofbiz.widget.model.HtmlWidget.HtmlTemplateDecorator;
 import org.apache.ofbiz.widget.model.HtmlWidget.HtmlTemplateDecoratorSection;
-import org.apache.ofbiz.widget.model.HtmlWidget.ScriptTemplate;
 import org.apache.ofbiz.widget.model.ModelScreenWidget.Column;
 import org.apache.ofbiz.widget.model.ModelScreenWidget.ColumnContainer;
 import org.apache.ofbiz.widget.model.ModelScreenWidget.Container;
@@ -167,6 +166,7 @@ public class XmlWidgetVisitor extends XmlAbstractWidgetVisitor implements ModelW
         writer.append("<html-template");
         visitModelWidget(htmlTemplate);
         visitAttribute("location", htmlTemplate.getLocationExdr());
+        visitAttribute("multi-block", htmlTemplate.isMultiBlock());
         writer.append("/>");
     }
 
@@ -406,14 +406,6 @@ public class XmlWidgetVisitor extends XmlAbstractWidgetVisitor implements ModelW
     }
 
     @Override
-    public void visit(ScriptTemplate scriptTemplate) throws Exception {
-        writer.append("<script-template");
-        visitModelWidget(scriptTemplate);
-        visitAttribute("location", scriptTemplate.getLocationExdr());
-        writer.append("/>");
-    }
-
-    @Override
     public void visit(ModelScreen modelScreen) throws Exception {
         writer.append("<screen");
         visitModelWidget(modelScreen);
diff --git a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/ScreenRenderer.java b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/ScreenRenderer.java
index 888d123..ccf1ea1 100644
--- a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/ScreenRenderer.java
+++ b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/ScreenRenderer.java
@@ -137,7 +137,12 @@ public class ScreenRenderer {
             }
         } else {
             context.put("renderFormSeqNumber", String.valueOf(renderFormSeqNumber));
-            modelScreen.renderScreenString(writer, context, screenStringRenderer);
+            if (context.get("MultiBlockWriter") != null) {
+                StringWriter stringWriter = (StringWriter) context.get("MultiBlockWriter");
+                modelScreen.renderScreenString(stringWriter, context, screenStringRenderer);
+            } else {
+                modelScreen.renderScreenString(writer, context, screenStringRenderer);
+            }
         }
         return "";
     }