Il semble que dans Sinatra tous les gestionnaires d’itinéraires soient écrits dans un seul fichier, si j’ai bien compris, il s’agit d’un contrôleur grand/petit. Existe-t-il un moyen de le scinder en plusieurs fichiers indépendants? Par conséquent, lorsque quelqu'un appelle "/" - une action est exécutée, et s'il ressemble à "/ posts/2", il en reçoit une autre - une logique similaire à celle appliquée en PHP ?
Voici un modèle de base pour les applications Sinatra que j'utilise. (Mes applications plus grandes ont plus de 200 fichiers ventilés comme ceci, sans compter les gemmes fournies par le fournisseur, couvrant 75 à 100 itinéraires explicites. Certains de ces itinéraires sont des itinéraires Regexp couvrant plus de 50 modèles d'itinéraire.) Lorsque vous utilisez Thin, vous exécutez un application comme celle-ci utilisant:thin -R config.ru start
Edit : Je maintiens maintenant mon propre squelette Monk basé sur ce qui est appelé Riblits. Pour l'utiliser pour copier mon modèle comme base de vos propres projets:
# Before creating your project
monk add riblits git://github.com/Phrogz/riblits.git
# Inside your empty project directory
monk init -s riblits
Disposition du fichier:
config.ru app.rb helpers / init.rb partials.rb modèles / init.rb user.rb routes / init.rb login.rb main.rb vues/ layout.haml login.haml main.haml
config.ru
root = ::File.dirname(__FILE__)
require ::File.join( root, 'app' )
run MyApp.new
app.rb
# encoding: utf-8
require 'sinatra'
require 'haml'
class MyApp < Sinatra::Application
enable :sessions
configure :production do
set :haml, { :ugly=>true }
set :clean_trace, true
end
configure :development do
# ...
end
helpers do
include Rack::Utils
alias_method :h, :escape_html
end
end
require_relative 'models/init'
require_relative 'helpers/init'
require_relative 'routes/init'
helpers/init.rb
# encoding: utf-8
require_relative 'partials'
MyApp.helpers PartialPartials
require_relative 'nicebytes'
MyApp.helpers NiceBytes
helpers/partials.rb
# encoding: utf-8
module PartialPartials
def spoof_request(uri,env_modifications={})
call(env.merge("PATH_INFO" => uri).merge(env_modifications)).last.join
end
def partial( page, variables={} )
haml page, {layout:false}, variables
end
end
helpers/nicebytes.rb
# encoding: utf-8
module NiceBytes
K = 2.0**10
M = 2.0**20
G = 2.0**30
T = 2.0**40
def Nice_bytes( bytes, max_digits=3 )
value, suffix, precision = case bytes
when 0...K
[ bytes, 'B', 0 ]
else
value, suffix = case bytes
when K...M then [ bytes / K, 'kiB' ]
when M...G then [ bytes / M, 'MiB' ]
when G...T then [ bytes / G, 'GiB' ]
else [ bytes / T, 'TiB' ]
end
used_digits = case value
when 0...10 then 1
when 10...100 then 2
when 100...1000 then 3
else 4
end
leftover_digits = max_digits - used_digits
[ value, suffix, leftover_digits > 0 ? leftover_digits : 0 ]
end
"%.#{precision}f#{suffix}" % value
end
module_function :Nice_bytes # Allow NiceBytes.Nice_bytes outside of Sinatra
end
models/init.rb
# encoding: utf-8
require 'sequel'
DB = Sequel.postgres 'dbname', user:'bduser', password:'dbpass', Host:'localhost'
DB << "SET CLIENT_ENCODING TO 'UTF8';"
require_relative 'users'
models/user.rb
# encoding: utf-8
class User < Sequel::Model
# ...
end
routes/init.rb
# encoding: utf-8
require_relative 'login'
require_relative 'main'
routes/login.rb
# encoding: utf-8
class MyApp < Sinatra::Application
get "/login" do
@title = "Login"
haml :login
end
post "/login" do
# Define your own check_login
if user = check_login
session[ :user ] = user.pk
redirect '/'
else
redirect '/login'
end
end
get "/logout" do
session[:user] = session[:pass] = nil
redirect '/'
end
end
routes/main.rb
# encoding: utf-8
class MyApp < Sinatra::Application
get "/" do
@title = "Welcome to MyApp"
haml :main
end
end
views/layout.haml
!!! XML
!!! 1.1
%html(xmlns="http://www.w3.org/1999/xhtml")
%head
%title= @title
%link(rel="icon" type="image/png" href="/favicon.png")
%meta(http-equiv="X-UA-Compatible" content="IE=8")
%meta(http-equiv="Content-Script-Type" content="text/javascript" )
%meta(http-equiv="Content-Style-Type" content="text/css" )
%meta(http-equiv="Content-Type" content="text/html; charset=utf-8" )
%meta(http-equiv="expires" content="0" )
%meta(name="author" content="MeWho")
%body{id:@action}
%h1= @title
#content= yield
Absolument. Pour voir un exemple, je vous recommande de télécharger la gemme Monk, décrite ici:
https://github.com/monkrb/monk
Vous pouvez l'installer via rubygems.org. Une fois que vous avez la gemme, générez un exemple d'application en suivant les instructions ci-dessus.
Notez que vous n'êtes pas obligé d'utiliser Monk pour votre développement actuel à moins que vous ne le vouliez (en fait, je pense que cela peut ne pas être courant). Le but est de voir comment vous pouvez facilement structurer votre application dans le style MVC (avec des fichiers de routage distincts similaires à ceux d'un contrôleur) si vous le souhaitez.
C'est assez simple si vous regardez comment Monk le gère, principalement en exigeant des fichiers dans des répertoires séparés, par exemple (vous devrez définir root_path):
Dir[root_path("app/**/*.rb")].each do |file|
require file
end
Effectuez une recherche Google sur "Sinatra" pour avoir des idées sur la manière dont les autres développent leurs applications Sinatra. À partir de là, vous pouvez probablement en trouver un qui répond à vos besoins ou tout simplement en créer un. Ce n'est pas trop difficile à faire. Au fur et à mesure que vous développez d'autres applications Sinatra, vous pouvez en ajouter à votre passe-partout.
Voici ce que j'ai fabriqué et utilisé pour tous mes projets:
Je sais que c’est une vieille requête, mais je ne peux toujours pas croire que personne ne soit mentionné Padrino Vous pouvez l’utiliser comme cadre au-dessus de Sinatra, ou ajouter au cas par cas uniquement les pierres précieuses qui vous intéressent. Il frappe dix fesses de cul!
Mon approche pour héberger différents projets sur le même site consiste à utiliser sinatra/namespace
de cette manière:
server.rb
require "sinatra"
require "sinatra/namespace"
if [ENV["LOGNAME"], ENV["USER"]] == [nil, "naki"]
require "sinatra/reloader"
register Sinatra::Reloader
set :port, 8719
else
set :environment, :production
end
for server in Dir.glob "server_*.rb"
require_relative server
end
get "/" do
"this route is useless"
end
server_someproject.rb
module SomeProject
def self.foo bar
...
end
...
end
namespace "/someproject" do
set :views, settings.root
get "" do
redirect request.env["REQUEST_PATH"] + "/"
end
get "/" do
haml :view_someproject
end
post "/foo" do
...
SomeProject.foo ...
end
end
view_someproject.haml
!!!
%html
...
Un autre détail concernant les sous-projets que j’ai utilisés est d’ajouter leurs noms, description et itinéraires à une sorte de variable globale, utilisée par "/"
faire une page d'accueil de guide, mais je n'ai pas d'extrait pour l'instant.
Lorsque Monk ne travaillait pas pour moi, j'ai commencé à travailler sur des modèles.
Si vous y réfléchissez, il n’ya rien de spécial à propos de l’arrimage d’un ensemble de fichiers. La philosophie du moine m’a été expliquée au début de 2011 lors de RedDotRubyConf et ils m’ont dit précisément que c’est vraiment facultatif de l’utiliser, en particulier maintenant que c’est à peine si elle est maintenue.
C'est un bon début pour ceux qui veulent utiliser ActiveRecord:
Sinatra simple MVC
La clé de la modularité sur Sinatra pour les grands projets consiste à apprendre à utiliser les outils sous-jacents.
SitePoint a un très bon tutoriel d'où vous pouvez voir des applications et des aides modulaires de Sinatra. Cependant, vous devez porter une attention particulière à un détail important. Vous conservez plusieurs applications Sinatra et les montez avec Rackup. Une fois que vous savez comment écrire une application de base, consultez le fichier config.ru de ce didacticiel et observez comment ils installent des applications indépendantes Sinatra.
Une fois que vous aurez appris à utiliser Sinatra avec Rack, un tout nouveau monde de stratégies de modularité s’ouvrira. Cela invite évidemment à essayer quelque chose de vraiment utile: vous pouvez maintenant compter sur des gems individuels pour chaque sous application, ce qui pourrait vous permettre de faire facilement la version de vos modules.
Ne sous-estimez pas la puissance de l'utilisation de gem-modules pour votre application. Vous pouvez facilement tester des modifications expérimentales dans un environnement bien délimité et les déployer facilement. Également facile à revenir en cas de problème.
Il existe mille façons d’organiser votre code, il n’est donc pas gênant d’obtenir une présentation similaire à Rails. Cependant, il y a aussi quelques excellents messages sur la façon de personnaliser votre propre structure. Cet article couvre d'autres besoins fréquents de la plupart des développeurs Web.
Si vous avez le temps, je vous encourage à en apprendre davantage sur Rack, le point de convergence de toute application Web basée sur Ruby). Cela pourrait avoir un impact beaucoup moins important sur la façon dont vous faites votre travail, mais Il existe toujours certaines tâches que la plupart des gens font sur leurs applications et qui conviennent mieux à un middleware Rack.
Lire la documentation ici:
Il semble que Sinatra vous permette de décomposer votre application en Ruby Modules, qui peuvent être insérés via la méthode "register" de Sinatra ou des méthodes "helpers", comme suit:
require 'sinatra/base'
module Sinatra
module Sample
module Helpers
def require_logged_in()
redirect('/login') unless session[:authenticated]
end
end
end
end
require 'sinatra/base'
module Sinatra
module Sample
module Routing
module Foos
def self.registered(app)
app.get '/foos/:id' do
# invoke a helper
require_logged_in
# load a foo, or whatever
erb :foos_view, :locals => { :foo => some_loaded_foo }
end
end
end
end
end
end
#!/usr/bin/env Ruby
require 'sinatra'
require_relative 'routing/foos'
class SampleApp < Sinatra::Base
helpers Sinatra::Sample::Helpers
register Sinatra::Sample::Routing::Foos
end