[
https://issues.apache.org/jira/browse/TILES-569?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13667623#comment-13667623
]
Mck SembWever commented on TILES-569:
-------------------------------------
The other blog seems to deal mostly with how to configure dependencies
correctly. The original blog is thin in this area and it's on my todo list to
improve.
OptionsRenderer can be read and easily forked here
https://github.com/apache/tiles/blob/trunk/tiles-extras/src/main/java/org/apache/tiles/extras/renderer/OptionsRenderer.java
It already implements caching.
It would be great to see support added for multiple conditions in the one
value.
> Proposal for conditionals in tiles definitions
> ----------------------------------------------
>
> Key: TILES-569
> URL: https://issues.apache.org/jira/browse/TILES-569
> Project: Tiles
> Issue Type: Improvement
> Components: tiles-core
> Affects Versions: 3.0.1
> Reporter: Marc Ewert
>
> Hi,
> I've recently tried the OptionsRenderer suggested in this tutorial
> [http://tech.finn.no/2012/07/25/the-ultimate-view-tiles-3/4/], but wasn't
> able to succeed. The defined attributes wasn't available for some reason.
> So I took the idea and implemented my own solution. Perhaps it's something
> for the trunk? My syntax is as follows:
> {code}
> <tiles-definitions>
> <definition name="main/*/*" template="/WEB-INF/tiles/_layout/main.jsp">
> <put-attribute name="title"
> value="/WEB-INF/tiles/[{1}/{2}|{1}|_common]/title.jsp"/>
> <put-attribute name="navigation"
> value="/WEB-INF/tiles/[{1}/{2}|{1}|_common]/navigation.jsp"/>
> <put-attribute name="content"
> value="/WEB-INF/tiles/[{1}/{2}|{1}|_common]/content.jsp"/>
> <put-attribute name="footer"
> value="/WEB-INF/tiles/[{1}/{2}|{1}|_common]/footer.jsp"/>
> <put-attribute name="javaScript"
> value="/WEB-INF/tiles/[{1}/{2}|{1}|_common]/javaScript.jsp"/>
> </definition>
> </tiles-definitions>
> {code}
> The renderer searches for patterns like [opt_1|opt_2|...|opt_n] which may
> occur several times in the value partameters. With a backtrack algorithm the
> first matching valid path is searched and rendered.
> I like the compactness of the notation, no need for attribute lists, which
> didn't function in my case.
> Here is my renderer implementation, perhaps you are interested in integrating
> it. The path evaluation eventually has to be refactored. I don't know if
> there is a more elegant way and how costly the current solution is. Perhaps
> there has to be done some caching...
> {code}
> /**
> * Renderer implementation supporting the notation "[CHOICE_1|...|CHOICE_n]"
> in the paths.
> * The first matching path replacement will be choosen.
> */
> public final class ChoiceRenderer implements Renderer {
> private static final Pattern CHOICE_PATTERN =
> Pattern.compile("\\[([^\\]]+)\\]");
> private final Renderer renderer;
> /**
> * Creates a new instance wrapping the given renderer.
> */
> public ChoiceRenderer(Renderer renderer) {
> this.renderer = renderer;
> }
> /**
> * @see
> org.apache.tiles.request.render.Renderer#isRenderable(java.lang.String,
> org.apache.tiles.request.Request)
> */
> @Override
> public boolean isRenderable(String path, Request request) {
> // only the overall format is checked, so no extra handling here
> return this.renderer.isRenderable(path, request);
> }
> /**
> * @see org.apache.tiles.request.render.Renderer#render(java.lang.String,
> org.apache.tiles.request.Request)
> */
> @Override
> public void render(String path, Request request) throws IOException {
> Matcher matcher = CHOICE_PATTERN.matcher(path);
> List<String[]> groups = new ArrayList<String[]>();
> StringBuffer sb = new StringBuffer();
> while (matcher.find()) {
> // adds a pattern to the resulting path, which will be replaced
> by the
> // available choices
> matcher.appendReplacement(sb, "{[" + groups.size() + "]}");
> groups.add(matcher.group(1).split("\\|"));
> }
> matcher.appendTail(sb);
> if (groups.isEmpty()) {
> this.renderer.render(path, request);
> } else {
> backtrackPaths(sb.toString(), request, groups, 0);
> }
> }
> private String backtrackPaths(String pathPattern, Request request,
> List<String[]> groups, int depth)
> throws IOException {
> String matchPath = null;
> String[] parts = groups.get(depth);
> for (int i = 0; i < parts.length; ++i) {
> String path = pathPattern.replace("{[" + depth + "]}", parts[i]);
> if (depth == groups.size() - 1) {
> if (isPathValid(path, request)) {
> // found the first matching choice
> this.renderer.render(path, request);
> matchPath = path;
> break;
> }
> } else {
> matchPath = backtrackPaths(path, request, groups, depth + 1);
> }
> }
> return matchPath;
> }
> // TODO should we use caching here?
> private boolean isPathValid(String path, Request request) {
> boolean rtn = false;
> // apparently the corresponding Renderer method seems to check the
> // path's format only
> if (this.renderer.isRenderable(path, request)) {
> try {
> rtn = request.getApplicationContext().getResource(path) !=
> null;
> } catch (IllegalArgumentException e) {
> // TODO the javadoc states that null will be returned, but
> // instead of it an exception is thrown.
> // Seems to be a bug?!
> boolean throwException = true;
> if (e.getCause() instanceof FileNotFoundException) {
> FileNotFoundException fex = (FileNotFoundException)
> e.getCause();
> throwException = fex.getMessage().indexOf(path) == -1;
> }
> if (throwException) {
> // seems to be a different reason as our searched path
> throw e;
> }
> }
> }
> return rtn;
> }
> }
> {code}
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira