Index: src/test/java/org/apache/sling/microsling/integration/NodetypeRenderingTest.java
===================================================================
--- src/test/java/org/apache/sling/microsling/integration/NodetypeRenderingTest.java (revision 591525)
+++ src/test/java/org/apache/sling/microsling/integration/NodetypeRenderingTest.java (working copy)
@@ -119,4 +119,15 @@
testClient.delete(toDelete);
}
}
-}
\ No newline at end of file
+
+ public void testErbHtml() throws IOException {
+ final String toDelete = uploadTestScript("rendering-test.erb","html.erb");
+ try {
+ final String content = getContent(displayUrl + ".html", CONTENT_TYPE_HTML);
+ assertTrue("Content includes Ruby marker",content.contains("Ruby template"));
+ assertTrue("Content contains formatted test text",content.contains("
" + testText + "
"));
+ } finally {
+ testClient.delete(toDelete);
+ }
+ }
+}
Index: src/test/resources/integration-test/rendering-test.erb
===================================================================
--- src/test/resources/integration-test/rendering-test.erb (revision 0)
+++ src/test/resources/integration-test/rendering-test.erb (revision 0)
@@ -0,0 +1,15 @@
+!-- used by ScriptedRenderingTest -->
+
+
+ Ruby template <%= Time.now %>
+ <%= resource.getRawData().getProperty("text").getString() %>
+ <% unless props.nil? or props.empty? %>
+
+ <% for prop, val in props %>
+ | <%= prop %>: | <%= val %> |
+ <% end %>
+
+ <% end %>
+
+
+
Index: src/main/java/org/apache/sling/microsling/scripting/engines/ruby/ErbScriptEngine.java
===================================================================
--- src/main/java/org/apache/sling/microsling/scripting/engines/ruby/ErbScriptEngine.java (revision 0)
+++ src/main/java/org/apache/sling/microsling/scripting/engines/ruby/ErbScriptEngine.java (revision 0)
@@ -0,0 +1,108 @@
+package org.apache.sling.microsling.scripting.engines.ruby;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Map;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.sling.api.HttpStatusCodeException;
+import org.apache.sling.api.SlingException;
+import org.apache.sling.api.scripting.SlingScript;
+import org.apache.sling.api.scripting.SlingScriptEngine;
+import org.jruby.Ruby;
+import org.jruby.RubyModule;
+import org.jruby.RubySymbol;
+import org.jruby.javasupport.JavaEmbedUtils;
+import org.jruby.runtime.builtin.IRubyObject;
+
+/**
+ * A ScriptEngine that uses ruby erb templates to render a Resource
+ */
+public class ErbScriptEngine implements SlingScriptEngine {
+
+ public static final String RUBY_SCRIPT_EXTENSION = "erb";
+ public Ruby runtime;
+ RubySymbol bindingSym;
+ RubyModule erbModule;
+
+ public ErbScriptEngine() throws SlingException {
+ runtime = Ruby.getDefaultInstance();
+
+ runtime.evalScript("require 'java';require 'erb';self.send :include, ERB::Util;class ERB;def get_binding;binding;end;attr_reader :props;def set_props(p);@props = p;"
+ + "for name,v in @props;instance_eval \"def #{name}; @props['#{name}'];end\";end;end;end;");
+
+ erbModule = runtime.getClassFromPath("ERB");
+ bindingSym = RubySymbol.newSymbol(runtime, "get_binding");
+ }
+
+ public String[] getExtensions() {
+ return new String[]{RUBY_SCRIPT_EXTENSION};
+ }
+
+ public String getEngineName() {
+ return "Ruby Erb Script Engine";
+ }
+
+ public String getEngineVersion() {
+ return "0.9";
+ }
+
+ public void eval(SlingScript script, Map props)
+ throws SlingException, IOException {
+ // ensure get method
+ HttpServletRequest request = (HttpServletRequest) props.get(REQUEST);
+ if(!"GET".equals(request.getMethod())) {
+ throw new HttpStatusCodeException(
+ HttpServletResponse.SC_METHOD_NOT_ALLOWED,
+ "Ruby templates only support GET requests");
+ }
+
+ try {
+ final Writer w = ((HttpServletResponse) props.get(RESPONSE)).getWriter();
+ PrintStream stream = new PrintStream(new OutputStream() {
+ public void write(int b) {
+ try {
+ w.write(b);
+ } catch(IOException ex) {
+ }
+ }
+ });
+
+ StringBuffer scriptString = new StringBuffer();
+ BufferedReader bufferedScript = (BufferedReader) script.getScriptReader();
+ String nextLine = bufferedScript.readLine();
+ while(nextLine != null) {
+ scriptString.append(nextLine);
+ scriptString.append("\n");
+ nextLine = bufferedScript.readLine();
+ }
+
+ IRubyObject scriptRubyString = JavaEmbedUtils.javaToRuby(runtime, scriptString.toString());
+ IRubyObject erb = (IRubyObject) JavaEmbedUtils
+ .invokeMethod(runtime, erbModule, "new", new Object[]{scriptRubyString}, IRubyObject.class);
+
+ JavaEmbedUtils.invokeMethod(runtime, erb, "set_props",
+ new Object[]{JavaEmbedUtils.javaToRuby(runtime, props)}, IRubyObject.class);
+
+ IRubyObject binding = (IRubyObject) JavaEmbedUtils
+ .invokeMethod(runtime, erb, "send", new Object[]{bindingSym}, IRubyObject.class);
+
+ String out = (String) JavaEmbedUtils.invokeMethod(runtime, erb, "result",
+ new Object[]{(Object) binding}, String.class);
+
+ stream.println(out);
+ stream.flush();
+
+ } catch(IOException ioe) {
+ throw ioe;
+ } catch(Throwable t) {
+ throw new SlingException("Failure running Ruby script ", t);
+ }
+ }
+}
Index: src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptResolver.java
===================================================================
--- src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptResolver.java (revision 591525)
+++ src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptResolver.java (working copy)
@@ -42,6 +42,7 @@
import org.apache.sling.api.scripting.SlingScriptResolver;
import org.apache.sling.microsling.resource.JcrNodeResource;
import org.apache.sling.microsling.scripting.engines.freemarker.FreemarkerScriptEngine;
+import org.apache.sling.microsling.scripting.engines.ruby.ErbScriptEngine;
import org.apache.sling.microsling.scripting.engines.rhino.RhinoJavasSriptEngine;
import org.apache.sling.microsling.scripting.engines.velocity.VelocityTemplatesScriptEngine;
import org.apache.sling.microsling.scripting.helpers.ScriptFilenameBuilder;
@@ -80,6 +81,7 @@
addScriptEngine(new RhinoJavasSriptEngine());
addScriptEngine(new VelocityTemplatesScriptEngine());
addScriptEngine(new FreemarkerScriptEngine());
+ addScriptEngine(new ErbScriptEngine());
}
/**
Index: src/main/webapp/erb-scripts.html
===================================================================
--- src/main/webapp/erb-scripts.html (revision 0)
+++ src/main/webapp/erb-scripts.html (revision 0)
@@ -0,0 +1,39 @@
+
+
+ microsling Ruby Erb templates
+
+
+
+ microsling Ruby Erb templates
+
+
+
+ Scripts found by the SlingScriptResolver using the .erb extension are executed by
+ the ErbScriptEngine.
+
+
+ This works exactly like the Velocity templates, except that
+ templates use the Erb syntax.
+
+
+ Here's an example HTML template. See the Erb docs website
+ more info about the syntax.
+
+ <html>
+ <body>
+ <p><span>This is an example Erb template <%= Time.now %></span></p>
+ <p><span><%= resource.getItem().getProperty("text").getString() %></span></p>
+ <% unless props.nil? or props.empty? %>
+ <table>
+ <% for prop, val in props %>
+ <tr><td><b><%= prop %></b>:</td><td><%= val %></td></tr>
+ <% end %>
+ </table>
+ <% end %>
+ </body>
+ </html>
+
+
+
Index: src/main/webapp/index.html
===================================================================
--- src/main/webapp/index.html (revision 591525)
+++ src/main/webapp/index.html (working copy)
@@ -40,6 +40,11 @@
FreeMarker templates
: explains how to use FreeMarker templates to render content.
+
+
+ Ruby Erb templates
+ : explains how to use Ruby Erb templates to render content.
+
Show me the code
@@ -144,4 +149,4 @@