Tutoriel du plugin Polls¶
Remarque : Pour suivre ce tutoriel, vous devez avoir installé Redmine devel r1786 ou supérieur.
- Table of contents
- Tutoriel du plugin Polls
Créer un nouveau plugin¶
Vous devez préalablement initialiser la variable RAILS_ENV sur "production" dans votre session shell pour continuer le tutotiel, pour ce faire, tapez :
$ export RAILS_ENV="production"
Pour créer un plugin Redmine, il existe des generateur pour les taches essentielles.
La syntaxe des générateurs est :
ruby script/generate redmine_plugin <plugin_name>
pour commencer, on va se positionner dans le répertoire de l'application Rails Redmine, puis créer la structure du plugin :
% ruby script/generate redmine_plugin Polls
La structure du plugin est créé dans le repertoire vendor/plugins/redmine_polls
:
create vendor/plugins/redmine_polls/app/controllers create vendor/plugins/redmine_polls/app/helpers create vendor/plugins/redmine_polls/app/models create vendor/plugins/redmine_polls/app/views create vendor/plugins/redmine_polls/db/migrate create vendor/plugins/redmine_polls/lib/tasks create vendor/plugins/redmine_polls/assets/images create vendor/plugins/redmine_polls/assets/javascripts create vendor/plugins/redmine_polls/assets/stylesheets create vendor/plugins/redmine_polls/lang create vendor/plugins/redmine_polls/README create vendor/plugins/redmine_polls/init.rb create vendor/plugins/redmine_polls/lang/en.yml
Editer vendor/plugins/redmine_polls/init.rb
pour adjuster les informations (attributs) du plugin (nom, auteur, description et version):
require 'redmine'
Redmine::Plugin.register :redmine_polls do
name 'Polls plugin'
author 'John Smith'
description 'A plugin for managing polls'
version '0.0.1'
end
Redemarrez l'application Redmine et ouvrez un navigateur sur l'URL http://localhost:3000/admin/plugins.
Après vous être loggué avec les droits d'administrateur Redmine, vous devriez voir la liste des plugins tel que :
Générer un modèle Rails de plugin Redmine¶
pour le moment le plugin ne persiste aucuns résultats
Nous allons donc créer un modèle Poll simple, tel que :
ruby script/generate redmine_plugin_model <plugin_name> <model_name> [<fields>]
La commande exacte pour notre cas sera :
ruby script/generate redmine_plugin_model polls poll question:string yes:integer no:integer
cette commande crée le modèle Rails Poll et les fichiers de migration correspondant
*Remarque : Il est possible que vous deviez renommer les fichiers de migration, les migrations avec des timestamps ne sont pas supportée par le moteur Redmine Actuelle, Si les migrations portent une numérotation avec des timestamps, renommez-les avec "001" "002", etc...
cd vendor/plugins/redmine_polls/db/migrate mv 20091009211553_create_polls.rb 001_create_polls.rb cd ../../../../..
Si vous avez déja executé une migration, vous devez mettre à jour les informations dans la table plugin_schema_info en adequation avec la nouvelle numérotation.
Migrer la base de données avec la commande :
rake db:migrate_plugins
Il est à noter que chaque plugin à son propre jeux de migration.
Nous allons ajouter des Votes via la console rails pour pouvoir faire des tests avec.
La console Rails permet l'ajout interactif d'enregistrement sur les modèles rails, c'est une shell Ruby Irb, qui pré-charge l'environnement de l'application rails depuis laquelle il est lancé.
Pour le moment nous allons juste créer un objet Poll
script/console >> Poll.create(:question => "Pouvez-vous voir ce vote ?") >> Poll.create(:question => "Pouvez-vous voir cet autre vote ?") >> exit
Editez vendor/plugins/redmine_polls/app/models/poll.rb
dans le répertoire de votre plugin et ajoutez une méthode #vote qui sera appelée par votre controller:
class Poll < ActiveRecord::Base
def vote(answer)
increment(answer == 'yes' ? :yes : :no)
end
end
Generer un controller¶
Pour le moment le plugins ne fait rien, donc nous allons créer un controller Rails pour celui-ci.
Nous pouvons utiliser le générateur Redmine prévue à cet effet :
ruby script/generate redmine_plugin_controller <plugin_name> <controller_name> [<actions>]
la commande exacte pour notre cas est :
% ruby script/generate redmine_plugin_controller Polls polls index vote exists app/controllers/ exists app/helpers/ create app/views/polls create test/functional/ create app/controllers/polls_controller.rb create test/functional/polls_controller_test.rb create app/helpers/polls_helper.rb create app/views/polls/index.html.erb create app/views/polls/vote.html.erb
un controlleur Rails PollsController
avec 2 actions (#index
et #vote
) vient d'être créé.
Editez vendor/plugins/redmine_polls/app/controllers/polls_controller.rb
dans le répertoire redmine_polls
pour implémenter ces deux actions.
class PollsController < ApplicationController
unloadable
def index
@polls = Poll.find(:all)
end
def vote
poll = Poll.find(params[:id])
poll.vote(params[:answer])
if poll.save
flash[:notice] = 'Vote saved.'
redirect_to :action => 'index'
end
end
end
Ensuite, editez la vue vendor/plugins/redmine_polls/app/views/polls/index.html.erb
qui va afficher les votes existants.
<h2>Polls</h2> <% @polls.each do |poll| %> <p> <%= poll[:question] %>? <%= link_to 'Yes', {:action => 'vote', :id => poll[:id], :answer => 'yes'}, :method => :post %> (<%= poll[:yes] %>) / <%= link_to 'No', {:action => 'vote', :id => poll[:id], :answer => 'no'}, :method => :post %> (<%= poll[:no] %>) </p> <% end %>
Vous pouvez supprimer la vue vendor/plugins/redmine_polls/app/views/polls/vote.html.erb
comme il n'y a pas de rendu pour l'action correspondante.
Redemarreez le serveur Rails de Redmine et ouvrez votre navigateur sur l'URL http://localhost:3000/polls.
Vous devriez voir deux votes et vous pouvez les essailler :
Remarque : les resultats des votes sont remis à zero à chaque requête si vous ne lancez pas votre application en environnement "production", vue que le modèle Poll est stocké dans une variable de classe dans notre exemple.
Traductions¶
L'emplacement des fichiers YAML d'internationalisation peut varier en fonction de votre version de Redmine :
Version | Path |
---|---|
< 0.9 | .../redmine_polls/lang |
>= 0.9 | .../redmine_polls/config/locales |
Si vous voulez que votre plugin marche dans les deux cas vous devez ajouter les fichiers dans les deux cas au bon format.
Gestion des menus¶
Notre controller marche bien, mais nos utilisateurs n'en connaissent pas l'existence, il faut donc utilser l'API Redmine pour etendre les menus
Nous allons ajouter un onglet au menu Application
So let's add a new item to the application menu.
Gestion du menu application¶
Editez le fichier vendor/plugins/redmine_polls/init.rb
à la racine de votre plugin et ajoutez la ligne suivante dans le bloc ""registration"" :
Redmine::Plugin.register :redmine_polls do
[...]
menu :application_menu, :polls, { :controller => 'polls', :action => 'index' }, :caption => 'Polls'
end
la syntaxe est :
menu(menu_name, item_name, url, options={})
Il y a cinq menu dans Redmine que vous pouvez étendre :
:top_menu
- le menu en haut à gauche:account_menu
- le menu en haut à droite avec la gestion des comptes et connexions:application_menu
- Le menu affiché quand un utilisateur n'est dans aucuns projets.:project_menu
- Le menu affiché quand un utilisateur est dans un projet.:admin_menu
- le menu d'administration
les options disponibles sont :
:param
- la clef parametre utilisée pour les id de projet (valeur par défaut:id
):if
- un Proc appelé avant de faire le rendu du menu,l'item est affiché que si le Proc retourne true:caption
- Le label du menu du type:- un symbole de chaine de caratères localisée
- une chaine de caratères
- un Proc qui peut pendre le project_id en argument
:before
,:after
- specifie ou l'item du menu doit être inséré (ex.:after => :activity
):first
,:last
- si ils sont true, l'item est positionné au début ou a la fin du menu (ex.:last => true
):html
- un hachage d'options html passés àlink_to
pour le rendu du menuitem
Dans notre exemple, nous avons ajoutez un item au menu application, qui est vide par defaut.
Redemarrez l'application et allez à l'URL http://localhost:3000:
Maintenant vous pouvez accéder aux votes en cliquant sur l'onglet Polls depuis l'ecran d'accueil de Redmine
Etendre le menu projet¶
On va considérer, mantenant que les votes sont définis au niveau des projets (même si ce n'est pas le cas dans le modèle de notre exemple)
Donc, on veut ajouter l'onglet au menu Projet et plus au menu Application.
Editez le fichier init.rb
et replacez la dernière ligne que nous avons ajoutez par les deux lignes suivantes :
Redmine::Plugin.register :redmine_polls do
[...]
permission :polls, {:polls => [:index, :vote]}, :public => true
menu :project_menu, :polls, { :controller => 'polls', :action => 'index' }, :caption => 'Polls', :after => :activity, :param => :project_id
end
la deuxième ligne ajoute l'onglet Polls dans le menu Projet juste derrière l'onglet Activité.
la première ligne sert à déclarer que nos deux actions du PollsController
sont publiques.
Nous reviendrons plus tard sur les permissions.
Redémarrez encore l'application et entrez dans un de vos projets:
If you click the Polls tab, you should notice that the project menu is no longer displayed.
To make the project menu visible, you have to initialize the controller's instance variable @project
.
Si vous cliquez sur l'onglet Polls, vous constatez que le menu projet n'est plus affiché.
Pour continuer à l'afficher, nous devons initialiser la variable d'instance @project
du controlleur.
Editez votre PollsController tel que:
def index
@project = Project.find(params[:project_id])
@polls = Poll.find(:all) # @project.polls
end
L'id du projet est disponible dans :project_id
grace à l'option :param => :project_id
dans la déclaration du menu item précédante.
Maintenant, vous devriez continuer à voir le menu projet quand vous visualisez un vote :
Ajouter des nouvelles permissions¶
Pour le moment, tout le monde peut voter.
On peut rendre ceci configurable en ajoutant des permissions Redmine.
Nous allons definir deux permissions au niveau Projet, une pour visualiser et une pour voter.
Ces permissions ne seront donc plus publiques (l'option :public => true
disparait)
Editez vendor/plugins/redmine_polls/init.rb
pour remplacer la permission précedante avec les deux lignes suivantes :
permission :view_polls, :polls => :index
permission :vote_polls, :polls => :vote
Redemarrez l'application et allez à l'URL http://localhost:3000/roles/report:
on voit donc deux permissions de plus ajoutable à votre role.
Biensur, il va falloir ajouter du code au PollsController, donc ces actions sont pour le moment protégé par les permissions de l'utilisateur courant.
Pour cela, nous avons juste à ajouter le filtre :authorize
et faire en sorte que la variable d'instance Herve Harster est initialisée avant d'appeler ce filtre
Voici à quoi ça doit ressembler dans l'action #index
:
class PollsController < ApplicationController
unloadable
before_filter :find_project, :authorize, :only => :index
[...]
def index
@polls = Poll.find(:all) # @project.polls
end
[...]
private
def find_project
# @project variable must be set before calling the authorize filter
@project = Project.find(params[:project_id])
end
end
Récupérer le projet courant avant le #vote
peut-être fait de façon très similaire.
Après ça, voir un vote et voter ne sera accessible qu'aux administrateur ou aux utilisateurs que on un rôle approprié dnas le projet.
Pour traduire les symboles de vos permissions dans plusieurs langues, vous devez ajouter les labels de textes necessaires dans vos fichiers de langues tel que :
labels like this:
permission_view_polls: Voir les votes
permission_vote_polls: Voter
Dans cette exemple, on a créé le fichier fr.yml, mais on peut créer des fichiers pour toutes les langues que l'on souhaite.
On voit dans cette exemple, que le lable est le symbole de la permission :view_polls
et :vote_polls
préfixé de permission_
Redemarrez votre application et pointer sur la section permissions.
Créer un module de projets¶
Pour le moment, la fonctionnalité de vote est ajoutée à tous vos projets, mais on souhaite la rendre activable ou désactivable pour chaque projet.
On va donc créer un module de projet 'Polls'.
On fait ceci en inclant les permissions dans un bloc #project_module
.
Editez init.rb
et changez la déclaration des permissions :
project_module :polls do
permission :view_polls, :polls => :index
permission :vote_polls, :polls => :vote
end
Redemarrez votre application et pointer sur un de vos projet dans sa configuration.
Cliquez sur l'onglet Modules, vous y verez le module Polls à la fin de la liste de modules, désactivé par defaut.
Vous pouvez l'activer ou le désactiver pour chaque projet.
Améliorer la vue du plugin¶
Ajouter des Styles CSS¶
On va commencer par ajouter un CSS à notre vue
Créez un fichier nommé voting.css
dans le répertoire vendor/plugins/redmine_polls/assets/stylesheets
:
a.vote { font-size: 120%; } a.vote.yes { color: green; } a.vote.no { color: red; }
Quand on redemarrer l'application, les plugin assets sont copié dans public/plugin_assets/redmine_polls/
par le moteur de Rails pour les rendrent disponibles via votre serveur Web.
Donc toute modification des CSS des plugins impliques un redemarrage de Rails.
Ensuite, on va devoir ajouter les lignes suivantes dans la vue vendor/plugins/redmine_polls/app/views/polls/index.html.erb
pour que nos CSS soient pris en compte et incluent dans le header de cette vue par Redmine :
<% content_for :header_tags do %> <%= stylesheet_link_tag 'voting', :plugin => 'redmine_polls' %> <% end %>
Notez que l'option :plugin => 'redmine_polls'
est requise quand on appelle le helper stylesheet_link_tag
.
Les Javascripts peuvent être inclut dans le plugin en utilisant le helper javascript_include_tag
de la même manière.
Modifier le titre de la page¶
on peut modifier le titre HTML de la page depuis le vue elle-même grace au helper html_title
Exemple:
<% html_title "Polls" -%>
Tester votre plugin¶
test/test_helper.rb:¶
Voici le contenu de mon fichier de tests :
require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')
Exemple de test:¶
Contenu de requirements_controller_test.rb:
require File.dirname(__FILE__) + '/../test_helper' require 'requirements_controller' class RequirementsControllerTest < ActionController::TestCase fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details, :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages, :attachments, :custom_fields, :custom_values, :time_entries def setup @skill = Skill.new(:skill_name => 'Java') @project = Project.find(1) @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new User.current = nil end def test_routing assert_routing( {:method => :get, :path => '/requirements'}, :controller => 'requirements', :action => 'index' ) end
Initialisation de la base de test :¶
Il semble plus facile d'initialiser la base de tests directement par la commande rake :
rake db:drop db:create db:migrate db:migrate_plugins redmine:load_default_data RAILS_ENV=test
Executer les tests:¶
Pour executer the requirements_controller_test.rb on utilise la commande suivante :
rake test:engines:all PLUGIN=redmine_requirements
Tester avec des utilisateurs et des projets¶
If your plugin requires membership to a project, add the following to the beginning of your functional tests:
Si votre plugin requière de appartenances à un projet, ajouter les lignes suivantes pour que ce soit opérationnel :
def setup @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new User.current = nil end def test_index @request.session[:user_id] = 2 get :index, :project_id => 1 assert_response :success assert_template :index end
Updated by Robert Tome almost 12 years ago · 3 revisions