Читали ли вы Расширение DSL и раздел Условия README ?
В данный момент вы на самом деле не расширяете DSL. Я бы немного переработал его, потому что похоже, что вы хотите сопоставить оператор case, но это будет означать создание большого количества классов или ужасного оператора сопоставления. Но у Синатры уже есть несколько действительно хороших способов соответствовать на маршрутах и условиях. Итак, что-то вроде этого было бы более идиоматическим c:
post '/', :locale => "Czech" do
"Czech"
end
post '/', :locale => "British English" do
"British"
end
или
post '/', :locale => "en-GB" do
"cs-CS"
end
post '/', :locale => "cs-CS" do
"cs-CS"
end
Как это сделать? Сначала вам понадобится фильтр для преобразования входящего JSON:
before do
if request.media_type == "application/json"
request.body.rewind
@json = JSON.parse request.body.read
@locale = @json["locale"] && Locales[@json["locale"]]
end
end
, а затем вам понадобится условие для проверки:
set(:locale) {|value|
condition {
!!@locale && (@locale == value || @json["locale"] == value)
}
}
Все вместе ( app.rb):
require 'sinatra'
Locales = {
'cs-CS' => "Czech",
'en-GB' => "British English"
}
before do
if request.media_type == "application/json"
request.body.rewind
@json = JSON.parse request.body.read
@locale = @json["locale"] && Locales[@json["locale"]]
end
end
set(:locale) {|value|
condition {
!!@locale && (@locale == value || @json["locale"] == value)
}
}
post '/', :locale => "en-GB" do
"cs-CS"
end
post '/', :locale => "cs-CS" do
"cs-CS"
end
Это работает, но не будет работать как расширение. Итак, опираясь на документы, которые я разместил сверху:
require 'sinatra/base'
module Sinatra
module Localiser
Locales = {
'cs-CS' => "Czech",
'en-GB' => "British English"
}
def localise!(locales=Locales)
before do
if request.media_type == "application/json"
request.body.rewind
@json = JSON.parse request.body.read
@locale = @json["locale"] && locales[@json["locale"]]
end
end
set(:locale) {|value|
condition {
!!@locale && (@locale == value || @json["locale"] == value)
}
}
end
end
register Localiser
end
Теперь он расширит DSL. Например:
require "sinatra/localiser"
class Localised < Sinatra::Base
register Sinatra::Localiser
localise!
post '/', :locale => "Czech" do
"Czech"
end
post '/', :locale => "British English" do
"British"
end
["get","post"].each{|verb|
send verb, "/*" do
"ELSE"
end
}
run! if app_file == $0
end
Надеюсь, это поможет вам кое-что прояснить.