Chris E. (CBL) skrev:
Hi all,
Has anyone ever thought about or implemented a way to use Rails to pull
content from a database and actually generate static html pages from view
templates?
I want to throw a bunch of content into a db using rails and then put all
my website templates into the views dir and write the files out with the
content inside.
Yes, I have. It requires a bit hacking though. A site is built by a
number of nodes, a node can be a page, an image, a file etc. Each node
type inherit from Node and Node has an empty publish(). Every node is
then responsible for writing itself to file while publishing. For
example PageNode:
def publish(options = {})
context_node = get_context_node(options)
path = publish_path(options)
result = yield(page.page_template.content,
:view_mode => “publish”,
:page_node => context_node,
:page => page,
:view_node => context_node)
File.open(path, “wb”) do |file|
file.write(result)
end
my_path = publish_path(:website_node => (options[:website_node] ||
find_website_node))
if(path != my_path)
File.open(my_path, “wb”) do |file|
file.write(result)
end
end
end
The content of the PageNode is held (and accessed) through the page
attribute. The node is only for site structure. This in turn is called
from a publish job (a remote Drb service) or from a controller.
publish() is called the follwoing way:
...
node.publish(options) { |template, vars|
vars.each_key { |key|
self.instance_eval("@#{key} = vars[key]")
}
begin
render_template(template)
rescue => e
msg = "Error while rendering node #{node_id} with ERb,
#{e}\n#{e.backtrace.join("\n")}"
err = true
end
}
…
def render_template(template)
erb_template = ERB.new(template)
erb_template.result(binding)
end
By “passing in” the ERB template using a block I could call it directly
from a controller as well altough that would violate DRY in this case.
To get the variables “inside” the template I need to bind the variables
put inside the vars hash (that happens when doing
self.instance_eval(…)). This hash is created (or passed into) the
publish() method in every Node instance. The result from the merging of
the template (ie the rendered page) is passed back from the block to the
calling node intstance (PageNode in this case) and is ready for file
write (and then possibly a transfer with FTP (we do at least…))
I know this isn’t in the Rails sweetspot. But all administration of the
sites is way inside the Rails sweetspot so that makes up (by far) for
this not being inside it.
/Marcus