A version of {@link #renderHTML(Component...)} that exports the resulting HTML to the specified File.

@param outputFile Output path
@param components Components to render
517245
public static void saveHTMLFile(File outputFile, Component... components) throws IOException {
        FileUtils.writeStringToFile(outputFile, renderHTML(components));
    }
1279775
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WTemplate template = (WTemplate) component;

		// Setup the context
		Map<String, Object> context = new HashMap<>();
		// Make the component available under the "wc" key.
		context.put("wc", template);
		// Load the parameters
		context.putAll(template.getParameters());

		// Get template renderer for the engine
		String engine = template.getEngineName();
		if (Util.empty(engine)) {
			engine = ConfigurationProperties.getDefaultRenderingEngine();
		}
		TemplateRenderer templateRenderer = TemplateRendererFactory.newInstance(engine);

		// Render
		if (!Util.empty(template.getTemplateName())) {
			// Render the template
			templateRenderer.renderTemplate(template.getTemplateName(), context, template.getTaggedComponents(), renderContext.getWriter(),
					template.getEngineOptions());
		} else if (!Util.empty(template.getInlineTemplate())) {
			// Render inline
			templateRenderer.renderInline(template.getInlineTemplate(), context, template.getTaggedComponents(), renderContext.getWriter(),
					template.getEngineOptions());
		}
	}
556030
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WAbbrText abbrText = (WAbbrText) component;
		XmlStringBuilder xml = renderContext.getWriter();

		xml.appendTagOpen("abbr");
		xml.appendOptionalAttribute("title", abbrText.getToolTip());
		xml.appendOptionalAttribute("class", abbrText.getHtmlClass());
		xml.appendClose();
		xml.append(abbrText.getText(), abbrText.isEncodeText());
		xml.appendEndTag("abbr");
	}
1258247
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WProgressBar progressBar = (WProgressBar) component;
		XmlStringBuilder xml = renderContext.getWriter();

		xml.appendTagOpen("html:progress");
		xml.appendAttribute("id", component.getId());
		xml.appendAttribute("class", getHtmlClass(progressBar));
		xml.appendOptionalAttribute("hidden", progressBar.isHidden(), "hidden");
		xml.appendOptionalAttribute("title", progressBar.getToolTip());
		xml.appendOptionalAttribute("aria-label", progressBar.getAccessibleText());
		xml.appendAttribute("value", progressBar.getValue());
		xml.appendOptionalAttribute("max", progressBar.getMax() > 0, progressBar.getMax());
		xml.appendClose();
		xml.appendEndTag("html:progress");
	}
1366227
public void write(final ComponentDocumentationWrapper componentWrapper, final OutputStream outputStream)
            throws IOException {

        final Map<String, Object> data = new HashMap<>();

        try {
            data.put("breadcrumbs", _breadcrumbs);
            data.put("component", componentWrapper);

            {
                final Set<ConfiguredPropertyDescriptor> configuredProperties =
                        componentWrapper.getComponentDescriptor().getConfiguredProperties();
                final List<ConfiguredPropertyDescriptor> properties = new ArrayList<>(configuredProperties);
                final List<ConfiguredPropertyDocumentationWrapper> propertyList = new ArrayList<>();
                for (final ConfiguredPropertyDescriptor property : properties) {
                    final HiddenProperty hiddenProperty = property.getAnnotation(HiddenProperty.class);
                    final Deprecated deprecatedProperty = property.getAnnotation(Deprecated.class);

                    // we do not show hidden or deprecated properties in docs
                    if ((hiddenProperty == null || hiddenProperty.hiddenForLocalAccess() == false)
                            && deprecatedProperty == null) {
                        final ConfiguredPropertyDocumentationWrapper wrapper =
                                new ConfiguredPropertyDocumentationWrapper(property);
                        propertyList.add(wrapper);
                    }
                }

                data.put("properties", propertyList);
            }

            /* Write data to a file */
            final Writer out = new OutputStreamWriter(outputStream);
            _template.process(data, out);
            out.flush();
            out.close();
        } catch (final TemplateException e) {
            throw new IllegalStateException("Unexpected templare exception", e);
        }
    }
1342430
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WFieldLayout fieldLayout = (WFieldLayout) component;
		XmlStringBuilder xml = renderContext.getWriter();
		int labelWidth = fieldLayout.getLabelWidth();
		String title = fieldLayout.getTitle();

		xml.appendTagOpen("ui:fieldlayout");
		xml.appendAttribute("id", component.getId());
		xml.appendOptionalAttribute("class", component.getHtmlClass());
		xml.appendOptionalAttribute("track", component.isTracking(), "true");
		xml.appendOptionalAttribute("hidden", fieldLayout.isHidden(), "true");
		xml.appendOptionalAttribute("labelWidth", labelWidth > 0, labelWidth);
		xml.appendAttribute("layout", fieldLayout.getLayoutType());
		xml.appendOptionalAttribute("title", title);
		// Ordered layout
		if (fieldLayout.isOrdered()) {
			xml.appendAttribute("ordered", fieldLayout.getOrderedOffset());
		}
		xml.appendClose();

		// Render margin
		MarginRendererUtil.renderMargin(fieldLayout, renderContext);

		// Paint Fields
		paintChildren(fieldLayout, renderContext);

		xml.appendEndTag("ui:fieldlayout");
	}
