Author: adrianc
Date: Sun Aug 25 18:00:43 2013 New Revision: 1517353 URL: http://svn.apache.org/r1517353 Log: Converted menu widget HTML renderer to a macro renderer. Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java ofbiz/trunk/framework/widget/templates/htmlMenuMacroLibrary.ftl Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java?rev=1517353&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java Sun Aug 25 18:00:43 2013 @@ -0,0 +1,347 @@ +/******************************************************************************* + * 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.ofbiz.widget.menu; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.StringUtil; +import org.ofbiz.base.util.UtilMisc; +import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.template.FreeMarkerWorker; +import org.ofbiz.webapp.control.RequestHandler; +import org.ofbiz.webapp.taglib.ContentUrlTag; +import org.ofbiz.widget.ModelWidget; +import org.ofbiz.widget.WidgetWorker; +import org.ofbiz.widget.menu.ModelMenuItem.Image; +import org.ofbiz.widget.menu.ModelMenuItem.Link; + +import freemarker.core.Environment; +import freemarker.template.Template; +import freemarker.template.TemplateException; + +public class MacroMenuRenderer implements MenuStringRenderer { + + public static final String module = MacroMenuRenderer.class.getName(); + private int macroCount = 999; + private final Map<Appendable, Environment> environments = new HashMap<Appendable, Environment>(); + private final Template macroLibrary; + private final HttpServletRequest request; + private final HttpServletResponse response; + + public MacroMenuRenderer(String macroLibraryPath, HttpServletRequest request, HttpServletResponse response) throws TemplateException, IOException { + this.macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath); + this.request = request; + this.response = response; + } + + // Made this a separate method so it can be externalized and reused. + private Map<String, Object> createImageParameters(Map<String, Object> context, Image image) { + Map<String, Object> parameters = new HashMap<String, Object>(); + parameters.put("id", image.getId(context)); + parameters.put("style", image.getStyle(context)); + parameters.put("width", image.getWidth(context)); + parameters.put("height", image.getHeight(context)); + parameters.put("border", image.getBorder(context)); + String src = image.getSrc(context); + if (UtilValidate.isNotEmpty(src) && request != null && response != null) { + String urlMode = image.getUrlMode(); + if ("ofbiz".equalsIgnoreCase(urlMode)) { + boolean fullPath = false; + boolean secure = false; + boolean encode = false; + ServletContext ctx = (ServletContext) request.getAttribute("servletContext"); + RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_"); + src = rh.makeLink(request, response, src, fullPath, secure, encode); + } else if ("content".equalsIgnoreCase(urlMode)) { + StringBuilder newURL = new StringBuilder(); + ContentUrlTag.appendContentPrefix(request, newURL); + newURL.append(src); + src = newURL.toString(); + } + } + parameters.put("src", src); + return parameters; + } + + private void executeMacro(Appendable writer, String macro) throws IOException, TemplateException { + Environment environment = getEnvironment(writer); + Reader templateReader = new StringReader(macro); + macroCount++; + String templateName = toString().concat("_") + macroCount; + Template template = new Template(templateName, templateReader, FreeMarkerWorker.getDefaultOfbizConfig()); + templateReader.close(); + environment.include(template); + } + + private void executeMacro(Appendable writer, String macroName, Map<String, Object> macroParameters) throws IOException, TemplateException { + StringBuilder sb = new StringBuilder("<@"); + sb.append(macroName); + if (macroParameters != null) { + for (Map.Entry<String, Object> parameter : macroParameters.entrySet()) { + sb.append(' '); + sb.append(parameter.getKey()); + sb.append("="); + Object value = parameter.getValue(); + if (value instanceof String) { + sb.append('"'); + sb.append(((String) value).replaceAll("\"", "\\\\\"")); + sb.append('"'); + } else { + sb.append(value); + } + } + } + sb.append(" />"); + if (Debug.verboseOn()) { + Debug.logVerbose("Executing macro: " + sb, module); + } + executeMacro(writer, sb.toString()); + } + + private Environment getEnvironment(Appendable writer) throws TemplateException, IOException { + Environment environment = environments.get(writer); + if (environment == null) { + Map<String, Object> input = UtilMisc.toMap("key", null); + environment = FreeMarkerWorker.renderTemplate(macroLibrary, input, writer); + environments.put(writer, environment); + } + return environment; + } + + private boolean isDisableIfEmpty(ModelMenuItem menuItem, Map<String, Object> context) { + boolean disabled = false; + String disableIfEmpty = menuItem.getDisableIfEmpty(); + if (UtilValidate.isNotEmpty(disableIfEmpty)) { + List<String> keys = StringUtil.split(disableIfEmpty, "|"); + for (String key : keys) { + Object obj = context.get(key); + if (obj == null) { + disabled = true; + break; + } + } + } + return disabled; + } + + private boolean isHideIfSelected(ModelMenuItem menuItem, Map<String, Object> context) { + ModelMenu menu = menuItem.getModelMenu(); + String currentMenuItemName = menu.getSelectedMenuItemContextFieldName(context); + String currentItemName = menuItem.getName(); + Boolean hideIfSelected = menuItem.getHideIfSelected(); + return (hideIfSelected != null && hideIfSelected.booleanValue() && currentMenuItemName != null && currentMenuItemName.equals(currentItemName)); + } + + @Override + public void renderFormatSimpleWrapperClose(Appendable writer, Map<String, Object> context, ModelMenu menu) throws IOException { + // Nothing to do. + } + + @Override + public void renderFormatSimpleWrapperOpen(Appendable writer, Map<String, Object> context, ModelMenu menu) throws IOException { + // Nothing to do. + } + + @Override + public void renderFormatSimpleWrapperRows(Appendable writer, Map<String, Object> context, Object menu) throws IOException { + List<ModelMenuItem> menuItemList = ((ModelMenu) menu).getMenuItemList(); + for (ModelMenuItem currentMenuItem : menuItemList) { + renderMenuItem(writer, context, currentMenuItem); + } + } + + @Override + public void renderImage(Appendable writer, Map<String, Object> context, Image image) throws IOException { + Map<String, Object> parameters = createImageParameters(context, image); + try { + executeMacro(writer, "renderImage", parameters); + } catch (TemplateException e) { + throw new IOException(e); + } + } + + @Override + public void renderLink(Appendable writer, Map<String, Object> context, Link link) throws IOException { + Map<String, Object> parameters = new HashMap<String, Object>(); + String target = link.getTarget(context); + ModelMenuItem menuItem = link.getLinkMenuItem(); + if (menuItem.getDisabled() || isDisableIfEmpty(menuItem, context)) { + target = null; + } + parameters.put("id", link.getId(context)); + parameters.put("style", link.getStyle(context)); + parameters.put("name", link.getName(context)); + parameters.put("text", link.getText(context)); + parameters.put("targetWindow", link.getTargetWindow(context)); + String uniqueItemName = menuItem.getModelMenu().getName() + "_" + menuItem.getName() + "_LF_" + UtilMisc.<String> addToBigDecimalInMap(context, "menuUniqueItemIndex", BigDecimal.ONE); + parameters.put("uniqueItemName", uniqueItemName); + String linkType = WidgetWorker.determineAutoLinkType(link.getLinkType(), target, link.getUrlMode(), request); + parameters.put("linkType", linkType); + String linkUrl = ""; + String actionUrl = ""; + StringBuilder targetParameters = new StringBuilder(); + if ("hidden-form".equals(linkType) || "ajax-window".equals(linkType)) { + StringBuilder sb = new StringBuilder(); + WidgetWorker.buildHyperlinkUrl(sb, target, link.getUrlMode(), null, link.getPrefix(context), link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context); + actionUrl = sb.toString(); + targetParameters.append("["); + for (Map.Entry<String, String> parameter : link.getParameterMap(context).entrySet()) { + if (targetParameters.length() > 1) { + targetParameters.append(","); + } + targetParameters.append("{'name':'"); + targetParameters.append(parameter.getKey()); + targetParameters.append("'"); + targetParameters.append(",'value':'"); + targetParameters.append(parameter.getValue()); + targetParameters.append("'}"); + } + targetParameters.append("]"); + + } + if (UtilValidate.isNotEmpty(target)) { + if (!"hidden-form".equals(linkType)) { + StringBuilder sb = new StringBuilder(); + WidgetWorker.buildHyperlinkUrl(sb, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context), link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context); + linkUrl = sb.toString(); + } + } + parameters.put("linkUrl", linkUrl); + parameters.put("actionUrl", actionUrl); + parameters.put("parameterList", targetParameters.toString()); + String imgStr = ""; + Image img = link.getImage(); + if (img != null) { + StringWriter sw = new StringWriter(); + renderImage(sw, context, img); + imgStr = sw.toString(); + } + parameters.put("imgStr", imgStr); + try { + executeMacro(writer, "renderLink", parameters); + } catch (TemplateException e) { + throw new IOException(e); + } + } + + @Override + public void renderMenuClose(Appendable writer, Map<String, Object> context, ModelMenu menu) throws IOException { + Map<String, Object> parameters = null; + if (ModelWidget.widgetBoundaryCommentsEnabled(context)) { + parameters = new HashMap<String, Object>(); + StringBuilder sb = new StringBuilder("End Menu Widget "); + sb.append(menu.getBoundaryCommentName()); + parameters.put("boundaryComment", sb.toString()); + } + try { + executeMacro(writer, "renderMenuEnd", parameters); + } catch (TemplateException e) { + throw new IOException(e); + } + } + + @Override + public void renderMenuItem(Appendable writer, Map<String, Object> context, ModelMenuItem menuItem) throws IOException { + if (isHideIfSelected(menuItem, context)) + return; + Map<String, Object> parameters = new HashMap<String, Object>(); + String style = menuItem.getWidgetStyle(); + if (menuItem.isSelected(context)) { + style = menuItem.getSelectedStyle(); + if (UtilValidate.isEmpty(style)) { + style = "selected"; + } + } + if (menuItem.getDisabled() || this.isDisableIfEmpty(menuItem, context)) { + style = menuItem.getDisabledTitleStyle(); + } + if (style == null) { + style = ""; + } + String alignStyle = menuItem.getAlignStyle(); + if (UtilValidate.isNotEmpty(alignStyle)) { + style = style.concat(" ").concat(alignStyle); + } + parameters.put("style", style); + parameters.put("toolTip", menuItem.getTooltip(context)); + String linkStr = ""; + Link link = menuItem.getLink(); + if (link != null) { + StringWriter sw = new StringWriter(); + renderLink(sw, context, link); + linkStr = sw.toString(); + } else { + linkStr = menuItem.getTitle(context); + StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder"); + if (simpleEncoder != null) { + linkStr = simpleEncoder.encode(linkStr); + } + } + parameters.put("linkStr", linkStr); + boolean containsNestedMenus = !menuItem.getMenuItemList().isEmpty(); + parameters.put("containsNestedMenus", containsNestedMenus); + try { + executeMacro(writer, "renderMenuItemBegin", parameters); + } catch (TemplateException e) { + throw new IOException(e); + } + if (containsNestedMenus) { + for (ModelMenuItem childMenuItem : menuItem.getMenuItemList()) { + childMenuItem.renderMenuItemString(writer, context, this); + } + } + parameters.clear(); + parameters.put("containsNestedMenus", containsNestedMenus); + try { + executeMacro(writer, "renderMenuItemEnd", parameters); + } catch (TemplateException e) { + throw new IOException(e); + } + } + + @Override + public void renderMenuOpen(Appendable writer, Map<String, Object> context, ModelMenu menu) throws IOException { + Map<String, Object> parameters = new HashMap<String, Object>(); + if (ModelWidget.widgetBoundaryCommentsEnabled(context)) { + StringBuilder sb = new StringBuilder("Begin Menu Widget "); + sb.append(menu.getBoundaryCommentName()); + parameters.put("boundaryComment", sb.toString()); + } + parameters.put("id", menu.getId()); + parameters.put("style", menu.getMenuContainerStyle(context)); + parameters.put("title", menu.getTitle(context)); + try { + executeMacro(writer, "renderMenuBegin", parameters); + } catch (TemplateException e) { + throw new IOException(e); + } + } +} Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java?rev=1517353&r1=1517352&r2=1517353&view=diff ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java (original) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java Sun Aug 25 18:00:43 2013 @@ -38,8 +38,10 @@ import org.ofbiz.webapp.view.AbstractVie import org.ofbiz.webapp.view.ViewHandlerException; import org.ofbiz.widget.form.FormStringRenderer; import org.ofbiz.widget.form.MacroFormRenderer; -import org.ofbiz.widget.tree.TreeStringRenderer; +import org.ofbiz.widget.menu.MacroMenuRenderer; +import org.ofbiz.widget.menu.MenuStringRenderer; import org.ofbiz.widget.tree.MacroTreeRenderer; +import org.ofbiz.widget.tree.TreeStringRenderer; import org.xml.sax.SAXException; import freemarker.template.TemplateException; @@ -90,15 +92,13 @@ public class MacroScreenViewHandler exte ScreenStringRenderer screenStringRenderer = new MacroScreenRenderer(UtilProperties.getPropertyValue("widget", getName() + ".name"), UtilProperties.getPropertyValue("widget", getName() + ".screenrenderer")); FormStringRenderer formStringRenderer = new MacroFormRenderer(UtilProperties.getPropertyValue("widget", getName() + ".formrenderer"), request, response); TreeStringRenderer treeStringRenderer = new MacroTreeRenderer(UtilProperties.getPropertyValue("widget", getName() + ".treerenderer"), writer); - // TODO: uncomment these lines when the renderers are implemented - //MenuStringRenderer menuStringRenderer = new MacroMenuRenderer(UtilProperties.getPropertyValue("widget", getName() + ".menurenderer"), writer); + MenuStringRenderer menuStringRenderer = new MacroMenuRenderer(UtilProperties.getPropertyValue("widget", getName() + ".menurenderer"), request, response); ScreenRenderer screens = new ScreenRenderer(writer, null, screenStringRenderer); screens.populateContextForRequest(request, response, servletContext); - // this is the object used to render forms from their definitions screens.getContext().put("formStringRenderer", formStringRenderer); screens.getContext().put("treeStringRenderer", treeStringRenderer); - //screens.getContext().put("menuStringRenderer", menuStringRenderer); + screens.getContext().put("menuStringRenderer", menuStringRenderer); screens.getContext().put("simpleEncoder", StringUtil.getEncoder(UtilProperties.getPropertyValue("widget", getName() + ".encoder"))); screenStringRenderer.renderScreenBegin(writer, screens.getContext()); screens.render(page); Added: ofbiz/trunk/framework/widget/templates/htmlMenuMacroLibrary.ftl URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/templates/htmlMenuMacroLibrary.ftl?rev=1517353&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/templates/htmlMenuMacroLibrary.ftl (added) +++ ofbiz/trunk/framework/widget/templates/htmlMenuMacroLibrary.ftl Sun Aug 25 18:00:43 2013 @@ -0,0 +1,72 @@ +<#-- +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. +--> + +<#macro renderMenuBegin boundaryComment id style title> + <#if boundaryComment?has_content> +<!-- ${boundaryComment} --> + </#if> + <div<#if id?has_content> id="${id}"</#if><#if style?has_content> class="${style}"</#if>> + <#if title?has_content> + <h2>${title}</h2> + </#if> + <ul> + <li> + <ul> +</#macro> + +<#macro renderMenuEnd boundaryComment> + </ul> + </li> + </ul> + <br class="clear"/> + </div> + <#if boundaryComment?has_content> +<!-- ${boundaryComment} --> + </#if> +</#macro> + +<#macro renderImage src id style width height border> + <img src="${src}"<#if id?has_content> id="${id}"</#if><#if style?has_content> class="${style}"</#if><#if width?has_content> width="${width}"</#if><#if height?has_content> height="${height}"</#if><#if border?has_content> border="${border}"</#if> /> +</#macro> + +<#macro renderLink linkType linkUrl parameterList targetWindow uniqueItemName actionUrl id="" style="" name="" height="" width="" text="" imgStr=""> + <#if "hidden-form" == linkType> + <form method="post" action="${actionUrl}"<#if targetWindow?has_content> target="${targetWindow}"</#if> onsubmit="javascript:submitFormDisableSubmits(this)" name="${uniqueItemName}"><#rt/> + <#list parameterList as parameter> + <input name="${parameter.name}" value="${parameter.value}" type="hidden"/><#rt/> + </#list> + </form><#rt/> + </#if> + <a<#if id?has_content> id="${id}"</#if><#if style?has_content> class="${style}"</#if><#if name?has_content> name="${name}"</#if><#if targetWindow?has_content> target="${targetWindow}"</#if> href="<#if "hidden-form"==linkType>javascript:document.${uniqueItemName}.submit()<#else>${linkUrl}</#if>"><#if imgStr?has_content>${imgStr}</#if><#if text?has_content>${text}</#if></a> +</#macro> + +<#macro renderMenuItemBegin style toolTip linkStr containsNestedMenus> + <li<#if style?has_content> class="${style}"</#if><#if toolTip?has_content> title="${title}"</#if>> + <#if linkStr?has_content>${linkStr}</#if> + <#if containsNestedMenus> + <ul> + </#if> +</#macro> + +<#macro renderMenuItemEnd containsNestedMenus> + <#if containsNestedMenus> + </ul> + </#if> + </li> +</#macro> |
Free forum by Nabble | Edit this page |