Permalink
Browse files

Basic template rendering

  • Loading branch information...
1 parent 8dc2a85 commit 552f9c8b0381ee2bbea6e6c041bf678bbc97d8a5 @josevalim josevalim committed Sep 7, 2012
View
@@ -36,7 +36,7 @@ defmodule Dynamo.App.Config do
quote do
name = :"__initializer_#{unquote(name)}"
@initializers { name, unquote(__CALLER__.line), [] }
- defp name, [], [], do: unquote(block)
+ defp name, [], [], do: unquote(Macro.escape block)
end
end
@@ -83,7 +83,7 @@ defmodule Dynamo.Router.Callbacks do
name = :"__prepare_callback_#{length(@__prepare_callbacks)}"
args = quote do: [var!(conn)]
guards = quote do: [is_tuple(var!(conn))]
- defp name, args, guards, do: unquote(block)
+ defp name, args, guards, do: unquote(Macro.escape block)
@__prepare_callbacks name
end
end
@@ -102,7 +102,7 @@ defmodule Dynamo.Router.Callbacks do
name = :"__finalize_callback_#{length(@__finalize_callbacks)}"
args = quote do: [var!(conn)]
guards = quote do: [is_tuple(var!(conn))]
- defp name, args, guards, do: unquote(block)
+ defp name, args, guards, do: unquote(Macro.escape block)
@__finalize_callbacks name
end
end
View
@@ -0,0 +1,47 @@
+defmodule Dynamo.Views do
+ defrecord Template, identifier: nil, format: nil, handler: nil, source: nil, updated_at: nil
+
+ defexception TemplateNotFound, query: nil, view_paths: nil do
+ def message(exception) do
+ "Could not find template #{inspect exception.query} in any of view paths: #{inspect exception.view_paths}"
+ end
+ end
+
+ def render(query, view_paths, assigns) do
+ template = Enum.find_value(view_paths, fn(x) -> x.find(query) end)
+ module = compile_template template, query, view_paths
+
+ try do
+ module.render(assigns, template)
+ after
+ :code.purge(module)
+ :code.delete(module)
+ end
+ end
+
+ defp compile_template(nil, query, view_paths) do
+ raise Dynamo.Views.TemplateNotFound, query: query, view_paths: view_paths
+ end
+
+ defp compile_template(Dynamo.Views.Template[handler: handler] = template, _, _) do
+ source = get_handler(handler).compile(template)
+
+ source = quote hygiene: false do
+ _ = assigns
+ _ = template
+ unquote(source)
+ end
+
+ defmodule Elixir.Dynamo.Views.CompiledTemplate do
+ args = quote hygiene: false, do: [assigns, template]
+ def :render, args, [], do: source
+ end
+
+ Dynamo.Views.CompiledTemplate
+ end
+
+ # TODO: Remove hardcoded handler.
+ defp get_handler("eex") do
+ Dynamo.Views.EEXHandler
+ end
+end
View
@@ -0,0 +1,31 @@
+
+
+defmodule Dynamo.Views.PathFinder do
+ # TODO: Define handler behaviour
+
+ def new(path) do
+ { __MODULE__, File.expand_path(path) }
+ end
+
+ def find(template, { __MODULE__, path }) do
+ query = File.join(path, template <> ".*")
+ tmpl = Enum.first File.wildcard(query)
+
+ if tmpl do
+ Dynamo.Views.Template[
+ updated_at: File.stat!(tmpl).mtime,
+ identifier: tmpl,
+ handler: extname(tmpl),
+ format: extname(File.rootname(tmpl)),
+ source: File.read!(tmpl)
+ ]
+ end
+ end
+
+ defp extname(path) do
+ case File.extname(path) do
+ "." <> ext -> ext
+ ext -> ext
+ end
+ end
+end
@@ -0,0 +1,7 @@
+defmodule Dynamo.Views.EEXHandler do
+ # TODO: Define handler behaviour
+
+ def compile(Dynamo.Views.Template[source: source, identifier: identifier]) do
+ EEx.compile_string(source, file: identifier)
+ end
+end
View
@@ -10,7 +10,7 @@ defmodule Dynamo.AppTest do
endpoint Dynamo.AppTest
config :dynamo,
- public_root: File.expand_path("../../fixtures", __FILE__),
+ public_root: File.expand_path("../../fixtures/public", __FILE__),
public_route: "/public",
compile_on_demand: false,
reload_modules: false
@@ -37,7 +37,7 @@ defmodule Dynamo.AppTest do
end
test "adds public filter" do
- file = File.expand_path("../../fixtures", __FILE__)
+ file = File.expand_path("../../fixtures/public", __FILE__)
assert Enum.first(App.filters) == Dynamo.Filters.Static.new("/public", file)
end
@@ -278,7 +278,7 @@ defmodule Dynamo.Cowboy.HTTPTest do
end
def sendfile(conn) do
- file = File.expand_path("../../../fixtures/file.txt", __FILE__)
+ file = File.expand_path("../../../fixtures/public/file.txt", __FILE__)
conn = conn.sendfile(file)
assert conn.state == :sent
assert conn.status == 200
@@ -21,7 +21,7 @@ defmodule Dynamo.Filters.StaticTest do
@app StaticApp
test "serves the file" do
- conn = get("/public/fixtures/file.txt")
+ conn = get("/public/fixtures/public/file.txt")
assert conn.status == 200
assert conn.resp_body == "HELLO"
assert conn.resp_headers["Content-Type"] == "text/plain"
@@ -46,7 +46,7 @@ defmodule Dynamo.Filters.StaticTest do
end
test "returns 404 for unsecure paths" do
- conn = get("/public/fixtures/../fixtures/file.txt")
+ conn = get("/public/fixtures/../fixtures/public/file.txt")
assert conn.status == 404
assert conn.resp_body == "File not served"
end
@@ -130,7 +130,7 @@ defmodule Dynamo.HTTP.TestTest do
end
test :sendfile do
- file = File.expand_path("../../../fixtures/file.txt", __FILE__)
+ file = File.expand_path("../../../fixtures/public/file.txt", __FILE__)
conn = conn(:GET, "/").sendfile(file)
assert conn.state == :sent
assert conn.status == 200
@@ -4,7 +4,7 @@ defmodule Dynamo.ReloaderTest do
use ExUnit.Case
defp fixture_path do
- File.expand_path("../../fixtures", __FILE__)
+ File.expand_path("../../fixtures/reloader", __FILE__)
end
def setup_all do
@@ -0,0 +1,19 @@
+Code.require_file "../../../test_helper.exs", __FILE__
+
+defmodule Dynamo.Views.PathFinderTest do
+ use ExUnit.Case, async: true
+
+ @view_path File.expand_path("../../../fixtures/views", __FILE__)
+ @finder Dynamo.Views.PathFinder.new(@view_path)
+
+ test "finds available template" do
+ path = File.join(@view_path, "hello.html.eex")
+
+ assert Dynamo.Views.Template[identifier: ^path,
+ handler: "eex", format: "html"] = @finder.find "hello.html"
+ end
+
+ test "returns nil if no template is found" do
+ assert @finder.find("unknown.html") == nil
+ end
+end
View
@@ -0,0 +1,12 @@
+Code.require_file "../../test_helper.exs", __FILE__
+
+defmodule Dynamo.ViewsTest do
+ use ExUnit.Case, async: true
+
+ @view_paths [Dynamo.Views.PathFinder.new(File.expand_path("../../fixtures/views", __FILE__))]
+
+ test "renders a template" do
+ body = Dynamo.Views.render "hello.html", @view_paths, []
+ assert body == "HELLO!"
+ end
+end
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1 @@
+<%= "HELLO!" %>

0 comments on commit 552f9c8

Please sign in to comment.