838823
protected void renderId(
      FacesContext context,
      UIComponent  component) throws IOException
    {
      if (shouldRenderId(context, component))
      {
        String clientId = getClientId(context, component);
        context.getResponseWriter().writeAttribute(HTML.ID_ATTR, clientId, JSFAttr.ID_ATTR);
      }
    }
1310837
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WPanel panel = (WPanel) component;
		XmlStringBuilder xml = renderContext.getWriter();
		FlowLayout layout = (FlowLayout) panel.getLayout();
		Size gap = layout.getSpace();
		String gapString = gap != null ? gap.toString() : null;
		FlowLayout.Alignment align = layout.getAlignment();

		xml.appendTagOpen("ui:flowlayout");

		switch (align) {
			case RIGHT: {
				xml.appendAttribute("align", "right");
				break;
			}
			case CENTER: {
				xml.appendAttribute("align", "center");
				break;
			}
			case LEFT: {
				xml.appendAttribute("align", "left");
				break;
			}

			case VERTICAL:
				xml.appendAttribute("align", "vertical");
				break;

			default:
				throw new IllegalStateException("Unknown layout type: " + layout.getAlignment());
		}

		if (layout.getContentAlignment() != null) {
			switch (layout.getContentAlignment()) {
				case TOP: {
					xml.appendAttribute("valign", "top");
					break;
				}
				case MIDDLE: {
					xml.appendAttribute("valign", "middle");
					break;
				}
				case BASELINE: {
					xml.appendAttribute("valign", "baseline");
					break;
				}

				case BOTTOM:
					xml.appendAttribute("valign", "bottom");
					break;

				default:
					throw new IllegalStateException("Unknown content alignment type: " + layout.
							getContentAlignment());
			}
		}
		xml.appendOptionalAttribute("gap", gapString);

		xml.appendClose();

		int size = panel.getChildCount();

		for (int i = 0; i < size; i++) {
			xml.appendTag("ui:cell");
			WComponent child = panel.getChildAt(i);
			child.paint(renderContext);
			xml.appendEndTag("ui:cell");
		}

		xml.appendEndTag("ui:flowlayout");
	}
82326
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		XmlStringBuilder xml = renderContext.getWriter();
		WButton button = (WButton) component;
		String text = button.getText();
		String imageUrl = button.getImageUrl();
		String accessibleText = button.getAccessibleText();
		String toolTip = button.getToolTip();

		if (Util.empty(text) && imageUrl == null && Util.empty(accessibleText) && Util.empty(toolTip)) {
			throw new SystemException("WButton text or imageUrl must be specified");
		}

		xml.appendTagOpen(getTagName(button));

		String buttonId = button.getId();
		ImagePosition pos = button.getImagePosition();
		if (Util.empty(text) && Util.empty(toolTip) && Util.empty(accessibleText)) {
			// If the button has an imageUrl but no text equivalent get the text equivalent off of the image
			WImage imgHolder = button.getImageHolder();
			if (null != imgHolder) {
				toolTip = imgHolder.getAlternativeText();
			}
		}

		xml.appendAttribute("id", buttonId);
		xml.appendAttribute("name", buttonId);
		xml.appendAttribute("value", "x");
		xml.appendAttribute("type", getButtonType(button));
		xml.appendAttribute("class", geHtmlClassName(button));
		xml.appendOptionalAttribute("disabled", button.isDisabled(), "disabled");
		xml.appendOptionalAttribute("hidden", button.isHidden(), "hidden");
		xml.appendOptionalAttribute("title", toolTip);
		xml.appendOptionalAttribute("aria-label", accessibleText);
		xml.appendOptionalAttribute("aria-haspopup", button.isPopupTrigger(), "true");
		xml.appendOptionalAttribute("accesskey", Util.upperCase(button.getAccessKeyAsString()));
		xml.appendOptionalAttribute("data-wc-btnmsg", button.getMessage());

		if (button.isCancel()) {
			xml.appendAttribute("formnovalidate", "formnovalidate");
		} else {
			Action action = button.getAction();
			if (action instanceof ValidatingAction) {
				WComponent validationTarget = ((ValidatingAction) action).getComponentToValidate();
				xml.appendAttribute("data-wc-validate", validationTarget.getId());
			}
		}

		xml.appendClose();

		if (imageUrl != null) {
			xml.appendTagOpen("span");
			String imageHolderClass =  "wc_nti";
			if (pos != null) {
				StringBuffer imageHolderClassBuffer = new StringBuffer("wc_btn_img wc_btn_img");
				switch (pos) {
					case NORTH:
						imageHolderClassBuffer.append("n");
						break;
					case EAST:
						imageHolderClassBuffer.append("e");
						break;
					case SOUTH:
						imageHolderClassBuffer.append("s");
						break;
					case WEST:
						imageHolderClassBuffer.append("w");
						break;
					default:
						throw new SystemException("Unknown image position: " + pos);
				}
				imageHolderClass = imageHolderClassBuffer.toString();
			}
			xml.appendAttribute("class", imageHolderClass);
			xml.appendClose();

			if (pos != null && text != null) {
				xml.appendTag("span");
				xml.appendEscaped(text);
				xml.appendEndTag("span");
			}

			xml.appendTagOpen("img");
			xml.appendUrlAttribute("src", imageUrl);
			String alternateText = pos == null ? text : "";
			xml.appendAttribute("alt", alternateText);
			xml.appendEnd();
			xml.appendEndTag("span");
		} else if (text != null) {
			xml.appendEscaped(text);
		}

		xml.appendEndTag(getTagName(button));

		if (button.isAjax()) {
			paintAjax(button, xml);
		}
	}
