Sinatra
Contents |
Sinatra
Default folder for partials is views/
and name is with .erb
extension.
Default layout file is views/layout.erb
. Always use symbols when referencing
templates, event with subfolder erb :'subdir/home'
. Instance variables are
accessible in templates.
Static files are server from public/
folder.
For stylesheet use scss :stylesheet, style: :expanded
For coffescript coffee :index
# to change default views folder
set :views, settings.root + '/templates'
Filter can be used to modify request and response, set instance variable.
before '/protected/*' do
authenticate!
end
Session and other configuration options
require 'securerandom'
enable :sessions
set :session_secret, ENV.fetch('SESSION_SECRET') { SecureRandom.hex(64) }
# to be able to access from other computers, or run with `ruby app.rb -o 0.0.0.0
set :bind, '0.0.0.0'
get '/:value' do
session['val'] = params['value']
end
Redirect with redirect to('/foo?bar=42')
.
Cache-control header is set with cache_control :public
. Rack cache can be used
for caching.
Top level application assumes a micro app style configuration (a single app
file, public and views folders).
If you want modular style (run is disabled by default) you can inherit from
Sinatra::Base
(logging and inline templates disabled by default).
If you want similar to classic style, you can write with:
require 'sinatra/base'
class MyApp < Sinatra::Application
get '/' do
'Hello world!'
end
end
# config.ru
require './app'
run MyApp
Run with
bundle exec rackup -p- 4567
Sinatra Contrib
http://sinatrarb.com/contrib/
Reloading in Sinatra can be done with rerun
http://sinatrarb.com/faq.html or
with
require 'sinatra/reloader' if development?
Sinatra book
http://sinatra-org-book.herokuapp.com/
Logger
Inside get
actions you can define helper and use request logger
get '/' do
logger.info 'get_root'
end
For use in templates you can define helpers
helpers do
def logger
request.logger
end
end
To enable logging to a file use as well to stdout. Problem is that I do not see
custom logs with logger.info params
# http://recipes.sinatrarb.com/p/middleware/rack_commonlogger
configure do
# logging is enabled by default in classic style applications,
# so `enable :logging` is not needed
# create folder `mkdir log` and gitignore with `touch log/.keep`
file = File.new("#{settings.root}/log/#{settings.environment}.log", 'a+')
file.sync = true
use Rack::CommonLogger, file
end
For use in other places you can create global variable (I do not know how to
access logger outside of actions). But the problem here is that I do not see
messages in file (but see in STDOUT on developemnt) when I use $logger.info
but logger.info
inside actions works fine.
# https://stackoverflow.com/questions/5995854/logging-in-sinatra
configure :production do
$logger = Logger.new('log/common.log', 'hourly')
$logger.level = Logger::WARN
# Spit stdout and stderr to a file during production
# in case something goes wrong
$stdout.reopen("log/#{settings.environment}.log", 'w')
$stdout.sync = true
$stderr.reopen($stdout)
end
configure :development do
$logger = Logger.new(STDOUT)
end
https://github.com/minodes/sinatra-logger
Enviroments
APP_ENV=production ruby my_app.rb
# or
ruby my_app.rb -e production
Sinatra Sass
To add support to scss you can add gem 'sass'
and if using modular style
# config.ru
require 'sass/plugin/rack'
Sass::Plugin.options[:style] = :compressed
use Sass::Plugin::Rack
or is using classis style, run
sass --watch public/assets/stylesheets/sass:public/assets/stylesheets
and include in layout
<link rel="stylesheet" href="/assets/stylesheets/switch.css">
Activerecord
https://github.com/janko-m/sinatra-activerecord
# Gemfile
gem 'sinatra-activerecord'
gem 'sqlite3'
gem 'rake'
# app.rb
require 'sinatra/activerecord'
set :database, adapter: 'sqlite3', database: "#{__dir__}/db/home_automation.sqlite3"
# Rakefile
require 'sinatra/activerecord/rake'
namespace :db do
task :load_config do
require './app'
end
end
Note that we use __dir__
to get app_file folder so it works fine when we run
the app from non root path ruby some/path/to/app.rb
And you can create tables
rake db:create_migration NAME=create_temperatures
and models
class Temperature < ActiveRecord::Base
end
On raspberri pi you should install sqlite3
sudo apt-get autoremove; sudo apt-get autoclean;sudo apt-get clean
sudo apt-get update; sudo apt-get -y dist-upgrade; sudo apt-get install sqlite3
sudo apt-get install libsqlite3-dev
Sinatra tests
https://www.sitepoint.com/build-sinatra-api-using-tdd-heroku-continuous-integration-travis/
Console
You can access console like rails c
with https://github.com/sickill/racksh
Webpack
You can use javascript with hot reloading using https://github.com/kopylovvlad/sinatra-webpack-vuejs-template
Sending emails
# Gemfile
gem 'mail'
# my_mail.rb
require 'mail'
# test with
# rvmsudo ruby -e "load 'my_mail.rb';MyMail.send()"
# using sudo requires -E to pass enviroment variables
# sudo -E ruby -e "load 'my_mail.rb';MyMail.send()"
GMAIL_EMAIL = ENV['GMAIL_EMAIL'] # ENV['rvm_EMAIL_USER_NAME'],
GMAIL_PASSWORD = ENV['GMAIL_PASSWORD'] # ENV['rvm_EMAIL_PASSWORD'],
EXCEPTION_RECIPIENTS = ENV['EXCEPTION_RECIPIENTS'] # ENV['rvm_EMAIL_RECIPIENT_EMAIL']
options = {
address: 'smtp.gmail.com',
port: 587,
user_name: GMAIL_EMAIL,
password: GMAIL_PASSWORD,
}
# puts options
Mail.defaults do
delivery_method :smtp, options
end
module MyMail
def self.send(subject: 'alert', text: 'hi', attachment: nil)
puts "Send email #{text} #{attachment}"
Mail.deliver do
to EXCEPTION_RECIPIENTS
from GMAIL_EMAIL
subject subject
body text
add_file attachment unless attachment.nil?
end
rescue StandardError => e
puts "MyMail.send failed #{e}"
end
end
Usage in app.rb
is like
MyMail.send attachment: image_file, text: S3.getUrl(video_file)
Timezone
In pure ruby, you can show UTC time in your time zone by specifying offset
Time.now.localtime("+02:00")
Examples of opensource apps
- https://github.com/swanson/stringer Nice Sinatra ActiveRecord Backbone app. It
- https://lbrito1.github.io/blog/2020/02/repurposing-android.html Running sinatra on mobile phone
Backbone
https://backbonejs.org/