/* * Copyright 2008 Google Inc. * * Licensed 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 com.google.template.soy.tofu; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableSortedSet; import com.google.template.soy.data.SanitizedContent; import com.google.template.soy.data.SoyRecord; import com.google.template.soy.msgs.SoyMsgBundle; import com.google.template.soy.parseinfo.SoyTemplateInfo; import com.google.template.soy.shared.SoyCssRenamingMap; import com.google.template.soy.shared.SoyIdRenamingMap; import java.util.Map; import javax.annotation.Nullable; /** * SoyTofu is the public interface for a Java object that represents a compiled Soy file set. * * <p>Important: If you're a user of Soy, you should use the methods here (on a SoyTofu object * created by Soy), but should not create your own implementations of this interface. * */ public interface SoyTofu { /** * Gets the namespace of this SoyTofu object. The namespace is simply a convenience allowing * {@code newRenderer()} to be called with a partial template name (e.g. ".fooTemplate"). Note: * The namespace may be null, in which case {@code newRenderer()} must be called with the full * template name. * * @return The namespace of this SoyTofu object, or null if no namespace. */ String getNamespace(); /** * Gets a new SoyTofu instance with a different namespace (or no namespace). Note: The new SoyTofu * instance will still be backed by the same compiled Soy file set. * * @param namespace The namespace for the new SoyTofu instance, or null for no namespace. * @return A new SoyTofu instance with a different namespace (or no namespace). */ SoyTofu forNamespace(@Nullable String namespace); /** * Gets a new Renderer for a template. * * <p>The usage pattern is * soyTofu.newRenderer(...).setData(...).setInjectedData(...).setMsgBundle(...).render() where any * of the set* parts can be omitted if it's null. * * @param templateInfo Info for the template to render. * @return A new renderer for the given template. */ Renderer newRenderer(SoyTemplateInfo templateInfo); /** * Gets a new Renderer for a template. * * <p>The usage pattern is * soyTofu.newRenderer(...).setData(...).setInjectedData(...).setMsgBundle(...).render() where any * of the set* parts can be omitted if it's null. * * @param templateName The name of the template to render. If this SoyTofu instance is not * namespaced, then this parameter should be the full name of the template including the * namespace. If this SoyTofu instance is namespaced, then this parameter should be a partial * name beginning with a dot (e.g. ".fooTemplate"). * @return A new renderer for the given template. */ Renderer newRenderer(String templateName); /** * Gets the set of injected param keys used by a template (and its transitive callees). * * <p>Note: The {@code SoyTemplateInfo} object already has a method {@code getUsedIjParams()}. * That method should produce the same results as this method, unless the bundle of Soy files * included when running the SoyParseInfoGenerator is different from the bundle of Soy files * included when creating this SoyTofu object. * * @param templateInfo Info for the template to get injected params of. * @return The set of injected param keys used by the given template. */ ImmutableSortedSet<String> getUsedIjParamsForTemplate(SoyTemplateInfo templateInfo); /** * Gets the set of injected param keys used by a template (and its transitive callees). * * @param templateName The name of the template to get injected params of. * @return The set of injected param keys used by the given template. */ ImmutableSortedSet<String> getUsedIjParamsForTemplate(String templateName); // ----------------------------------------------------------------------------------------------- // Renderer interface. /** * Renderer for a template. * * <p>Important: If you're a user of Soy, you should use the methods here (on a Renderer object * created by Soy), but should not create your own implementations of this interface. */ interface Renderer { /** * Sets the data to call the template with. Can be null if the template has no parameters. * * <p>Note: If you call this method instead of {@link #setData(SoyRecord)}, your template data * will be converted to a {@code SoyMapData} object on each call. This may not be a big deal if * you only need to use the data object once. But if you need to reuse the same data object for * multiple calls, it's more efficient to build your own {@code SoyRecord} object and reuse it * with {@link #setData(SoyRecord)}. */ Renderer setData(Map<String, ?> data); /** Sets the data to call the template with. Can be null if the template has no parameters. */ Renderer setData(SoyRecord data); /** * Sets the injected data to call the template with. Can be null if not used. * * <p>Note: If you call this method instead of {@link #setIjData(SoyRecord)}, the data will be * converted to a {@code SoyRecord} object on each call. This may not be a big deal if you only * need to use the data object once. But if you need to reuse the same data object for multiple * calls, it's more efficient to build your own {@code SoyRecord} object and reuse it with * {@link #setIjData(SoyRecord)}. */ Renderer setIjData(Map<String, ?> ijData); /** Sets the injected data to call the template with. Can be null if not used. */ Renderer setIjData(SoyRecord ijData); /** * Sets the predicate to use for testing whether or not a given {@code delpackage} is active. */ Renderer setActiveDelegatePackageSelector(Predicate<String> activeDelegatePackageSelector); /** Sets the bundle of translated messages, or null to use the messages from the Soy source. */ Renderer setMsgBundle(SoyMsgBundle msgBundle); /** Sets the ID renaming map. */ Renderer setIdRenamingMap(SoyIdRenamingMap idRenamingMap); /** Sets the CSS renaming map. */ Renderer setCssRenamingMap(SoyCssRenamingMap cssRenamingMap); /** * Sets the expected content kind. * * <p>An attempt to render a non-strict template or a strict template with a different kind will * fail if this has been called. */ Renderer setContentKind(SanitizedContent.ContentKind contentKind); /** * Renders the template using the data, injected data, and message bundle previously set. * * <p>Checks the content kind of the template. Non-strict and kind="html" templates are allowed, * unless setContentKind was called. The goal is to prevent accidental rendering of unescaped * kind="text" in contexts where that could XSS. * * @throws SoyTofuException if an error occurs during rendering. */ String render(); /** * Renders the strict-mode template as a SanitizedContent object, which can be used as an input * to another Soy template, or used to verify that the output type is correct. * * <p>This returns a SanitizedContent object corresponding to the kind="..." attribute of the * template. The expected content kind must be set beforehand, unless HTML is expected, to avoid * an exception. * * @throws IllegalArgumentException If the template is non-strict, or the kind doesn't match the * expected kind (from setContentKind, or the default of HTML). * @throws SoyTofuException if an error occurs during rendering. */ SanitizedContent renderStrict(); /** * Renders the template using the data, injected data, and message bundle previously set into * the given Appendable. * * <p>Checks the content kind of the template. Non-strict and kind="html" templates are allowed, * unless setContentKind was called. The goal is to prevent accidental rendering of unescaped * kind="text" in contexts where that could XSS. * * @throws SoyTofuException if an error occurs during rendering. */ SanitizedContent.ContentKind render(Appendable out); } // ----------------------------------------------------------------------------------------------- // Old render methods. /** * Renders a template. * * @param templateInfo Info for the template to render. * @param data The data to call the template with. Can be null if the template has no parameters. * @param msgBundle The bundle of translated messages, or null to use the messages from the Soy * source. * @return The rendered text. * @deprecated Use {@link #newRenderer(SoyTemplateInfo)}. */ @Deprecated String render( SoyTemplateInfo templateInfo, @Nullable SoyRecord data, @Nullable SoyMsgBundle msgBundle); /** * Renders a template. * * <p>Note: If you call this method instead of {@link #render(String, SoyRecord, SoyMsgBundle)}, * your template data will be converted to a {@code SoyRecord} object on each call. This may not * be a big deal if you only need to use the data object once. But if you need to reuse the same * data object for multiple calls, it's more efficient to build your own {@code SoyRecord} object * and reuse it with {@link #render(String, SoyRecord, SoyMsgBundle)}. * * @param templateName The name of the template to render. If this SoyTofu instance is namespaced, * then this parameter should be a partial name beginning with a dot (e.g. ".fooTemplate"). * @param data The data to call the template with. Can be null if the template has no parameters. * @param msgBundle The bundle of translated messages, or null to use the messages from the Soy * source. * @return The rendered text. * @deprecated Use {@link #newRenderer(String)}. */ @Deprecated String render( String templateName, @Nullable Map<String, ?> data, @Nullable SoyMsgBundle msgBundle); /** * Renders a template. * * @param templateName The name of the template to render. If this SoyTofu instance is namespaced, * then this parameter should be a partial name beginning with a dot (e.g. ".fooTemplate"). * @param data The data to call the template with. Can be null if the template has no parameters. * @param msgBundle The bundle of translated messages, or null to use the messages from the Soy * source. * @return The rendered text. * @deprecated Use {@link #newRenderer(String)}. */ @Deprecated String render(String templateName, @Nullable SoyRecord data, @Nullable SoyMsgBundle msgBundle); }