1341234
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WComponentGroup group = (WComponentGroup) component;
		XmlStringBuilder xml = renderContext.getWriter();
		List<WComponent> components = group.getComponents();

		if (components != null && !components.isEmpty()) {
			xml.appendTagOpen("ui:componentGroup");
			xml.appendAttribute("id", component.getId());
			xml.appendOptionalAttribute("track", component.isTracking(), "true");
			xml.appendClose();

			for (WComponent comp : components) {
				xml.appendTagOpen("ui:component");
				xml.appendAttribute("id", comp.getId());
				xml.appendEnd();
			}

			xml.appendEndTag("ui:componentGroup");
		}
	}
962194
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WHiddenComment hiddenComponent = (WHiddenComment) component;
		XmlStringBuilder xml = renderContext.getWriter();

		String hiddenText = hiddenComponent.getText();

		if (!Util.empty(hiddenText)) {
			xml.appendTag("ui:comment");
			xml.appendEscaped(hiddenText);
			xml.appendEndTag("ui:comment");
		}
	}
807494
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WDateField dateField = (WDateField) component;
		XmlStringBuilder xml = renderContext.getWriter();
		boolean readOnly = dateField.isReadOnly();

		Date date = dateField.getDate();

		xml.appendTagOpen("ui:datefield");
		xml.appendAttribute("id", component.getId());
		xml.appendOptionalAttribute("class", component.getHtmlClass());
		xml.appendOptionalAttribute("track", component.isTracking(), "true");
		xml.appendOptionalAttribute("hidden", dateField.isHidden(), "true");
		if (readOnly) {
			xml.appendAttribute("readOnly", "true");
		} else {
			xml.appendOptionalAttribute("disabled", dateField.isDisabled(), "true");
			xml.appendOptionalAttribute("required", dateField.isMandatory(), "true");
			xml.appendOptionalAttribute("toolTip", dateField.getToolTip());
			xml.appendOptionalAttribute("accessibleText", dateField.getAccessibleText());

			WComponent submitControl = dateField.getDefaultSubmitButton();
			String submitControlId = submitControl == null ? null : submitControl.getId();
			xml.appendOptionalAttribute("buttonId", submitControlId);

			Date minDate = dateField.getMinDate();
			Date maxDate = dateField.getMaxDate();
			if (minDate != null) {
				xml.appendAttribute("min", new SimpleDateFormat(INTERNAL_DATE_FORMAT).format(minDate));
			}
			if (maxDate != null) {
				xml.appendAttribute("max", new SimpleDateFormat(INTERNAL_DATE_FORMAT).format(maxDate));
			}

			String autocomplete = dateField.getAutocomplete();
			xml.appendOptionalAttribute("autocomplete", !Util.empty(autocomplete), autocomplete);
		}

		if (date != null) {
			xml.appendAttribute("date", new SimpleDateFormat(INTERNAL_DATE_FORMAT).format(date));
		}

		xml.appendClose();

		if (date == null) {
			xml.appendEscaped(dateField.getText());
		}

		if (!readOnly) {
			DiagnosticRenderUtil.renderDiagnostics(dateField, renderContext);
		}

		xml.appendEndTag("ui:datefield");
	}
