Search in sources :

Example 1 with MaybeMissingTemplate

use of freemarker.cache.TemplateCache.MaybeMissingTemplate in project freemarker by apache.

the class Configuration method getTemplate.

/**
 * Retrieves the template with the given name (and according the specified further parameters) from the template
 * cache, loading it into the cache first if it's missing/staled.
 *
 * <p>
 * This method is thread-safe.
 *
 * <p>
 * See {@link Configuration} for an example of basic usage.
 *
 * @param name
 *            The name or path of the template, which is not a real path, but interpreted inside the current
 *            {@link TemplateLoader}. Can't be {@code null}. The exact syntax of the name depends on the underlying
 *            {@link TemplateLoader}, but the cache makes some assumptions. First, the name is expected to be a
 *            hierarchical path, with path components separated by a slash character (not with backslash!). The path
 *            (the name) given here must <em>not</em> begin with slash; it's always interpreted relative to the
 *            "template root directory". Then, the {@code ..} and {@code .} path meta-elements will be resolved. For
 *            example, if the name is {@code a/../b/./c.ftl}, then it will be simplified to {@code b/c.ftl}. The
 *            rules regarding this are the same as with conventional UN*X paths. The path must not reach outside the
 *            template root directory, that is, it can't be something like {@code "../templates/my.ftl"} (not even
 *            if this path happens to be equivalent with {@code "/my.ftl"}). Furthermore, the path is allowed to
 *            contain at most one path element whose name is {@code *} (asterisk). This path meta-element triggers
 *            the <i>acquisition mechanism</i>. If the template is not found in the location described by the
 *            concatenation of the path left to the asterisk (called base path) and the part to the right of the
 *            asterisk (called resource path), the cache will attempt to remove the rightmost path component from
 *            the base path ("go up one directory") and concatenate that with the resource path. The process is
 *            repeated until either a template is found, or the base path is completely exhausted.
 *
 * @param locale
 *            The requested locale of the template. This is what {@link Template#getLocale()} on the resulting
 *            {@link Template} will return (unless it's overridden via {@link #getTemplateConfigurations()}). This
 *            parameter can be {@code null} since 2.3.22, in which case it defaults to
 *            {@link Configuration#getLocale()} (note that {@link Template#getLocale()} will give the default value,
 *            not {@code null}). This parameter also drives localized template lookup. Assuming that you have
 *            specified {@code en_US} as the locale and {@code myTemplate.ftl} as the name of the template, and the
 *            default {@link TemplateLookupStrategy} is used and
 *            {@code #setLocalizedLookup(boolean) localized_lookup} is {@code true}, FreeMarker will first try to
 *            retrieve {@code myTemplate_en_US.html}, then {@code myTemplate.en.ftl}, and finally
 *            {@code myTemplate.ftl}. Note that that the template's locale will be {@code en_US} even if it only
 *            finds {@code myTemplate.ftl}. Note that when the {@code locale} setting is overridden with a
 *            {@link TemplateConfiguration} provided by {@link #getTemplateConfigurations()}, that overrides the
 *            value specified here, but only after the localized lookup, that is, it modifies the template
 *            found by the localized lookup.
 *
 * @param customLookupCondition
 *            This value can be used by a custom {@link TemplateLookupStrategy}; has no effect with the default one.
 *            Can be {@code null} (though it's up to the custom {@link TemplateLookupStrategy} if it allows that).
 *            This object will be used as part of the cache key, so it must to have a proper
 *            {@link Object#equals(Object)} and {@link Object#hashCode()} method. It also should have reasonable
 *            {@link Object#toString()}, as it's possibly quoted in error messages. The expected type is up to the
 *            custom {@link TemplateLookupStrategy}. See also:
 *            {@link TemplateLookupContext#getCustomLookupCondition()}.
 *
 * @param encoding
 *            Deprecated mechanism, {@code null} is the recommended; the charset used to interpret the template
 *            source code bytes (if it's read from a binary source). Can be {@code null} since 2.3.22, in which case
 *            it will default to {@link Configuration#getEncoding(Locale)} where {@code Locale} is the
 *            {@code locale} parameter (when {@code locale} was {@code null} too, the its default value is used
 *            instead). Why is this deprecated: It doesn't make sense to get the <em>same</em> template with
 *            different encodings, hence, it's error prone to specify the encoding where you get the template.
 *            Instead, if you have template "files" with different charsets, you should use
 *            {@link #setTemplateConfigurations(TemplateConfigurationFactory)}, where you can associate encodings to
 *            individual templates based on their names (like which "directory" are they in, what's their file
 *            extension, etc.). The encoding associated with the templates that way overrides the encoding that you
 *            specify here.
 *
 * @param parseAsFTL
 *            If {@code true}, the loaded template is parsed and interpreted normally, as a regular FreeMarker
 *            template. If {@code false}, the loaded template is treated as a static text, so <code>${...}</code>,
 *            {@code <#...>} etc. will not have special meaning in it.
 *
 * @param ignoreMissing
 *            If {@code true}, the method won't throw {@link TemplateNotFoundException} if the template doesn't
 *            exist, instead it returns {@code null}. Other kind of exceptions won't be suppressed.
 *
 * @return the requested template; maybe {@code null} when the {@code ignoreMissing} parameter is {@code true}.
 *
 * @throws TemplateNotFoundException
 *             If the template could not be found. Note that this exception extends {@link IOException}.
 * @throws MalformedTemplateNameException
 *             If the template name given was in violation with the {@link TemplateNameFormat} in use. Note that
 *             this exception extends {@link IOException}.
 * @throws ParseException
 *             (extends <code>IOException</code>) if the template is syntactically bad. Note that this exception
 *             extends {@link IOException}.
 * @throws IOException
 *             If there was some other problem with reading the template "file". Note that the other exceptions
 *             extend {@link IOException}, so this should be catched the last.
 *
 * @since 2.3.22
 */
