require 'noumenon' require 'sinatra' # The core Noumenon web application, responsible for loading content from the repository, # and then either rendering it with the appropriate template, or passing it to the specified # application. # # @api public class Noumenon::Core < Sinatra::Base # Renders a content item within it's template and layout. # # If the template or layout is not specified then it will be set to "default". # # @param [ Hash ] page The content item to render. # @option page [ String ] :template The template to use when rendering the item. # @option page [ String ] :layout The layout to put the template within. # @return [ String ] The rendered page, or an error message if any templates could not be rendered. # @api public def render_page(page) page[:template] ||= "default" page[:layout] ||= "default" begin template = Noumenon.theme.template("#{page[:template]}.nou.html") content = template.render(page) wrap_with_layout(content, page) rescue Noumenon::Template::NotFoundError => e halt 500, "

Missing Template

The template '#{page[:template]}' does not exist within the current theme.

" rescue Noumenon::Template::MissingContentError => e halt 500, "

Missing Fields

#{e}

" end end # Convenience method to access the current content repository. # # @api public # @return [ Noumenon::Repository ] the current content repository def content Noumenon.content_repository end get "/assets/*" do |path| asset = Noumenon.asset_repository.get_asset("/#{path}") halt 404, "Asset not found" unless asset asset end get "*" do |path| page = content.get(path) unless page # Search up the tree until we either hit the top, and 404, or find a mounted application. path = path.split("/") while path.size > 0 path.pop page = content.get(path.join("/")) break if page && page[:type] == "application" end halt 404, "

Page Not Found

" unless page path = path.join("/") end case page[:type] when "application" app = page[:application].constantize # Rewrite PATH_INFO so that the child application can listen to URLs assuming it's at the root. env["PATH_INFO"].gsub!("#{path}", "") env["PATH_INFO"] = "/" if env["PATH_INFO"] == "" app.new(page).call(env) else render_page(page) end end private def wrap_with_layout(content, page) begin layout = Noumenon.theme.layout("#{page[:layout]}.nou.html") return layout.render( page.merge(content: content) ) rescue Noumenon::Template::NotFoundError => e if page[:layout] == "default" return content else halt 500, "

Missing Layout

The layout '#{page[:layout]}' does not exist within the current theme.

" end end end end