diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a8154340 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/log/* diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb index 1526a689..14bca21d 100644 --- a/app/controllers/tests_controller.rb +++ b/app/controllers/tests_controller.rb @@ -2,10 +2,17 @@ class TestsController < Simpler::Controller def index @time = Time.now + @tests = Test.all + # status 201 + # headers['Content-Type'] = 'text/plain' + # render plain: "Time: #{@time}" + # puts headers end - def create - + def show + @test = Test.find(id: params[:id]) end + def create; end + end diff --git a/app/views/tests/index.html.erb b/app/views/tests/index.html.erb index 39fce580..4c5dc2b5 100644 --- a/app/views/tests/index.html.erb +++ b/app/views/tests/index.html.erb @@ -8,5 +8,6 @@

Simpler framework at work!

<%= @time %>

+

<%= @tests %>

- \ No newline at end of file + diff --git a/app/views/tests/show.html.erb b/app/views/tests/show.html.erb new file mode 100644 index 00000000..c87bd9f7 --- /dev/null +++ b/app/views/tests/show.html.erb @@ -0,0 +1,12 @@ + + + + + Show | Simpler application + + +

Simpler framework at work!

+ +

<%= @test&.title %>

+ + diff --git a/config.ru b/config.ru index 3060cc20..99604262 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,5 @@ require_relative 'config/environment' +require_relative 'lib/middleware/simpler_logger' +use SimplerLogger, logdev: File.expand_path('log/app.log', __dir__) run Simpler.application diff --git a/config/routes.rb b/config/routes.rb index 4a751251..347c4041 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Simpler.application.routes do + get '/tests/:id', 'tests#show' get '/tests', 'tests#index' post '/tests', 'tests#create' end diff --git a/lib/middleware/simpler_logger.rb b/lib/middleware/simpler_logger.rb new file mode 100644 index 00000000..212ded79 --- /dev/null +++ b/lib/middleware/simpler_logger.rb @@ -0,0 +1,47 @@ +require 'logger' + +class SimplerLogger + def initialize(app, **options) + @logger = Logger.new(options[:logdev] || STDOUT) + @app = app + end + + def call(env) + request = Rack::Request.new(env) + status, headers, body = @app.call(env) + @logger.info(log_message(request, status, headers, env)) + + [status, headers, body] + end + + private + + def log_message(request, status, headers, env) + <<~LOG + Request: #{request.request_method} #{request.fullpath} + Handler: #{controller(env)}##{action(env)} + Parameters: #{request.params.inspect} + Response: #{status} [#{content_type(headers)}] #{template(env)} + LOG + end + + def controller(env) + env['simpler.controller'] ? env['simpler.controller'].class.name : 'UnknownController' + end + + def action(env) + env['simpler.action'] || 'unknown_action' + end + + def template(env) + return "#{env['simpler.template']}.html.erb" if env['simpler.template'] + + controller_name = env['simpler.controller']&.name || 'unknown_controller' + action = env['simpler.action'] || 'unknown_action' + "#{controller_name}/#{action}.html.erb" + end + + def content_type(headers) + headers['Content-Type'] || 'unknown_content_type' + end +end diff --git a/lib/simpler/application.rb b/lib/simpler/application.rb index 711946a9..1c3b8ddf 100644 --- a/lib/simpler/application.rb +++ b/lib/simpler/application.rb @@ -28,6 +28,8 @@ def routes(&block) def call(env) route = @router.route_for(env) + return not_found_response unless route + controller = route.controller.new(env) action = route.action @@ -54,5 +56,9 @@ def make_response(controller, action) controller.make_response(action) end + def not_found_response + [404, { 'Content-Type' => 'text/plain' }, ['404 Not Found']] + end + end end diff --git a/lib/simpler/controller.rb b/lib/simpler/controller.rb index 9383b035..3c48cb4a 100644 --- a/lib/simpler/controller.rb +++ b/lib/simpler/controller.rb @@ -22,6 +22,18 @@ def make_response(action) @response.finish end + def params + @request.params.update(@request.env['simpler.params']) + end + + def headers + @response.headers + end + + def status(code) + @response.status = code + end + private def extract_name @@ -42,12 +54,18 @@ def render_body View.new(@request.env).render(binding) end - def params - @request.params + def render(template) + if template.is_a?(Hash) + render_plain(template[:plain]) if template.key?(:plain) + else + @request.env['simpler.template'] = template + end end - def render(template) - @request.env['simpler.template'] = template + def render_plain(text) + @response['Content-Type'] = 'text/plain' + + @response.write(text) end end diff --git a/lib/simpler/router.rb b/lib/simpler/router.rb index 14b3415c..835726ff 100644 --- a/lib/simpler/router.rb +++ b/lib/simpler/router.rb @@ -19,7 +19,7 @@ def route_for(env) method = env['REQUEST_METHOD'].downcase.to_sym path = env['PATH_INFO'] - @routes.find { |route| route.match?(method, path) } + @routes.find { |route| route.match?(method, path, env) } end private diff --git a/lib/simpler/router/route.rb b/lib/simpler/router/route.rb index 4c66b4b7..0ae89778 100644 --- a/lib/simpler/router/route.rb +++ b/lib/simpler/router/route.rb @@ -2,17 +2,28 @@ module Simpler class Router class Route - attr_reader :controller, :action + attr_reader :controller, :action, :params def initialize(method, path, controller, action) @method = method @path = path @controller = controller @action = action + @pattern = path_pattern(path) end - def match?(method, path) - @method == method && path.match(@path) + def match?(method, path, env) + match = path.match(@pattern) + return false unless @method == method && match + + @params = match.named_captures.transform_keys(&:to_sym) + env['simpler.params'] = @params + end + + private + + def path_pattern(path) + Regexp.new("^#{path.gsub('/', '\/').gsub(/:(\w+)/, '(?<\1>[^/]+)')}$") end end