import java.io.StringWriter;
import java.io.Writer;
import java.io.IOException;
+import java.io.FileNotFoundException;
import java.util.*;
import org.ibex.util.*;
import org.ibex.js.*;
public class Template extends JSElement {
- public static Template parse(String path, Template.Scope s) throws IOException {
+ public static Template parse(String path, Template.Scope s) throws FileNotFoundException, IOException {
Reader xmlreader = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
XML.Document doc = new XML.Document();
doc.parse(xmlreader);
case "js": e = new Template.JSTag(e); break;
case "foreach": e = new Template.ForEach(e); break;
case "children": e = new Template.Children(e); break;
+ case "redirect": e = new Template.Redirect(e); break;
case "transaction": e = new Template.Transaction(e, s); break;
//#end
//throw new JSElement.Exn("Unknown XT library: "+uri);
} else if (uri.startsWith("local:")) {
- Template t = parse(s.getLocalPath() + uri.substring(6), s);
+ // merge a new template into this tree
+ String path = uri.substring(6) + e.getLocalName() + ".xt";
+ Template t = parse(s.getLocalPath() + path, s);
List c = e.getChildren();
if (c.size() > 0) {
e.getChildren().clear();
}
- // merge original attributes with replacement template
- e = new JSElement.Merge(t, e);
+ XML.Element merged = new JSElement.Merge(t, e);
+
+ // remap the parent of the original element
+ if (e.getParent() != null) {
+ List ch = e.getParent().getChildren();
+ ch.set(ch.indexOf(e), merged);
+ }
+
+ return wrap(merged, s);
}
XML.Attributes a = e.getAttributes();
}
/** Returns the first Template.Children child found. */
- private static Template.Children findPlaceholder(XML.Element e) {
- if (e instanceof Template.Children) return (Template.Children)e;
+ private static XML.Element findPlaceholder(XML.Element e) {
+ if ("http://xt.ibex.org/".equals(e.getUri()) && "children".equals(e.getLocalName()))
+ return e;
+
List c = e.getChildren();
for (int i=0; i < c.size(); i++) {
if (!(c.get(i) instanceof XML.Element)) continue;
- Template.Children ret = findPlaceholder((XML.Element)c.get(i));
+ XML.Element ret = findPlaceholder((XML.Element)c.get(i));
if (ret != null) return ret;
}
return null;
public Children(XML.Element e) { super(e); }
}
+ public static final class Redirect extends JSElement {
+ public Redirect(XML.Element e) { super(e); }
+
+ public void out(Writer w) throws IOException {
+ loadAttr();
+
+ try {
+ Object p = get("page"); if (p != null) undeclare("page");
+ if (p == null || !(p instanceof String) || ((String)p).trim().equals(""))
+ throw new JSElement.Exn("<"+getPrefix()+":redirect> requires 'page' "+
+ "attribute to be a valid template path");
+ throw new RedirectSignal((String)p);
+ } catch (JSExn e) { throw new JSElement.Exn(e); }
+ }
+ }
+
// TODO: finish
public static final class Transaction extends JSElement {
private final Template.Scope scope; // FIXME: HACK. unstatisise all tags, or do this to all