/** * Finds the parent layout template that will surround the inner layout template. By default it * will look in the same directory as the inner template for a template called 'layout'. * * @param newViewName not null. * @param templateLoader not null. * @return null if not found. * @throws Exception */ protected String findParentLayoutTemplate(String newViewName, TemplateLoader templateLoader) throws Exception { String parentTemplate = null; String[] paths = StringUtils.tokenizeToStringArray(newViewName, "/"); if (paths == null) return null; List<String> ps = new ArrayList<String>(); String cur = ""; for (String p : paths) { if (hasText(p)) { cur = cur + "/" + p; ps.add(cur); } } reverse(ps); if (!ps.isEmpty()) { ps.remove(0); for (String p : ps) { try { String n = p + "/" + getLayoutTemplateName(); templateLoader.getTemplate(n); parentTemplate = n; break; } catch (FileNotFoundException e1) { // Ignore as there is no layout template. } } } return parentTemplate; }
@Override protected AbstractUrlBasedView buildView(String viewName) throws Exception { final MustacheView view = (MustacheView) super.buildView(viewName); URI uri = new URI(viewName); String newViewName = uri.getPath(); Map<String, String> aliases = parseQueryString(uri.getQuery()); view.setPartialAliases(aliases); /* * Normalize the path. */ if (endsWithIgnoreCase(getPrefix(), "/") && startsWithIgnoreCase(newViewName, "/")) { newViewName = trimLeadingCharacter(newViewName, '/'); } TemplateLoader templateLoader = this.templateLoader.withPartialAliases(aliases); Compiler compiler = this.compiler.withLoader(templateLoader); /* * Reset the view url */ view.setUrl(getPrefix() + newViewName + getSuffix()); aliases.put(getInnerPartialAlias(), newViewName); /* * Go find the parent layout template if one is not defined. * We walk up the tree to find the parent. */ if (!hasText(aliases.get(getLayoutPartialAlias()))) { String parentTemplate = findParentLayoutTemplate(newViewName, templateLoader); if (hasText(parentTemplate)) aliases.put(getLayoutPartialAlias(), parentTemplate); } String templateName = null; boolean found = hasText(templateName = aliases.get(getLayoutPartialAlias())) || hasText(templateName = aliases.get(getInnerPartialAlias())); if (found) view.setTemplate(compiler.compile(templateLoader.getTemplate(templateName))); else throw new IllegalStateException("Body is missing"); return view; }