Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/controllers/tests_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ def create

end

def show
render plain: params[:id]
end

end
2 changes: 1 addition & 1 deletion app/views/tests/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@

<p><%= @time %></p>
</body>
</html>
</html>
11 changes: 11 additions & 0 deletions app/views/tests/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Show Page | Simpler application</title>
</head>
<body>
<h1>Simpler framework at work!</h1>

</body>
</html>
3 changes: 2 additions & 1 deletion config.ru
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require_relative 'config/environment'

require_relative 'lib/simpler_logger'
use SimplerLogger
run Simpler.application
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Simpler.application.routes do
get '/tests', 'tests#index'
post '/tests', 'tests#create'
get '/tests/:id', 'tests#show'
end
16 changes: 11 additions & 5 deletions lib/simpler/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ def routes(&block)
end

def call(env)
route = @router.route_for(env)
controller = route.controller.new(env)
action = route.action

make_response(controller, action)
if route = @router.route_for(env)
controller = route.controller.new(env)
action = route.action
make_response(controller, action)
else
error
end
end

private
Expand All @@ -54,5 +56,9 @@ def make_response(controller, action)
controller.make_response(action)
end

def error
[404, {'Content-Type' => 'text/plain'}, ['404: Page not found']]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rack::Response?

end

end
end
13 changes: 10 additions & 3 deletions lib/simpler/controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ def make_response(action)
@response.finish
end

def status(code)
@response.status = code
end

def headers
@response.headers
end

private

def extract_name
Expand All @@ -39,16 +47,15 @@ def write_response
end

def render_body
View.new(@request.env).render(binding)
View.new(@request.env, @response).render(binding)
end

def params
@request.params
@request.env['simpler.params'].merge!(@request.params)
end

def render(template)
@request.env['simpler.template'] = template
end

end
end
6 changes: 4 additions & 2 deletions lib/simpler/router.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ def post(path, route_point)
def route_for(env)
method = env['REQUEST_METHOD'].downcase.to_sym
path = env['PATH_INFO']

@routes.find { |route| route.match?(method, path) }
if found_route = @routes.find { |route| route.match?(method, path) }
env['simpler.params'] = found_route.params
found_route
end
end

private
Expand Down
25 changes: 22 additions & 3 deletions lib/simpler/router/route.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
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
@params = {}
end

def match?(method, path)
@method == method && path.match(@path)
@method == method && path_handler(path)
end

def path_handler(path)
router_path = @path.split('/')
request = path.split('/')
return if request.size != router_path.size

router_path.each_with_index do |part, id|
if part.include?(':') && request[id].to_i.positive?
params[sym!(part)] = request[id].to_i
elsif part != request[id]
return
end
end
end

private

def sym!(part)
part.delete(':').to_sym
end
end
end
end
21 changes: 17 additions & 4 deletions lib/simpler/view.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
require 'erb'
require 'json'

module Simpler
class View

VIEW_BASE_PATH = 'app/views'.freeze

def initialize(env)
def initialize(env, response)
@env = env
@response = response
end

def render(binding)
template = File.read(template_path)
return send template.keys.first, template.values.first if template&.keys

template = File.read(template_path)
ERB.new(template).result(binding)
end

Expand All @@ -30,10 +33,20 @@ def template
end

def template_path
path = template || [controller.name, action].join('/')

path = [controller.name, action].join('/')
@env['simpler.template_path'] = "#{path}.html.erb"
Simpler.root.join(VIEW_BASE_PATH, "#{path}.html.erb")
end

def plain(content)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно сделать отдельный класс для рендеринга каждого типа ответа: HTMLRenderer, PlainTextRenderrer. Каждый из таких классов может определять свой метод render. Тогда в обязанность View будет входить выбор нужного класса на основе информации из env и делегирование ему вызова метода render.

@response.headers['Content-Type'] = 'text/plain'
content
end

def json(content)
@response.headers['Content-Type'] = 'json'
content.to_json
end

end
end
32 changes: 32 additions & 0 deletions lib/simpler_logger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require 'logger'
class SimplerLogger
def initialize(app)
@app = app
end

def call(env)
@request = Rack::Request.new(env)
status, headers, body = @app.call(env)
logger = Logger.new('log/app.log')
if status == 404
logger.error("\n#{log_error(@request, status, headers)}")
else
logger.info("\n#{log_info(@request, status, headers)}")
end
[status, headers, body]
end

private

def log_info(request, status, headers)
"Request: #{request.request_method} #{request.fullpath}\n" \
"Handler: #{request.env['simpler.controller'].class}##{request.env['simpler.action']}\n" \
"Parameters: #{request.env['simpler.params'].merge!(request.params)}\n" \
"Response: #{status} #{headers['Content-Type']} #{request.env['simpler.template_path']}\n" \
end

def log_error(request, status, headers)
"Request: #{request.request_method} #{request.fullpath}\n" \
"Response: #{status} #{headers['Content-Type']}\n" \
end
end
Empty file added log/app.log
Empty file.