public MacroMenuRenderer( String macroLibraryPath, HttpServletRequest request, HttpServletResponse response) throws TemplateException, IOException { this.macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath); this.request = request; this.response = response; }
public static void renderHtmlTemplate( Appendable writer, FlexibleStringExpander locationExdr, Map<String, Object> context) { String location = locationExdr.expandString(context); // Debug.logInfo("Rendering template at location [" + location + "] with context: \n" + context, // module); if (UtilValidate.isEmpty(location)) { throw new IllegalArgumentException("Template location is empty"); } /* // ======================================================================= // Go through the context and find GenericValue objects and wrap them // NOTE PROBLEM: there are still problems with this as it gets some things // but does not get non-entity data including lots of strings // directly in the context or things prepared or derived right in // the FTL file, like the results of service calls, etc; we could // do something more aggressive to encode and wrap EVERYTHING in // the context, but I've been thinking that even this is too much // overhead and that would be crazy // NOTE ALTERNATIVE1: considering instead to use the FTL features to wrap // everything in an <#escape x as x?html>...</#escape>, but that could // cause problems with ${} expansions that have HTML in them, including: // included screens (using ${screens.render(...)}), content that should // have HTML in it (lots of general, product, category, etc content), etc // NOTE ALTERNATIVE2: kind of like the "#escape X as x?html" option, // implement an FTL *Model class and load it through a ObjectWrapper // FINAL NOTE: after testing all of these alternatives, this one seems // to behave the best, so going with that for now. // isolate the scope so these wrapper objects go away after rendering is done MapStack<String> contextMs; if (!(context instanceof MapStack)) { contextMs = MapStack.create(context); context = contextMs; } else { contextMs = UtilGenerics.cast(context); } contextMs.push(); for(Map.Entry<String, Object> mapEntry: contextMs.entrySet()) { Object value = mapEntry.getValue(); if (value instanceof GenericValue) { contextMs.put(mapEntry.getKey(), GenericValueHtmlWrapper.create((GenericValue) value)); } else if (value instanceof List) { if (((List) value).size() > 0 && ((List) value).get(0) instanceof GenericValue) { List<GenericValue> theList = (List<GenericValue>) value; List<GenericValueHtmlWrapper> newList = FastList.newInstance(); for (GenericValue gv: theList) { newList.add(GenericValueHtmlWrapper.create(gv)); } contextMs.put(mapEntry.getKey(), newList); } } // TODO and NOTE: should get most stuff, but we could support Maps // and Lists in Maps and such; that's tricky because we have to go // through the entire Map and not just one entry, and we would // have to shallow copy the whole Map too } // this line goes at the end of the method, but moved up here to be part of the big comment about this contextMs.pop(); */ if (location.endsWith(".ftl")) { try { Map<String, ? extends Object> parameters = UtilGenerics.checkMap(context.get("parameters")); boolean insertWidgetBoundaryComments = ModelWidget.widgetBoundaryCommentsEnabled(parameters); if (insertWidgetBoundaryComments) { writer.append(HtmlWidgetRenderer.formatBoundaryComment("Begin", "Template", location)); } // FreeMarkerWorker.renderTemplateAtLocation(location, context, writer); Template template = null; if (location.endsWith(".fo.ftl")) { // FOP can't render correctly escaped characters template = FreeMarkerWorker.getTemplate(location); } else { template = FreeMarkerWorker.getTemplate(location, specialTemplateCache, specialConfig); } FreeMarkerWorker.renderTemplate(template, context, writer); if (insertWidgetBoundaryComments) { writer.append(HtmlWidgetRenderer.formatBoundaryComment("End", "Template", location)); } } catch (IllegalArgumentException e) { String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString(); Debug.logError(e, errMsg, module); writeError(writer, errMsg); } catch (MalformedURLException e) { String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString(); Debug.logError(e, errMsg, module); writeError(writer, errMsg); } catch (TemplateException e) { String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString(); Debug.logError(e, errMsg, module); writeError(writer, errMsg); } catch (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); } }
public MacroScreenRenderer(String name, String macroLibraryPath) throws TemplateException, IOException { macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath); rendererName = name; }