468388
private void renderRecipe() throws IOException {
		StringBuilder sb = new StringBuilder();

		// First pages
		if( ! Constants.GENERATED.equalsIgnoreCase( this.applicationTemplate.getName())) {
			sb.append( renderDocumentTitle());
			sb.append( renderPageBreak());

			sb.append( renderParagraph( this.messages.get( "intro" ))); //$NON-NLS-1$
			sb.append( renderPageBreak());

			sb.append( renderDocumentIndex());
			sb.append( renderPageBreak());

			sb.append( startTable());
			sb.append( addTableLine( this.messages.get( "app.name" ), this.applicationTemplate.getName())); //$NON-NLS-1$
			sb.append( addTableLine( this.messages.get( "app.qualifier" ), this.applicationTemplate.getVersion())); //$NON-NLS-1$
			sb.append( endTable());

			sb.append( renderApplicationDescription());
			sb.append( renderPageBreak());
			sb.append( renderSections( new ArrayList<String>( 0 )));

		} else {
			sb.append( renderDocumentIndex());
			sb.append( renderPageBreak());
		}

		// Render information about components
		sb.append( renderComponents());

		// Render information about facets
		sb.append( renderFacets());

		writeFileContent( sb.toString());
	}
794861
protected void renderDummyMarkup(FacesContext context, UIComponent component, String clientId) throws IOException {
        ResponseWriter writer = context.getResponseWriter();

        writer.startElement("div", null);
        writer.writeAttribute("id", clientId, null);
        writer.writeAttribute("style", "display: none;", null);

        renderPassThruAttributes(context, component, null);

        writer.endElement("div");
    }
830303
private IRenderer buildRenderer(
			File outputDirectory,
			ApplicationTemplate applicationTemplate,
			File applicationDirectory,
			Renderer renderer,
			Map<String,String> typeAnnotations ) {

		IRenderer result = null;
		switch( renderer ) {
		case HTML:
			result = new HtmlRenderer( outputDirectory, applicationTemplate, applicationDirectory, typeAnnotations );
			break;

		case MARKDOWN:
			result = new MarkdownRenderer( outputDirectory, applicationTemplate, applicationDirectory, typeAnnotations );
			break;

		case FOP:
			result = new FopRenderer( outputDirectory, applicationTemplate, applicationDirectory, typeAnnotations );
			break;

		case PDF:
			result = new PdfRenderer( outputDirectory, applicationTemplate, applicationDirectory, typeAnnotations );
			break;

		default:
			break;
		}

		return result;
	}
255215
protected void writeHtml(final MBasicTable table, final OutputStream outputStream,
			final boolean isSelection) throws IOException {
		final Writer out = new OutputStreamWriter(outputStream, "UTF-8");

		final String eol = isSelection ? "\n" : System.getProperty("line.separator");
		// eol = "\n" si sélection, "\r\n" sinon pour un fichier windows et "\n" pour un fichier unix

		out.write("<!-- Fichier genere par ");
		out.write(System.getProperty("user.name"));
		out.write(" le ");
		out.write(DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG)
				.format(new Date()));
		out.write(" -->");
		out.write(eol);

		out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
		out.write("<html>");
		out.write(eol);
		final String title = buildTitle(table);
		writeHtmlHead(title, out, eol);
		out.write("<body>");
		out.write(eol);
		if (title != null) {
			out.write("<h3>");
			out.write(title);
			out.write("</h3>");
		}
		out.write(eol);

		writeHtmlTable(table, isSelection, out, eol);
		out.write("</body>");
		out.write(eol);
		out.write("</html>");
		out.flush();
	}
1304007
@Override
	public void doRender(final WComponent component, final WebXmlRenderContext renderContext) {
		WSection section = (WSection) component;
		XmlStringBuilder xml = renderContext.getWriter();

		boolean renderChildren = isRenderContent(section);

		xml.appendTagOpen("ui:section");
		xml.appendAttribute("id", component.getId());
		xml.appendOptionalAttribute("class", component.getHtmlClass());
		xml.appendOptionalAttribute("track", component.isTracking(), "true");
		if (SectionMode.LAZY.equals(section.getMode())) {
			xml.appendOptionalAttribute("hidden", !renderChildren, "true");
		} else {
			xml.appendOptionalAttribute("hidden", component.isHidden(), "true");
		}

		SectionMode mode = section.getMode();
		if (mode != null) {
			switch (mode) {
				case LAZY:
					xml.appendAttribute("mode", "lazy");
					break;
				case EAGER:
					xml.appendAttribute("mode", "eager");
					break;
				default:
					throw new SystemException("Unknown section mode: " + section.getMode());
			}
		}

		xml.appendClose();

		// Render margin
		MarginRendererUtil.renderMargin(section, renderContext);

		if (renderChildren) {
			// Label
			section.getDecoratedLabel().paint(renderContext);
			// Content
			section.getContent().paint(renderContext);
		}

		xml.appendEndTag("ui:section");
	}