This is an automated email from the ASF dual-hosted git repository. nmalin 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 26a9dc7 Implemented: Rendering widget screen from ftl with the current context (OFBIZ-12310) 26a9dc7 is described below commit 26a9dc73366a3f37a716d7d7e54b378a3ac2fc4d Author: Nicolas Malin <nicolas.ma...@nereide.fr> AuthorDate: Fri Sep 3 18:29:48 2021 +0200 Implemented: Rendering widget screen from ftl with the current context (OFBIZ-12310) Currently, when you would be rendering a widget screen from a ftl template, you can use a element screen present on context to call the renderer : ${screens.render("component://common/widget/CommonScreens.xml#countries")} This rendering is realized with the context present when the object screen has been initialized. To simplify the screen call from freemarker template, I implemented a new macro ofbizScreen You can call a Ofbiz screen with the ftl context with simple macro <@ofbizScreen>component://mycomponent/widget/MyComponentScreens.xml#MyScreen</@ofbizScreen> You can also write <@ofbizScreen location="component://mycomponent/widget/MyComponentScreens.xml" name="MyScreen"/> Or set a default location on your context action : context.defaultTemplateLocation = "component://mycomponent/widget/MyComponentScreens.xml" widget : <@ofbizScreen>MyScreen</@ofbizScreen> When the screen would be call, the context to rendering the screen would be use the current context: <#list contactMechs as contactMech> <#assign contactMechId = contactMech.contachMechId/> <@ofbizScreen>component://mycomponent/widget/MyComponentScreens.xml#DisplayContactMech</@ofbizScreen> </#list> --- .../party/template/party/EditContactMech.ftl | 4 +- .../ofbiz/webapp/ftl/OfbizScreenTransform.java | 149 +++++++++++++++++++++ .../ofbiz/webapp/freemarkerTransforms.properties | 1 + 3 files changed, 152 insertions(+), 2 deletions(-) diff --git a/applications/party/template/party/EditContactMech.ftl b/applications/party/template/party/EditContactMech.ftl index 53a4fcd..f418ab3 100644 --- a/applications/party/template/party/EditContactMech.ftl +++ b/applications/party/template/party/EditContactMech.ftl @@ -165,14 +165,14 @@ under the License. <td> <select name="countryGeoId" id="editcontactmechform_countryGeoId"> - ${screens.render("component://common/widget/CommonScreens.xml#countries")} <#if (mechMap.postalAddress??) && (mechMap.postalAddress.countryGeoId??)> <#assign defaultCountryGeoId = mechMap.postalAddress.countryGeoId> <#else> <#assign defaultCountryGeoId = Static["org.apache.ofbiz.entity.util.EntityUtilProperties"].getPropertyValue("general", "country.geo.id.default", delegator)> </#if> + <@ofbizScreen>countries</@ofbizScreen> <option selected="selected" value="${defaultCountryGeoId}"> - <#assign countryGeo = delegator.findOne("Geo",Static["org.apache.ofbiz.base.util.UtilMisc"].toMap("geoId",defaultCountryGeoId), false)> + <#assign countryGeo = delegator.findOne("Geo", {"geoId": defaultCountryGeoId}, false)> ${countryGeo.get("geoName",locale)} </option> </select> diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizScreenTransform.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizScreenTransform.java new file mode 100644 index 0000000..977d593 --- /dev/null +++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/OfbizScreenTransform.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * 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.ofbiz.webapp.ftl; + +import freemarker.core.Environment; +import freemarker.ext.beans.BeanModel; +import freemarker.template.TemplateException; +import freemarker.template.TemplateModelException; +import freemarker.template.TemplateTransformModel; +import freemarker.template.TemplateScalarModel; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.xml.parsers.ParserConfigurationException; +import org.apache.ofbiz.base.util.Debug; +import org.apache.ofbiz.base.util.GeneralException; +import org.apache.ofbiz.base.util.UtilGenerics; +import org.apache.ofbiz.base.util.UtilHttp; +import org.apache.ofbiz.base.util.collections.MapStack; +import org.apache.ofbiz.base.util.template.FreeMarkerWorker; +import org.apache.ofbiz.widget.model.ModelTheme; +import org.apache.ofbiz.widget.renderer.ScreenRenderer; +import org.apache.ofbiz.widget.renderer.ScreenStringRenderer; +import org.apache.ofbiz.widget.renderer.VisualTheme; +import org.apache.ofbiz.widget.renderer.macro.MacroScreenRenderer; +import org.xml.sax.SAXException; + +/** + * OfbizScreenTransform - Freemarker Transform to display a screen by is location and name + * + * You can call a Ofbiz screen with the ftl context with simple macro + * <@ofbizScreen>component://mycomponent/widget/MyComponentScreens.xml#MyScreen</@ofbizScreen> + * + * You can also write + * <@ofbizScreen location="component://mycomponent/widget/MyComponentScreens.xml" name="MyScreen"/> + * + * Or set a default location on your context + * action : + * context.defaultTemplateLocation = "component://mycomponent/widget/MyComponentScreens.xml" + * widget : + * <@ofbizScreen>MyScreen</@ofbizScreen> + * + */ +public class OfbizScreenTransform implements TemplateTransformModel { + + private static final String MODULE = OfbizScreenTransform.class.getName(); + + private static String convertToString(Object o) { + String result = ""; + if (o != null) { + if (Debug.verboseOn()) { + Debug.logVerbose("Arg Object : " + o.getClass().getName(), MODULE); + } + if (o instanceof TemplateScalarModel) { + TemplateScalarModel s = (TemplateScalarModel) o; + try { + result = s.getAsString(); + } catch (TemplateModelException e) { + Debug.logError(e, "Template Exception", MODULE); + } + } else { + result = o.toString(); + } + } + return result; + } + + @Override + public Writer getWriter(Writer out, @SuppressWarnings("rawtypes") Map args) { + final StringBuilder buf = new StringBuilder(); + final Map<String, Object> context = UtilGenerics.cast(FreeMarkerWorker.createEnvironmentMap(Environment.getCurrentEnvironment())); + final String location = convertToString(args.get("location")); + final String name = convertToString(args.get("name")); + final String screenType = args.get("type") != null + ? convertToString(args.get("type")) + : "screen"; + return new Writer(out) { + @Override + public void write(char cbuf[], int off, int len) { + buf.append(cbuf, off, len); + } + + @Override + public void flush() throws IOException { + out.flush(); + } + + @Override + public void close() throws IOException { + try { + Environment env = Environment.getCurrentEnvironment(); + BeanModel req = (BeanModel) env.getVariable("request"); + HttpServletRequest request = req == null ? null : (HttpServletRequest) req.getWrappedObject(); + VisualTheme visualTheme = UtilHttp.getVisualTheme(request); + ModelTheme modelTheme = visualTheme.getModelTheme(); + + String screenName = name.isEmpty() ? buf.toString() : name; + + String screenMacroLibraryPath = modelTheme.getScreenRendererLocation(screenType); + ScreenStringRenderer screenStringRenderer = new MacroScreenRenderer(modelTheme.getType(screenType), screenMacroLibraryPath); + + Writer writer = new StringWriter(); + ScreenRenderer screens = new ScreenRenderer(writer, MapStack.create(context), screenStringRenderer); + + //check if the name is combined + if (screenName.contains("#")) { + if (Debug.verboseOn()) { + Debug.logVerbose("Call screen with combined location" + screenName, MODULE); + } + screens.render(screenName); + } else { + String forwardLocation = !location.isEmpty() + ? location + : FreeMarkerWorker.unwrap(env.getVariable("defaultTemplateLocation")); + if (forwardLocation == null) { + forwardLocation = "component://common/widget/CommonScreens.xml"; + } + if (Debug.verboseOn()) { + Debug.logVerbose("Call screen " + screenName + ", at location : " + forwardLocation, MODULE); + } + screens.render(forwardLocation, screenName); + } + + out.write(writer.toString()); + } catch (GeneralException | SAXException | ParserConfigurationException | TemplateException e) { + throw new IOException(e.getMessage()); + } + } + }; + } +} diff --git a/framework/webapp/src/main/resources/org/apache/ofbiz/webapp/freemarkerTransforms.properties b/framework/webapp/src/main/resources/org/apache/ofbiz/webapp/freemarkerTransforms.properties index 755ef77..62e7749 100644 --- a/framework/webapp/src/main/resources/org/apache/ofbiz/webapp/freemarkerTransforms.properties +++ b/framework/webapp/src/main/resources/org/apache/ofbiz/webapp/freemarkerTransforms.properties @@ -26,6 +26,7 @@ ofbizContentUrl=org.apache.ofbiz.webapp.ftl.OfbizContentTransform ofbizCurrency=org.apache.ofbiz.webapp.ftl.OfbizCurrencyTransform ofbizAmount=org.apache.ofbiz.webapp.ftl.OfbizAmountTransform ofbizNumber=org.apache.ofbiz.webapp.ftl.OfbizNumberTransform +ofbizScreen=org.apache.ofbiz.webapp.ftl.OfbizScreenTransform setRequestAttribute=org.apache.ofbiz.webapp.ftl.SetRequestAttributeMethod renderWrappedText=org.apache.ofbiz.webapp.ftl.RenderWrappedTextTransform setContextField=org.apache.ofbiz.webapp.ftl.SetContextFieldTransform