Add these lines to your application's Gemfile:
source 'https://gem.fury.io/universityofyork/' do gem 'uoy-faculty-sinatra', '~> 0.1', require: 'sinatra' end
And then execute:
$ bundle
Or install it yourself as:
$ gem install uoy-faculty-sinatra
configure
blockno_master_web_library_in_production!
configure do
no_master_web_library_in_production!
end
current_url?(path)
current_url? '/staff'
)full_url(relative_url)
rel('/login') => https://app.domain/app/app_name/login
path_with_web_root
BootstrapNavbar
so the current page can be highlighted correctlyrel(relative_url)
rel('/login') => /app/app_name/login
web_library(resource)
/web-library
subdirectoryweb_library('css/app.css') => /path/to/library/css/app.css
web_root
''
in AWS; /app/app_name
on a local serverFor local development:
configure do
register Sinatra::BasicPasswordlessAuth
end
We can register different Auth schemes depending on environment (e.g. Cognito auth in AWS)
Define rescuable HTTP statuses.
get '/path/ do
raise http_status(403) unless user_can_view_this_page?
end
We can define custom error pages in app.rb
:
error_handler HTTPStatus::AnyStatus, :error
error_handler HTTPStatus::Forbidden, :'error/403'
error_handler HTTPStatus::NotFound, :'error/404'
error(Sinatra::NotFound) { erb :'error/404' }
param_validator :valid_user do param :id, Integer, required: true end post '/user-record/id', validate_params: :valid_user do # ...your logic here... end
General validation will return a 403 forbidden error if the validation fails.
form_validator :sample_form do param :name, String, required: true param :day, Date, required: true, message: 'Must provide a Date' one_of :a, :b end post '/sample-form', validate_form: :sample_form do # ...your logic here... end
If the validator fails, it will redirect back to the form and flash the form params to the session.
To make use of these params, you should use the form_value
helper.
There is also a form_error?
helper for checking if a specific field had an error,
and invalid_feedback
to retrieve the error for the given field.
<input type="text" class="form-control <%= 'is-invalid' if form_error? :name %>" name="name" id="name" required value="<%= form_value :name %>"> <div class="invalid-feedback"> <%= invalid_feedback :name, 'Please provide an event name.' %> </div>
If your form should already have values populated, you can use the form_values
helper in your route.
This sets the default values for fields, which will be overridden by flashed values if they exist.
get '/sample-form' do form_values({ name: 'Foo' }) erb :sample_form end
param
, one_of
and any_of
are valid methods on the validator object;
see sinatra/param for details of these methods.
If you have code you wish to run that depends on a parameter value, you can pass a block. This will run immediately after the parameter was validated - unless the parameter was invalid, in which case it will not be run.
param_validator :block_example do param :user_id, Integer, required: true do @user = get_user(params[:user_id]) end end
If you wish to run some code in the context of the route, use block
. This will always be run, so be aware if using
previously validated parameters, there is no guarantee they will be valid.
param_validator :block_test do block do #... end end
Multiple validators can be passed as an array:
post '/sample-form', validate_form: %i[validator1 validator2] do # ...your logic here... end
Validators can take parameters, which can be passed by wrapping the validator identifier with validator
:
param_validator :sample do |parameter| # ... end post '/sample', validate_params: validator(:sample, parameter) do # ...your logic here... end
Pass messages to the next page through the session.
This extends the standard sinatra-flash
implementation and uses a single key for all flash messages,
so we can define multiple messages with the same type.
Pass a message and a message type (a bootstrap contextual class, e.g. :success
or :danger
; defaults to :info
)
in your route:
flash_message 'The default type is "info".' flash_message 'Added something successfully.', type: :success flash_message 'We want to warn you about something.', type: :warning
And add the template to your view, where appropriate:
<%== erb :flash_messages %>
You can also pass an array of messages for a single type, which will be output in a single alert
, one per line:
flash_message ['Added A.', 'Added B.']
Your Gem's version is picked up automatically from lib/sinatra.rb
. When any
changes are pushed to master, after the normal CI tasks the pipeline will push
to gemfury automatically. The usual workflow is:
For minor changes, update VERSION
and make the change in a single commit
For anything else, create a branch and set VERSION
to the version you're
aiming to release for. Make the changes; when the branch is merged, the gem
will be uploaded.
Note that gemfury will never overwrite an existing gem version, even if the old one is yanked!
Tests can be run via rake: bundle exec rake spec
- this doesn't run
performance tests; they can be run separately via bundle exec rake perf
.
You can also run rspec
normally e.g. bundle exec rspec -fd
.
If you have performance tests that take a while, tag the context
/ describe
block like this:
context 'when foo is bar baz', :perf do
...
end
Bug reports and pull requests are welcome at https://github.com/university-of-york/faculty-dev-sinatra-gem