public Template getTemplate(String name, Locale locale, Object customLookupCondition, String encoding, boolean parseAsFTL, boolean ignoreMissing) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
    if (locale == null) {
        locale = getLocale();
    }
    if (encoding == null) {
        encoding = getEncoding(locale);
    }
    final MaybeMissingTemplate maybeTemp = cache.getTemplate(name, locale, customLookupCondition, encoding, parseAsFTL);
    final Template temp = maybeTemp.getTemplate();
    if (temp == null) {
        if (ignoreMissing) {
            return null;
        }
        TemplateLoader tl = getTemplateLoader();
        String msg;
        if (tl == null) {
            msg = "Don't know where to load template " + StringUtil.jQuote(name) + " from because the \"template_loader\" FreeMarker " + "setting wasn't set (Configuration.setTemplateLoader), so it's null.";
        } else {
            final String missingTempNormName = maybeTemp.getMissingTemplateNormalizedName();
            final String missingTempReason = maybeTemp.getMissingTemplateReason();
            final TemplateLookupStrategy templateLookupStrategy = getTemplateLookupStrategy();
            msg = "Template not found for name " + StringUtil.jQuote(name) + (missingTempNormName != null && name != null && !removeInitialSlash(name).equals(missingTempNormName) ? " (normalized: " + StringUtil.jQuote(missingTempNormName) + ")" : "") + (customLookupCondition != null ? " and custom lookup condition " + StringUtil.jQuote(customLookupCondition) : "") + "." + (missingTempReason != null ? "\nReason given: " + ensureSentenceIsClosed(missingTempReason) : "") + "\nThe name was interpreted by this TemplateLoader: " + StringUtil.tryToString(tl) + "." + (!isKnownNonConfusingLookupStrategy(templateLookupStrategy) ? "\n(Before that, the name was possibly changed by this lookup strategy: " + StringUtil.tryToString(templateLookupStrategy) + ".)" : "") + // Suspected reasons or warning:
            (!templateLoaderExplicitlySet ? "\nWarning: The \"template_loader\" FreeMarker setting " + "wasn't set (Configuration.setTemplateLoader), and using the default value " + "is most certainly not intended and dangerous, and can be the cause of this error." : "") + (missingTempReason == null && name.indexOf('\\') != -1 ? "\nWarning: The name contains backslash (\"\\\") instead of slash (\"/\"); " + "template names should use slash only." : "");
        }
        String normName = maybeTemp.getMissingTemplateNormalizedName();
        throw new TemplateNotFoundException(normName != null ? normName : name, customLookupCondition, msg);
    }
    return temp;
}
Also used : MaybeMissingTemplate(freemarker.cache.TemplateCache.MaybeMissingTemplate) TemplateLoader(freemarker.cache.TemplateLoader) MultiTemplateLoader(freemarker.cache.MultiTemplateLoader) ClassTemplateLoader(freemarker.cache.ClassTemplateLoader) URLTemplateLoader(freemarker.cache.URLTemplateLoader) FileTemplateLoader(freemarker.cache.FileTemplateLoader) TemplateLookupStrategy(freemarker.cache.TemplateLookupStrategy) MaybeMissingTemplate(freemarker.cache.TemplateCache.MaybeMissingTemplate)

Aggregations

ClassTemplateLoader (freemarker.cache.ClassTemplateLoader)1 FileTemplateLoader (freemarker.cache.FileTemplateLoader)1 MultiTemplateLoader (freemarker.cache.MultiTemplateLoader)1 MaybeMissingTemplate (freemarker.cache.TemplateCache.MaybeMissingTemplate)1 TemplateLoader (freemarker.cache.TemplateLoader)1 TemplateLookupStrategy (freemarker.cache.TemplateLookupStrategy)1 URLTemplateLoader (freemarker.cache.URLTemplateLoader)1