Ce document est en cours de rédaction et il évolue régulièrement. N'hésitez pas à venir le consulter périodiquement, à nous faire part de vos remarques et ainsi à nous aider à l'améliorer
Présentation
Capcode ?
Capcode est un micro-framework permettant de créer facilement des applications Web avec Ruby.
Il a été initialement pensé pour faciliter la diffusion d'applications développées avec Cappuccino. Il a cependant rapidement évolué afin de permettre la création d'applications Web classiques et reprend aujourd'hui l'ensemble des solutions proposées pas les principaux frameworks MVC.
Capcode s'inspire très largement du framework Camping dont il reprend les grands principes. A savoir, les contrôleurs sont des classes et les vues des méthodes. Nous verrons un peu plus loin qu'il existe des exceptions qui ont fait qu'au fil du développement, Capcode s'est éloigné de plus en plus de Camping.
Bien entendu, Capcode ne peut pas (et ne souhaite pas) rivaliser avec des mastodontes tel que Rails/Merb. Capcode est et restera un framework minimaliste.
Installation
La page officielle du projet se trouve sur RubyForge. Vous trouverez sur cette page les archives des sources, les gems et le repository officiel. Le repository officiel se trouve sur Github.
La solution la plus simple pour installer Capcode est d'utiliser RubyGems :
sudo gem install Capcode
Capcode dépend de Rack et mime-types. Si ces deux modules ne sont pas présents sur votre machine, ils seront installés automatiquement. Nous verrons plus loin qu'il existe d'autres dépendances, mais qui ne sont pas obligatoires, car tributaires de vos besoins.
Un "Hello World" c'est obligatoire
#!/usr/bin/env ruby
require 'rubygems'
require 'capcode'
module Capcode
class Index < Route "/"
def get
render :text => "Bonjour, il est #{Time.now.strftime( '%H h %M' )}"
end
end
end
Capcode.run( )
Exécutez ce code, et connectez-vous à l'adresse http://localhost:3000.
Contrôleur
Avec Capcode, les contrôleurs sont déclarés comme des classes du module Capcode héritant de la classe Route (cette dernière prenant en paramètre la route) et contenant les méthodes ! -- outch !
Un exemple sera plus parlant :
1 module Capcode
2 class Index < Route '/index'
3 def get
4 # ...
5 end
6 end
7 end
Explications !
Nous déclarons une contrôleur Index (ligne 2) comme étant une classe appartenant au module Capcode (ligne 1). Pour définir la route d'accès à ce contrôleur, la classe Index hérite de la classe Route qui prend en paramètre le chemin d'accès (ligne 2 : < Route '/index'). Pour plus de détails sur les routes, voir la section correspondante.
Pour pouvoir accéder à ce contrôleur, nous utilisons l'adresse http://server:3000/index. Il faut cependant avoir définit au moins une méthode d'accès. Dans cet exemple, nous définissons la méthode get (lignes 3 à 5). Cette méthode sera appelé si nous faisons un accès de type GET. Si vous souhaitez faire une accès de type POST, vous devez définit une méthode post.
Astuce : si vous avez besoin de définir un get et un post contenant le même code, l'utilisation d'un alias fera parfaitement l'affaire :
module Capcode class Index < Route '/index' def get # ... end alias_method :post, :get end endSi par la suite vous avez vraiment besoin de connaître la méthode utilisée, vous pourrez toujours vous référer à l'environnement (Cf. Environnement)
Les routes
La définition des routes se fait en utilisant la syntaxe des expressions rationnelles Ruby. Les parties capturées par la regexp seront passées en paramètre aux méthodes du contrôleur. Donc si nous déclarons le contrôleur suivants :
module Capcode
class MyController < Route '/user/([^/]*)/post/(.+)'
# ...
end
end
Si vous appelez l'UTL http://example.com/user/2/post/7, c'est le contrôleur défini ci-dessus qui sera utilisé avec deux captures (2 et 7). Les méthodes définies dans ce contrôleur devront donc être définies comme prenant deux paramètres :
module Capcode
class MyController < Route '/user/([^/]*)/post/(.+)'
def get( userID, postID )
# ...
end
# ...
end
end
En faisant un appel GET sur http://example.com/user/2/post/7, dans la méthode get de MyController, userID contiendra la valeur "2" et postID contiendra la valeur "7".
Attention, vous devez obligatoirement capturer les éléments dynamiques, et déclarer une route avec '/user/[^/]*/post/(.+)' en paramètre entrainera une erreur. Par contre, vous avez parfaitement le droit de définir plusieurs routes pour un même contrôleur :
module Capcode
class MyController < Route '/user/([^/]*)/post/(.+)', '/users/post/(.+)'
def get( userID, postID )
# ...
end
# ...
end
end
Dans ce cas, si vous faite une GET sur http://example.com/users/post/8, userID contiendra la valeur "9" et postID contiendra la valeur nil.
La solution la plus simple pour gérer les routes multiples dans un contrôleur est de déclarer les méthodes comme acceptant un tableau de paramètres :
module Capcode class MyController < Route '/user/([^/]*)/post/(.+)', '/users/post/(.+)' def get( *args ) # ... end # ... end end
REST
Capcode peut répondre aux méthodes de type GET, POST, PUT et DELETE. Pour cela il suffit de définir les méthodes correspondantes dans vos contrôleurs :
module Capcode
class MyController < Route '/path/to/controller'
def get
# ...
end
def post
# ...
end
def put
# ...
end
def delete
# ...
end
end
end
L'accès aux méthodes put et delete se fait en fait via un POST avec le paramètre _method positionné avec la valeur put ou delete. Vous pouvez voir cela en action via l'exemple rest.rb.
Vous n'êtes pas obligé de vous restreindre à ces 4 méthodes. Vous pouvez en définir autant qu'il vous plaira. Il suffit simplement de créer dans le contrôleur une méthode ayant pour nom la valeur du paramètre _methode.
Environnement
Authentification HTTP
Vues
Redirection
Haml et Sass
Erb
JSON
XML
Pages statiques
Layouts
WebDAV
Modeles
DataMapper
CouchDB
Helpers
Erreurs
Tests unitaires
Déploiement
Phusion Passenger
Commencez par créer la structure des répertoire de l'application.
my_app/
my_app/tmp
my_app/public
Placez ensuite le code de votre application dans my_app/ puis commentez ou supprimez la ligne contenant le Capcode.run.
Créez une fichier de configuration rackup (config.ru) dans my_app/
require 'app'
run Capcode.application()
Capcode.application prend les même paramètres que Capcode.run (bloc compris). Si vous utiliser le moteur de rendu pour les fichier statics, vous devez positionner l'option :root (:root => File.expand_path(File.dirname(__FILE__)) sera souvent la bonne solution).
Vous pouvez maintenant déployer votre application comme une "application Ruby basée sur Rack".
Contribuer
Le code de Capcode est disponible sur Github à l'adresse http://github.com/glejeune/Capcode. N'hésitez pas à le cloner.