##// END OF EJS Templates
0.3 unstable...
Jean-Philippe Lang -
r10:310a0f924aa0
parent child
Show More
@@ -0,0 +1,82
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 class AuthSourcesController < ApplicationController
19 layout 'base'
20 before_filter :require_admin
21
22 def index
23 list
24 render :action => 'list'
25 end
26
27 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
28 verify :method => :post, :only => [ :destroy, :create, :update ],
29 :redirect_to => { :action => :list }
30
31 def list
32 @auth_source_pages, @auth_sources = paginate :auth_sources, :per_page => 10
33 end
34
35 def new
36 @auth_source = AuthSourceLdap.new
37 end
38
39 def create
40 @auth_source = AuthSourceLdap.new(params[:auth_source])
41 if @auth_source.save
42 flash[:notice] = l(:notice_successful_create)
43 redirect_to :action => 'list'
44 else
45 render :action => 'new'
46 end
47 end
48
49 def edit
50 @auth_source = AuthSource.find(params[:id])
51 end
52
53 def update
54 @auth_source = AuthSource.find(params[:id])
55 if @auth_source.update_attributes(params[:auth_source])
56 flash[:notice] = l(:notice_successful_update)
57 redirect_to :action => 'list'
58 else
59 render :action => 'edit'
60 end
61 end
62
63 def test_connection
64 @auth_method = AuthSource.find(params[:id])
65 begin
66 @auth_method.test_connection
67 rescue => text
68 flash[:notice] = text
69 end
70 flash[:notice] ||= l(:notice_successful_connection)
71 redirect_to :action => 'list'
72 end
73
74 def destroy
75 @auth_source = AuthSource.find(params[:id])
76 unless @auth_source.users.find(:first)
77 @auth_source.destroy
78 flash[:notice] = l(:notice_successful_delete)
79 end
80 redirect_to :action => 'list'
81 end
82 end
@@ -0,0 +1,19
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 module AuthSourcesHelper
19 end
@@ -0,0 +1,47
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 class AuthSource < ActiveRecord::Base
19 has_many :users
20
21 validates_presence_of :name
22 validates_uniqueness_of :name
23
24 def authenticate(login, password)
25 end
26
27 def test_connection
28 end
29
30 def auth_method_name
31 "Abstract"
32 end
33
34 # Try to authenticate a user not yet registered against available sources
35 def self.authenticate(login, password)
36 AuthSource.find(:all, :conditions => ["onthefly_register=?", true]).each do |source|
37 begin
38 logger.debug "Authenticating '#{login}' against '#{source.name}'" if logger && logger.debug?
39 attrs = source.authenticate(login, password)
40 rescue
41 attrs = nil
42 end
43 return attrs if attrs
44 end
45 return nil
46 end
47 end
@@ -0,0 +1,79
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require 'net/ldap'
19 require 'iconv'
20
21 class AuthSourceLdap < AuthSource
22 validates_presence_of :host, :port, :attr_login
23
24 def after_initialize
25 self.port = 389 if self.port == 0
26 end
27
28 def authenticate(login, password)
29 attrs = []
30 # get user's DN
31 ldap_con = initialize_ldap_con(self.account, self.account_password)
32 login_filter = Net::LDAP::Filter.eq( self.attr_login, login )
33 object_filter = Net::LDAP::Filter.eq( "objectClass", "organizationalPerson" )
34 dn = String.new
35 ldap_con.search( :base => self.base_dn,
36 :filter => object_filter & login_filter,
37 :attributes=> ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail]) do |entry|
38 dn = entry.dn
39 attrs = [:firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
40 :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
41 :mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
42 :auth_source_id => self.id ]
43 end
44 return nil if dn.empty?
45 logger.debug "DN found for #{login}: #{dn}" if logger && logger.debug?
46 # authenticate user
47 ldap_con = initialize_ldap_con(dn, password)
48 return nil unless ldap_con.bind
49 # return user's attributes
50 logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
51 attrs
52 rescue Net::LDAP::LdapError => text
53 raise "LdapError: " + text
54 end
55
56 # test the connection to the LDAP
57 def test_connection
58 ldap_con = initialize_ldap_con(self.account, self.account_password)
59 ldap_con.open { }
60 rescue Net::LDAP::LdapError => text
61 raise "LdapError: " + text
62 end
63
64 def auth_method_name
65 "LDAP"
66 end
67
68 private
69 def initialize_ldap_con(ldap_user, ldap_password)
70 Net::LDAP.new( {:host => self.host,
71 :port => self.port,
72 :auth => { :method => :simple, :username => Iconv.new('iso-8859-15', 'utf-8').iconv(ldap_user), :password => Iconv.new('iso-8859-15', 'utf-8').iconv(ldap_password) }}
73 )
74 end
75
76 def self.get_attr(entry, attr_name)
77 entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
78 end
79 end
@@ -0,0 +1,27
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 class IssueCustomField < CustomField
19 has_and_belongs_to_many :projects, :join_table => "custom_fields_projects", :foreign_key => "custom_field_id"
20 has_and_belongs_to_many :trackers, :join_table => "custom_fields_trackers", :foreign_key => "custom_field_id"
21 has_many :issues, :through => :issue_custom_values
22
23 def type_name
24 :label_issue_plural
25 end
26 end
27
@@ -0,0 +1,22
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 class ProjectCustomField < CustomField
19 def type_name
20 :label_project_plural
21 end
22 end
@@ -0,0 +1,44
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 class Token < ActiveRecord::Base
19 belongs_to :user
20
21 @@validity_time = 1.day
22
23 def before_create
24 self.value = Token.generate_token_value
25 end
26
27 # Return true if token has expired
28 def expired?
29 return Time.now > self.created_on + @@validity_time
30 end
31
32 # Delete all expired tokens
33 def self.destroy_expired
34 Token.delete_all ["created_on < ?", Time.now - @@validity_time]
35 end
36
37 private
38 def self.generate_token_value
39 chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
40 token_value = ''
41 40.times { |i| token_value << chars[rand(chars.size-1)] }
42 token_value
43 end
44 end
@@ -0,0 +1,23
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 class UserCustomField < CustomField
19 def type_name
20 :label_user_plural
21 end
22 end
23
@@ -0,0 +1,14
1 <center>
2 <div class="box login">
3 <h2><%=l(:label_password_lost)%></h2>
4
5 <%= start_form_tag %>
6
7 <p><label for="mail"><%=l(:field_mail)%> <span class="required">*</span></label><br/>
8 <%= text_field_tag 'mail', nil, :size => 40 %></p>
9
10 <p><center><%= submit_tag l(:button_submit) %></center></p>
11
12 <%= end_form_tag %>
13 </div>
14 </center> No newline at end of file
@@ -0,0 +1,21
1 <center>
2 <div class="box login">
3 <h2><%=l(:label_password_lost)%></h2>
4
5 <p><%=l(:field_login)%>: <strong><%= @user.login %></strong><br />
6
7 <%= error_messages_for 'user' %>
8
9 <%= start_form_tag :token => @token.value %>
10
11 <p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label><br/>
12 <%= password_field_tag 'new_password', nil, :size => 25 %></p>
13
14 <p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label><br/>
15 <%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>
16
17 <p><center><%= submit_tag l(:button_save) %></center></p>
18 <%= end_form_tag %>
19
20 </div>
21 </center> No newline at end of file
@@ -0,0 +1,46
1 <h2><%=l(:label_register)%></h2>
2
3 <%= start_form_tag %>
4
5 <%= error_messages_for 'user' %>
6
7 <div class="box">
8 <!--[form:user]-->
9 <p><label for="user_login"><%=l(:field_login)%></label> <span class="required">*</span><br/>
10 <%= text_field 'user', 'login', :size => 25 %></p>
11
12 <p><label for="password"><%=l(:field_password)%></label> <span class="required">*</span><br/>
13 <%= password_field_tag 'password', nil, :size => 25 %></p>
14
15 <p><label for="password_confirmation"><%=l(:field_password_confirmation)%></label> <span class="required">*</span><br/>
16 <%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
17
18 <p><label for="user_firstname"><%=l(:field_firstname)%></label> <span class="required">*</span><br/>
19 <%= text_field 'user', 'firstname' %></p>
20
21 <p><label for="user_lastname"><%=l(:field_lastname)%></label> <span class="required">*</span><br/>
22 <%= text_field 'user', 'lastname' %></p>
23
24 <p><label for="user_mail"><%=l(:field_mail)%></label> <span class="required">*</span><br/>
25 <%= text_field 'user', 'mail' %></p>
26
27 <p><label for="user_language"><%=l(:field_language)%></label><br/>
28 <%= select("user", "language", Localization.langs.invert) %></p>
29
30 <% for custom_value in @custom_values %>
31 <div style="float:left;margin-right:10px;">
32 <p><%= content_tag "label", custom_value.custom_field.name %>
33 <% if custom_value.custom_field.is_required? %><span class="required">*</span><% end %>
34 <br />
35 <%= custom_field_tag custom_value %></p>
36 </div>
37 <% end %>
38
39 <div style="clear: both;"></div>
40
41 <p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=l(:field_mail_notification)%></label></p>
42 <!--[eoform:user]-->
43 </div>
44
45 <%= submit_tag l(:button_submit) %>
46 <%= end_form_tag %>
@@ -0,0 +1,49
1 <%= error_messages_for 'auth_source' %>
2
3 <div class="box">
4 <!--[form:auth_source]-->
5 <p><label for="auth_source_name"><%=l(:field_name)%></label> <span class="required">*</span><br/>
6 <%= text_field 'auth_source', 'name' %></p>
7
8 <p><label for="auth_source_host"><%=l(:field_host)%></label> <span class="required">*</span><br/>
9 <%= text_field 'auth_source', 'host' %></p>
10
11 <p><label for="auth_source_port"><%=l(:field_port)%></label> <span class="required">*</span><br/>
12 <%= text_field 'auth_source', 'port', :size => 6 %></p>
13
14 <p><label for="auth_source_account"><%=l(:field_account)%></label><br/>
15 <%= text_field 'auth_source', 'account' %></p>
16
17 <p><label for="auth_source_account_password"><%=l(:field_password)%></label><br/>
18 <%= password_field 'auth_source', 'account_password' %></p>
19
20 <p><label for="auth_source_base_dn"><%=l(:field_base_dn)%></label> <span class="required">*</span><br/>
21 <%= text_field 'auth_source', 'base_dn', :size => 60 %></p>
22
23 <p><%= check_box 'auth_source', 'onthefly_register' %>
24 <label for="auth_source_onthefly_register"><%=l(:field_onthefly)%></label></p>
25
26 <fieldset><legend><%=l(:label_attribute_plural)%></legend>
27 <div style="float:left;margin-right:10px;">
28 <p><label for="auth_source_attr_login"><%=l(:field_login)%></label> <span class="required">*</span><br/>
29 <%= text_field 'auth_source', 'attr_login', :size => 20 %></p>
30 </div>
31
32 <div style="float:left;margin-right:10px;">
33 <p><label for="auth_source_attr_firstname"><%=l(:field_firstname)%></label><br/>
34 <%= text_field 'auth_source', 'attr_firstname', :size => 20 %></p>
35 </div>
36
37 <div style="float:left;margin-right:10px;">
38 <p><label for="auth_source_attr_lastname"><%=l(:field_lastname)%></label><br/>
39 <%= text_field 'auth_source', 'attr_lastname', :size => 20 %></p>
40 </div>
41
42 <div>
43 <p><label for="auth_source_attr_mail"><%=l(:field_mail)%></label><br/>
44 <%= text_field 'auth_source', 'attr_mail', :size => 20 %></p>
45 </div>
46 </fieldset>
47
48 <!--[eoform:auth_source]-->
49 </div>
@@ -0,0 +1,7
1 <h2><%=l(:label_auth_source)%> (<%= @auth_source.auth_method_name %>)</h2>
2
3 <%= start_form_tag :action => 'update', :id => @auth_source %>
4 <%= render :partial => 'form' %>
5 <%= submit_tag l(:button_save) %>
6 <%= end_form_tag %>
7
@@ -0,0 +1,32
1 <h2><%=l(:label_auth_source_plural)%></h2>
2
3 <table border="0" cellspacing="1" cellpadding="2" class="listTableContent">
4 <tr class="ListHead">
5 <td><%=l(:field_name)%></td>
6 <td><%=l(:field_type)%></td>
7 <td><%=l(:field_host)%></td>
8 <td></td>
9 <td></td>
10 </tr>
11
12 <% for source in @auth_sources %>
13 <tr class="<%= cycle("odd", "even") %>">
14 <td><%= link_to source.name, :action => 'edit', :id => source%></td>
15 <td align="center"><%= source.auth_method_name %></td>
16 <td align="center"><%= source.host %></td>
17 <td align="center">
18 <%= link_to l(:button_test), :action => 'test_connection', :id => source %>
19 </td>
20 <td align="center">
21 <%= start_form_tag :action => 'destroy', :id => source %>
22 <%= submit_tag l(:button_delete), :class => "button-small" %>
23 <%= end_form_tag %>
24 </td>
25 </tr>
26 <% end %>
27 </table>
28
29 <%= pagination_links_full @auth_source_pages %>
30 <br />
31 <%= link_to '&#187; ' + l(:label_auth_source_new), :action => 'new' %>
32
@@ -0,0 +1,6
1 <h2><%=l(:label_auth_source_new)%> (<%= @auth_source.auth_method_name %>)</h2>
2
3 <%= start_form_tag :action => 'create' %>
4 <%= render :partial => 'form' %>
5 <%= submit_tag l(:button_create) %>
6 <%= end_form_tag %>
@@ -0,0 +1,3
1 Une nouvelle demande (#<%= @issue.id %>) a été soumise.
2 ----------------------------------------
3 <%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %> No newline at end of file
@@ -0,0 +1,3
1 La demande #<%= @issue.id %> a été mise à jour au statut "<%= @issue.status.name %>".
2 ----------------------------------------
3 <%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %> No newline at end of file
@@ -0,0 +1,3
1 To change your password, use the following link:
2
3 http://<%= $RDM_HOST_NAME %>/account/lost_password?token=<%= @token.value %> No newline at end of file
@@ -0,0 +1,3
1 Pour changer votre mot de passe, utilisez le lien suivant:
2
3 http://<%= $RDM_HOST_NAME %>/account/lost_password?token=<%= @token.value %> No newline at end of file
@@ -0,0 +1,3
1 To activate your redMine account, use the following link:
2
3 http://<%= $RDM_HOST_NAME %>/account/register?token=<%= @token.value %> No newline at end of file
@@ -0,0 +1,3
1 Pour activer votre compte sur redMine, utilisez le lien suivant:
2
3 http://<%= $RDM_HOST_NAME %>/account/register?token=<%= @token.value %> No newline at end of file
@@ -0,0 +1,57
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18
19 # To set your own configuration, rename this file to config_custom.rb
20 # and edit parameters below
21 # Don't forget to restart the application after any change.
22
23
24 # Application host name
25 # Used to provide absolute links in mail notifications
26 # $RDM_HOST_NAME = "somenet.foo"
27
28 # File storage path
29 # Directory used to store uploaded files
30 # #{RAILS_ROOT} represents application's home directory
31 # $RDM_STORAGE_PATH = "#{RAILS_ROOT}/files"
32
33 # Set $RDM_LOGIN_REQUIRED to true if you want to force users to login
34 # to access any page of the application
35 # $RDM_LOGIN_REQUIRED = false
36
37 # Uncomment to disable user self-registration
38 # $RDM_SELF_REGISTRATION = false
39
40 # Default langage ('en', 'es', 'fr' are available)
41 # $RDM_DEFAULT_LANG = 'en'
42
43 # Page title
44 # $RDM_HEADER_TITLE = "Title"
45
46 # Page sub-title
47 # $RDM_HEADER_SUBTITLE = "Sub title"
48
49 # Welcome page title
50 # $RDM_WELCOME_TITLE = "Welcome"
51
52 # Welcome page text
53 # $RDM_WELCOME_TEXT = ""
54
55 # Signature displayed in footer
56 # Email adresses will be automatically displayed as a mailto link
57 # $RDM_FOOTER_SIG = "admin@somenet.foo"
@@ -0,0 +1,113
1 _gloc_rule_default: '|n| n==1 ? "" : "_plural" '
2
3 actionview_datehelper_select_day_prefix:
4 actionview_datehelper_select_month_names: January,February,March,April,May,June,July,August,September,October,November,December
5 actionview_datehelper_select_month_names_abbr: Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
6 actionview_datehelper_select_month_prefix:
7 actionview_datehelper_select_year_prefix:
8 actionview_datehelper_time_in_words_day: 1 day
9 actionview_datehelper_time_in_words_day_plural: %d days
10 actionview_datehelper_time_in_words_hour_about: about an hour
11 actionview_datehelper_time_in_words_hour_about_plural: about %d hours
12 actionview_datehelper_time_in_words_hour_about_single: about an hour
13 actionview_datehelper_time_in_words_minute: 1 minute
14 actionview_datehelper_time_in_words_minute_half: half a minute
15 actionview_datehelper_time_in_words_minute_less_than: less than a minute
16 actionview_datehelper_time_in_words_minute_plural: %d minutes
17 actionview_datehelper_time_in_words_minute_single: 1 minute
18 actionview_datehelper_time_in_words_second_less_than: less than a second
19 actionview_datehelper_time_in_words_second_less_than_plural: less than %d seconds
20 actionview_instancetag_blank_option: Please select
21
22 activerecord_error_inclusion: is not included in the list
23 activerecord_error_exclusion: is reserved
24 activerecord_error_invalid: is invalid
25 activerecord_error_confirmation: doesn't match confirmation
26 activerecord_error_accepted: must be accepted
27 activerecord_error_empty: can't be empty
28 activerecord_error_blank: can't be blank
29 activerecord_error_too_long: is too long
30 activerecord_error_too_short: is too short
31 activerecord_error_wrong_length: is the wrong length
32 activerecord_error_taken: has already been taken
33 activerecord_error_not_a_number: is not a number
34
35 general_fmt_age: %d yr
36 general_fmt_age_plural: %d yrs
37 general_fmt_date: %%b %%d, %%Y (%%a)
38 general_fmt_datetime: %%b %%d, %%Y (%%a), %%I:%%M %%p
39 general_fmt_datetime_short: %%b %%d, %%I:%%M %%p
40 general_fmt_time: %%I:%%M %%p
41 general_text_No: 'No'
42 general_text_Yes: 'Yes'
43 general_text_no: 'no'
44 general_text_yes: 'yes'
45
46 notice_account_updated: Account was successfully updated.
47 notice_account_invalid_creditentials: Invalid user or password
48 notice_account_password_updated: Password was successfully updated.
49 notice_account_wrong_password: Wrong password
50 notice_account_register_done: Account was successfully created.
51 notice_account_unknown_email: Unknown user.
52 notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you.
53
54 gui_menu_home: Home
55 gui_menu_my_page: My page
56 gui_menu_projects: Projects
57 gui_menu_my_account: My account
58 gui_menu_admin: Administration
59 gui_menu_login: Login
60 gui_menu_logout: Logout
61 gui_menu_help: Help
62 gui_validation_error: 1 error
63 gui_validation_error_plural: %d errors
64
65 field_name: Name
66 field_description: Description
67 field_summary: Summary
68 field_is_required: Required
69 field_firstname: Firstname
70 field_lastname: Lastname
71 field_mail: Email
72 field_filename: File
73 field_filesize: Size
74 field_downloads: Downloads
75 field_author: Author
76 field_created_on: Created
77 field_updated_on: Updated
78 field_field_format: Format
79 field_is_for_all: For all projects
80 field_possible_values: Possible values
81 field_regexp: Regular expression
82 field_min_length: Minimum length
83 field_max_length: Maximum length
84 field_value: Value
85 field_category: Catogory
86 field_title: Title
87 field_project: Project
88 field_issue: Issue
89 field_status: Status
90 field_notes: Notes
91 field_is_closed: Issue closed
92 field_is_default: Default status
93 field_html_color: Color
94 field_tracker: Tracker
95 field_subject: Subject
96 field_assigned_to: Assigned to
97 field_priority: Priority
98 field_fixed_version: Fixed version
99 field_user: User
100 field_role: Role
101 field_homepage: Homepage
102 field_is_public: Public
103 field_parent: Subproject de
104 field_is_in_chlog: Issues displayed in changelog
105 field_login: Login
106 field_mail_notification: Mail notifications
107 field_admin: Administrator
108 field_locked: Locked
109 field_last_login_on: Last connection
110 field_language: Language
111 field_effective_date: Date
112 field_password: Password
113 field_password_confirmation: Confirmation No newline at end of file
@@ -0,0 +1,199
1 _gloc_rule_default: '|n| n==1 ? "" : "_plural" '
2
3 actionview_datehelper_select_day_prefix:
4 actionview_datehelper_select_month_names: Janvier,Février,Mars,Avril,Mai,Juin,Juillet,Août,Septembre,Octobre,Novembre,Décembre
5 actionview_datehelper_select_month_names_abbr: Jan,Fév,Mars,Avril,Mai,Juin,Juil,Août,Sept,Oct,Nov,Déc
6 actionview_datehelper_select_month_prefix:
7 actionview_datehelper_select_year_prefix:
8 actionview_datehelper_time_in_words_day: 1 jour
9 actionview_datehelper_time_in_words_day_plural: %d jours
10 actionview_datehelper_time_in_words_hour_about: about an hour
11 actionview_datehelper_time_in_words_hour_about_plural: about %d hours
12 actionview_datehelper_time_in_words_hour_about_single: about an hour
13 actionview_datehelper_time_in_words_minute: 1 minute
14 actionview_datehelper_time_in_words_minute_half: 30 secondes
15 actionview_datehelper_time_in_words_minute_less_than: moins d'une minute
16 actionview_datehelper_time_in_words_minute_plural: %d minutes
17 actionview_datehelper_time_in_words_minute_single: 1 minute
18 actionview_datehelper_time_in_words_second_less_than: moins d'une seconde
19 actionview_datehelper_time_in_words_second_less_than_plural: moins de %d secondes
20 actionview_instancetag_blank_option: Choisir
21
22 activerecord_error_inclusion: n'est pas inclus dans la liste
23 activerecord_error_exclusion: est reservé
24 activerecord_error_invalid: est invalide
25 activerecord_error_confirmation: ne correspond pas à la confirmation
26 activerecord_error_accepted: doit être accepté
27 activerecord_error_empty: doit être renseigné
28 activerecord_error_blank: doit être renseigné
29 activerecord_error_too_long: est trop long
30 activerecord_error_too_short: est trop court
31 activerecord_error_wrong_length: n'est pas de la bonne longueur
32 activerecord_error_taken: est déjà utilisé
33 activerecord_error_not_a_number: n'est pas un nombre
34
35 general_fmt_age: %d an
36 general_fmt_age_plural: %d ans
37 general_fmt_date: %%d/%%m/%%Y
38 general_fmt_datetime: %%d/%%m/%%Y %%H:%%M
39 general_fmt_datetime_short: %%d/%%m %%H:%%M
40 general_fmt_time: %%H:%%M
41 general_text_No: 'Non'
42 general_text_Yes: 'Oui'
43 general_text_no: 'non'
44 general_text_yes: 'oui'
45
46 notice_account_updated: Le compte a été mis à jour avec succès.
47 notice_account_invalid_creditentials: Identifiant ou mot de passe invalide.
48 notice_account_password_updated: Mot de passe mis à jour avec succès.
49 notice_account_wrong_password: Mot de passe incorrect
50 notice_account_register_done: Un message contenant les instructions pour activer votre compte vous a été envoyé.
51 notice_account_unknown_email: Aucun compte ne correspond à cette adresse.
52 notice_account_lost_email_sent: Un message contenant les instructions pour choisir un nouveau mot de passe vous a été envoyé.
53 notice_account_activated: Votre compte a été activé. Vous pouvez à présent vous connecter.
54 notice_successful_update: Mise à jour effectuée avec succès.
55 notice_successful_create: Création effectuée avec succès.
56 notice_successful_delete: Suppression effectuée avec succès.
57 notice_successful_connection: Connection réussie.
58
59 gui_validation_error: 1 erreur
60 gui_validation_error_plural: %d erreurs
61
62 field_name: Nom
63 field_description: Description
64 field_summary: Résumé
65 field_is_required: Obligatoire
66 field_firstname: Prénom
67 field_lastname: Nom
68 field_mail: Email
69 field_filename: Fichier
70 field_filesize: Taille
71 field_downloads: Téléchargements
72 field_author: Auteur
73 field_created_on: Créé
74 field_updated_on: Mis à jour
75 field_field_format: Format
76 field_is_for_all: Pour tous les projets
77 field_possible_values: Valeurs possibles
78 field_regexp: Expression régulière
79 field_min_length: Longueur minimum
80 field_max_length: Longueur maximum
81 field_value: Valeur
82 field_category: Catégorie
83 field_title: Titre
84 field_project: Projet
85 field_issue: Demande
86 field_status: Statut
87 field_notes: Notes
88 field_is_closed: Demande fermée
89 field_is_default: Statut par défaut
90 field_html_color: Couleur
91 field_tracker: Tracker
92 field_subject: Sujet
93 field_assigned_to: Assigné à
94 field_priority: Priorité
95 field_fixed_version: Version corrigée
96 field_user: Utilisateur
97 field_role: Rôle
98 field_homepage: Site web
99 field_is_public: Public
100 field_parent: Sous-projet de
101 field_is_in_chlog: Demandes affichées dans l'historique
102 field_login: Identifiant
103 field_mail_notification: Notifications par mail
104 field_admin: Administrateur
105 field_locked: Verrouillé
106 field_last_login_on: Dernière connexion
107 field_language: Langue
108 field_effective_date: Date
109 field_password: Mot de passe
110 field_new_password: Nouveau mot de passe
111 field_password_confirmation: Confirmation
112 field_version: Version
113 field_type: Type
114 field_host: Hôte
115 field_port: Port
116 field_account: Compte
117 field_base_dn: Base DN
118 field_attr_login: Attribut Identifiant
119 field_attr_firstname: Attribut Prénom
120 field_attr_lastname: Attribut Nom
121 field_attr_mail: Attribut Email
122 field_onthefly: Création des utilisateurs à la volée
123
124 label_user: Utilisateur
125 label_user_plural: Utilisateurs
126 label_user_new: Nouvel utilisateur
127 label_project: Projet
128 label_project_new: Nouveau projet
129 label_project_plural: Projets
130 label_issue: Demande
131 label_issue_new: Nouvelle demande
132 label_issue_plural: Demandes
133 label_role: Rôle
134 label_role_plural: Rôles
135 label_role_add: Nouveau rôle
136 label_role_and_permissions: Rôles et permissions
137 label_tracker: Tracker
138 label_tracker_plural: Trackers
139 label_tracker_add: Nouveau tracker
140 label_workflow: Workflow
141 label_issue_status: Statut de demandes
142 label_issue_status_plural: Statuts de demandes
143 label_issue_status_add: Nouveau statut
144 label_custom_field: Champ personnalisé
145 label_custom_field_plural: Champs personnalisés
146 label_custom_field_new: Nouveau champ personnalisé
147 label_enumerations: Listes de valeurs
148 label_information: Information
149 label_information_plural: Informations
150 label_please_login: Identification
151 label_register: S'enregistrer
152 label_password_lost: Mot de passe perdu
153 label_home: Accueil
154 label_my_page: Ma page
155 label_my_account: Mon compte
156 label_administration: Administration
157 label_login: Connexion
158 label_logout: Déconnexion
159 label_help: Aide
160 label_reported_issues: Demandes soumises
161 label_assigned_to_me_issues: Demandes qui me sont assignées
162 label_last_login: Dernière connexion
163 label_last_updates: Dernière mise à jour
164 label_last_updates_plural: %d dernières mises à jour
165 label_registered_on: Inscrit le
166 label_activity: Activité
167 label_new: Nouveau
168 label_logged_as: Connecté en tant que
169 label_environment: Environnement
170 label_authentication: Authentification
171 label_auth_source: Mode d'authentification
172 label_auth_source_new: Nouveau mode d'authentification
173 label_auth_source_plural: Modes d'authentification
174 label_subproject: Sous-projet
175 label_subproject_plural: Sous-projets
176 label_min_max_length: Longueurs mini - maxi
177 label_list: Liste
178 label_date: Date
179 label_integer: Entier
180 label_boolean: Booléen
181 label_string: Chaîne
182 label_text: Texte
183 label_attribute: Attribut
184 label_attribute_plural: Attributs
185
186
187 button_login: Connexion
188 button_submit: Soumettre
189 button_save: Valider
190 button_check_all: Tout cocher
191 button_uncheck_all: Tout décocher
192 button_delete: Supprimer
193 button_create: Créer
194 button_test: Tester
195
196 text_select_mail_notifications: Sélectionner les actions pour lesquelles la notification par mail doit être activée.
197 text_regexp_info: eg. ^[A-Z0-9]+$
198 text_min_max_length_info: 0 pour aucune restriction
199 text_possible_values_info: valeurs séparées par | No newline at end of file
@@ -0,0 +1,24
1 desc 'Create YAML test fixtures from data in an existing database.
2 Defaults to development database. Set RAILS_ENV to override.'
3
4 task :extract_fixtures => :environment do
5 sql = "SELECT * FROM %s"
6 skip_tables = ["schema_info"]
7 ActiveRecord::Base.establish_connection
8 (ActiveRecord::Base.connection.tables - skip_tables).each do |table_name|
9 i = "000"
10 File.open("#{RAILS_ROOT}/#{table_name}.yml", 'w' ) do |file|
11 data = ActiveRecord::Base.connection.select_all(sql % table_name)
12 file.write data.inject({}) { |hash, record|
13
14 # cast extracted values
15 ActiveRecord::Base.connection.columns(table_name).each { |col|
16 record[col.name] = col.type_cast(record[col.name]) if record[col.name]
17 }
18
19 hash["#{table_name}_#{i.succ!}"] = record
20 hash
21 }.to_yaml
22 end
23 end
24 end No newline at end of file
This diff has been collapsed as it changes many lines, (556 lines changed) Show them Hide them
@@ -0,0 +1,556
1 //*****************************************************************************
2 // Do not remove this notice.
3 //
4 // Copyright 2000-2004 by Mike Hall.
5 // See http://www.brainjar.com for terms of use.
6 //*****************************************************************************
7
8 //----------------------------------------------------------------------------
9 // Emulation de la fonction push pour IE5.0
10 //----------------------------------------------------------------------------
11 if(!Array.prototype.push){Array.prototype.push=function(){for(var i=0;i<arguments.length;i++)this[this.length]=arguments[i];};};
12
13 //----------------------------------------------------------------------------
14 // Code to determine the browser and version.
15 //----------------------------------------------------------------------------
16
17 function Browser() {
18
19 var ua, s, i;
20
21 this.isIE = false; // Internet Explorer
22 this.isOP = false; // Opera
23 this.isNS = false; // Netscape
24 this.version = null;
25 //-- debut ajout ci ----
26 this.isIE5mac = false; // Internet Explorer 5 mac
27 //-- fin ajout ci ----
28
29 ua = navigator.userAgent;
30
31 //-- debut ajout ci ----
32 if (ua.indexOf("Opera")==-1 && ua.indexOf("MSIE 5")>-1 && ua.indexOf("Mac")>-1) {
33 this.isIE5mac = true;
34 this.version = "";
35 return;
36 }
37 //-- fin ajout ci ----
38
39 s = "Opera";
40 if ((i = ua.indexOf(s)) >= 0) {
41 this.isOP = true;
42 this.version = parseFloat(ua.substr(i + s.length));
43 return;
44 }
45
46 s = "Netscape6/";
47 if ((i = ua.indexOf(s)) >= 0) {
48 this.isNS = true;
49 this.version = parseFloat(ua.substr(i + s.length));
50 return;
51 }
52
53 // Treat any other "Gecko" browser as Netscape 6.1.
54
55 s = "Gecko";
56 if ((i = ua.indexOf(s)) >= 0) {
57 this.isNS = true;
58 this.version = 6.1;
59 return;
60 }
61
62 s = "MSIE";
63 if ((i = ua.indexOf(s))) {
64 this.isIE = true;
65 this.version = parseFloat(ua.substr(i + s.length));
66 return;
67 }
68 }
69
70 var browser = new Browser();
71
72 //----------------------------------------------------------------------------
73 // Code for handling the menu bar and active button.
74 //----------------------------------------------------------------------------
75
76 var activeButton = null;
77
78
79 function buttonClick(event, menuId) {
80
81 var button;
82
83 // Get the target button element.
84
85 if (browser.isIE)
86 button = window.event.srcElement;
87 else
88 button = event.currentTarget;
89
90 // Blur focus from the link to remove that annoying outline.
91
92 button.blur();
93
94 // Associate the named menu to this button if not already done.
95 // Additionally, initialize menu display.
96
97 if (button.menu == null) {
98 button.menu = document.getElementById(menuId);
99 if (button.menu.isInitialized == null)
100 menuInit(button.menu);
101 }
102
103 // Set mouseout event handler for the button, if not already done.
104
105 if (button.onmouseout == null)
106 button.onmouseout = buttonOrMenuMouseout;
107
108 // Exit if this button is the currently active one.
109
110 if (button == activeButton)
111 return false;
112
113 // Reset the currently active button, if any.
114
115 if (activeButton != null)
116 resetButton(activeButton);
117
118 // Activate this button, unless it was the currently active one.
119
120 if (button != activeButton) {
121 depressButton(button);
122 activeButton = button;
123 }
124 else
125 activeButton = null;
126
127 return false;
128 }
129
130 function buttonMouseover(event, menuId) {
131
132 var button;
133 //-- debut ajout ci ----
134 if (!browser.isIE5mac) {
135 //-- fin ajout ci ----
136
137 //-- debut ajout ci ----
138 cicacheselect();
139 //-- fin ajout ci ----
140
141 // Activates this button's menu if no other is currently active.
142
143 if (activeButton == null) {
144 buttonClick(event, menuId);
145 return;
146 }
147
148 // Find the target button element.
149
150 if (browser.isIE)
151 button = window.event.srcElement;
152 else
153 button = event.currentTarget;
154
155 // If any other button menu is active, make this one active instead.
156
157 if (activeButton != null && activeButton != button)
158 buttonClick(event, menuId);
159 //-- debut ajout ci ----
160 }
161 //-- fin ajout ci ----
162
163 }
164
165 function depressButton(button) {
166
167 var x, y;
168
169 // Update the button's style class to make it look like it's
170 // depressed.
171
172 button.className += " menuButtonActive";
173
174 // Set mouseout event handler for the button, if not already done.
175
176 if (button.onmouseout == null)
177 button.onmouseout = buttonOrMenuMouseout;
178 if (button.menu.onmouseout == null)
179 button.menu.onmouseout = buttonOrMenuMouseout;
180
181 // Position the associated drop down menu under the button and
182 // show it.
183
184 x = getPageOffsetLeft(button);
185 y = getPageOffsetTop(button) + button.offsetHeight - 1;
186
187 // For IE, adjust position.
188
189 if (browser.isIE) {
190 x += button.offsetParent.clientLeft;
191 y += button.offsetParent.clientTop;
192 }
193
194 button.menu.style.left = x + "px";
195 button.menu.style.top = y + "px";0
196 button.menu.style.visibility = "visible";
197 }
198
199 function resetButton(button) {
200
201 // Restore the button's style class.
202
203 removeClassName(button, "menuButtonActive");
204
205 // Hide the button's menu, first closing any sub menus.
206
207 if (button.menu != null) {
208 closeSubMenu(button.menu);
209 button.menu.style.visibility = "hidden";
210 }
211 }
212
213 //----------------------------------------------------------------------------
214 // Code to handle the menus and sub menus.
215 //----------------------------------------------------------------------------
216
217 function menuMouseover(event) {
218
219 var menu;
220 //-- debut ajout ci ----
221 if (!browser.isIE5mac) {
222 //-- fin ajout ci ----
223 //-- debut ajout ci ----
224 cicacheselect();
225 //-- fin ajout ci ----
226
227 // Find the target menu element.
228 if (browser.isIE)
229 menu = getContainerWith(window.event.srcElement, "DIV", "menu");
230 else
231 menu = event.currentTarget;
232
233 // Close any active sub menu.
234
235 if (menu.activeItem != null)
236 closeSubMenu(menu);
237 //-- debut ajout ci ----
238 }
239 //-- fin ajout ci ----
240 }
241
242 function menuItemMouseover(event, menuId) {
243
244 var item, menu, x, y;
245 //-- debut ajout ci ----
246 cicacheselect();
247 //-- fin ajout ci ----
248
249 // Find the target item element and its parent menu element.
250
251 if (browser.isIE)
252 item = getContainerWith(window.event.srcElement, "A", "menuItem");
253 else
254 item = event.currentTarget;
255 menu = getContainerWith(item, "DIV", "menu");
256
257 // Close any active sub menu and mark this one as active.
258
259 if (menu.activeItem != null)
260 closeSubMenu(menu);
261 menu.activeItem = item;
262
263 // Highlight the item element.
264
265 item.className += " menuItemHighlight";
266
267 // Initialize the sub menu, if not already done.
268
269 if (item.subMenu == null) {
270 item.subMenu = document.getElementById(menuId);
271 if (item.subMenu.isInitialized == null)
272 menuInit(item.subMenu);
273 }
274
275 // Set mouseout event handler for the sub menu, if not already done.
276
277 if (item.subMenu.onmouseout == null)
278 item.subMenu.onmouseout = buttonOrMenuMouseout;
279
280 // Get position for submenu based on the menu item.
281
282 x = getPageOffsetLeft(item) + item.offsetWidth;
283 y = getPageOffsetTop(item);
284
285 // Adjust position to fit in view.
286
287 var maxX, maxY;
288
289 if (browser.isIE) {
290 maxX = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft) +
291 (document.documentElement.clientWidth != 0 ? document.documentElement.clientWidth : document.body.clientWidth);
292 maxY = Math.max(document.documentElement.scrollTop, document.body.scrollTop) +
293 (document.documentElement.clientHeight != 0 ? document.documentElement.clientHeight : document.body.clientHeight);
294 }
295 if (browser.isOP) {
296 maxX = document.documentElement.scrollLeft + window.innerWidth;
297 maxY = document.documentElement.scrollTop + window.innerHeight;
298 }
299 if (browser.isNS) {
300 maxX = window.scrollX + window.innerWidth;
301 maxY = window.scrollY + window.innerHeight;
302 }
303 maxX -= item.subMenu.offsetWidth;
304 maxY -= item.subMenu.offsetHeight;
305
306 if (x > maxX)
307 x = Math.max(0, x - item.offsetWidth - item.subMenu.offsetWidth
308 + (menu.offsetWidth - item.offsetWidth));
309 y = Math.max(0, Math.min(y, maxY));
310
311 // Position and show the sub menu.
312
313 item.subMenu.style.left = x + "px";
314 item.subMenu.style.top = y + "px";
315 item.subMenu.style.visibility = "visible";
316
317 // Stop the event from bubbling.
318
319 if (browser.isIE)
320 window.event.cancelBubble = true;
321 else
322 event.stopPropagation();
323 }
324
325 function closeSubMenu(menu) {
326
327 if (menu == null || menu.activeItem == null)
328 return;
329
330 // Recursively close any sub menus.
331
332 if (menu.activeItem.subMenu != null) {
333 closeSubMenu(menu.activeItem.subMenu);
334 menu.activeItem.subMenu.style.visibility = "hidden";
335 menu.activeItem.subMenu = null;
336 }
337 removeClassName(menu.activeItem, "menuItemHighlight");
338 menu.activeItem = null;
339 }
340
341
342 function buttonOrMenuMouseout(event) {
343
344 var el;
345
346 // If there is no active button, exit.
347
348 if (activeButton == null)
349 return;
350
351 // Find the element the mouse is moving to.
352
353 if (browser.isIE)
354 el = window.event.toElement;
355 else if (event.relatedTarget != null)
356 el = (event.relatedTarget.tagName ? event.relatedTarget : event.relatedTarget.parentNode);
357
358 // If the element is not part of a menu, reset the active button.
359
360 if (getContainerWith(el, "DIV", "menu") == null) {
361 resetButton(activeButton);
362 activeButton = null;
363 //-- debut ajout ci ----
364 cimontreselect();
365 //-- fin ajout ci ----
366 }
367 }
368
369
370 //----------------------------------------------------------------------------
371 // Code to initialize menus.
372 //----------------------------------------------------------------------------
373
374 function menuInit(menu) {
375
376 var itemList, spanList;
377 var textEl, arrowEl;
378 var itemWidth;
379 var w, dw;
380 var i, j;
381
382 // For IE, replace arrow characters.
383
384 if (browser.isIE) {
385 menu.style.lineHeight = "2.5ex";
386 spanList = menu.getElementsByTagName("SPAN");
387 for (i = 0; i < spanList.length; i++)
388 if (hasClassName(spanList[i], "menuItemArrow")) {
389 spanList[i].style.fontFamily = "Webdings";
390 spanList[i].firstChild.nodeValue = "4";
391 }
392 }
393
394 // Find the width of a menu item.
395
396 itemList = menu.getElementsByTagName("A");
397 if (itemList.length > 0)
398 itemWidth = itemList[0].offsetWidth;
399 else
400 return;
401
402 // For items with arrows, add padding to item text to make the
403 // arrows flush right.
404
405 for (i = 0; i < itemList.length; i++) {
406 spanList = itemList[i].getElementsByTagName("SPAN");
407 textEl = null;
408 arrowEl = null;
409 for (j = 0; j < spanList.length; j++) {
410 if (hasClassName(spanList[j], "menuItemText"))
411 textEl = spanList[j];
412 if (hasClassName(spanList[j], "menuItemArrow"))
413 arrowEl = spanList[j];
414 }
415 if (textEl != null && arrowEl != null) {
416 textEl.style.paddingRight = (itemWidth
417 - (textEl.offsetWidth + arrowEl.offsetWidth)) + "px";
418 // For Opera, remove the negative right margin to fix a display bug.
419 if (browser.isOP)
420 arrowEl.style.marginRight = "0px";
421 }
422 }
423
424 // Fix IE hover problem by setting an explicit width on first item of
425 // the menu.
426
427 if (browser.isIE) {
428 w = itemList[0].offsetWidth;
429 itemList[0].style.width = w + "px";
430 dw = itemList[0].offsetWidth - w;
431 w -= dw;
432 itemList[0].style.width = w + "px";
433 }
434
435 // Mark menu as initialized.
436
437 menu.isInitialized = true;
438 }
439
440 //----------------------------------------------------------------------------
441 // General utility functions.
442 //----------------------------------------------------------------------------
443
444 function getContainerWith(node, tagName, className) {
445
446 // Starting with the given node, find the nearest containing element
447 // with the specified tag name and style class.
448
449 while (node != null) {
450 if (node.tagName != null && node.tagName == tagName &&
451 hasClassName(node, className))
452 return node;
453 node = node.parentNode;
454 }
455
456 return node;
457 }
458
459 function hasClassName(el, name) {
460
461 var i, list;
462
463 // Return true if the given element currently has the given class
464 // name.
465
466 list = el.className.split(" ");
467 for (i = 0; i < list.length; i++)
468 if (list[i] == name)
469 return true;
470
471 return false;
472 }
473
474 function removeClassName(el, name) {
475
476 var i, curList, newList;
477
478 if (el.className == null)
479 return;
480
481 // Remove the given class name from the element's className property.
482
483 newList = new Array();
484 curList = el.className.split(" ");
485 for (i = 0; i < curList.length; i++)
486 if (curList[i] != name)
487 newList.push(curList[i]);
488 el.className = newList.join(" ");
489 }
490
491 function getPageOffsetLeft(el) {
492
493 var x;
494
495 // Return the x coordinate of an element relative to the page.
496
497 x = el.offsetLeft;
498 if (el.offsetParent != null)
499 x += getPageOffsetLeft(el.offsetParent);
500
501 return x;
502 }
503
504 function getPageOffsetTop(el) {
505
506 var y;
507
508 // Return the x coordinate of an element relative to the page.
509
510 y = el.offsetTop;
511 if (el.offsetParent != null)
512 y += getPageOffsetTop(el.offsetParent);
513
514 return y;
515 }
516
517 //-- debut ajout ci ----
518 function cicacheselect(){
519 if (browser.isIE) {
520 oSelects = document.getElementsByTagName('SELECT');
521 if (oSelects.length > 0) {
522 for (i = 0; i < oSelects.length; i++) {
523 oSlt = oSelects[i];
524 if (oSlt.style.visibility != 'hidden') {oSlt.style.visibility = 'hidden';}
525 }
526 }
527 oSelects = document.getElementsByName('masquable');
528 if (oSelects.length > 0) {
529 for (i = 0; i < oSelects.length; i++) {
530 oSlt = oSelects[i];
531 if (oSlt.style.visibility != 'hidden') {oSlt.style.visibility = 'hidden';}
532 }
533 }
534 }
535 }
536
537 function cimontreselect(){
538 if (browser.isIE) {
539 oSelects = document.getElementsByTagName('SELECT');
540 if (oSelects.length > 0) {
541 for (i = 0; i < oSelects.length; i++) {
542 oSlt = oSelects[i];
543 if (oSlt.style.visibility != 'visible') {oSlt.style.visibility = 'visible';}
544 }
545 }
546 oSelects = document.getElementsByName('masquable');
547 if (oSelects.length > 0) {
548 for (i = 0; i < oSelects.length; i++) {
549 oSlt = oSelects[i];
550 if (oSlt.style.visibility != 'visible') {oSlt.style.visibility = 'visible';}
551 }
552 }
553 }
554 }
555
556 //-- fin ajout ci ----
@@ -0,0 +1,39
1 /*========== Drop down menu ==============*/
2 div.menu {
3 background-color: #FFFFFF;
4 border-style: solid;
5 border-width: 1px;
6 border-color: #7F9DB9;
7 position: absolute;
8 top: 0px;
9 left: 0px;
10 padding: 0;
11 visibility: hidden;
12 z-index: 101;
13 }
14
15 div.menu a.menuItem {
16 font-size: 10px;
17 font-weight: normal;
18 line-height: 2em;
19 color: #000000;
20 background-color: #FFFFFF;
21 cursor: default;
22 display: block;
23 padding: 0 1em;
24 margin: 0;
25 border: 0;
26 text-decoration: none;
27 white-space: nowrap;
28 }
29
30 div.menu a.menuItem:hover, div.menu a.menuItemHighlight {
31 background-color: #80b0da;
32 color: #ffffff;
33 }
34
35 div.menu a.menuItem span.menuItemText {}
36
37 div.menu a.menuItem span.menuItemArrow {
38 margin-right: -.75em;
39 }
@@ -0,0 +1,13
1 ---
2 attachments_001:
3 created_on: 2006-07-19 21:07:27 +02:00
4 downloads: 0
5 content_type: text/plain
6 disk_filename: 060719210727_error281.txt
7 container_id: 3
8 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
9 id: 1
10 container_type: Issue
11 filesize: 28
12 filename: error281.txt
13 author_id: 2
@@ -0,0 +1,2
1 --- {}
2
@@ -0,0 +1,45
1 ---
2 custom_fields_001:
3 name: Database
4 min_length: 0
5 regexp: ""
6 is_for_all: false
7 type: IssueCustomField
8 max_length: 0
9 possible_values: MySQL|PostgreSQL|Oracle
10 id: 1
11 is_required: false
12 field_format: list
13 custom_fields_002:
14 name: Build
15 min_length: 1
16 regexp: ""
17 is_for_all: true
18 type: IssueCustomField
19 max_length: 10
20 possible_values: ""
21 id: 2
22 is_required: false
23 field_format: string
24 custom_fields_003:
25 name: Development status
26 min_length: 0
27 regexp: ""
28 is_for_all: false
29 type: ProjectCustomField
30 max_length: 0
31 possible_values: Stable|Beta|Alpha|Planning
32 id: 3
33 is_required: true
34 field_format: list
35 custom_fields_004:
36 name: Phone number
37 min_length: 0
38 regexp: ""
39 is_for_all: false
40 type: UserCustomField
41 max_length: 0
42 possible_values: ""
43 id: 4
44 is_required: false
45 field_format: string
@@ -0,0 +1,2
1 --- {}
2
@@ -0,0 +1,10
1 ---
2 custom_fields_trackers_001:
3 custom_field_id: 1
4 tracker_id: 1
5 custom_fields_trackers_002:
6 custom_field_id: 2
7 tracker_id: 1
8 custom_fields_trackers_003:
9 custom_field_id: 2
10 tracker_id: 3
@@ -0,0 +1,43
1 ---
2 custom_values_006:
3 customized_type: Issue
4 custom_field_id: 2
5 customized_id: 3
6 id: 9
7 value: "125"
8 custom_values_007:
9 customized_type: Project
10 custom_field_id: 3
11 customized_id: 1
12 id: 10
13 value: Stable
14 custom_values_001:
15 customized_type: User
16 custom_field_id: 4
17 customized_id: 3
18 id: 2
19 value: ""
20 custom_values_002:
21 customized_type: User
22 custom_field_id: 4
23 customized_id: 4
24 id: 3
25 value: 01 23 45 67 89
26 custom_values_003:
27 customized_type: User
28 custom_field_id: 4
29 customized_id: 2
30 id: 4
31 value: ""
32 custom_values_004:
33 customized_type: Issue
34 custom_field_id: 2
35 customized_id: 1
36 id: 7
37 value: "101"
38 custom_values_005:
39 customized_type: Issue
40 custom_field_id: 2
41 customized_id: 2
42 id: 8
43 value: ""
@@ -0,0 +1,2
1 --- {}
2
@@ -0,0 +1,33
1 ---
2 enumerations_001:
3 name: Uncategorized
4 id: 1
5 opt: DCAT
6 enumerations_002:
7 name: User documentation
8 id: 2
9 opt: DCAT
10 enumerations_003:
11 name: Technical documentation
12 id: 3
13 opt: DCAT
14 enumerations_004:
15 name: Low
16 id: 4
17 opt: IPRI
18 enumerations_005:
19 name: Normal
20 id: 5
21 opt: IPRI
22 enumerations_006:
23 name: High
24 id: 6
25 opt: IPRI
26 enumerations_007:
27 name: Urgent
28 id: 7
29 opt: IPRI
30 enumerations_008:
31 name: Immediate
32 id: 8
33 opt: IPRI
@@ -0,0 +1,9
1 ---
2 issue_categories_001:
3 name: Printing
4 project_id: 1
5 id: 1
6 issue_categories_002:
7 name: Recipes
8 project_id: 1
9 id: 2
@@ -0,0 +1,29
1 ---
2 issue_histories_003:
3 created_on: 2006-07-19 21:07:27 +02:00
4 notes:
5 issue_id: 3
6 id: 3
7 author_id: 2
8 status_id: 1
9 issue_histories_004:
10 created_on: 2006-07-19 21:09:50 +02:00
11 notes: Should be bone quickly
12 issue_id: 2
13 id: 4
14 author_id: 2
15 status_id: 2
16 issue_histories_001:
17 created_on: 2006-07-19 21:02:17 +02:00
18 notes:
19 issue_id: 1
20 id: 1
21 author_id: 2
22 status_id: 1
23 issue_histories_002:
24 created_on: 2006-07-19 21:04:21 +02:00
25 notes:
26 issue_id: 2
27 id: 2
28 author_id: 2
29 status_id: 1
@@ -0,0 +1,37
1 ---
2 issue_statuses_006:
3 name: Rejected
4 is_default: false
5 html_color: F5C28B
6 is_closed: true
7 id: 6
8 issue_statuses_001:
9 name: New
10 is_default: true
11 html_color: F98787
12 is_closed: false
13 id: 1
14 issue_statuses_002:
15 name: Assigned
16 is_default: false
17 html_color: C0C0FF
18 is_closed: false
19 id: 2
20 issue_statuses_003:
21 name: Resolved
22 is_default: false
23 html_color: 88E0B3
24 is_closed: false
25 id: 3
26 issue_statuses_004:
27 name: Feedback
28 is_default: false
29 html_color: F3A4F4
30 is_closed: false
31 id: 4
32 issue_statuses_005:
33 name: Closed
34 is_default: false
35 html_color: DBDBDB
36 is_closed: true
37 id: 5
@@ -0,0 +1,43
1 ---
2 issues_001:
3 created_on: 2006-07-19 21:02:17 +02:00
4 project_id: 1
5 updated_on: 2006-07-19 21:04:30 +02:00
6 priority_id: 4
7 subject: Can't print recipes
8 id: 1
9 fixed_version_id:
10 category_id: 1
11 description: Unable to print recipes
12 tracker_id: 1
13 assigned_to_id:
14 author_id: 2
15 status_id: 1
16 issues_002:
17 created_on: 2006-07-19 21:04:21 +02:00
18 project_id: 1
19 updated_on: 2006-07-19 21:09:50 +02:00
20 priority_id: 5
21 subject: Add ingredients categories
22 id: 2
23 fixed_version_id:
24 category_id:
25 description: Ingredients should be classified by categories
26 tracker_id: 2
27 assigned_to_id: 3
28 author_id: 2
29 status_id: 2
30 issues_003:
31 created_on: 2006-07-19 21:07:27 +02:00
32 project_id: 1
33 updated_on: 2006-07-19 21:07:27 +02:00
34 priority_id: 4
35 subject: Error 281 when updating a recipe
36 id: 3
37 fixed_version_id:
38 category_id:
39 description: Error 281 is encountered when saving a recipe
40 tracker_id: 1
41 assigned_to_id:
42 author_id: 2
43 status_id: 1
@@ -0,0 +1,13
1 ---
2 members_001:
3 created_on: 2006-07-19 19:35:33 +02:00
4 project_id: 1
5 role_id: 1
6 id: 1
7 user_id: 2
8 members_002:
9 created_on: 2006-07-19 19:35:36 +02:00
10 project_id: 1
11 role_id: 2
12 id: 2
13 user_id: 3
@@ -0,0 +1,20
1 ---
2 news_001:
3 created_on: 2006-07-19 22:40:26 +02:00
4 project_id: 1
5 title: eCookbook first release !
6 id: 1
7 description: |-
8 eCookbook 1.0 has been released.
9
10 Visit http://ecookbook.somenet.foo/
11 summary: First version was released...
12 author_id: 2
13 news_002:
14 created_on: 2006-07-19 22:42:58 +02:00
15 project_id: 1
16 title: 100,000 downloads for eCookbook
17 id: 2
18 description: eCookbook 1.0 have downloaded 100,000 times
19 summary: eCookbook 1.0 have downloaded 100,000 times
20 author_id: 2
@@ -0,0 +1,379
1 ---
2 permissions_041:
3 action: add_file
4 id: 41
5 description: Add
6 controller: projects
7 mail_enabled: false
8 mail_option: false
9 sort: 1320
10 is_public: false
11 permissions_030:
12 action: destroy
13 id: 30
14 description: Delete
15 controller: news
16 mail_enabled: false
17 mail_option: false
18 sort: 1122
19 is_public: false
20 permissions_019:
21 action: download
22 id: 19
23 description: Download file
24 controller: issues
25 mail_enabled: false
26 mail_option: false
27 sort: 1010
28 is_public: true
29 permissions_008:
30 action: edit
31 id: 8
32 description: Edit
33 controller: members
34 mail_enabled: false
35 mail_option: false
36 sort: 221
37 is_public: false
38 permissions_042:
39 action: destroy_file
40 id: 42
41 description: Delete
42 controller: versions
43 mail_enabled: false
44 mail_option: false
45 sort: 1322
46 is_public: false
47 permissions_031:
48 action: list_documents
49 id: 31
50 description: View list
51 controller: projects
52 mail_enabled: false
53 mail_option: false
54 sort: 1200
55 is_public: true
56 permissions_020:
57 action: add_issue
58 id: 20
59 description: Report an issue
60 controller: projects
61 mail_enabled: true
62 mail_option: true
63 sort: 1050
64 is_public: false
65 permissions_009:
66 action: destroy
67 id: 9
68 description: Delete
69 controller: members
70 mail_enabled: false
71 mail_option: false
72 sort: 222
73 is_public: false
74 permissions_032:
75 action: show
76 id: 32
77 description: View
78 controller: documents
79 mail_enabled: false
80 mail_option: false
81 sort: 1201
82 is_public: true
83 permissions_021:
84 action: edit
85 id: 21
86 description: Edit
87 controller: issues
88 mail_enabled: false
89 mail_option: false
90 sort: 1055
91 is_public: false
92 permissions_010:
93 action: add_version
94 id: 10
95 description: New version
96 controller: projects
97 mail_enabled: false
98 mail_option: false
99 sort: 320
100 is_public: false
101 permissions_033:
102 action: download
103 id: 33
104 description: Download
105 controller: documents
106 mail_enabled: false
107 mail_option: false
108 sort: 1202
109 is_public: true
110 permissions_022:
111 action: change_status
112 id: 22
113 description: Change status
114 controller: issues
115 mail_enabled: true
116 mail_option: true
117 sort: 1060
118 is_public: false
119 permissions_011:
120 action: edit
121 id: 11
122 description: Edit
123 controller: versions
124 mail_enabled: false
125 mail_option: false
126 sort: 321
127 is_public: false
128 permissions_034:
129 action: add_document
130 id: 34
131 description: Add
132 controller: projects
133 mail_enabled: false
134 mail_option: false
135 sort: 1220
136 is_public: false
137 permissions_023:
138 action: destroy
139 id: 23
140 description: Delete
141 controller: issues
142 mail_enabled: false
143 mail_option: false
144 sort: 1065
145 is_public: false
146 permissions_012:
147 action: destroy
148 id: 12
149 description: Delete
150 controller: versions
151 mail_enabled: false
152 mail_option: false
153 sort: 322
154 is_public: false
155 permissions_001:
156 action: show
157 id: 1
158 description: Overview
159 controller: projects
160 mail_enabled: false
161 mail_option: false
162 sort: 100
163 is_public: true
164 permissions_035:
165 action: edit
166 id: 35
167 description: Edit
168 controller: documents
169 mail_enabled: false
170 mail_option: false
171 sort: 1221
172 is_public: false
173 permissions_024:
174 action: add_attachment
175 id: 24
176 description: Add file
177 controller: issues
178 mail_enabled: false
179 mail_option: false
180 sort: 1070
181 is_public: false
182 permissions_013:
183 action: add_issue_category
184 id: 13
185 description: New issue category
186 controller: projects
187 mail_enabled: false
188 mail_option: false
189 sort: 420
190 is_public: false
191 permissions_002:
192 action: changelog
193 id: 2
194 description: View change log
195 controller: projects
196 mail_enabled: false
197 mail_option: false
198 sort: 105
199 is_public: true
200 permissions_036:
201 action: destroy
202 id: 36
203 description: Delete
204 controller: documents
205 mail_enabled: false
206 mail_option: false
207 sort: 1222
208 is_public: false
209 permissions_025:
210 action: destroy_attachment
211 id: 25
212 description: Delete file
213 controller: issues
214 mail_enabled: false
215 mail_option: false
216 sort: 1075
217 is_public: false
218 permissions_014:
219 action: edit
220 id: 14
221 description: Edit
222 controller: issue_categories
223 mail_enabled: false
224 mail_option: false
225 sort: 421
226 is_public: false
227 permissions_003:
228 action: issue_report
229 id: 3
230 description: View reports
231 controller: reports
232 mail_enabled: false
233 mail_option: false
234 sort: 110
235 is_public: true
236 permissions_037:
237 action: add_attachment
238 id: 37
239 description: Add file
240 controller: documents
241 mail_enabled: false
242 mail_option: false
243 sort: 1223
244 is_public: false
245 permissions_026:
246 action: list_news
247 id: 26
248 description: View list
249 controller: projects
250 mail_enabled: false
251 mail_option: false
252 sort: 1100
253 is_public: true
254 permissions_015:
255 action: destroy
256 id: 15
257 description: Delete
258 controller: issue_categories
259 mail_enabled: false
260 mail_option: false
261 sort: 422
262 is_public: false
263 permissions_004:
264 action: settings
265 id: 4
266 description: Settings
267 controller: projects
268 mail_enabled: false
269 mail_option: false
270 sort: 150
271 is_public: false
272 permissions_038:
273 action: destroy_attachment
274 id: 38
275 description: Delete file
276 controller: documents
277 mail_enabled: false
278 mail_option: false
279 sort: 1224
280 is_public: false
281 permissions_027:
282 action: show
283 id: 27
284 description: View
285 controller: news
286 mail_enabled: false
287 mail_option: false
288 sort: 1101
289 is_public: true
290 permissions_016:
291 action: list_issues
292 id: 16
293 description: View list
294 controller: projects
295 mail_enabled: false
296 mail_option: false
297 sort: 1000
298 is_public: true
299 permissions_005:
300 action: edit
301 id: 5
302 description: Edit
303 controller: projects
304 mail_enabled: false
305 mail_option: false
306 sort: 151
307 is_public: false
308 permissions_039:
309 action: list_files
310 id: 39
311 description: View list
312 controller: projects
313 mail_enabled: false
314 mail_option: false
315 sort: 1300
316 is_public: true
317 permissions_028:
318 action: add_news
319 id: 28
320 description: Add
321 controller: projects
322 mail_enabled: false
323 mail_option: false
324 sort: 1120
325 is_public: false
326 permissions_017:
327 action: export_issues_csv
328 id: 17
329 description: Export list to CSV
330 controller: projects
331 mail_enabled: false
332 mail_option: false
333 sort: 1001
334 is_public: true
335 permissions_006:
336 action: list_members
337 id: 6
338 description: View list
339 controller: projects
340 mail_enabled: false
341 mail_option: false
342 sort: 200
343 is_public: true
344 permissions_040:
345 action: download
346 id: 40
347 description: Download
348 controller: versions
349 mail_enabled: false
350 mail_option: false
351 sort: 1301
352 is_public: true
353 permissions_029:
354 action: edit
355 id: 29
356 description: Edit
357 controller: news
358 mail_enabled: false
359 mail_option: false
360 sort: 1121
361 is_public: false
362 permissions_018:
363 action: show
364 id: 18
365 description: View
366 controller: issues
367 mail_enabled: false
368 mail_option: false
369 sort: 1005
370 is_public: true
371 permissions_007:
372 action: add_member
373 id: 7
374 description: New member
375 controller: projects
376 mail_enabled: false
377 mail_option: false
378 sort: 220
379 is_public: false
@@ -0,0 +1,379
1 ---
2 permissions_roles_075:
3 role_id: 3
4 permission_id: 34
5 permissions_roles_047:
6 role_id: 1
7 permission_id: 15
8 permissions_roles_102:
9 role_id: 2
10 permission_id: 4
11 permissions_roles_019:
12 role_id: 3
13 permission_id: 30
14 permissions_roles_048:
15 role_id: 2
16 permission_id: 24
17 permissions_roles_103:
18 role_id: 2
19 permission_id: 27
20 permissions_roles_076:
21 role_id: 2
22 permission_id: 41
23 permissions_roles_049:
24 role_id: 1
25 permission_id: 3
26 permissions_roles_104:
27 role_id: 2
28 permission_id: 36
29 permissions_roles_077:
30 role_id: 2
31 permission_id: 7
32 permissions_roles_105:
33 role_id: 2
34 permission_id: 32
35 permissions_roles_078:
36 role_id: 3
37 permission_id: 38
38 permissions_roles_106:
39 role_id: 2
40 permission_id: 14
41 permissions_roles_020:
42 role_id: 2
43 permission_id: 9
44 permissions_roles_079:
45 role_id: 2
46 permission_id: 18
47 permissions_roles_107:
48 role_id: 3
49 permission_id: 40
50 permissions_roles_021:
51 role_id: 1
52 permission_id: 13
53 permissions_roles_108:
54 role_id: 1
55 permission_id: 29
56 permissions_roles_050:
57 role_id: 2
58 permission_id: 29
59 permissions_roles_022:
60 role_id: 3
61 permission_id: 4
62 permissions_roles_109:
63 role_id: 3
64 permission_id: 22
65 permissions_roles_051:
66 role_id: 3
67 permission_id: 37
68 permissions_roles_023:
69 role_id: 1
70 permission_id: 23
71 permissions_roles_052:
72 role_id: 2
73 permission_id: 33
74 permissions_roles_024:
75 role_id: 1
76 permission_id: 1
77 permissions_roles_080:
78 role_id: 2
79 permission_id: 13
80 permissions_roles_053:
81 role_id: 2
82 permission_id: 1
83 permissions_roles_025:
84 role_id: 2
85 permission_id: 10
86 permissions_roles_081:
87 role_id: 3
88 permission_id: 20
89 permissions_roles_054:
90 role_id: 2
91 permission_id: 12
92 permissions_roles_026:
93 role_id: 1
94 permission_id: 36
95 permissions_roles_082:
96 role_id: 1
97 permission_id: 39
98 permissions_roles_110:
99 role_id: 3
100 permission_id: 6
101 permissions_roles_027:
102 role_id: 3
103 permission_id: 31
104 permissions_roles_083:
105 role_id: 1
106 permission_id: 33
107 permissions_roles_055:
108 role_id: 1
109 permission_id: 38
110 permissions_roles_111:
111 role_id: 3
112 permission_id: 1
113 permissions_roles_028:
114 role_id: 1
115 permission_id: 24
116 permissions_roles_084:
117 role_id: 3
118 permission_id: 16
119 permissions_roles_056:
120 role_id: 2
121 permission_id: 5
122 permissions_roles_029:
123 role_id: 1
124 permission_id: 9
125 permissions_roles_085:
126 role_id: 3
127 permission_id: 27
128 permissions_roles_057:
129 role_id: 1
130 permission_id: 16
131 permissions_roles_112:
132 role_id: 1
133 permission_id: 20
134 permissions_roles_086:
135 role_id: 3
136 permission_id: 12
137 permissions_roles_058:
138 role_id: 1
139 permission_id: 26
140 permissions_roles_113:
141 role_id: 2
142 permission_id: 37
143 permissions_roles_087:
144 role_id: 1
145 permission_id: 5
146 permissions_roles_059:
147 role_id: 3
148 permission_id: 18
149 permissions_roles_114:
150 role_id: 2
151 permission_id: 20
152 permissions_roles_115:
153 role_id: 2
154 permission_id: 15
155 permissions_roles_088:
156 role_id: 2
157 permission_id: 3
158 permissions_roles_001:
159 role_id: 2
160 permission_id: 21
161 permissions_roles_116:
162 role_id: 3
163 permission_id: 23
164 permissions_roles_030:
165 role_id: 1
166 permission_id: 30
167 permissions_roles_089:
168 role_id: 1
169 permission_id: 28
170 permissions_roles_002:
171 role_id: 3
172 permission_id: 29
173 permissions_roles_117:
174 role_id: 3
175 permission_id: 28
176 permissions_roles_031:
177 role_id: 2
178 permission_id: 38
179 permissions_roles_003:
180 role_id: 3
181 permission_id: 41
182 permissions_roles_118:
183 role_id: 1
184 permission_id: 34
185 permissions_roles_032:
186 role_id: 3
187 permission_id: 9
188 permissions_roles_004:
189 role_id: 2
190 permission_id: 8
191 permissions_roles_060:
192 role_id: 2
193 permission_id: 2
194 permissions_roles_119:
195 role_id: 1
196 permission_id: 21
197 permissions_roles_033:
198 role_id: 2
199 permission_id: 28
200 permissions_roles_005:
201 role_id: 3
202 permission_id: 3
203 permissions_roles_061:
204 role_id: 2
205 permission_id: 40
206 permissions_roles_006:
207 role_id: 3
208 permission_id: 14
209 permissions_roles_090:
210 role_id: 2
211 permission_id: 26
212 permissions_roles_062:
213 role_id: 1
214 permission_id: 19
215 permissions_roles_034:
216 role_id: 2
217 permission_id: 11
218 permissions_roles_007:
219 role_id: 1
220 permission_id: 35
221 permissions_roles_091:
222 role_id: 3
223 permission_id: 35
224 permissions_roles_063:
225 role_id: 2
226 permission_id: 30
227 permissions_roles_035:
228 role_id: 2
229 permission_id: 23
230 permissions_roles_008:
231 role_id: 2
232 permission_id: 17
233 permissions_roles_092:
234 role_id: 2
235 permission_id: 31
236 permissions_roles_064:
237 role_id: 3
238 permission_id: 33
239 permissions_roles_036:
240 role_id: 3
241 permission_id: 5
242 permissions_roles_120:
243 role_id: 3
244 permission_id: 13
245 permissions_roles_009:
246 role_id: 1
247 permission_id: 12
248 permissions_roles_093:
249 role_id: 2
250 permission_id: 42
251 permissions_roles_065:
252 role_id: 3
253 permission_id: 26
254 permissions_roles_037:
255 role_id: 1
256 permission_id: 42
257 permissions_roles_121:
258 role_id: 3
259 permission_id: 2
260 permissions_roles_094:
261 role_id: 3
262 permission_id: 39
263 permissions_roles_066:
264 role_id: 2
265 permission_id: 6
266 permissions_roles_038:
267 role_id: 1
268 permission_id: 25
269 permissions_roles_122:
270 role_id: 1
271 permission_id: 7
272 permissions_roles_095:
273 role_id: 2
274 permission_id: 19
275 permissions_roles_067:
276 role_id: 1
277 permission_id: 17
278 permissions_roles_039:
279 role_id: 3
280 permission_id: 36
281 permissions_roles_123:
282 role_id: 3
283 permission_id: 24
284 permissions_roles_096:
285 role_id: 1
286 permission_id: 18
287 permissions_roles_068:
288 role_id: 1
289 permission_id: 32
290 permissions_roles_124:
291 role_id: 1
292 permission_id: 11
293 permissions_roles_010:
294 role_id: 1
295 permission_id: 8
296 permissions_roles_069:
297 role_id: 3
298 permission_id: 19
299 permissions_roles_097:
300 role_id: 2
301 permission_id: 35
302 permissions_roles_125:
303 role_id: 2
304 permission_id: 16
305 permissions_roles_011:
306 role_id: 3
307 permission_id: 42
308 permissions_roles_098:
309 role_id: 1
310 permission_id: 6
311 permissions_roles_126:
312 role_id: 3
313 permission_id: 7
314 permissions_roles_012:
315 role_id: 3
316 permission_id: 8
317 permissions_roles_040:
318 role_id: 1
319 permission_id: 2
320 permissions_roles_099:
321 role_id: 3
322 permission_id: 17
323 permissions_roles_041:
324 role_id: 2
325 permission_id: 39
326 permissions_roles_013:
327 role_id: 1
328 permission_id: 40
329 permissions_roles_070:
330 role_id: 3
331 permission_id: 11
332 permissions_roles_042:
333 role_id: 1
334 permission_id: 37
335 permissions_roles_014:
336 role_id: 1
337 permission_id: 22
338 permissions_roles_071:
339 role_id: 1
340 permission_id: 4
341 permissions_roles_043:
342 role_id: 3
343 permission_id: 32
344 permissions_roles_015:
345 role_id: 2
346 permission_id: 22
347 permissions_roles_072:
348 role_id: 1
349 permission_id: 27
350 permissions_roles_044:
351 role_id: 1
352 permission_id: 14
353 permissions_roles_016:
354 role_id: 3
355 permission_id: 15
356 permissions_roles_073:
357 role_id: 2
358 permission_id: 34
359 permissions_roles_045:
360 role_id: 3
361 permission_id: 10
362 permissions_roles_100:
363 role_id: 1
364 permission_id: 10
365 permissions_roles_017:
366 role_id: 3
367 permission_id: 25
368 permissions_roles_074:
369 role_id: 2
370 permission_id: 25
371 permissions_roles_046:
372 role_id: 1
373 permission_id: 31
374 permissions_roles_101:
375 role_id: 3
376 permission_id: 21
377 permissions_roles_018:
378 role_id: 1
379 permission_id: 41
@@ -0,0 +1,1
1 ---
@@ -0,0 +1,13
1 ---
2 trackers_001:
3 name: Bug
4 id: 1
5 is_in_chlog: true
6 trackers_002:
7 name: Feature request
8 id: 2
9 is_in_chlog: true
10 trackers_003:
11 name: Support request
12 id: 3
13 is_in_chlog: false
@@ -0,0 +1,17
1 ---
2 versions_001:
3 created_on: 2006-07-19 21:00:07 +02:00
4 name: "0.1"
5 project_id: 1
6 updated_on: 2006-07-19 21:00:07 +02:00
7 id: 1
8 description: Beta
9 effective_date: 2006-07-01
10 versions_002:
11 created_on: 2006-07-19 21:00:33 +02:00
12 name: "1.0"
13 project_id: 1
14 updated_on: 2006-07-19 21:00:33 +02:00
15 id: 2
16 description: Stable release
17 effective_date: 2006-07-19
This diff has been collapsed as it changes many lines, (1621 lines changed) Show them Hide them
@@ -0,0 +1,1621
1 ---
2 workflows_189:
3 new_status_id: 5
4 role_id: 1
5 old_status_id: 2
6 id: 189
7 tracker_id: 3
8 workflows_001:
9 new_status_id: 2
10 role_id: 1
11 old_status_id: 1
12 id: 1
13 tracker_id: 1
14 workflows_002:
15 new_status_id: 3
16 role_id: 1
17 old_status_id: 1
18 id: 2
19 tracker_id: 1
20 workflows_003:
21 new_status_id: 4
22 role_id: 1
23 old_status_id: 1
24 id: 3
25 tracker_id: 1
26 workflows_110:
27 new_status_id: 6
28 role_id: 1
29 old_status_id: 4
30 id: 110
31 tracker_id: 2
32 workflows_004:
33 new_status_id: 5
34 role_id: 1
35 old_status_id: 1
36 id: 4
37 tracker_id: 1
38 workflows_030:
39 new_status_id: 5
40 role_id: 1
41 old_status_id: 6
42 id: 30
43 tracker_id: 1
44 workflows_111:
45 new_status_id: 1
46 role_id: 1
47 old_status_id: 5
48 id: 111
49 tracker_id: 2
50 workflows_005:
51 new_status_id: 6
52 role_id: 1
53 old_status_id: 1
54 id: 5
55 tracker_id: 1
56 workflows_031:
57 new_status_id: 2
58 role_id: 2
59 old_status_id: 1
60 id: 31
61 tracker_id: 1
62 workflows_112:
63 new_status_id: 2
64 role_id: 1
65 old_status_id: 5
66 id: 112
67 tracker_id: 2
68 workflows_006:
69 new_status_id: 1
70 role_id: 1
71 old_status_id: 2
72 id: 6
73 tracker_id: 1
74 workflows_032:
75 new_status_id: 3
76 role_id: 2
77 old_status_id: 1
78 id: 32
79 tracker_id: 1
80 workflows_113:
81 new_status_id: 3
82 role_id: 1
83 old_status_id: 5
84 id: 113
85 tracker_id: 2
86 workflows_220:
87 new_status_id: 6
88 role_id: 2
89 old_status_id: 2
90 id: 220
91 tracker_id: 3
92 workflows_007:
93 new_status_id: 3
94 role_id: 1
95 old_status_id: 2
96 id: 7
97 tracker_id: 1
98 workflows_033:
99 new_status_id: 4
100 role_id: 2
101 old_status_id: 1
102 id: 33
103 tracker_id: 1
104 workflows_060:
105 new_status_id: 5
106 role_id: 2
107 old_status_id: 6
108 id: 60
109 tracker_id: 1
110 workflows_114:
111 new_status_id: 4
112 role_id: 1
113 old_status_id: 5
114 id: 114
115 tracker_id: 2
116 workflows_140:
117 new_status_id: 6
118 role_id: 2
119 old_status_id: 4
120 id: 140
121 tracker_id: 2
122 workflows_221:
123 new_status_id: 1
124 role_id: 2
125 old_status_id: 3
126 id: 221
127 tracker_id: 3
128 workflows_008:
129 new_status_id: 4
130 role_id: 1
131 old_status_id: 2
132 id: 8
133 tracker_id: 1
134 workflows_034:
135 new_status_id: 5
136 role_id: 2
137 old_status_id: 1
138 id: 34
139 tracker_id: 1
140 workflows_115:
141 new_status_id: 6
142 role_id: 1
143 old_status_id: 5
144 id: 115
145 tracker_id: 2
146 workflows_141:
147 new_status_id: 1
148 role_id: 2
149 old_status_id: 5
150 id: 141
151 tracker_id: 2
152 workflows_222:
153 new_status_id: 2
154 role_id: 2
155 old_status_id: 3
156 id: 222
157 tracker_id: 3
158 workflows_223:
159 new_status_id: 4
160 role_id: 2
161 old_status_id: 3
162 id: 223
163 tracker_id: 3
164 workflows_009:
165 new_status_id: 5
166 role_id: 1
167 old_status_id: 2
168 id: 9
169 tracker_id: 1
170 workflows_035:
171 new_status_id: 6
172 role_id: 2
173 old_status_id: 1
174 id: 35
175 tracker_id: 1
176 workflows_061:
177 new_status_id: 2
178 role_id: 3
179 old_status_id: 1
180 id: 61
181 tracker_id: 1
182 workflows_116:
183 new_status_id: 1
184 role_id: 1
185 old_status_id: 6
186 id: 116
187 tracker_id: 2
188 workflows_142:
189 new_status_id: 2
190 role_id: 2
191 old_status_id: 5
192 id: 142
193 tracker_id: 2
194 workflows_250:
195 new_status_id: 6
196 role_id: 3
197 old_status_id: 2
198 id: 250
199 tracker_id: 3
200 workflows_224:
201 new_status_id: 5
202 role_id: 2
203 old_status_id: 3
204 id: 224
205 tracker_id: 3
206 workflows_036:
207 new_status_id: 1
208 role_id: 2
209 old_status_id: 2
210 id: 36
211 tracker_id: 1
212 workflows_062:
213 new_status_id: 3
214 role_id: 3
215 old_status_id: 1
216 id: 62
217 tracker_id: 1
218 workflows_117:
219 new_status_id: 2
220 role_id: 1
221 old_status_id: 6
222 id: 117
223 tracker_id: 2
224 workflows_143:
225 new_status_id: 3
226 role_id: 2
227 old_status_id: 5
228 id: 143
229 tracker_id: 2
230 workflows_170:
231 new_status_id: 6
232 role_id: 3
233 old_status_id: 4
234 id: 170
235 tracker_id: 2
236 workflows_251:
237 new_status_id: 1
238 role_id: 3
239 old_status_id: 3
240 id: 251
241 tracker_id: 3
242 workflows_225:
243 new_status_id: 6
244 role_id: 2
245 old_status_id: 3
246 id: 225
247 tracker_id: 3
248 workflows_037:
249 new_status_id: 3
250 role_id: 2
251 old_status_id: 2
252 id: 37
253 tracker_id: 1
254 workflows_063:
255 new_status_id: 4
256 role_id: 3
257 old_status_id: 1
258 id: 63
259 tracker_id: 1
260 workflows_090:
261 new_status_id: 5
262 role_id: 3
263 old_status_id: 6
264 id: 90
265 tracker_id: 1
266 workflows_118:
267 new_status_id: 3
268 role_id: 1
269 old_status_id: 6
270 id: 118
271 tracker_id: 2
272 workflows_144:
273 new_status_id: 4
274 role_id: 2
275 old_status_id: 5
276 id: 144
277 tracker_id: 2
278 workflows_252:
279 new_status_id: 2
280 role_id: 3
281 old_status_id: 3
282 id: 252
283 tracker_id: 3
284 workflows_226:
285 new_status_id: 1
286 role_id: 2
287 old_status_id: 4
288 id: 226
289 tracker_id: 3
290 workflows_038:
291 new_status_id: 4
292 role_id: 2
293 old_status_id: 2
294 id: 38
295 tracker_id: 1
296 workflows_064:
297 new_status_id: 5
298 role_id: 3
299 old_status_id: 1
300 id: 64
301 tracker_id: 1
302 workflows_091:
303 new_status_id: 2
304 role_id: 1
305 old_status_id: 1
306 id: 91
307 tracker_id: 2
308 workflows_119:
309 new_status_id: 4
310 role_id: 1
311 old_status_id: 6
312 id: 119
313 tracker_id: 2
314 workflows_145:
315 new_status_id: 6
316 role_id: 2
317 old_status_id: 5
318 id: 145
319 tracker_id: 2
320 workflows_171:
321 new_status_id: 1
322 role_id: 3
323 old_status_id: 5
324 id: 171
325 tracker_id: 2
326 workflows_253:
327 new_status_id: 4
328 role_id: 3
329 old_status_id: 3
330 id: 253
331 tracker_id: 3
332 workflows_227:
333 new_status_id: 2
334 role_id: 2
335 old_status_id: 4
336 id: 227
337 tracker_id: 3
338 workflows_039:
339 new_status_id: 5
340 role_id: 2
341 old_status_id: 2
342 id: 39
343 tracker_id: 1
344 workflows_065:
345 new_status_id: 6
346 role_id: 3
347 old_status_id: 1
348 id: 65
349 tracker_id: 1
350 workflows_092:
351 new_status_id: 3
352 role_id: 1
353 old_status_id: 1
354 id: 92
355 tracker_id: 2
356 workflows_146:
357 new_status_id: 1
358 role_id: 2
359 old_status_id: 6
360 id: 146
361 tracker_id: 2
362 workflows_172:
363 new_status_id: 2
364 role_id: 3
365 old_status_id: 5
366 id: 172
367 tracker_id: 2
368 workflows_254:
369 new_status_id: 5
370 role_id: 3
371 old_status_id: 3
372 id: 254
373 tracker_id: 3
374 workflows_228:
375 new_status_id: 3
376 role_id: 2
377 old_status_id: 4
378 id: 228
379 tracker_id: 3
380 workflows_066:
381 new_status_id: 1
382 role_id: 3
383 old_status_id: 2
384 id: 66
385 tracker_id: 1
386 workflows_093:
387 new_status_id: 4
388 role_id: 1
389 old_status_id: 1
390 id: 93
391 tracker_id: 2
392 workflows_147:
393 new_status_id: 2
394 role_id: 2
395 old_status_id: 6
396 id: 147
397 tracker_id: 2
398 workflows_173:
399 new_status_id: 3
400 role_id: 3
401 old_status_id: 5
402 id: 173
403 tracker_id: 2
404 workflows_255:
405 new_status_id: 6
406 role_id: 3
407 old_status_id: 3
408 id: 255
409 tracker_id: 3
410 workflows_229:
411 new_status_id: 5
412 role_id: 2
413 old_status_id: 4
414 id: 229
415 tracker_id: 3
416 workflows_067:
417 new_status_id: 3
418 role_id: 3
419 old_status_id: 2
420 id: 67
421 tracker_id: 1
422 workflows_148:
423 new_status_id: 3
424 role_id: 2
425 old_status_id: 6
426 id: 148
427 tracker_id: 2
428 workflows_174:
429 new_status_id: 4
430 role_id: 3
431 old_status_id: 5
432 id: 174
433 tracker_id: 2
434 workflows_256:
435 new_status_id: 1
436 role_id: 3
437 old_status_id: 4
438 id: 256
439 tracker_id: 3
440 workflows_068:
441 new_status_id: 4
442 role_id: 3
443 old_status_id: 2
444 id: 68
445 tracker_id: 1
446 workflows_094:
447 new_status_id: 5
448 role_id: 1
449 old_status_id: 1
450 id: 94
451 tracker_id: 2
452 workflows_149:
453 new_status_id: 4
454 role_id: 2
455 old_status_id: 6
456 id: 149
457 tracker_id: 2
458 workflows_175:
459 new_status_id: 6
460 role_id: 3
461 old_status_id: 5
462 id: 175
463 tracker_id: 2
464 workflows_257:
465 new_status_id: 2
466 role_id: 3
467 old_status_id: 4
468 id: 257
469 tracker_id: 3
470 workflows_069:
471 new_status_id: 5
472 role_id: 3
473 old_status_id: 2
474 id: 69
475 tracker_id: 1
476 workflows_095:
477 new_status_id: 6
478 role_id: 1
479 old_status_id: 1
480 id: 95
481 tracker_id: 2
482 workflows_176:
483 new_status_id: 1
484 role_id: 3
485 old_status_id: 6
486 id: 176
487 tracker_id: 2
488 workflows_258:
489 new_status_id: 3
490 role_id: 3
491 old_status_id: 4
492 id: 258
493 tracker_id: 3
494 workflows_096:
495 new_status_id: 1
496 role_id: 1
497 old_status_id: 2
498 id: 96
499 tracker_id: 2
500 workflows_177:
501 new_status_id: 2
502 role_id: 3
503 old_status_id: 6
504 id: 177
505 tracker_id: 2
506 workflows_259:
507 new_status_id: 5
508 role_id: 3
509 old_status_id: 4
510 id: 259
511 tracker_id: 3
512 workflows_097:
513 new_status_id: 3
514 role_id: 1
515 old_status_id: 2
516 id: 97
517 tracker_id: 2
518 workflows_178:
519 new_status_id: 3
520 role_id: 3
521 old_status_id: 6
522 id: 178
523 tracker_id: 2
524 workflows_098:
525 new_status_id: 4
526 role_id: 1
527 old_status_id: 2
528 id: 98
529 tracker_id: 2
530 workflows_179:
531 new_status_id: 4
532 role_id: 3
533 old_status_id: 6
534 id: 179
535 tracker_id: 2
536 workflows_099:
537 new_status_id: 5
538 role_id: 1
539 old_status_id: 2
540 id: 99
541 tracker_id: 2
542 workflows_100:
543 new_status_id: 6
544 role_id: 1
545 old_status_id: 2
546 id: 100
547 tracker_id: 2
548 workflows_020:
549 new_status_id: 6
550 role_id: 1
551 old_status_id: 4
552 id: 20
553 tracker_id: 1
554 workflows_101:
555 new_status_id: 1
556 role_id: 1
557 old_status_id: 3
558 id: 101
559 tracker_id: 2
560 workflows_021:
561 new_status_id: 1
562 role_id: 1
563 old_status_id: 5
564 id: 21
565 tracker_id: 1
566 workflows_102:
567 new_status_id: 2
568 role_id: 1
569 old_status_id: 3
570 id: 102
571 tracker_id: 2
572 workflows_210:
573 new_status_id: 5
574 role_id: 1
575 old_status_id: 6
576 id: 210
577 tracker_id: 3
578 workflows_022:
579 new_status_id: 2
580 role_id: 1
581 old_status_id: 5
582 id: 22
583 tracker_id: 1
584 workflows_103:
585 new_status_id: 4
586 role_id: 1
587 old_status_id: 3
588 id: 103
589 tracker_id: 2
590 workflows_023:
591 new_status_id: 3
592 role_id: 1
593 old_status_id: 5
594 id: 23
595 tracker_id: 1
596 workflows_104:
597 new_status_id: 5
598 role_id: 1
599 old_status_id: 3
600 id: 104
601 tracker_id: 2
602 workflows_130:
603 new_status_id: 6
604 role_id: 2
605 old_status_id: 2
606 id: 130
607 tracker_id: 2
608 workflows_211:
609 new_status_id: 2
610 role_id: 2
611 old_status_id: 1
612 id: 211
613 tracker_id: 3
614 workflows_024:
615 new_status_id: 4
616 role_id: 1
617 old_status_id: 5
618 id: 24
619 tracker_id: 1
620 workflows_050:
621 new_status_id: 6
622 role_id: 2
623 old_status_id: 4
624 id: 50
625 tracker_id: 1
626 workflows_105:
627 new_status_id: 6
628 role_id: 1
629 old_status_id: 3
630 id: 105
631 tracker_id: 2
632 workflows_131:
633 new_status_id: 1
634 role_id: 2
635 old_status_id: 3
636 id: 131
637 tracker_id: 2
638 workflows_212:
639 new_status_id: 3
640 role_id: 2
641 old_status_id: 1
642 id: 212
643 tracker_id: 3
644 workflows_025:
645 new_status_id: 6
646 role_id: 1
647 old_status_id: 5
648 id: 25
649 tracker_id: 1
650 workflows_051:
651 new_status_id: 1
652 role_id: 2
653 old_status_id: 5
654 id: 51
655 tracker_id: 1
656 workflows_106:
657 new_status_id: 1
658 role_id: 1
659 old_status_id: 4
660 id: 106
661 tracker_id: 2
662 workflows_132:
663 new_status_id: 2
664 role_id: 2
665 old_status_id: 3
666 id: 132
667 tracker_id: 2
668 workflows_213:
669 new_status_id: 4
670 role_id: 2
671 old_status_id: 1
672 id: 213
673 tracker_id: 3
674 workflows_240:
675 new_status_id: 5
676 role_id: 2
677 old_status_id: 6
678 id: 240
679 tracker_id: 3
680 workflows_026:
681 new_status_id: 1
682 role_id: 1
683 old_status_id: 6
684 id: 26
685 tracker_id: 1
686 workflows_052:
687 new_status_id: 2
688 role_id: 2
689 old_status_id: 5
690 id: 52
691 tracker_id: 1
692 workflows_107:
693 new_status_id: 2
694 role_id: 1
695 old_status_id: 4
696 id: 107
697 tracker_id: 2
698 workflows_133:
699 new_status_id: 4
700 role_id: 2
701 old_status_id: 3
702 id: 133
703 tracker_id: 2
704 workflows_214:
705 new_status_id: 5
706 role_id: 2
707 old_status_id: 1
708 id: 214
709 tracker_id: 3
710 workflows_241:
711 new_status_id: 2
712 role_id: 3
713 old_status_id: 1
714 id: 241
715 tracker_id: 3
716 workflows_027:
717 new_status_id: 2
718 role_id: 1
719 old_status_id: 6
720 id: 27
721 tracker_id: 1
722 workflows_053:
723 new_status_id: 3
724 role_id: 2
725 old_status_id: 5
726 id: 53
727 tracker_id: 1
728 workflows_080:
729 new_status_id: 6
730 role_id: 3
731 old_status_id: 4
732 id: 80
733 tracker_id: 1
734 workflows_108:
735 new_status_id: 3
736 role_id: 1
737 old_status_id: 4
738 id: 108
739 tracker_id: 2
740 workflows_134:
741 new_status_id: 5
742 role_id: 2
743 old_status_id: 3
744 id: 134
745 tracker_id: 2
746 workflows_160:
747 new_status_id: 6
748 role_id: 3
749 old_status_id: 2
750 id: 160
751 tracker_id: 2
752 workflows_215:
753 new_status_id: 6
754 role_id: 2
755 old_status_id: 1
756 id: 215
757 tracker_id: 3
758 workflows_242:
759 new_status_id: 3
760 role_id: 3
761 old_status_id: 1
762 id: 242
763 tracker_id: 3
764 workflows_028:
765 new_status_id: 3
766 role_id: 1
767 old_status_id: 6
768 id: 28
769 tracker_id: 1
770 workflows_054:
771 new_status_id: 4
772 role_id: 2
773 old_status_id: 5
774 id: 54
775 tracker_id: 1
776 workflows_081:
777 new_status_id: 1
778 role_id: 3
779 old_status_id: 5
780 id: 81
781 tracker_id: 1
782 workflows_109:
783 new_status_id: 5
784 role_id: 1
785 old_status_id: 4
786 id: 109
787 tracker_id: 2
788 workflows_135:
789 new_status_id: 6
790 role_id: 2
791 old_status_id: 3
792 id: 135
793 tracker_id: 2
794 workflows_161:
795 new_status_id: 1
796 role_id: 3
797 old_status_id: 3
798 id: 161
799 tracker_id: 2
800 workflows_216:
801 new_status_id: 1
802 role_id: 2
803 old_status_id: 2
804 id: 216
805 tracker_id: 3
806 workflows_243:
807 new_status_id: 4
808 role_id: 3
809 old_status_id: 1
810 id: 243
811 tracker_id: 3
812 workflows_029:
813 new_status_id: 4
814 role_id: 1
815 old_status_id: 6
816 id: 29
817 tracker_id: 1
818 workflows_055:
819 new_status_id: 6
820 role_id: 2
821 old_status_id: 5
822 id: 55
823 tracker_id: 1
824 workflows_082:
825 new_status_id: 2
826 role_id: 3
827 old_status_id: 5
828 id: 82
829 tracker_id: 1
830 workflows_136:
831 new_status_id: 1
832 role_id: 2
833 old_status_id: 4
834 id: 136
835 tracker_id: 2
836 workflows_162:
837 new_status_id: 2
838 role_id: 3
839 old_status_id: 3
840 id: 162
841 tracker_id: 2
842 workflows_217:
843 new_status_id: 3
844 role_id: 2
845 old_status_id: 2
846 id: 217
847 tracker_id: 3
848 workflows_270:
849 new_status_id: 5
850 role_id: 3
851 old_status_id: 6
852 id: 270
853 tracker_id: 3
854 workflows_244:
855 new_status_id: 5
856 role_id: 3
857 old_status_id: 1
858 id: 244
859 tracker_id: 3
860 workflows_056:
861 new_status_id: 1
862 role_id: 2
863 old_status_id: 6
864 id: 56
865 tracker_id: 1
866 workflows_137:
867 new_status_id: 2
868 role_id: 2
869 old_status_id: 4
870 id: 137
871 tracker_id: 2
872 workflows_163:
873 new_status_id: 4
874 role_id: 3
875 old_status_id: 3
876 id: 163
877 tracker_id: 2
878 workflows_190:
879 new_status_id: 6
880 role_id: 1
881 old_status_id: 2
882 id: 190
883 tracker_id: 3
884 workflows_218:
885 new_status_id: 4
886 role_id: 2
887 old_status_id: 2
888 id: 218
889 tracker_id: 3
890 workflows_245:
891 new_status_id: 6
892 role_id: 3
893 old_status_id: 1
894 id: 245
895 tracker_id: 3
896 workflows_057:
897 new_status_id: 2
898 role_id: 2
899 old_status_id: 6
900 id: 57
901 tracker_id: 1
902 workflows_083:
903 new_status_id: 3
904 role_id: 3
905 old_status_id: 5
906 id: 83
907 tracker_id: 1
908 workflows_138:
909 new_status_id: 3
910 role_id: 2
911 old_status_id: 4
912 id: 138
913 tracker_id: 2
914 workflows_164:
915 new_status_id: 5
916 role_id: 3
917 old_status_id: 3
918 id: 164
919 tracker_id: 2
920 workflows_191:
921 new_status_id: 1
922 role_id: 1
923 old_status_id: 3
924 id: 191
925 tracker_id: 3
926 workflows_219:
927 new_status_id: 5
928 role_id: 2
929 old_status_id: 2
930 id: 219
931 tracker_id: 3
932 workflows_246:
933 new_status_id: 1
934 role_id: 3
935 old_status_id: 2
936 id: 246
937 tracker_id: 3
938 workflows_058:
939 new_status_id: 3
940 role_id: 2
941 old_status_id: 6
942 id: 58
943 tracker_id: 1
944 workflows_084:
945 new_status_id: 4
946 role_id: 3
947 old_status_id: 5
948 id: 84
949 tracker_id: 1
950 workflows_139:
951 new_status_id: 5
952 role_id: 2
953 old_status_id: 4
954 id: 139
955 tracker_id: 2
956 workflows_165:
957 new_status_id: 6
958 role_id: 3
959 old_status_id: 3
960 id: 165
961 tracker_id: 2
962 workflows_192:
963 new_status_id: 2
964 role_id: 1
965 old_status_id: 3
966 id: 192
967 tracker_id: 3
968 workflows_247:
969 new_status_id: 3
970 role_id: 3
971 old_status_id: 2
972 id: 247
973 tracker_id: 3
974 workflows_059:
975 new_status_id: 4
976 role_id: 2
977 old_status_id: 6
978 id: 59
979 tracker_id: 1
980 workflows_085:
981 new_status_id: 6
982 role_id: 3
983 old_status_id: 5
984 id: 85
985 tracker_id: 1
986 workflows_166:
987 new_status_id: 1
988 role_id: 3
989 old_status_id: 4
990 id: 166
991 tracker_id: 2
992 workflows_248:
993 new_status_id: 4
994 role_id: 3
995 old_status_id: 2
996 id: 248
997 tracker_id: 3
998 workflows_086:
999 new_status_id: 1
1000 role_id: 3
1001 old_status_id: 6
1002 id: 86
1003 tracker_id: 1
1004 workflows_167:
1005 new_status_id: 2
1006 role_id: 3
1007 old_status_id: 4
1008 id: 167
1009 tracker_id: 2
1010 workflows_193:
1011 new_status_id: 4
1012 role_id: 1
1013 old_status_id: 3
1014 id: 193
1015 tracker_id: 3
1016 workflows_249:
1017 new_status_id: 5
1018 role_id: 3
1019 old_status_id: 2
1020 id: 249
1021 tracker_id: 3
1022 workflows_087:
1023 new_status_id: 2
1024 role_id: 3
1025 old_status_id: 6
1026 id: 87
1027 tracker_id: 1
1028 workflows_168:
1029 new_status_id: 3
1030 role_id: 3
1031 old_status_id: 4
1032 id: 168
1033 tracker_id: 2
1034 workflows_194:
1035 new_status_id: 5
1036 role_id: 1
1037 old_status_id: 3
1038 id: 194
1039 tracker_id: 3
1040 workflows_088:
1041 new_status_id: 3
1042 role_id: 3
1043 old_status_id: 6
1044 id: 88
1045 tracker_id: 1
1046 workflows_169:
1047 new_status_id: 5
1048 role_id: 3
1049 old_status_id: 4
1050 id: 169
1051 tracker_id: 2
1052 workflows_195:
1053 new_status_id: 6
1054 role_id: 1
1055 old_status_id: 3
1056 id: 195
1057 tracker_id: 3
1058 workflows_089:
1059 new_status_id: 4
1060 role_id: 3
1061 old_status_id: 6
1062 id: 89
1063 tracker_id: 1
1064 workflows_196:
1065 new_status_id: 1
1066 role_id: 1
1067 old_status_id: 4
1068 id: 196
1069 tracker_id: 3
1070 workflows_197:
1071 new_status_id: 2
1072 role_id: 1
1073 old_status_id: 4
1074 id: 197
1075 tracker_id: 3
1076 workflows_198:
1077 new_status_id: 3
1078 role_id: 1
1079 old_status_id: 4
1080 id: 198
1081 tracker_id: 3
1082 workflows_199:
1083 new_status_id: 5
1084 role_id: 1
1085 old_status_id: 4
1086 id: 199
1087 tracker_id: 3
1088 workflows_010:
1089 new_status_id: 6
1090 role_id: 1
1091 old_status_id: 2
1092 id: 10
1093 tracker_id: 1
1094 workflows_011:
1095 new_status_id: 1
1096 role_id: 1
1097 old_status_id: 3
1098 id: 11
1099 tracker_id: 1
1100 workflows_012:
1101 new_status_id: 2
1102 role_id: 1
1103 old_status_id: 3
1104 id: 12
1105 tracker_id: 1
1106 workflows_200:
1107 new_status_id: 6
1108 role_id: 1
1109 old_status_id: 4
1110 id: 200
1111 tracker_id: 3
1112 workflows_013:
1113 new_status_id: 4
1114 role_id: 1
1115 old_status_id: 3
1116 id: 13
1117 tracker_id: 1
1118 workflows_120:
1119 new_status_id: 5
1120 role_id: 1
1121 old_status_id: 6
1122 id: 120
1123 tracker_id: 2
1124 workflows_201:
1125 new_status_id: 1
1126 role_id: 1
1127 old_status_id: 5
1128 id: 201
1129 tracker_id: 3
1130 workflows_040:
1131 new_status_id: 6
1132 role_id: 2
1133 old_status_id: 2
1134 id: 40
1135 tracker_id: 1
1136 workflows_121:
1137 new_status_id: 2
1138 role_id: 2
1139 old_status_id: 1
1140 id: 121
1141 tracker_id: 2
1142 workflows_202:
1143 new_status_id: 2
1144 role_id: 1
1145 old_status_id: 5
1146 id: 202
1147 tracker_id: 3
1148 workflows_014:
1149 new_status_id: 5
1150 role_id: 1
1151 old_status_id: 3
1152 id: 14
1153 tracker_id: 1
1154 workflows_041:
1155 new_status_id: 1
1156 role_id: 2
1157 old_status_id: 3
1158 id: 41
1159 tracker_id: 1
1160 workflows_122:
1161 new_status_id: 3
1162 role_id: 2
1163 old_status_id: 1
1164 id: 122
1165 tracker_id: 2
1166 workflows_203:
1167 new_status_id: 3
1168 role_id: 1
1169 old_status_id: 5
1170 id: 203
1171 tracker_id: 3
1172 workflows_015:
1173 new_status_id: 6
1174 role_id: 1
1175 old_status_id: 3
1176 id: 15
1177 tracker_id: 1
1178 workflows_230:
1179 new_status_id: 6
1180 role_id: 2
1181 old_status_id: 4
1182 id: 230
1183 tracker_id: 3
1184 workflows_123:
1185 new_status_id: 4
1186 role_id: 2
1187 old_status_id: 1
1188 id: 123
1189 tracker_id: 2
1190 workflows_204:
1191 new_status_id: 4
1192 role_id: 1
1193 old_status_id: 5
1194 id: 204
1195 tracker_id: 3
1196 workflows_016:
1197 new_status_id: 1
1198 role_id: 1
1199 old_status_id: 4
1200 id: 16
1201 tracker_id: 1
1202 workflows_042:
1203 new_status_id: 2
1204 role_id: 2
1205 old_status_id: 3
1206 id: 42
1207 tracker_id: 1
1208 workflows_231:
1209 new_status_id: 1
1210 role_id: 2
1211 old_status_id: 5
1212 id: 231
1213 tracker_id: 3
1214 workflows_070:
1215 new_status_id: 6
1216 role_id: 3
1217 old_status_id: 2
1218 id: 70
1219 tracker_id: 1
1220 workflows_124:
1221 new_status_id: 5
1222 role_id: 2
1223 old_status_id: 1
1224 id: 124
1225 tracker_id: 2
1226 workflows_150:
1227 new_status_id: 5
1228 role_id: 2
1229 old_status_id: 6
1230 id: 150
1231 tracker_id: 2
1232 workflows_205:
1233 new_status_id: 6
1234 role_id: 1
1235 old_status_id: 5
1236 id: 205
1237 tracker_id: 3
1238 workflows_017:
1239 new_status_id: 2
1240 role_id: 1
1241 old_status_id: 4
1242 id: 17
1243 tracker_id: 1
1244 workflows_043:
1245 new_status_id: 4
1246 role_id: 2
1247 old_status_id: 3
1248 id: 43
1249 tracker_id: 1
1250 workflows_232:
1251 new_status_id: 2
1252 role_id: 2
1253 old_status_id: 5
1254 id: 232
1255 tracker_id: 3
1256 workflows_125:
1257 new_status_id: 6
1258 role_id: 2
1259 old_status_id: 1
1260 id: 125
1261 tracker_id: 2
1262 workflows_151:
1263 new_status_id: 2
1264 role_id: 3
1265 old_status_id: 1
1266 id: 151
1267 tracker_id: 2
1268 workflows_206:
1269 new_status_id: 1
1270 role_id: 1
1271 old_status_id: 6
1272 id: 206
1273 tracker_id: 3
1274 workflows_018:
1275 new_status_id: 3
1276 role_id: 1
1277 old_status_id: 4
1278 id: 18
1279 tracker_id: 1
1280 workflows_044:
1281 new_status_id: 5
1282 role_id: 2
1283 old_status_id: 3
1284 id: 44
1285 tracker_id: 1
1286 workflows_071:
1287 new_status_id: 1
1288 role_id: 3
1289 old_status_id: 3
1290 id: 71
1291 tracker_id: 1
1292 workflows_233:
1293 new_status_id: 3
1294 role_id: 2
1295 old_status_id: 5
1296 id: 233
1297 tracker_id: 3
1298 workflows_126:
1299 new_status_id: 1
1300 role_id: 2
1301 old_status_id: 2
1302 id: 126
1303 tracker_id: 2
1304 workflows_152:
1305 new_status_id: 3
1306 role_id: 3
1307 old_status_id: 1
1308 id: 152
1309 tracker_id: 2
1310 workflows_207:
1311 new_status_id: 2
1312 role_id: 1
1313 old_status_id: 6
1314 id: 207
1315 tracker_id: 3
1316 workflows_019:
1317 new_status_id: 5
1318 role_id: 1
1319 old_status_id: 4
1320 id: 19
1321 tracker_id: 1
1322 workflows_045:
1323 new_status_id: 6
1324 role_id: 2
1325 old_status_id: 3
1326 id: 45
1327 tracker_id: 1
1328 workflows_260:
1329 new_status_id: 6
1330 role_id: 3
1331 old_status_id: 4
1332 id: 260
1333 tracker_id: 3
1334 workflows_234:
1335 new_status_id: 4
1336 role_id: 2
1337 old_status_id: 5
1338 id: 234
1339 tracker_id: 3
1340 workflows_127:
1341 new_status_id: 3
1342 role_id: 2
1343 old_status_id: 2
1344 id: 127
1345 tracker_id: 2
1346 workflows_153:
1347 new_status_id: 4
1348 role_id: 3
1349 old_status_id: 1
1350 id: 153
1351 tracker_id: 2
1352 workflows_180:
1353 new_status_id: 5
1354 role_id: 3
1355 old_status_id: 6
1356 id: 180
1357 tracker_id: 2
1358 workflows_208:
1359 new_status_id: 3
1360 role_id: 1
1361 old_status_id: 6
1362 id: 208
1363 tracker_id: 3
1364 workflows_046:
1365 new_status_id: 1
1366 role_id: 2
1367 old_status_id: 4
1368 id: 46
1369 tracker_id: 1
1370 workflows_072:
1371 new_status_id: 2
1372 role_id: 3
1373 old_status_id: 3
1374 id: 72
1375 tracker_id: 1
1376 workflows_261:
1377 new_status_id: 1
1378 role_id: 3
1379 old_status_id: 5
1380 id: 261
1381 tracker_id: 3
1382 workflows_235:
1383 new_status_id: 6
1384 role_id: 2
1385 old_status_id: 5
1386 id: 235
1387 tracker_id: 3
1388 workflows_154:
1389 new_status_id: 5
1390 role_id: 3
1391 old_status_id: 1
1392 id: 154
1393 tracker_id: 2
1394 workflows_181:
1395 new_status_id: 2
1396 role_id: 1
1397 old_status_id: 1
1398 id: 181
1399 tracker_id: 3
1400 workflows_209:
1401 new_status_id: 4
1402 role_id: 1
1403 old_status_id: 6
1404 id: 209
1405 tracker_id: 3
1406 workflows_047:
1407 new_status_id: 2
1408 role_id: 2
1409 old_status_id: 4
1410 id: 47
1411 tracker_id: 1
1412 workflows_073:
1413 new_status_id: 4
1414 role_id: 3
1415 old_status_id: 3
1416 id: 73
1417 tracker_id: 1
1418 workflows_128:
1419 new_status_id: 4
1420 role_id: 2
1421 old_status_id: 2
1422 id: 128
1423 tracker_id: 2
1424 workflows_262:
1425 new_status_id: 2
1426 role_id: 3
1427 old_status_id: 5
1428 id: 262
1429 tracker_id: 3
1430 workflows_236:
1431 new_status_id: 1
1432 role_id: 2
1433 old_status_id: 6
1434 id: 236
1435 tracker_id: 3
1436 workflows_155:
1437 new_status_id: 6
1438 role_id: 3
1439 old_status_id: 1
1440 id: 155
1441 tracker_id: 2
1442 workflows_048:
1443 new_status_id: 3
1444 role_id: 2
1445 old_status_id: 4
1446 id: 48
1447 tracker_id: 1
1448 workflows_074:
1449 new_status_id: 5
1450 role_id: 3
1451 old_status_id: 3
1452 id: 74
1453 tracker_id: 1
1454 workflows_129:
1455 new_status_id: 5
1456 role_id: 2
1457 old_status_id: 2
1458 id: 129
1459 tracker_id: 2
1460 workflows_263:
1461 new_status_id: 3
1462 role_id: 3
1463 old_status_id: 5
1464 id: 263
1465 tracker_id: 3
1466 workflows_237:
1467 new_status_id: 2
1468 role_id: 2
1469 old_status_id: 6
1470 id: 237
1471 tracker_id: 3
1472 workflows_182:
1473 new_status_id: 3
1474 role_id: 1
1475 old_status_id: 1
1476 id: 182
1477 tracker_id: 3
1478 workflows_049:
1479 new_status_id: 5
1480 role_id: 2
1481 old_status_id: 4
1482 id: 49
1483 tracker_id: 1
1484 workflows_075:
1485 new_status_id: 6
1486 role_id: 3
1487 old_status_id: 3
1488 id: 75
1489 tracker_id: 1
1490 workflows_156:
1491 new_status_id: 1
1492 role_id: 3
1493 old_status_id: 2
1494 id: 156
1495 tracker_id: 2
1496 workflows_264:
1497 new_status_id: 4
1498 role_id: 3
1499 old_status_id: 5
1500 id: 264
1501 tracker_id: 3
1502 workflows_238:
1503 new_status_id: 3
1504 role_id: 2
1505 old_status_id: 6
1506 id: 238
1507 tracker_id: 3
1508 workflows_183:
1509 new_status_id: 4
1510 role_id: 1
1511 old_status_id: 1
1512 id: 183
1513 tracker_id: 3
1514 workflows_076:
1515 new_status_id: 1
1516 role_id: 3
1517 old_status_id: 4
1518 id: 76
1519 tracker_id: 1
1520 workflows_157:
1521 new_status_id: 3
1522 role_id: 3
1523 old_status_id: 2
1524 id: 157
1525 tracker_id: 2
1526 workflows_265:
1527 new_status_id: 6
1528 role_id: 3
1529 old_status_id: 5
1530 id: 265
1531 tracker_id: 3
1532 workflows_239:
1533 new_status_id: 4
1534 role_id: 2
1535 old_status_id: 6
1536 id: 239
1537 tracker_id: 3
1538 workflows_077:
1539 new_status_id: 2
1540 role_id: 3
1541 old_status_id: 4
1542 id: 77
1543 tracker_id: 1
1544 workflows_158:
1545 new_status_id: 4
1546 role_id: 3
1547 old_status_id: 2
1548 id: 158
1549 tracker_id: 2
1550 workflows_184:
1551 new_status_id: 5
1552 role_id: 1
1553 old_status_id: 1
1554 id: 184
1555 tracker_id: 3
1556 workflows_266:
1557 new_status_id: 1
1558 role_id: 3
1559 old_status_id: 6
1560 id: 266
1561 tracker_id: 3
1562 workflows_078:
1563 new_status_id: 3
1564 role_id: 3
1565 old_status_id: 4
1566 id: 78
1567 tracker_id: 1
1568 workflows_159:
1569 new_status_id: 5
1570 role_id: 3
1571 old_status_id: 2
1572 id: 159
1573 tracker_id: 2
1574 workflows_185:
1575 new_status_id: 6
1576 role_id: 1
1577 old_status_id: 1
1578 id: 185
1579 tracker_id: 3
1580 workflows_267:
1581 new_status_id: 2
1582 role_id: 3
1583 old_status_id: 6
1584 id: 267
1585 tracker_id: 3
1586 workflows_079:
1587 new_status_id: 5
1588 role_id: 3
1589 old_status_id: 4
1590 id: 79
1591 tracker_id: 1
1592 workflows_186:
1593 new_status_id: 1
1594 role_id: 1
1595 old_status_id: 2
1596 id: 186
1597 tracker_id: 3
1598 workflows_268:
1599 new_status_id: 3
1600 role_id: 3
1601 old_status_id: 6
1602 id: 268
1603 tracker_id: 3
1604 workflows_187:
1605 new_status_id: 3
1606 role_id: 1
1607 old_status_id: 2
1608 id: 187
1609 tracker_id: 3
1610 workflows_269:
1611 new_status_id: 4
1612 role_id: 3
1613 old_status_id: 6
1614 id: 269
1615 tracker_id: 3
1616 workflows_188:
1617 new_status_id: 4
1618 role_id: 1
1619 old_status_id: 2
1620 id: 188
1621 tracker_id: 3
@@ -0,0 +1,51
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require File.dirname(__FILE__) + '/../test_helper'
19
20 class MemberTest < Test::Unit::TestCase
21 fixtures :users, :projects, :roles, :members
22
23 def setup
24 @jsmith = Member.find(1)
25 end
26
27 def test_create
28 member = Member.new(:project_id => 1, :user_id => 4, :role_id => 1)
29 assert member.save
30 end
31
32 def test_update
33 assert_equal "eCookbook", @jsmith.project.name
34 assert_equal "Manager", @jsmith.role.name
35 assert_equal "jsmith", @jsmith.user.login
36
37 @jsmith.role = Role.find(2)
38 assert @jsmith.save
39 end
40
41 def test_validate
42 member = Member.new(:project_id => 1, :user_id => 2, :role_id =>2)
43 # same use can't have more than one role for a project
44 assert !member.save
45 end
46
47 def test_destroy
48 @jsmith.destroy
49 assert_raise(ActiveRecord::RecordNotFound) { Member.find(@jsmith.id) }
50 end
51 end
@@ -0,0 +1,10
1 require File.dirname(__FILE__) + '/../test_helper'
2
3 class TokenTest < Test::Unit::TestCase
4 fixtures :tokens
5
6 # Replace this with your real tests.
7 def test_truth
8 assert true
9 end
10 end
@@ -0,0 +1,19
1 == Version 1.1 (28 May 2006)
2
3 * The charset for each and/or all languages can now be easily configured.
4 * Added a ActionController filter that auto-detects the client language.
5 * The rake task "sort" now merges lines that match 100%, and warns if duplicate keys are found.
6 * Rule support. Create flexible rules to handle issues such as pluralization.
7 * Massive speed and stability improvements to development mode.
8 * Added Russian strings. (Thanks to Evgeny Lineytsev)
9 * Complete RDoc documentation.
10 * Improved helpers.
11 * GLoc now configurable via get_config and set_config
12 * Added an option to tell GLoc to output various verbose information.
13 * More useful functions such as set_language_if_valid, similar_language
14 * GLoc's entire internal state can now be backed up and restored.
15
16
17 == Version 1.0 (17 April 2006)
18
19 * Initial public release.
@@ -0,0 +1,19
1 Copyright (c) 2005-2006 David Barri
2
3 Permission is hereby granted, free of charge, to any person obtaining a copy
4 of this software and associated documentation files (the "Software"), to deal
5 in the Software without restriction, including without limitation the rights
6 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 copies of the Software, and to permit persons to whom the Software is
8 furnished to do so, subject to the following conditions:
9
10 The above copyright notice and this permission notice shall be included in
11 all copies or substantial portions of the Software.
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 THE SOFTWARE. No newline at end of file
@@ -0,0 +1,208
1 = About
2
3 === Preface
4 I originally started designing this on weekends and after work in 2005. We started to become very interested in Rails at work and I wanted to get some experience with ruby with before we started using it full-time. I didn't have very many ideas for anything interesting to create so, because we write a lot of multilingual webapps at my company, I decided to write a localization library. That way if my little hobby project developed into something decent, I could at least put it to good use.
5 And here we are in 2006, my little hobby project has come a long way and become quite a useful piece of software. Not only do I use it in production sites I write at work, but I also prefer it to other existing alternatives. Therefore I have decided to make it publicly available, and I hope that other developers will find it useful too.
6
7 === About
8 GLoc is a localization library. It doesn't aim to do everything l10n-related that you can imagine, but what it does, it does very well. It was originally designed as a Rails plugin, but can also be used for plain ruby projects. Here are a list of its main features:
9 * Lightweight and efficient.
10 * Uses file-based string bundles. Strings can also be set directly.
11 * Intelligent, cascading language configuration.
12 * Create flexible rules to handle issues such as pluralization.
13 * Includes a ActionController filter that auto-detects the client language.
14 * Works perfectly with Rails Engines and allows strings to be overridden just as easily as controllers, models, etc.
15 * Automatically localizes Rails functions such as distance_in_minutes, select_month etc
16 * Supports different charsets. You can even specify the encoding to use for each language seperately.
17 * Special Rails mods/helpers.
18
19 === What does GLoc mean?
20 If you're wondering about the name "GLoc", I'm sure you're not alone.
21 This project was originally just called "Localization" which was a bit too common, so when I decided to release it I decided to call it "Golly's Localization Library" instead (Golly is my nickname), and that was long and boring so I then abbreviated that to "GLoc". What a fun story!!
22
23 === Localization helpers
24 This also includes a few helpers for common situations such as displaying localized date, time, "yes" or "no", etc.
25
26 === Rails Localization
27 At the moment, unless you manually remove the <tt>require 'gloc-rails-text'</tt> line from init.rb, this plugin overrides certain Rails functions to provide multilingual versions. This automatically localizes functions such as select_date(), distance_of_time_in_words() and more...
28 The strings can be found in lang/*.yml.
29 NOTE: This is not complete. Timezones and countries are not currently localized.
30
31
32
33
34 = Usage
35
36 === Quickstart
37
38 Windows users will need to first install iconv. http://wiki.rubyonrails.com/rails/pages/iconv
39
40 * Create a dir "#{RAILS_ROOT}/lang"
41 * Create a file "#{RAILS_ROOT}/lang/en.yml" and write your strings. The format is "key: string". Save it as UTF-8. If you save it in a different encoding, add a key called file_charset (eg. "file_charset: iso-2022-jp")
42 * Put the following in config/environment.rb and change the values as you see fit. The following example is for an app that uses English and Japanese, with Japanese being the default.
43 GLoc.set_config :default_language => :ja
44 GLoc.clear_strings_except :en, :ja
45 GLoc.set_kcode
46 GLoc.load_localized_strings
47 * Add 'include GLoc' to all classes that will use localization. This is added to most Rails classes automatically.
48 * Optionally, you can set the language for models and controllers by simply inserting <tt>set_language :en</tt> in classes and/or methods.
49 * To use localized strings, replace text such as <tt>"Welcome"</tt> with <tt>l(:welcome_string_key)</tt>, and <tt>"Hello #{name}."</tt> with <tt>l(:hello_string_key, name)</tt>. (Of course the strings will need to exist in your string bundle.)
50
51 There is more functionality provided by this plugin, that is not demonstrated above. Please read the API summary for details.
52
53 === API summary
54
55 The following methods are added as both class methods and instance methods to modules/classes that include GLoc. They are also available as class methods of GLoc.
56 current_language # Returns the current language
57 l(symbol, *arguments) # Returns a localized string
58 ll(lang, symbol, *arguments) # Returns a localized string in a specific language
59 ltry(possible_key) # Returns a localized string if passed a Symbol, else returns the same argument passed
60 lwr(symbol, *arguments) # Uses the default rule to return a localized string.
61 lwr_(rule, symbol, *arguments) # Uses a specified rule to return a localized string.
62 l_has_string?(symbol) # Checks if a localized string exists
63 set_language(language) # Sets the language for the current class or class instance
64 set_language_if_valid(lang) # Sets the current language if the language passed is a valid language
65
66 The GLoc module also defines the following class methods:
67 add_localized_strings(lang, symbol_hash, override=true) # Adds a hash of localized strings
68 backup_state(clear=false) # Creates a backup of GLoc's internal state and optionally clears everything too
69 clear_strings(*languages) # Removes localized strings from memory
70 clear_strings_except(*languages) # Removes localized strings from memory except for those of certain specified languages
71 get_charset(lang) # Returns the charset used to store localized strings in memory
72 get_config(key) # Returns a GLoc configuration value (see below)
73 load_localized_strings(dir=nil, override=true) # Loads localized strings from all YML files in a given directory
74 restore_state(state) # Restores a backup of GLoc's internal state
75 set_charset(new_charset, *langs) # Sets the charset used to internally store localized strings
76 set_config(hash) # Sets GLoc configuration values (see below)
77 set_kcode(charset=nil) # Sets the $KCODE global variable
78 similar_language(language) # Tries to find a valid language that is similar to the argument passed
79 valid_languages # Returns an array of (currently) valid languages (ie. languages for which localized data exists)
80 valid_language?(language) # Checks whether any localized strings are in memory for a given language
81
82 GLoc uses the following configuration items. They can be accessed via <tt>get_config</tt> and <tt>set_config</tt>.
83 :default_cookie_name
84 :default_language
85 :default_param_name
86 :raise_string_not_found_errors
87 :verbose
88
89 The GLoc module is automatically included in the following classes:
90 ActionController::Base
91 ActionMailer::Base
92 ActionView::Base
93 ActionView::Helpers::InstanceTag
94 ActiveRecord::Base
95 ActiveRecord::Errors
96 ApplicationHelper
97 Test::Unit::TestCase
98
99 The GLoc module also defines the following controller filters:
100 autodetect_language_filter
101
102 GLoc also makes the following change to Rails:
103 * Views for ActionMailer are now #{view_name}_#{language}.rb rather than just #{view_name}.rb
104 * All ActiveRecord validation class methods now accept a localized string key (symbol) as a :message value.
105 * ActiveRecord::Errors.add now accepts symbols as valid message values. At runtime these symbols are converted to localized strings using the current_language of the base record.
106 * ActiveRecord::Errors.add now accepts arrays as arguments so that printf-style strings can be generated at runtime. This also applies to the validates_* class methods.
107 Eg. validates_xxxxxx_of :name, :message => ['Your name must be at least %d characters.', MIN_LEN]
108 Eg. validates_xxxxxx_of :name, :message => [:user_error_validation_name_too_short, MIN_LEN]
109 * Instances of ActiveView inherit their current_language from the controller (or mailer) creating them.
110
111 This plugin also adds the following rake tasks:
112 * gloc:sort - Sorts the keys in the lang ymls (also accepts a DIR argument)
113
114 === Cascading language configuration
115
116 The language can be set at three levels:
117 1. The default # GLoc.get_config :default_language
118 2. Class level # class A; set_language :de; end
119 3. Instance level # b= B.new; b.set_language :zh
120
121 Instance level has the highest priority and the default has the lowest.
122
123 Because GLoc is included at class level too, it becomes easy to associate languages with contexts.
124 For example:
125 class Student
126 set_language :en
127 def say_hello
128 puts "We say #{l :hello} but our teachers say #{Teacher.l :hello}"
129 end
130 end
131
132 === Rules
133
134 There are often situations when depending on the value of one or more variables, the surrounding text
135 changes. The most common case of this is pluralization. Rather than hardcode these rules, they are
136 completely definable by the user so that the user can eaasily accomodate for more complicated grammatical
137 rules such as those found in Russian and Polish (or so I hear). To define a rule, simply include a string
138 in the string bundle whose key begins with "_gloc_rule_" and then write ruby code as the value. The ruby
139 code will be converted to a Proc when the string bundle is first read, and should return a prefix that will
140 be appended to the string key at runtime to point to a new string. Make sense? Probably not... Please look
141 at the following example and I am sure it will all make sense.
142
143 Simple example (string bundle / en.yml)
144 _gloc_rule_default: ' |n| n==1 ? "_single" : "_plural" '
145 man_count_plural: There are %d men.
146 man_count_single: There is 1 man.
147
148 Simple example (code)
149 lwr(:man_count, 1) # => There is 1 man.
150 lwr(:man_count, 8) # => There are 8 men.
151
152 To use rules other than the default simply call lwr_ instead of lwr, and specify the rule.
153
154 Example #2 (string bundle / en.yml)
155 _gloc_rule_default: ' |n| n==1 ? "_single" : "_plural" '
156 _gloc_rule_custom: ' |n| return "_none" if n==0; return "_heaps" if n>100; n==1 ? "_single" : "_plural" '
157 man_count_none: There are no men.
158 man_count_heaps: There are heaps of men!!
159 man_count_plural: There are %d men.
160 man_count_single: There is 1 man.
161
162 Example #2 (code)
163 lwr_(:custom, :man_count, 0) # => There are no men.
164 lwr_(:custom, :man_count, 1) # => There is 1 man.
165 lwr_(:custom, :man_count, 8) # => There are 8 men.
166 lwr_(:custom, :man_count, 150) # => There are heaps of men!!
167
168
169 === Helpers
170
171 GLoc includes the following helpers:
172 l_age(age) # Returns a localized version of an age. eg "3 years old"
173 l_date(date) # Returns a date in a localized format
174 l_datetime(date) # Returns a date+time in a localized format
175 l_datetime_short(date) # Returns a date+time in a localized short format.
176 l_lang_name(l,dl=nil) # Returns the name of a language (you must supply your own strings)
177 l_strftime(date,fmt) # Formats a date/time in a localized format.
178 l_time(date) # Returns a time in a localized format
179 l_YesNo(value) # Returns localized string of "Yes" or "No" depending on the arg
180 l_yesno(value) # Returns localized string of "yes" or "no" depending on the arg
181
182 === Rails localization
183
184 Not all of Rails is covered but the following functions are:
185 distance_of_time_in_words
186 select_day
187 select_month
188 select_year
189 add_options
190
191
192
193
194 = FAQ
195
196 ==== How do I use it in engines?
197 Simply put this in your init_engine.rb
198 GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
199 That way your engines strings will be loaded when the engine is started. Just simply make sure that you load your application strings after you start your engines to safely override any engine strings.
200
201 ==== Why am I getting an Iconv::IllegalSequence error when calling GLoc.set_charset?
202 By default GLoc loads all of its default strings at startup. For example, calling <tt>set_charset 'iso-2022-jp'</tt> will cause this error because Russian strings are loaded by default, and the Russian strings use characters that cannot be expressed in the ISO-2022-JP charset.
203 Before calling <tt>set_charset</tt> you should call <tt>clear_strings_except</tt> to remove strings from any languages that you will not be using.
204 Alternatively, you can simply specify the language(s) as follows, <tt>set_charset 'iso-2022-jp', :ja</tt>.
205
206 ==== How do I make GLoc ignore StringNotFoundErrors?
207 Disable it as follows:
208 GLoc.set_config :raise_string_not_found_errors => false
@@ -0,0 +1,15
1 Dir.glob("#{File.dirname(__FILE__)}/tasks/*.rake").each {|f| load f}
2
3 task :default => 'gloc:sort'
4
5 # RDoc task
6 require 'rake/rdoctask'
7 Rake::RDocTask.new() { |rdoc|
8 rdoc.rdoc_dir = 'doc'
9 rdoc.title = "GLoc Localization Library Documentation"
10 rdoc.options << '--line-numbers' << '--inline-source'
11 rdoc.rdoc_files.include('README', 'CHANGELOG')
12 rdoc.rdoc_files.include('lib/**/*.rb')
13 rdoc.rdoc_files.exclude('lib/gloc-dev.rb')
14 rdoc.rdoc_files.exclude('lib/gloc-config.rb')
15 }
@@ -0,0 +1,230
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>Module: ActionController::Filters::ClassMethods</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="classHeader">
50 <table class="header-table">
51 <tr class="top-aligned-row">
52 <td><strong>Module</strong></td>
53 <td class="class-name-in-header">ActionController::Filters::ClassMethods</td>
54 </tr>
55 <tr class="top-aligned-row">
56 <td><strong>In:</strong></td>
57 <td>
58 <a href="../../../files/lib/gloc-rails_rb.html">
59 lib/gloc-rails.rb
60 </a>
61 <br />
62 </td>
63 </tr>
64
65 </table>
66 </div>
67 <!-- banner header -->
68
69 <div id="bodyContent">
70
71
72
73 <div id="contextContent">
74
75
76
77 </div>
78
79 <div id="method-list">
80 <h3 class="section-bar">Methods</h3>
81
82 <div class="name-list">
83 <a href="#M000001">autodetect_language_filter</a>&nbsp;&nbsp;
84 </div>
85 </div>
86
87 </div>
88
89
90 <!-- if includes -->
91
92 <div id="section">
93
94
95
96
97
98
99
100
101 <!-- if method_list -->
102 <div id="methods">
103 <h3 class="section-bar">Public Instance methods</h3>
104
105 <div id="method-M000001" class="method-detail">
106 <a name="M000001"></a>
107
108 <div class="method-heading">
109 <a href="#M000001" class="method-signature">
110 <span class="method-name">autodetect_language_filter</span><span class="method-args">(*args)</span>
111 </a>
112 </div>
113
114 <div class="method-description">
115 <p>
116 This filter attempts to auto-detect the clients desired language. It first
117 checks the params, then a cookie and then the HTTP_ACCEPT_LANGUAGE request
118 header. If a language is found to match or be similar to a currently valid
119 language, then it sets the current_language of the controller.
120 </p>
121 <pre>
122 class ExampleController &lt; ApplicationController
123 set_language :en
124 autodetect_language_filter :except =&gt; 'monkey', :on_no_lang =&gt; :lang_not_autodetected_callback
125 autodetect_language_filter :only =&gt; 'monkey', :check_cookie =&gt; 'monkey_lang', :check_accept_header =&gt; false
126 ...
127 def lang_not_autodetected_callback
128 redirect_to somewhere
129 end
130 end
131 </pre>
132 <p>
133 The <tt>args</tt> for this filter are exactly the same the arguments of
134 <tt>before_filter</tt> with the following exceptions:
135 </p>
136 <ul>
137 <li><tt>:check_params</tt> &#8212; If false, then params will not be checked
138 for a language. If a String, then this will value will be used as the name
139 of the param.
140
141 </li>
142 <li><tt>:check_cookie</tt> &#8212; If false, then the cookie will not be
143 checked for a language. If a String, then this will value will be used as
144 the name of the cookie.
145
146 </li>
147 <li><tt>:check_accept_header</tt> &#8212; If false, then HTTP_ACCEPT_LANGUAGE
148 will not be checked for a language.
149
150 </li>
151 <li><tt>:on_set_lang</tt> &#8212; You can specify the name of a callback
152 function to be called when the language is successfully detected and set.
153 The param must be a Symbol or a String which is the name of the function.
154 The callback function must accept one argument (the language) and must be
155 instance level.
156
157 </li>
158 <li><tt>:on_no_lang</tt> &#8212; You can specify the name of a callback
159 function to be called when the language couldn&#8217;t be detected
160 automatically. The param must be a Symbol or a String which is the name of
161 the function. The callback function must be instance level.
162
163 </li>
164 </ul>
165 <p>
166 You override the default names of the param or cookie by calling <tt><a
167 href="../../GLoc.html#M000014">GLoc.set_config</a> :default_param_name
168 =&gt; &#8216;new_param_name&#8216;</tt> and <tt><a
169 href="../../GLoc.html#M000014">GLoc.set_config</a> :default_cookie_name
170 =&gt; &#8216;new_cookie_name&#8216;</tt>.
171 </p>
172 <p><a class="source-toggle" href="#"
173 onclick="toggleCode('M000001-source');return false;">[Source]</a></p>
174 <div class="method-source-code" id="M000001-source">
175 <pre>
176 <span class="ruby-comment cmt"># File lib/gloc-rails.rb, line 43</span>
177 43: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">autodetect_language_filter</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">args</span>)
178 44: <span class="ruby-identifier">options</span>= <span class="ruby-identifier">args</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Hash</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">args</span>.<span class="ruby-identifier">last</span> <span class="ruby-operator">:</span> {}
179 45: <span class="ruby-identifier">x</span>= <span class="ruby-value str">'Proc.new { |c| l= nil;'</span>
180 46: <span class="ruby-comment cmt"># :check_params</span>
181 47: <span class="ruby-keyword kw">unless</span> (<span class="ruby-identifier">v</span>= <span class="ruby-identifier">options</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">:check_params</span>)) <span class="ruby-operator">==</span> <span class="ruby-keyword kw">false</span>
182 48: <span class="ruby-identifier">name</span>= <span class="ruby-identifier">v</span> <span class="ruby-value">? </span><span class="ruby-node">&quot;:#{v}&quot;</span> <span class="ruby-operator">:</span> <span class="ruby-value str">'GLoc.get_config(:default_param_name)'</span>
183 49: <span class="ruby-identifier">x</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-node">&quot;l ||= GLoc.similar_language(c.params[#{name}]);&quot;</span>
184 50: <span class="ruby-keyword kw">end</span>
185 51: <span class="ruby-comment cmt"># :check_cookie</span>
186 52: <span class="ruby-keyword kw">unless</span> (<span class="ruby-identifier">v</span>= <span class="ruby-identifier">options</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">:check_cookie</span>)) <span class="ruby-operator">==</span> <span class="ruby-keyword kw">false</span>
187 53: <span class="ruby-identifier">name</span>= <span class="ruby-identifier">v</span> <span class="ruby-value">? </span><span class="ruby-node">&quot;:#{v}&quot;</span> <span class="ruby-operator">:</span> <span class="ruby-value str">'GLoc.get_config(:default_cookie_name)'</span>
188 54: <span class="ruby-identifier">x</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-node">&quot;l ||= GLoc.similar_language(c.send(:cookies)[#{name}]);&quot;</span>
189 55: <span class="ruby-keyword kw">end</span>
190 56: <span class="ruby-comment cmt"># :check_accept_header</span>
191 57: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">:check_accept_header</span>) <span class="ruby-operator">==</span> <span class="ruby-keyword kw">false</span>
192 58: <span class="ruby-identifier">x</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-value str">%&lt;
193 59: unless l
194 60: a= c.request.env['HTTP_ACCEPT_LANGUAGE'].split(/,|;/) rescue nil
195 61: a.each {|x| l ||= GLoc.similar_language(x)} if a
196 62: end; &gt;</span>
197 63: <span class="ruby-keyword kw">end</span>
198 64: <span class="ruby-comment cmt"># Set language</span>
199 65: <span class="ruby-identifier">x</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-value str">'ret= true;'</span>
200 66: <span class="ruby-identifier">x</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-value str">'if l; c.set_language(l); c.headers[\'Content-Language\']= l.to_s; '</span>
201 67: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">:on_set_lang</span>)
202 68: <span class="ruby-identifier">x</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-node">&quot;ret= c.#{options.delete(:on_set_lang)}(l);&quot;</span>
203 69: <span class="ruby-keyword kw">end</span>
204 70: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">:on_no_lang</span>)
205 71: <span class="ruby-identifier">x</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-node">&quot;else; ret= c.#{options.delete(:on_no_lang)};&quot;</span>
206 72: <span class="ruby-keyword kw">end</span>
207 73: <span class="ruby-identifier">x</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-value str">'end; ret }'</span>
208 74:
209 75: <span class="ruby-comment cmt"># Create filter</span>
210 76: <span class="ruby-identifier">block</span>= <span class="ruby-identifier">eval</span> <span class="ruby-identifier">x</span>
211 77: <span class="ruby-identifier">before_filter</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">args</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
212 78: <span class="ruby-keyword kw">end</span>
213 </pre>
214 </div>
215 </div>
216 </div>
217
218
219 </div>
220
221
222 </div>
223
224
225 <div id="validator-badges">
226 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
227 </div>
228
229 </body>
230 </html> No newline at end of file
@@ -0,0 +1,140
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>Class: ActionMailer::Base</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="classHeader">
50 <table class="header-table">
51 <tr class="top-aligned-row">
52 <td><strong>Class</strong></td>
53 <td class="class-name-in-header">ActionMailer::Base</td>
54 </tr>
55 <tr class="top-aligned-row">
56 <td><strong>In:</strong></td>
57 <td>
58 <a href="../../files/lib/gloc-rails_rb.html">
59 lib/gloc-rails.rb
60 </a>
61 <br />
62 </td>
63 </tr>
64
65 <tr class="top-aligned-row">
66 <td><strong>Parent:</strong></td>
67 <td>
68 Object
69 </td>
70 </tr>
71 </table>
72 </div>
73 <!-- banner header -->
74
75 <div id="bodyContent">
76
77
78
79 <div id="contextContent">
80
81 <div id="description">
82 <p>
83 In addition to including <a href="../GLoc.html">GLoc</a>,
84 <tt>render_message</tt> is also overridden so that mail templates contain
85 the current language at the end of the file. Eg. <tt>deliver_hello</tt>
86 will render <tt>hello_en.rhtml</tt>.
87 </p>
88
89 </div>
90
91
92 </div>
93
94
95 </div>
96
97
98 <!-- if includes -->
99 <div id="includes">
100 <h3 class="section-bar">Included Modules</h3>
101
102 <div id="includes-list">
103 <span class="include-name"><a href="../GLoc.html">GLoc</a></span>
104 </div>
105 </div>
106
107 <div id="section">
108
109
110
111 <div id="aliases-list">
112 <h3 class="section-bar">External Aliases</h3>
113
114 <div class="name-list">
115 <table summary="aliases">
116 <tr class="top-aligned-row context-row">
117 <td class="context-item-name">render_message</td>
118 <td>-></td>
119 <td class="context-item-value">render_message_without_gloc</td>
120 </tr>
121 </table>
122 </div>
123 </div>
124
125
126
127
128
129 <!-- if method_list -->
130
131
132 </div>
133
134
135 <div id="validator-badges">
136 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
137 </div>
138
139 </body>
140 </html> No newline at end of file
@@ -0,0 +1,174
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>Class: ActionView::Base</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="classHeader">
50 <table class="header-table">
51 <tr class="top-aligned-row">
52 <td><strong>Class</strong></td>
53 <td class="class-name-in-header">ActionView::Base</td>
54 </tr>
55 <tr class="top-aligned-row">
56 <td><strong>In:</strong></td>
57 <td>
58 <a href="../../files/lib/gloc-rails_rb.html">
59 lib/gloc-rails.rb
60 </a>
61 <br />
62 </td>
63 </tr>
64
65 <tr class="top-aligned-row">
66 <td><strong>Parent:</strong></td>
67 <td>
68 Object
69 </td>
70 </tr>
71 </table>
72 </div>
73 <!-- banner header -->
74
75 <div id="bodyContent">
76
77
78
79 <div id="contextContent">
80
81 <div id="description">
82 <p>
83 <tt>initialize</tt> is overridden so that new instances of this class
84 inherit the current language of the controller.
85 </p>
86
87 </div>
88
89
90 </div>
91
92 <div id="method-list">
93 <h3 class="section-bar">Methods</h3>
94
95 <div class="name-list">
96 <a href="#M000046">new</a>&nbsp;&nbsp;
97 </div>
98 </div>
99
100 </div>
101
102
103 <!-- if includes -->
104 <div id="includes">
105 <h3 class="section-bar">Included Modules</h3>
106
107 <div id="includes-list">
108 <span class="include-name"><a href="../GLoc.html">GLoc</a></span>
109 </div>
110 </div>
111
112 <div id="section">
113
114
115
116 <div id="aliases-list">
117 <h3 class="section-bar">External Aliases</h3>
118
119 <div class="name-list">
120 <table summary="aliases">
121 <tr class="top-aligned-row context-row">
122 <td class="context-item-name">initialize</td>
123 <td>-></td>
124 <td class="context-item-value">initialize_without_gloc</td>
125 </tr>
126 </table>
127 </div>
128 </div>
129
130
131
132
133
134 <!-- if method_list -->
135 <div id="methods">
136 <h3 class="section-bar">Public Class methods</h3>
137
138 <div id="method-M000046" class="method-detail">
139 <a name="M000046"></a>
140
141 <div class="method-heading">
142 <a href="#M000046" class="method-signature">
143 <span class="method-name">new</span><span class="method-args">(base_path = nil, assigns_for_first_render = {}, controller = nil)</span>
144 </a>
145 </div>
146
147 <div class="method-description">
148 <p><a class="source-toggle" href="#"
149 onclick="toggleCode('M000046-source');return false;">[Source]</a></p>
150 <div class="method-source-code" id="M000046-source">
151 <pre>
152 <span class="ruby-comment cmt"># File lib/gloc-rails.rb, line 109</span>
153 109: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">base_path</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">assigns_for_first_render</span> = {}, <span class="ruby-identifier">controller</span> = <span class="ruby-keyword kw">nil</span>)
154 110: <span class="ruby-identifier">initialize_without_gloc</span>(<span class="ruby-identifier">base_path</span>, <span class="ruby-identifier">assigns_for_first_render</span>, <span class="ruby-identifier">controller</span>)
155 111: <span class="ruby-identifier">set_language</span> <span class="ruby-identifier">controller</span>.<span class="ruby-identifier">current_language</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">controller</span>.<span class="ruby-identifier">nil?</span>
156 112: <span class="ruby-keyword kw">end</span>
157 </pre>
158 </div>
159 </div>
160 </div>
161
162
163 </div>
164
165
166 </div>
167
168
169 <div id="validator-badges">
170 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
171 </div>
172
173 </body>
174 </html> No newline at end of file
@@ -0,0 +1,348
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>Module: ActionView::Helpers::DateHelper</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="classHeader">
50 <table class="header-table">
51 <tr class="top-aligned-row">
52 <td><strong>Module</strong></td>
53 <td class="class-name-in-header">ActionView::Helpers::DateHelper</td>
54 </tr>
55 <tr class="top-aligned-row">
56 <td><strong>In:</strong></td>
57 <td>
58 <a href="../../../files/lib/gloc-rails-text_rb.html">
59 lib/gloc-rails-text.rb
60 </a>
61 <br />
62 </td>
63 </tr>
64
65 </table>
66 </div>
67 <!-- banner header -->
68
69 <div id="bodyContent">
70
71
72
73 <div id="contextContent">
74
75
76
77 </div>
78
79 <div id="method-list">
80 <h3 class="section-bar">Methods</h3>
81
82 <div class="name-list">
83 <a href="#M000041">distance_of_time_in_words</a>&nbsp;&nbsp;
84 <a href="#M000042">select_day</a>&nbsp;&nbsp;
85 <a href="#M000043">select_month</a>&nbsp;&nbsp;
86 <a href="#M000044">select_year</a>&nbsp;&nbsp;
87 </div>
88 </div>
89
90 </div>
91
92
93 <!-- if includes -->
94
95 <div id="section">
96
97
98 <div id="constants-list">
99 <h3 class="section-bar">Constants</h3>
100
101 <div class="name-list">
102 <table summary="Constants">
103 <tr class="top-aligned-row context-row">
104 <td class="context-item-name">LOCALIZED_HELPERS</td>
105 <td>=</td>
106 <td class="context-item-value">true</td>
107 </tr>
108 <tr class="top-aligned-row context-row">
109 <td class="context-item-name">LOCALIZED_MONTHNAMES</td>
110 <td>=</td>
111 <td class="context-item-value">{}</td>
112 </tr>
113 <tr class="top-aligned-row context-row">
114 <td class="context-item-name">LOCALIZED_ABBR_MONTHNAMES</td>
115 <td>=</td>
116 <td class="context-item-value">{}</td>
117 </tr>
118 </table>
119 </div>
120 </div>
121
122
123
124
125
126
127 <!-- if method_list -->
128 <div id="methods">
129 <h3 class="section-bar">Public Instance methods</h3>
130
131 <div id="method-M000041" class="method-detail">
132 <a name="M000041"></a>
133
134 <div class="method-heading">
135 <a href="#M000041" class="method-signature">
136 <span class="method-name">distance_of_time_in_words</span><span class="method-args">(from_time, to_time = 0, include_seconds = false)</span>
137 </a>
138 </div>
139
140 <div class="method-description">
141 <p>
142 This method uses <tt>current_language</tt> to return a localized string.
143 </p>
144 <p><a class="source-toggle" href="#"
145 onclick="toggleCode('M000041-source');return false;">[Source]</a></p>
146 <div class="method-source-code" id="M000041-source">
147 <pre>
148 <span class="ruby-comment cmt"># File lib/gloc-rails-text.rb, line 16</span>
149 16: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">distance_of_time_in_words</span>(<span class="ruby-identifier">from_time</span>, <span class="ruby-identifier">to_time</span> = <span class="ruby-value">0</span>, <span class="ruby-identifier">include_seconds</span> = <span class="ruby-keyword kw">false</span>)
150 17: <span class="ruby-identifier">from_time</span> = <span class="ruby-identifier">from_time</span>.<span class="ruby-identifier">to_time</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">from_time</span>.<span class="ruby-identifier">respond_to?</span>(<span class="ruby-identifier">:to_time</span>)
151 18: <span class="ruby-identifier">to_time</span> = <span class="ruby-identifier">to_time</span>.<span class="ruby-identifier">to_time</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">to_time</span>.<span class="ruby-identifier">respond_to?</span>(<span class="ruby-identifier">:to_time</span>)
152 19: <span class="ruby-identifier">distance_in_minutes</span> = (((<span class="ruby-identifier">to_time</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">from_time</span>).<span class="ruby-identifier">abs</span>)<span class="ruby-operator">/</span><span class="ruby-value">60</span>).<span class="ruby-identifier">round</span>
153 20: <span class="ruby-identifier">distance_in_seconds</span> = ((<span class="ruby-identifier">to_time</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">from_time</span>).<span class="ruby-identifier">abs</span>).<span class="ruby-identifier">round</span>
154 21:
155 22: <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">distance_in_minutes</span>
156 23: <span class="ruby-keyword kw">when</span> <span class="ruby-value">0</span><span class="ruby-operator">..</span><span class="ruby-value">1</span>
157 24: <span class="ruby-keyword kw">return</span> (<span class="ruby-identifier">distance_in_minutes</span><span class="ruby-operator">==</span><span class="ruby-value">0</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_minute_less_than</span>) <span class="ruby-operator">:</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_minute_single</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">include_seconds</span>
158 25: <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">distance_in_seconds</span>
159 26: <span class="ruby-keyword kw">when</span> <span class="ruby-value">0</span><span class="ruby-operator">..</span><span class="ruby-value">5</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_second_less_than</span>, <span class="ruby-value">5</span>)
160 27: <span class="ruby-keyword kw">when</span> <span class="ruby-value">6</span><span class="ruby-operator">..</span><span class="ruby-value">10</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_second_less_than</span>, <span class="ruby-value">10</span>)
161 28: <span class="ruby-keyword kw">when</span> <span class="ruby-value">11</span><span class="ruby-operator">..</span><span class="ruby-value">20</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_second_less_than</span>, <span class="ruby-value">20</span>)
162 29: <span class="ruby-keyword kw">when</span> <span class="ruby-value">21</span><span class="ruby-operator">..</span><span class="ruby-value">40</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_minute_half</span>)
163 30: <span class="ruby-keyword kw">when</span> <span class="ruby-value">41</span><span class="ruby-operator">..</span><span class="ruby-value">59</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_minute_less_than</span>)
164 31: <span class="ruby-keyword kw">else</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_minute</span>)
165 32: <span class="ruby-keyword kw">end</span>
166 33:
167 34: <span class="ruby-keyword kw">when</span> <span class="ruby-value">2</span><span class="ruby-operator">..</span><span class="ruby-value">45</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_minute</span>, <span class="ruby-identifier">distance_in_minutes</span>)
168 35: <span class="ruby-keyword kw">when</span> <span class="ruby-value">46</span><span class="ruby-operator">..</span><span class="ruby-value">90</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_hour_about_single</span>)
169 36: <span class="ruby-keyword kw">when</span> <span class="ruby-value">90</span><span class="ruby-operator">..</span><span class="ruby-value">1440</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_hour_about</span>, (<span class="ruby-identifier">distance_in_minutes</span>.<span class="ruby-identifier">to_f</span> <span class="ruby-operator">/</span> <span class="ruby-value">60.0</span>).<span class="ruby-identifier">round</span>)
170 37: <span class="ruby-keyword kw">when</span> <span class="ruby-value">1441</span><span class="ruby-operator">..</span><span class="ruby-value">2880</span> <span class="ruby-keyword kw">then</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_day</span>, <span class="ruby-value">1</span>)
171 38: <span class="ruby-keyword kw">else</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">:actionview_datehelper_time_in_words_day</span>, (<span class="ruby-identifier">distance_in_minutes</span> <span class="ruby-operator">/</span> <span class="ruby-value">1440</span>).<span class="ruby-identifier">round</span>)
172 39: <span class="ruby-keyword kw">end</span>
173 40: <span class="ruby-keyword kw">end</span>
174 </pre>
175 </div>
176 </div>
177 </div>
178
179 <div id="method-M000042" class="method-detail">
180 <a name="M000042"></a>
181
182 <div class="method-heading">
183 <a href="#M000042" class="method-signature">
184 <span class="method-name">select_day</span><span class="method-args">(date, options = {})</span>
185 </a>
186 </div>
187
188 <div class="method-description">
189 <p>
190 This method has been modified so that a localized string can be appended to
191 the day numbers.
192 </p>
193 <p><a class="source-toggle" href="#"
194 onclick="toggleCode('M000042-source');return false;">[Source]</a></p>
195 <div class="method-source-code" id="M000042-source">
196 <pre>
197 <span class="ruby-comment cmt"># File lib/gloc-rails-text.rb, line 43</span>
198 43: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">select_day</span>(<span class="ruby-identifier">date</span>, <span class="ruby-identifier">options</span> = {})
199 44: <span class="ruby-identifier">day_options</span> = []
200 45: <span class="ruby-identifier">prefix</span> = <span class="ruby-identifier">l</span> <span class="ruby-identifier">:actionview_datehelper_select_day_prefix</span>
201 46:
202 47: <span class="ruby-value">1</span>.<span class="ruby-identifier">upto</span>(<span class="ruby-value">31</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">day</span><span class="ruby-operator">|</span>
203 48: <span class="ruby-identifier">day_options</span> <span class="ruby-operator">&lt;&lt;</span> ((<span class="ruby-identifier">date</span> <span class="ruby-operator">&amp;&amp;</span> (<span class="ruby-identifier">date</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">Fixnum</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">date</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">date</span>.<span class="ruby-identifier">day</span>) <span class="ruby-operator">==</span> <span class="ruby-identifier">day</span>) <span class="ruby-operator">?</span>
204 49: <span class="ruby-node">%(&lt;option value=&quot;#{day}&quot; selected=&quot;selected&quot;&gt;#{day}#{prefix}&lt;/option&gt;\n)</span> <span class="ruby-operator">:</span>
205 50: <span class="ruby-node">%(&lt;option value=&quot;#{day}&quot;&gt;#{day}#{prefix}&lt;/option&gt;\n)</span>
206 51: )
207 52: <span class="ruby-keyword kw">end</span>
208 53:
209 54: <span class="ruby-identifier">select_html</span>(<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:field_name</span>] <span class="ruby-operator">||</span> <span class="ruby-value str">'day'</span>, <span class="ruby-identifier">day_options</span>, <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:prefix</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:include_blank</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:discard_type</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:disabled</span>])
210 55: <span class="ruby-keyword kw">end</span>
211 </pre>
212 </div>
213 </div>
214 </div>
215
216 <div id="method-M000043" class="method-detail">
217 <a name="M000043"></a>
218
219 <div class="method-heading">
220 <a href="#M000043" class="method-signature">
221 <span class="method-name">select_month</span><span class="method-args">(date, options = {})</span>
222 </a>
223 </div>
224
225 <div class="method-description">
226 <p>
227 This method has been modified so that
228 </p>
229 <ul>
230 <li>the month names are localized.
231
232 </li>
233 <li>it uses options: <tt>:min_date</tt>, <tt>:max_date</tt>,
234 <tt>:start_month</tt>, <tt>:end_month</tt>
235
236 </li>
237 <li>a localized string can be appended to the month numbers when the
238 <tt>:use_month_numbers</tt> option is specified.
239
240 </li>
241 </ul>
242 <p><a class="source-toggle" href="#"
243 onclick="toggleCode('M000043-source');return false;">[Source]</a></p>
244 <div class="method-source-code" id="M000043-source">
245 <pre>
246 <span class="ruby-comment cmt"># File lib/gloc-rails-text.rb, line 61</span>
247 61: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">select_month</span>(<span class="ruby-identifier">date</span>, <span class="ruby-identifier">options</span> = {})
248 62: <span class="ruby-keyword kw">unless</span> <span class="ruby-constant">LOCALIZED_MONTHNAMES</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">current_language</span>)
249 63: <span class="ruby-constant">LOCALIZED_MONTHNAMES</span>[<span class="ruby-identifier">current_language</span>] = [<span class="ruby-value str">''</span>] <span class="ruby-operator">+</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_select_month_names</span>).<span class="ruby-identifier">split</span>(<span class="ruby-value str">','</span>)
250 64: <span class="ruby-constant">LOCALIZED_ABBR_MONTHNAMES</span>[<span class="ruby-identifier">current_language</span>] = [<span class="ruby-value str">''</span>] <span class="ruby-operator">+</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">:actionview_datehelper_select_month_names_abbr</span>).<span class="ruby-identifier">split</span>(<span class="ruby-value str">','</span>)
251 65: <span class="ruby-keyword kw">end</span>
252 66:
253 67: <span class="ruby-identifier">month_options</span> = []
254 68: <span class="ruby-identifier">month_names</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:use_short_month</span>] <span class="ruby-operator">?</span> <span class="ruby-constant">LOCALIZED_ABBR_MONTHNAMES</span>[<span class="ruby-identifier">current_language</span>] <span class="ruby-operator">:</span> <span class="ruby-constant">LOCALIZED_MONTHNAMES</span>[<span class="ruby-identifier">current_language</span>]
255 69:
256 70: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">:min_date</span>) <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">:max_date</span>)
257 71: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:min_date</span>].<span class="ruby-identifier">year</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:max_date</span>].<span class="ruby-identifier">year</span>
258 72: <span class="ruby-identifier">start_month</span>, <span class="ruby-identifier">end_month</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:min_date</span>].<span class="ruby-identifier">month</span>, <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:max_date</span>].<span class="ruby-identifier">month</span>
259 73: <span class="ruby-keyword kw">end</span>
260 74: <span class="ruby-keyword kw">end</span>
261 75: <span class="ruby-identifier">start_month</span> = (<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:start_month</span>] <span class="ruby-operator">||</span> <span class="ruby-value">1</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">start_month</span>
262 76: <span class="ruby-identifier">end_month</span> = (<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:end_month</span>] <span class="ruby-operator">||</span> <span class="ruby-value">12</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">end_month</span>
263 77: <span class="ruby-identifier">prefix</span> = <span class="ruby-identifier">l</span> <span class="ruby-identifier">:actionview_datehelper_select_month_prefix</span>
264 78:
265 79: <span class="ruby-identifier">start_month</span>.<span class="ruby-identifier">upto</span>(<span class="ruby-identifier">end_month</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">month_number</span><span class="ruby-operator">|</span>
266 80: <span class="ruby-identifier">month_name</span> = <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:use_month_numbers</span>]
267 81: <span class="ruby-node">&quot;#{month_number}#{prefix}&quot;</span>
268 82: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:add_month_numbers</span>]
269 83: <span class="ruby-identifier">month_number</span>.<span class="ruby-identifier">to_s</span> <span class="ruby-operator">+</span> <span class="ruby-value str">' - '</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">month_names</span>[<span class="ruby-identifier">month_number</span>]
270 84: <span class="ruby-keyword kw">else</span>
271 85: <span class="ruby-identifier">month_names</span>[<span class="ruby-identifier">month_number</span>]
272 86: <span class="ruby-keyword kw">end</span>
273 87:
274 88: <span class="ruby-identifier">month_options</span> <span class="ruby-operator">&lt;&lt;</span> ((<span class="ruby-identifier">date</span> <span class="ruby-operator">&amp;&amp;</span> (<span class="ruby-identifier">date</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">Fixnum</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">date</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">date</span>.<span class="ruby-identifier">month</span>) <span class="ruby-operator">==</span> <span class="ruby-identifier">month_number</span>) <span class="ruby-operator">?</span>
275 89: <span class="ruby-node">%(&lt;option value=&quot;#{month_number}&quot; selected=&quot;selected&quot;&gt;#{month_name}&lt;/option&gt;\n)</span> <span class="ruby-operator">:</span>
276 90: <span class="ruby-node">%(&lt;option value=&quot;#{month_number}&quot;&gt;#{month_name}&lt;/option&gt;\n)</span>
277 91: )
278 92: <span class="ruby-keyword kw">end</span>
279 93:
280 94: <span class="ruby-identifier">select_html</span>(<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:field_name</span>] <span class="ruby-operator">||</span> <span class="ruby-value str">'month'</span>, <span class="ruby-identifier">month_options</span>, <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:prefix</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:include_blank</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:discard_type</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:disabled</span>])
281 95: <span class="ruby-keyword kw">end</span>
282 </pre>
283 </div>
284 </div>
285 </div>
286
287 <div id="method-M000044" class="method-detail">
288 <a name="M000044"></a>
289
290 <div class="method-heading">
291 <a href="#M000044" class="method-signature">
292 <span class="method-name">select_year</span><span class="method-args">(date, options = {})</span>
293 </a>
294 </div>
295
296 <div class="method-description">
297 <p>
298 This method has been modified so that
299 </p>
300 <ul>
301 <li>it uses options: <tt>:min_date</tt>, <tt>:max_date</tt>
302
303 </li>
304 <li>a localized string can be appended to the years numbers.
305
306 </li>
307 </ul>
308 <p><a class="source-toggle" href="#"
309 onclick="toggleCode('M000044-source');return false;">[Source]</a></p>
310 <div class="method-source-code" id="M000044-source">
311 <pre>
312 <span class="ruby-comment cmt"># File lib/gloc-rails-text.rb, line 100</span>
313 100: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">select_year</span>(<span class="ruby-identifier">date</span>, <span class="ruby-identifier">options</span> = {})
314 101: <span class="ruby-identifier">year_options</span> = []
315 102: <span class="ruby-identifier">y</span> = <span class="ruby-identifier">date</span> <span class="ruby-value">? </span>(<span class="ruby-identifier">date</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">Fixnum</span>) <span class="ruby-operator">?</span> (<span class="ruby-identifier">y</span> = (<span class="ruby-identifier">date</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>) <span class="ruby-operator">?</span> <span class="ruby-constant">Date</span>.<span class="ruby-identifier">today</span>.<span class="ruby-identifier">year</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">date</span>) <span class="ruby-operator">:</span> <span class="ruby-identifier">date</span>.<span class="ruby-identifier">year</span>) <span class="ruby-operator">:</span> <span class="ruby-constant">Date</span>.<span class="ruby-identifier">today</span>.<span class="ruby-identifier">year</span>
316 103:
317 104: <span class="ruby-identifier">start_year</span> = <span class="ruby-identifier">options</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">:min_date</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:min_date</span>].<span class="ruby-identifier">year</span> <span class="ruby-operator">:</span> (<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:start_year</span>] <span class="ruby-operator">||</span> <span class="ruby-identifier">y</span><span class="ruby-operator">-</span><span class="ruby-value">5</span>)
318 105: <span class="ruby-identifier">end_year</span> = <span class="ruby-identifier">options</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">:max_date</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:max_date</span>].<span class="ruby-identifier">year</span> <span class="ruby-operator">:</span> (<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:end_year</span>] <span class="ruby-operator">||</span> <span class="ruby-identifier">y</span><span class="ruby-operator">+</span><span class="ruby-value">5</span>)
319 106: <span class="ruby-identifier">step_val</span> = <span class="ruby-identifier">start_year</span> <span class="ruby-operator">&lt;</span> <span class="ruby-identifier">end_year</span> <span class="ruby-value">? </span><span class="ruby-value">1</span> <span class="ruby-operator">:</span> <span class="ruby-value">-1</span>
320 107: <span class="ruby-identifier">prefix</span> = <span class="ruby-identifier">l</span> <span class="ruby-identifier">:actionview_datehelper_select_year_prefix</span>
321 108:
322 109: <span class="ruby-identifier">start_year</span>.<span class="ruby-identifier">step</span>(<span class="ruby-identifier">end_year</span>, <span class="ruby-identifier">step_val</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">year</span><span class="ruby-operator">|</span>
323 110: <span class="ruby-identifier">year_options</span> <span class="ruby-operator">&lt;&lt;</span> ((<span class="ruby-identifier">date</span> <span class="ruby-operator">&amp;&amp;</span> (<span class="ruby-identifier">date</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">Fixnum</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">date</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">date</span>.<span class="ruby-identifier">year</span>) <span class="ruby-operator">==</span> <span class="ruby-identifier">year</span>) <span class="ruby-operator">?</span>
324 111: <span class="ruby-node">%(&lt;option value=&quot;#{year}&quot; selected=&quot;selected&quot;&gt;#{year}#{prefix}&lt;/option&gt;\n)</span> <span class="ruby-operator">:</span>
325 112: <span class="ruby-node">%(&lt;option value=&quot;#{year}&quot;&gt;#{year}#{prefix}&lt;/option&gt;\n)</span>
326 113: )
327 114: <span class="ruby-keyword kw">end</span>
328 115:
329 116: <span class="ruby-identifier">select_html</span>(<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:field_name</span>] <span class="ruby-operator">||</span> <span class="ruby-value str">'year'</span>, <span class="ruby-identifier">year_options</span>, <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:prefix</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:include_blank</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:discard_type</span>], <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:disabled</span>])
330 117: <span class="ruby-keyword kw">end</span>
331 </pre>
332 </div>
333 </div>
334 </div>
335
336
337 </div>
338
339
340 </div>
341
342
343 <div id="validator-badges">
344 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
345 </div>
346
347 </body>
348 </html> No newline at end of file
@@ -0,0 +1,167
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>Class: ActionView::Helpers::InstanceTag</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="classHeader">
50 <table class="header-table">
51 <tr class="top-aligned-row">
52 <td><strong>Class</strong></td>
53 <td class="class-name-in-header">ActionView::Helpers::InstanceTag</td>
54 </tr>
55 <tr class="top-aligned-row">
56 <td><strong>In:</strong></td>
57 <td>
58 <a href="../../../files/lib/gloc-rails-text_rb.html">
59 lib/gloc-rails-text.rb
60 </a>
61 <br />
62 <a href="../../../files/lib/gloc-rails_rb.html">
63 lib/gloc-rails.rb
64 </a>
65 <br />
66 </td>
67 </tr>
68
69 <tr class="top-aligned-row">
70 <td><strong>Parent:</strong></td>
71 <td>
72 Object
73 </td>
74 </tr>
75 </table>
76 </div>
77 <!-- banner header -->
78
79 <div id="bodyContent">
80
81
82
83 <div id="contextContent">
84
85 <div id="description">
86 <p>
87 The private method <tt>add_options</tt> is overridden so that &quot;Please
88 select&quot; is localized.
89 </p>
90
91 </div>
92
93
94 </div>
95
96 <div id="method-list">
97 <h3 class="section-bar">Methods</h3>
98
99 <div class="name-list">
100 <a href="#M000045">current_language</a>&nbsp;&nbsp;
101 </div>
102 </div>
103
104 </div>
105
106
107 <!-- if includes -->
108 <div id="includes">
109 <h3 class="section-bar">Included Modules</h3>
110
111 <div id="includes-list">
112 <span class="include-name"><a href="../../GLoc.html">GLoc</a></span>
113 </div>
114 </div>
115
116 <div id="section">
117
118
119
120
121
122
123
124
125 <!-- if method_list -->
126 <div id="methods">
127 <h3 class="section-bar">Public Instance methods</h3>
128
129 <div id="method-M000045" class="method-detail">
130 <a name="M000045"></a>
131
132 <div class="method-heading">
133 <a href="#M000045" class="method-signature">
134 <span class="method-name">current_language</span><span class="method-args">()</span>
135 </a>
136 </div>
137
138 <div class="method-description">
139 <p>
140 Inherits the current language from the template object.
141 </p>
142 <p><a class="source-toggle" href="#"
143 onclick="toggleCode('M000045-source');return false;">[Source]</a></p>
144 <div class="method-source-code" id="M000045-source">
145 <pre>
146 <span class="ruby-comment cmt"># File lib/gloc-rails.rb, line 119</span>
147 119: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">current_language</span>
148 120: <span class="ruby-ivar">@template_object</span>.<span class="ruby-identifier">current_language</span>
149 121: <span class="ruby-keyword kw">end</span>
150 </pre>
151 </div>
152 </div>
153 </div>
154
155
156 </div>
157
158
159 </div>
160
161
162 <div id="validator-badges">
163 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
164 </div>
165
166 </body>
167 </html> No newline at end of file
@@ -0,0 +1,215
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>Class: ActiveRecord::Errors</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="classHeader">
50 <table class="header-table">
51 <tr class="top-aligned-row">
52 <td><strong>Class</strong></td>
53 <td class="class-name-in-header">ActiveRecord::Errors</td>
54 </tr>
55 <tr class="top-aligned-row">
56 <td><strong>In:</strong></td>
57 <td>
58 <a href="../../files/lib/gloc-rails_rb.html">
59 lib/gloc-rails.rb
60 </a>
61 <br />
62 </td>
63 </tr>
64
65 <tr class="top-aligned-row">
66 <td><strong>Parent:</strong></td>
67 <td>
68 Object
69 </td>
70 </tr>
71 </table>
72 </div>
73 <!-- banner header -->
74
75 <div id="bodyContent">
76
77
78
79 <div id="contextContent">
80
81
82
83 </div>
84
85 <div id="method-list">
86 <h3 class="section-bar">Methods</h3>
87
88 <div class="name-list">
89 <a href="#M000039">add</a>&nbsp;&nbsp;
90 <a href="#M000040">current_language</a>&nbsp;&nbsp;
91 </div>
92 </div>
93
94 </div>
95
96
97 <!-- if includes -->
98 <div id="includes">
99 <h3 class="section-bar">Included Modules</h3>
100
101 <div id="includes-list">
102 <span class="include-name"><a href="../GLoc.html">GLoc</a></span>
103 </div>
104 </div>
105
106 <div id="section">
107
108
109
110 <div id="aliases-list">
111 <h3 class="section-bar">External Aliases</h3>
112
113 <div class="name-list">
114 <table summary="aliases">
115 <tr class="top-aligned-row context-row">
116 <td class="context-item-name">add</td>
117 <td>-></td>
118 <td class="context-item-value">add_without_gloc</td>
119 </tr>
120 </table>
121 </div>
122 </div>
123
124
125
126
127
128 <!-- if method_list -->
129 <div id="methods">
130 <h3 class="section-bar">Public Instance methods</h3>
131
132 <div id="method-M000039" class="method-detail">
133 <a name="M000039"></a>
134
135 <div class="method-heading">
136 <a href="#M000039" class="method-signature">
137 <span class="method-name">add</span><span class="method-args">(attribute, msg= @@default_error_messages[:invalid])</span>
138 </a>
139 </div>
140
141 <div class="method-description">
142 <p>
143 The <a href="../GLoc.html">GLoc</a> version of this method provides two
144 extra features
145 </p>
146 <ul>
147 <li>If <tt>msg</tt> is a string, it will be considered a <a
148 href="../GLoc.html">GLoc</a> string key.
149
150 </li>
151 <li>If <tt>msg</tt> is an array, the first element will be considered the
152 string and the remaining elements will be considered arguments for the
153 string. Eg. <tt>[&#8216;Hi %s.&#8217;,&#8217;John&#8217;]</tt>
154
155 </li>
156 </ul>
157 <p><a class="source-toggle" href="#"
158 onclick="toggleCode('M000039-source');return false;">[Source]</a></p>
159 <div class="method-source-code" id="M000039-source">
160 <pre>
161 <span class="ruby-comment cmt"># File lib/gloc-rails.rb, line 141</span>
162 141: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">add</span>(<span class="ruby-identifier">attribute</span>, <span class="ruby-identifier">msg</span>= <span class="ruby-ivar">@@default_error_messages</span>[<span class="ruby-identifier">:invalid</span>])
163 142: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">msg</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Array</span>)
164 143: <span class="ruby-identifier">args</span>= <span class="ruby-identifier">msg</span>.<span class="ruby-identifier">clone</span>
165 144: <span class="ruby-identifier">msg</span>= <span class="ruby-identifier">args</span>.<span class="ruby-identifier">shift</span>
166 145: <span class="ruby-identifier">args</span>= <span class="ruby-keyword kw">nil</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">args</span>.<span class="ruby-identifier">empty?</span>
167 146: <span class="ruby-keyword kw">end</span>
168 147: <span class="ruby-identifier">msg</span>= <span class="ruby-identifier">ltry</span>(<span class="ruby-identifier">msg</span>)
169 148: <span class="ruby-identifier">msg</span>= <span class="ruby-identifier">msg</span> <span class="ruby-operator">%</span> <span class="ruby-identifier">args</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">args</span>.<span class="ruby-identifier">nil?</span>
170 149: <span class="ruby-identifier">add_without_gloc</span>(<span class="ruby-identifier">attribute</span>, <span class="ruby-identifier">msg</span>)
171 150: <span class="ruby-keyword kw">end</span>
172 </pre>
173 </div>
174 </div>
175 </div>
176
177 <div id="method-M000040" class="method-detail">
178 <a name="M000040"></a>
179
180 <div class="method-heading">
181 <a href="#M000040" class="method-signature">
182 <span class="method-name">current_language</span><span class="method-args">()</span>
183 </a>
184 </div>
185
186 <div class="method-description">
187 <p>
188 Inherits the current language from the base record.
189 </p>
190 <p><a class="source-toggle" href="#"
191 onclick="toggleCode('M000040-source');return false;">[Source]</a></p>
192 <div class="method-source-code" id="M000040-source">
193 <pre>
194 <span class="ruby-comment cmt"># File lib/gloc-rails.rb, line 152</span>
195 152: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">current_language</span>
196 153: <span class="ruby-ivar">@base</span>.<span class="ruby-identifier">current_language</span>
197 154: <span class="ruby-keyword kw">end</span>
198 </pre>
199 </div>
200 </div>
201 </div>
202
203
204 </div>
205
206
207 </div>
208
209
210 <div id="validator-badges">
211 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
212 </div>
213
214 </body>
215 </html> No newline at end of file
@@ -0,0 +1,217
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>Module: ActiveRecord::Validations::ClassMethods</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="classHeader">
50 <table class="header-table">
51 <tr class="top-aligned-row">
52 <td><strong>Module</strong></td>
53 <td class="class-name-in-header">ActiveRecord::Validations::ClassMethods</td>
54 </tr>
55 <tr class="top-aligned-row">
56 <td><strong>In:</strong></td>
57 <td>
58 <a href="../../../files/lib/gloc-rails_rb.html">
59 lib/gloc-rails.rb
60 </a>
61 <br />
62 </td>
63 </tr>
64
65 </table>
66 </div>
67 <!-- banner header -->
68
69 <div id="bodyContent">
70
71
72
73 <div id="contextContent">
74
75
76
77 </div>
78
79 <div id="method-list">
80 <h3 class="section-bar">Methods</h3>
81
82 <div class="name-list">
83 <a href="#M000037">validates_length_of</a>&nbsp;&nbsp;
84 <a href="#M000038">validates_size_of</a>&nbsp;&nbsp;
85 </div>
86 </div>
87
88 </div>
89
90
91 <!-- if includes -->
92
93 <div id="section">
94
95
96
97
98
99
100
101
102 <!-- if method_list -->
103 <div id="methods">
104 <h3 class="section-bar">Public Instance methods</h3>
105
106 <div id="method-M000037" class="method-detail">
107 <a name="M000037"></a>
108
109 <div class="method-heading">
110 <a href="#M000037" class="method-signature">
111 <span class="method-name">validates_length_of</span><span class="method-args">(*attrs)</span>
112 </a>
113 </div>
114
115 <div class="method-description">
116 <p>
117 The default Rails version of this function creates an error message and
118 then passes it to <a href="../Errors.html">ActiveRecord.Errors</a>. The <a
119 href="../../GLoc.html">GLoc</a> version of this method, sends an array to
120 <a href="../Errors.html">ActiveRecord.Errors</a> that will be turned into a
121 string by <a href="../Errors.html">ActiveRecord.Errors</a> which in turn
122 allows for the message of this validation function to be a <a
123 href="../../GLoc.html">GLoc</a> string key.
124 </p>
125 <p><a class="source-toggle" href="#"
126 onclick="toggleCode('M000037-source');return false;">[Source]</a></p>
127 <div class="method-source-code" id="M000037-source">
128 <pre>
129 <span class="ruby-comment cmt"># File lib/gloc-rails.rb, line 164</span>
130 164: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">validates_length_of</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">attrs</span>)
131 165: <span class="ruby-comment cmt"># Merge given options with defaults.</span>
132 166: <span class="ruby-identifier">options</span> = {
133 167: <span class="ruby-identifier">:too_long</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-constant">ActiveRecord</span><span class="ruby-operator">::</span><span class="ruby-constant">Errors</span>.<span class="ruby-identifier">default_error_messages</span>[<span class="ruby-identifier">:too_long</span>],
134 168: <span class="ruby-identifier">:too_short</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-constant">ActiveRecord</span><span class="ruby-operator">::</span><span class="ruby-constant">Errors</span>.<span class="ruby-identifier">default_error_messages</span>[<span class="ruby-identifier">:too_short</span>],
135 169: <span class="ruby-identifier">:wrong_length</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-constant">ActiveRecord</span><span class="ruby-operator">::</span><span class="ruby-constant">Errors</span>.<span class="ruby-identifier">default_error_messages</span>[<span class="ruby-identifier">:wrong_length</span>]
136 170: }.<span class="ruby-identifier">merge</span>(<span class="ruby-constant">DEFAULT_VALIDATION_OPTIONS</span>)
137 171: <span class="ruby-identifier">options</span>.<span class="ruby-identifier">update</span>(<span class="ruby-identifier">attrs</span>.<span class="ruby-identifier">pop</span>.<span class="ruby-identifier">symbolize_keys</span>) <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">attrs</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Hash</span>)
138 172:
139 173: <span class="ruby-comment cmt"># Ensure that one and only one range option is specified.</span>
140 174: <span class="ruby-identifier">range_options</span> = <span class="ruby-constant">ALL_RANGE_OPTIONS</span> <span class="ruby-operator">&amp;</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">keys</span>
141 175: <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">range_options</span>.<span class="ruby-identifier">size</span>
142 176: <span class="ruby-keyword kw">when</span> <span class="ruby-value">0</span>
143 177: <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-value str">'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'</span>
144 178: <span class="ruby-keyword kw">when</span> <span class="ruby-value">1</span>
145 179: <span class="ruby-comment cmt"># Valid number of options; do nothing.</span>
146 180: <span class="ruby-keyword kw">else</span>
147 181: <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-value str">'Too many range options specified. Choose only one.'</span>
148 182: <span class="ruby-keyword kw">end</span>
149 183:
150 184: <span class="ruby-comment cmt"># Get range option and value.</span>
151 185: <span class="ruby-identifier">option</span> = <span class="ruby-identifier">range_options</span>.<span class="ruby-identifier">first</span>
152 186: <span class="ruby-identifier">option_value</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">range_options</span>.<span class="ruby-identifier">first</span>]
153 187:
154 188: <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">option</span>
155 189: <span class="ruby-keyword kw">when</span> <span class="ruby-identifier">:within</span>, <span class="ruby-identifier">:in</span>
156 190: <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-node">&quot;:#{option} must be a Range&quot;</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">option_value</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Range</span>)
157 191:
158 192: <span class="ruby-identifier">too_short</span> = [<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:too_short</span>] , <span class="ruby-identifier">option_value</span>.<span class="ruby-identifier">begin</span>]
159 193: <span class="ruby-identifier">too_long</span> = [<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:too_long</span>] , <span class="ruby-identifier">option_value</span>.<span class="ruby-identifier">end</span> ]
160 194:
161 195: <span class="ruby-identifier">validates_each</span>(<span class="ruby-identifier">attrs</span>, <span class="ruby-identifier">options</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">record</span>, <span class="ruby-identifier">attr</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
162 196: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-keyword kw">or</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">split</span>(<span class="ruby-regexp re">//</span>).<span class="ruby-identifier">size</span> <span class="ruby-operator">&lt;</span> <span class="ruby-identifier">option_value</span>.<span class="ruby-identifier">begin</span>
163 197: <span class="ruby-identifier">record</span>.<span class="ruby-identifier">errors</span>.<span class="ruby-identifier">add</span>(<span class="ruby-identifier">attr</span>, <span class="ruby-identifier">too_short</span>)
164 198: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">split</span>(<span class="ruby-regexp re">//</span>).<span class="ruby-identifier">size</span> <span class="ruby-operator">&gt;</span> <span class="ruby-identifier">option_value</span>.<span class="ruby-identifier">end</span>
165 199: <span class="ruby-identifier">record</span>.<span class="ruby-identifier">errors</span>.<span class="ruby-identifier">add</span>(<span class="ruby-identifier">attr</span>, <span class="ruby-identifier">too_long</span>)
166 200: <span class="ruby-keyword kw">end</span>
167 201: <span class="ruby-keyword kw">end</span>
168 202: <span class="ruby-keyword kw">when</span> <span class="ruby-identifier">:is</span>, <span class="ruby-identifier">:minimum</span>, <span class="ruby-identifier">:maximum</span>
169 203: <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-node">&quot;:#{option} must be a nonnegative Integer&quot;</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">option_value</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Integer</span>) <span class="ruby-keyword kw">and</span> <span class="ruby-identifier">option_value</span> <span class="ruby-operator">&gt;=</span> <span class="ruby-value">0</span>
170 204:
171 205: <span class="ruby-comment cmt"># Declare different validations per option.</span>
172 206: <span class="ruby-identifier">validity_checks</span> = { <span class="ruby-identifier">:is</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">&quot;==&quot;</span>, <span class="ruby-identifier">:minimum</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">&quot;&gt;=&quot;</span>, <span class="ruby-identifier">:maximum</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">&quot;&lt;=&quot;</span> }
173 207: <span class="ruby-identifier">message_options</span> = { <span class="ruby-identifier">:is</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:wrong_length</span>, <span class="ruby-identifier">:minimum</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:too_short</span>, <span class="ruby-identifier">:maximum</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:too_long</span> }
174 208:
175 209: <span class="ruby-identifier">message</span> = [(<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:message</span>] <span class="ruby-operator">||</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">message_options</span>[<span class="ruby-identifier">option</span>]]) , <span class="ruby-identifier">option_value</span>]
176 210:
177 211: <span class="ruby-identifier">validates_each</span>(<span class="ruby-identifier">attrs</span>, <span class="ruby-identifier">options</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">record</span>, <span class="ruby-identifier">attr</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
178 212: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">String</span>)
179 213: <span class="ruby-identifier">record</span>.<span class="ruby-identifier">errors</span>.<span class="ruby-identifier">add</span>(<span class="ruby-identifier">attr</span>, <span class="ruby-identifier">message</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-operator">!</span><span class="ruby-identifier">value</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-keyword kw">and</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">split</span>(<span class="ruby-regexp re">//</span>).<span class="ruby-identifier">size</span>.<span class="ruby-identifier">method</span>(<span class="ruby-identifier">validity_checks</span>[<span class="ruby-identifier">option</span>])[<span class="ruby-identifier">option_value</span>]
180 214: <span class="ruby-keyword kw">else</span>
181 215: <span class="ruby-identifier">record</span>.<span class="ruby-identifier">errors</span>.<span class="ruby-identifier">add</span>(<span class="ruby-identifier">attr</span>, <span class="ruby-identifier">message</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-operator">!</span><span class="ruby-identifier">value</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-keyword kw">and</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">size</span>.<span class="ruby-identifier">method</span>(<span class="ruby-identifier">validity_checks</span>[<span class="ruby-identifier">option</span>])[<span class="ruby-identifier">option_value</span>]
182 216: <span class="ruby-keyword kw">end</span>
183 217: <span class="ruby-keyword kw">end</span>
184 218: <span class="ruby-keyword kw">end</span>
185 219: <span class="ruby-keyword kw">end</span>
186 </pre>
187 </div>
188 </div>
189 </div>
190
191 <div id="method-M000038" class="method-detail">
192 <a name="M000038"></a>
193
194 <div class="method-heading">
195 <span class="method-name">validates_size_of</span><span class="method-args">(*attrs)</span>
196 </div>
197
198 <div class="method-description">
199 <p>
200 Alias for <a href="ClassMethods.html#M000037">validates_length_of</a>
201 </p>
202 </div>
203 </div>
204
205
206 </div>
207
208
209 </div>
210
211
212 <div id="validator-badges">
213 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
214 </div>
215
216 </body>
217 </html> No newline at end of file
This diff has been collapsed as it changes many lines, (774 lines changed) Show them Hide them
@@ -0,0 +1,774
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>Module: GLoc</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="classHeader">
50 <table class="header-table">
51 <tr class="top-aligned-row">
52 <td><strong>Module</strong></td>
53 <td class="class-name-in-header">GLoc</td>
54 </tr>
55 <tr class="top-aligned-row">
56 <td><strong>In:</strong></td>
57 <td>
58 <a href="../files/lib/gloc-helpers_rb.html">
59 lib/gloc-helpers.rb
60 </a>
61 <br />
62 <a href="../files/lib/gloc-internal_rb.html">
63 lib/gloc-internal.rb
64 </a>
65 <br />
66 <a href="../files/lib/gloc-version_rb.html">
67 lib/gloc-version.rb
68 </a>
69 <br />
70 <a href="../files/lib/gloc_rb.html">
71 lib/gloc.rb
72 </a>
73 <br />
74 </td>
75 </tr>
76
77 </table>
78 </div>
79 <!-- banner header -->
80
81 <div id="bodyContent">
82
83
84
85 <div id="contextContent">
86
87 <div id="description">
88 <p>
89 Copyright &#169; 2005-2006 David Barri
90 </p>
91
92 </div>
93
94
95 </div>
96
97 <div id="method-list">
98 <h3 class="section-bar">Methods</h3>
99
100 <div class="name-list">
101 <a href="#M000004">add_localized_strings</a>&nbsp;&nbsp;
102 <a href="#M000005">backup_state</a>&nbsp;&nbsp;
103 <a href="#M000006">clear_strings</a>&nbsp;&nbsp;
104 <a href="#M000007">clear_strings_except</a>&nbsp;&nbsp;
105 <a href="#M000002">current_language</a>&nbsp;&nbsp;
106 <a href="#M000003">current_language</a>&nbsp;&nbsp;
107 <a href="#M000008">get_charset</a>&nbsp;&nbsp;
108 <a href="#M000009">get_config</a>&nbsp;&nbsp;
109 <a href="#M000010">load_gloc_default_localized_strings</a>&nbsp;&nbsp;
110 <a href="#M000011">load_localized_strings</a>&nbsp;&nbsp;
111 <a href="#M000012">restore_state</a>&nbsp;&nbsp;
112 <a href="#M000013">set_charset</a>&nbsp;&nbsp;
113 <a href="#M000014">set_config</a>&nbsp;&nbsp;
114 <a href="#M000015">set_kcode</a>&nbsp;&nbsp;
115 <a href="#M000016">similar_language</a>&nbsp;&nbsp;
116 <a href="#M000018">valid_language?</a>&nbsp;&nbsp;
117 <a href="#M000017">valid_languages</a>&nbsp;&nbsp;
118 </div>
119 </div>
120
121 </div>
122
123
124 <!-- if includes -->
125 <div id="includes">
126 <h3 class="section-bar">Included Modules</h3>
127
128 <div id="includes-list">
129 <span class="include-name"><a href="GLoc/InstanceMethods.html">::GLoc::InstanceMethods</a></span>
130 <span class="include-name"><a href="GLoc/InstanceMethods.html">::GLoc::InstanceMethods</a></span>
131 </div>
132 </div>
133
134 <div id="section">
135
136 <div id="class-list">
137 <h3 class="section-bar">Classes and Modules</h3>
138
139 Module <a href="GLoc/ClassMethods.html" class="link">GLoc::ClassMethods</a><br />
140 Module <a href="GLoc/Helpers.html" class="link">GLoc::Helpers</a><br />
141 Module <a href="GLoc/InstanceMethods.html" class="link">GLoc::InstanceMethods</a><br />
142
143 </div>
144
145 <div id="constants-list">
146 <h3 class="section-bar">Constants</h3>
147
148 <div class="name-list">
149 <table summary="Constants">
150 <tr class="top-aligned-row context-row">
151 <td class="context-item-name">LOCALIZED_STRINGS</td>
152 <td>=</td>
153 <td class="context-item-value">{}</td>
154 </tr>
155 <tr class="top-aligned-row context-row">
156 <td class="context-item-name">RULES</td>
157 <td>=</td>
158 <td class="context-item-value">{}</td>
159 </tr>
160 <tr class="top-aligned-row context-row">
161 <td class="context-item-name">LOWERCASE_LANGUAGES</td>
162 <td>=</td>
163 <td class="context-item-value">{}</td>
164 </tr>
165 <tr class="top-aligned-row context-row">
166 <td class="context-item-name">UTF_8</td>
167 <td>=</td>
168 <td class="context-item-value">'utf-8'</td>
169 </tr>
170 <tr class="top-aligned-row context-row">
171 <td class="context-item-name">SHIFT_JIS</td>
172 <td>=</td>
173 <td class="context-item-value">'sjis'</td>
174 </tr>
175 <tr class="top-aligned-row context-row">
176 <td class="context-item-name">EUC_JP</td>
177 <td>=</td>
178 <td class="context-item-value">'euc-jp'</td>
179 </tr>
180 </table>
181 </div>
182 </div>
183
184 <div id="aliases-list">
185 <h3 class="section-bar">External Aliases</h3>
186
187 <div class="name-list">
188 <table summary="aliases">
189 <tr class="top-aligned-row context-row">
190 <td class="context-item-name">clear_strings</td>
191 <td>-></td>
192 <td class="context-item-value">_clear_strings</td>
193 </tr>
194 </table>
195 </div>
196 </div>
197
198
199
200
201
202 <!-- if method_list -->
203 <div id="methods">
204 <h3 class="section-bar">Public Class methods</h3>
205
206 <div id="method-M000004" class="method-detail">
207 <a name="M000004"></a>
208
209 <div class="method-heading">
210 <a href="#M000004" class="method-signature">
211 <span class="method-name">add_localized_strings</span><span class="method-args">(lang, symbol_hash, override=true, strings_charset=nil)</span>
212 </a>
213 </div>
214
215 <div class="method-description">
216 <p>
217 Adds a collection of localized strings to the in-memory string store.
218 </p>
219 <p><a class="source-toggle" href="#"
220 onclick="toggleCode('M000004-source');return false;">[Source]</a></p>
221 <div class="method-source-code" id="M000004-source">
222 <pre>
223 <span class="ruby-comment cmt"># File lib/gloc.rb, line 113</span>
224 113: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">add_localized_strings</span>(<span class="ruby-identifier">lang</span>, <span class="ruby-identifier">symbol_hash</span>, <span class="ruby-identifier">override</span>=<span class="ruby-keyword kw">true</span>, <span class="ruby-identifier">strings_charset</span>=<span class="ruby-keyword kw">nil</span>)
225 114: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">&quot;Adding #{symbol_hash.size} #{lang} strings.&quot;</span>}
226 115: <span class="ruby-identifier">_add_localized_strings</span>(<span class="ruby-identifier">lang</span>, <span class="ruby-identifier">symbol_hash</span>, <span class="ruby-identifier">override</span>, <span class="ruby-identifier">strings_charset</span>)
227 116: <span class="ruby-identifier">_verbose_msg</span> <span class="ruby-identifier">:stats</span>
228 117: <span class="ruby-keyword kw">end</span>
229 </pre>
230 </div>
231 </div>
232 </div>
233
234 <div id="method-M000005" class="method-detail">
235 <a name="M000005"></a>
236
237 <div class="method-heading">
238 <a href="#M000005" class="method-signature">
239 <span class="method-name">backup_state</span><span class="method-args">(clear=false)</span>
240 </a>
241 </div>
242
243 <div class="method-description">
244 <p>
245 Creates a backup of the internal state of <a href="GLoc.html">GLoc</a> (ie.
246 strings, langs, rules, config) and optionally clears everything.
247 </p>
248 <p><a class="source-toggle" href="#"
249 onclick="toggleCode('M000005-source');return false;">[Source]</a></p>
250 <div class="method-source-code" id="M000005-source">
251 <pre>
252 <span class="ruby-comment cmt"># File lib/gloc.rb, line 121</span>
253 121: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">backup_state</span>(<span class="ruby-identifier">clear</span>=<span class="ruby-keyword kw">false</span>)
254 122: <span class="ruby-identifier">s</span>= <span class="ruby-identifier">_get_internal_state_vars</span>.<span class="ruby-identifier">map</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">o</span><span class="ruby-operator">|</span> <span class="ruby-identifier">o</span>.<span class="ruby-identifier">clone</span>}
255 123: <span class="ruby-identifier">_get_internal_state_vars</span>.<span class="ruby-identifier">each</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">o</span><span class="ruby-operator">|</span> <span class="ruby-identifier">o</span>.<span class="ruby-identifier">clear</span>} <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">clear</span>
256 124: <span class="ruby-identifier">s</span>
257 125: <span class="ruby-keyword kw">end</span>
258 </pre>
259 </div>
260 </div>
261 </div>
262
263 <div id="method-M000006" class="method-detail">
264 <a name="M000006"></a>
265
266 <div class="method-heading">
267 <a href="#M000006" class="method-signature">
268 <span class="method-name">clear_strings</span><span class="method-args">(*languages)</span>
269 </a>
270 </div>
271
272 <div class="method-description">
273 <p>
274 Removes all localized strings from memory, either of a certain language (or
275 languages), or entirely.
276 </p>
277 <p><a class="source-toggle" href="#"
278 onclick="toggleCode('M000006-source');return false;">[Source]</a></p>
279 <div class="method-source-code" id="M000006-source">
280 <pre>
281 <span class="ruby-comment cmt"># File lib/gloc.rb, line 129</span>
282 129: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">clear_strings</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">languages</span>)
283 130: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">languages</span>.<span class="ruby-identifier">empty?</span>
284 131: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-value str">&quot;Clearing all strings&quot;</span>}
285 132: <span class="ruby-constant">LOCALIZED_STRINGS</span>.<span class="ruby-identifier">clear</span>
286 133: <span class="ruby-constant">LOWERCASE_LANGUAGES</span>.<span class="ruby-identifier">clear</span>
287 134: <span class="ruby-keyword kw">else</span>
288 135: <span class="ruby-identifier">languages</span>.<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">l</span><span class="ruby-operator">|</span>
289 136: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">&quot;Clearing :#{l} strings&quot;</span>}
290 137: <span class="ruby-identifier">l</span>= <span class="ruby-identifier">l</span>.<span class="ruby-identifier">to_sym</span>
291 138: <span class="ruby-constant">LOCALIZED_STRINGS</span>.<span class="ruby-identifier">delete</span> <span class="ruby-identifier">l</span>
292 139: <span class="ruby-constant">LOWERCASE_LANGUAGES</span>.<span class="ruby-identifier">each_pair</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">k</span>,<span class="ruby-identifier">v</span><span class="ruby-operator">|</span> <span class="ruby-constant">LOWERCASE_LANGUAGES</span>.<span class="ruby-identifier">delete</span> <span class="ruby-identifier">k</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">v</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">l</span>}
293 140: }
294 141: <span class="ruby-keyword kw">end</span>
295 142: <span class="ruby-keyword kw">end</span>
296 </pre>
297 </div>
298 </div>
299 </div>
300
301 <div id="method-M000007" class="method-detail">
302 <a name="M000007"></a>
303
304 <div class="method-heading">
305 <a href="#M000007" class="method-signature">
306 <span class="method-name">clear_strings_except</span><span class="method-args">(*languages)</span>
307 </a>
308 </div>
309
310 <div class="method-description">
311 <p>
312 Removes all localized strings from memory, except for those of certain
313 specified languages.
314 </p>
315 <p><a class="source-toggle" href="#"
316 onclick="toggleCode('M000007-source');return false;">[Source]</a></p>
317 <div class="method-source-code" id="M000007-source">
318 <pre>
319 <span class="ruby-comment cmt"># File lib/gloc.rb, line 146</span>
320 146: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">clear_strings_except</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">languages</span>)
321 147: <span class="ruby-identifier">clear</span>= (<span class="ruby-constant">LOCALIZED_STRINGS</span>.<span class="ruby-identifier">keys</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">languages</span>)
322 148: <span class="ruby-identifier">_clear_strings</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">clear</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">clear</span>.<span class="ruby-identifier">empty?</span>
323 149: <span class="ruby-keyword kw">end</span>
324 </pre>
325 </div>
326 </div>
327 </div>
328
329 <div id="method-M000003" class="method-detail">
330 <a name="M000003"></a>
331
332 <div class="method-heading">
333 <a href="#M000003" class="method-signature">
334 <span class="method-name">current_language</span><span class="method-args">()</span>
335 </a>
336 </div>
337
338 <div class="method-description">
339 <p>
340 Returns the default language
341 </p>
342 <p><a class="source-toggle" href="#"
343 onclick="toggleCode('M000003-source');return false;">[Source]</a></p>
344 <div class="method-source-code" id="M000003-source">
345 <pre>
346 <span class="ruby-comment cmt"># File lib/gloc.rb, line 108</span>
347 108: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">current_language</span>
348 109: <span class="ruby-constant">GLoc</span><span class="ruby-operator">::</span><span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:default_language</span>]
349 110: <span class="ruby-keyword kw">end</span>
350 </pre>
351 </div>
352 </div>
353 </div>
354
355 <div id="method-M000008" class="method-detail">
356 <a name="M000008"></a>
357
358 <div class="method-heading">
359 <a href="#M000008" class="method-signature">
360 <span class="method-name">get_charset</span><span class="method-args">(lang)</span>
361 </a>
362 </div>
363
364 <div class="method-description">
365 <p>
366 Returns the charset used to store localized strings in memory.
367 </p>
368 <p><a class="source-toggle" href="#"
369 onclick="toggleCode('M000008-source');return false;">[Source]</a></p>
370 <div class="method-source-code" id="M000008-source">
371 <pre>
372 <span class="ruby-comment cmt"># File lib/gloc.rb, line 152</span>
373 152: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">get_charset</span>(<span class="ruby-identifier">lang</span>)
374 153: <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:internal_charset_per_lang</span>][<span class="ruby-identifier">lang</span>] <span class="ruby-operator">||</span> <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:internal_charset</span>]
375 154: <span class="ruby-keyword kw">end</span>
376 </pre>
377 </div>
378 </div>
379 </div>
380
381 <div id="method-M000009" class="method-detail">
382 <a name="M000009"></a>
383
384 <div class="method-heading">
385 <a href="#M000009" class="method-signature">
386 <span class="method-name">get_config</span><span class="method-args">(key)</span>
387 </a>
388 </div>
389
390 <div class="method-description">
391 <p>
392 Returns a <a href="GLoc.html">GLoc</a> configuration value.
393 </p>
394 <p><a class="source-toggle" href="#"
395 onclick="toggleCode('M000009-source');return false;">[Source]</a></p>
396 <div class="method-source-code" id="M000009-source">
397 <pre>
398 <span class="ruby-comment cmt"># File lib/gloc.rb, line 157</span>
399 157: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">get_config</span>(<span class="ruby-identifier">key</span>)
400 158: <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">key</span>]
401 159: <span class="ruby-keyword kw">end</span>
402 </pre>
403 </div>
404 </div>
405 </div>
406
407 <div id="method-M000010" class="method-detail">
408 <a name="M000010"></a>
409
410 <div class="method-heading">
411 <a href="#M000010" class="method-signature">
412 <span class="method-name">load_gloc_default_localized_strings</span><span class="method-args">(override=false)</span>
413 </a>
414 </div>
415
416 <div class="method-description">
417 <p>
418 Loads the localized strings that are included in the <a
419 href="GLoc.html">GLoc</a> library.
420 </p>
421 <p><a class="source-toggle" href="#"
422 onclick="toggleCode('M000010-source');return false;">[Source]</a></p>
423 <div class="method-source-code" id="M000010-source">
424 <pre>
425 <span class="ruby-comment cmt"># File lib/gloc.rb, line 162</span>
426 162: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">load_gloc_default_localized_strings</span>(<span class="ruby-identifier">override</span>=<span class="ruby-keyword kw">false</span>)
427 163: <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">load_localized_strings</span> <span class="ruby-node">&quot;#{File.dirname(__FILE__)}/../lang&quot;</span>, <span class="ruby-identifier">override</span>
428 164: <span class="ruby-keyword kw">end</span>
429 </pre>
430 </div>
431 </div>
432 </div>
433
434 <div id="method-M000011" class="method-detail">
435 <a name="M000011"></a>
436
437 <div class="method-heading">
438 <a href="#M000011" class="method-signature">
439 <span class="method-name">load_localized_strings</span><span class="method-args">(dir=nil, override=true)</span>
440 </a>
441 </div>
442
443 <div class="method-description">
444 <p>
445 Loads localized strings from all yml files in the specifed directory.
446 </p>
447 <p><a class="source-toggle" href="#"
448 onclick="toggleCode('M000011-source');return false;">[Source]</a></p>
449 <div class="method-source-code" id="M000011-source">
450 <pre>
451 <span class="ruby-comment cmt"># File lib/gloc.rb, line 167</span>
452 167: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">load_localized_strings</span>(<span class="ruby-identifier">dir</span>=<span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">override</span>=<span class="ruby-keyword kw">true</span>)
453 168: <span class="ruby-identifier">_charset_required</span>
454 169: <span class="ruby-identifier">_get_lang_file_list</span>(<span class="ruby-identifier">dir</span>).<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">filename</span><span class="ruby-operator">|</span>
455 170:
456 171: <span class="ruby-comment cmt"># Load file</span>
457 172: <span class="ruby-identifier">raw_hash</span> = <span class="ruby-constant">YAML</span><span class="ruby-operator">::</span><span class="ruby-identifier">load</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">read</span>(<span class="ruby-identifier">filename</span>))
458 173: <span class="ruby-identifier">raw_hash</span>={} <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">raw_hash</span>.<span class="ruby-identifier">kind_of?</span>(<span class="ruby-constant">Hash</span>)
459 174: <span class="ruby-identifier">filename</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/([^\/\\]+)\.ya?ml$/</span>
460 175: <span class="ruby-identifier">lang</span> = <span class="ruby-identifier">$1</span>.<span class="ruby-identifier">to_sym</span>
461 176: <span class="ruby-identifier">file_charset</span> = <span class="ruby-identifier">raw_hash</span>[<span class="ruby-value str">'file_charset'</span>] <span class="ruby-operator">||</span> <span class="ruby-constant">UTF_8</span>
462 177:
463 178: <span class="ruby-comment cmt"># Convert string keys to symbols</span>
464 179: <span class="ruby-identifier">dest_charset</span>= <span class="ruby-identifier">get_charset</span>(<span class="ruby-identifier">lang</span>)
465 180: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">&quot;Reading file #{filename} [charset: #{file_charset} --&gt; #{dest_charset}]&quot;</span>}
466 181: <span class="ruby-identifier">symbol_hash</span> = {}
467 182: <span class="ruby-constant">Iconv</span>.<span class="ruby-identifier">open</span>(<span class="ruby-identifier">dest_charset</span>, <span class="ruby-identifier">file_charset</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
468 183: <span class="ruby-identifier">raw_hash</span>.<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">key</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
469 184: <span class="ruby-identifier">symbol_hash</span>[<span class="ruby-identifier">key</span>.<span class="ruby-identifier">to_sym</span>] = <span class="ruby-identifier">i</span>.<span class="ruby-identifier">iconv</span>(<span class="ruby-identifier">value</span>)
470 185: }
471 186: <span class="ruby-keyword kw">end</span>
472 187:
473 188: <span class="ruby-comment cmt"># Add strings to repos</span>
474 189: <span class="ruby-identifier">_add_localized_strings</span>(<span class="ruby-identifier">lang</span>, <span class="ruby-identifier">symbol_hash</span>, <span class="ruby-identifier">override</span>)
475 190: }
476 191: <span class="ruby-identifier">_verbose_msg</span> <span class="ruby-identifier">:stats</span>
477 192: <span class="ruby-keyword kw">end</span>
478 </pre>
479 </div>
480 </div>
481 </div>
482
483 <div id="method-M000012" class="method-detail">
484 <a name="M000012"></a>
485
486 <div class="method-heading">
487 <a href="#M000012" class="method-signature">
488 <span class="method-name">restore_state</span><span class="method-args">(state)</span>
489 </a>
490 </div>
491
492 <div class="method-description">
493 <p>
494 Restores a backup of <a href="GLoc.html">GLoc</a>&#8217;s internal state
495 that was made with <a href="GLoc.html#M000005">backup_state</a>.
496 </p>
497 <p><a class="source-toggle" href="#"
498 onclick="toggleCode('M000012-source');return false;">[Source]</a></p>
499 <div class="method-source-code" id="M000012-source">
500 <pre>
501 <span class="ruby-comment cmt"># File lib/gloc.rb, line 195</span>
502 195: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">restore_state</span>(<span class="ruby-identifier">state</span>)
503 196: <span class="ruby-identifier">_get_internal_state_vars</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">o</span><span class="ruby-operator">|</span>
504 197: <span class="ruby-identifier">o</span>.<span class="ruby-identifier">clear</span>
505 198: <span class="ruby-identifier">o</span>.<span class="ruby-identifier">send</span> <span class="ruby-identifier">o</span>.<span class="ruby-identifier">respond_to?</span>(<span class="ruby-identifier">:merge!</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">:merge!</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">:concat</span>, <span class="ruby-identifier">state</span>.<span class="ruby-identifier">shift</span>
506 199: <span class="ruby-keyword kw">end</span>
507 200: <span class="ruby-keyword kw">end</span>
508 </pre>
509 </div>
510 </div>
511 </div>
512
513 <div id="method-M000013" class="method-detail">
514 <a name="M000013"></a>
515
516 <div class="method-heading">
517 <a href="#M000013" class="method-signature">
518 <span class="method-name">set_charset</span><span class="method-args">(new_charset, *langs)</span>
519 </a>
520 </div>
521
522 <div class="method-description">
523 <p>
524 Sets the charset used to internally store localized strings. You can set
525 the charset to use for a specific language or languages, or if none are
526 specified the charset for ALL localized strings will be set.
527 </p>
528 <p><a class="source-toggle" href="#"
529 onclick="toggleCode('M000013-source');return false;">[Source]</a></p>
530 <div class="method-source-code" id="M000013-source">
531 <pre>
532 <span class="ruby-comment cmt"># File lib/gloc.rb, line 205</span>
533 205: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">set_charset</span>(<span class="ruby-identifier">new_charset</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">langs</span>)
534 206: <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:internal_charset_per_lang</span>] <span class="ruby-operator">||=</span> {}
535 207:
536 208: <span class="ruby-comment cmt"># Convert symbol shortcuts</span>
537 209: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">new_charset</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Symbol</span>)
538 210: <span class="ruby-identifier">new_charset</span>= <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">new_charset</span>
539 211: <span class="ruby-keyword kw">when</span> <span class="ruby-identifier">:utf8</span>, <span class="ruby-identifier">:utf_8</span> <span class="ruby-keyword kw">then</span> <span class="ruby-constant">UTF_8</span>
540 212: <span class="ruby-keyword kw">when</span> <span class="ruby-identifier">:sjis</span>, <span class="ruby-identifier">:shift_jis</span>, <span class="ruby-identifier">:shiftjis</span> <span class="ruby-keyword kw">then</span> <span class="ruby-constant">SHIFT_JIS</span>
541 213: <span class="ruby-keyword kw">when</span> <span class="ruby-identifier">:eucjp</span>, <span class="ruby-identifier">:euc_jp</span> <span class="ruby-keyword kw">then</span> <span class="ruby-constant">EUC_JP</span>
542 214: <span class="ruby-keyword kw">else</span> <span class="ruby-identifier">new_charset</span>.<span class="ruby-identifier">to_s</span>
543 215: <span class="ruby-keyword kw">end</span>
544 216: <span class="ruby-keyword kw">end</span>
545 217:
546 218: <span class="ruby-comment cmt"># Convert existing strings</span>
547 219: (<span class="ruby-identifier">langs</span>.<span class="ruby-identifier">empty?</span> <span class="ruby-value">? </span><span class="ruby-constant">LOCALIZED_STRINGS</span>.<span class="ruby-identifier">keys</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">langs</span>).<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">lang</span><span class="ruby-operator">|</span>
548 220: <span class="ruby-identifier">cur_charset</span>= <span class="ruby-identifier">get_charset</span>(<span class="ruby-identifier">lang</span>)
549 221: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">cur_charset</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">new_charset</span> <span class="ruby-operator">!=</span> <span class="ruby-identifier">cur_charset</span>
550 222: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">&quot;Converting :#{lang} strings from #{cur_charset} to #{new_charset}&quot;</span>}
551 223: <span class="ruby-constant">Iconv</span>.<span class="ruby-identifier">open</span>(<span class="ruby-identifier">new_charset</span>, <span class="ruby-identifier">cur_charset</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
552 224: <span class="ruby-identifier">bundle</span>= <span class="ruby-constant">LOCALIZED_STRINGS</span>[<span class="ruby-identifier">lang</span>]
553 225: <span class="ruby-identifier">bundle</span>.<span class="ruby-identifier">each_pair</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">k</span>,<span class="ruby-identifier">v</span><span class="ruby-operator">|</span> <span class="ruby-identifier">bundle</span>[<span class="ruby-identifier">k</span>]= <span class="ruby-identifier">i</span>.<span class="ruby-identifier">iconv</span>(<span class="ruby-identifier">v</span>)}
554 226: <span class="ruby-keyword kw">end</span>
555 227: <span class="ruby-keyword kw">end</span>
556 228: <span class="ruby-keyword kw">end</span>
557 229:
558 230: <span class="ruby-comment cmt"># Set new charset value</span>
559 231: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">langs</span>.<span class="ruby-identifier">empty?</span>
560 232: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">&quot;Setting GLoc charset for all languages to #{new_charset}&quot;</span>}
561 233: <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:internal_charset</span>]= <span class="ruby-identifier">new_charset</span>
562 234: <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:internal_charset_per_lang</span>].<span class="ruby-identifier">clear</span>
563 235: <span class="ruby-keyword kw">else</span>
564 236: <span class="ruby-identifier">langs</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">lang</span><span class="ruby-operator">|</span>
565 237: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">&quot;Setting GLoc charset for :#{lang} strings to #{new_charset}&quot;</span>}
566 238: <span class="ruby-constant">CONFIG</span>[<span class="ruby-identifier">:internal_charset_per_lang</span>][<span class="ruby-identifier">lang</span>]= <span class="ruby-identifier">new_charset</span>
567 239: <span class="ruby-keyword kw">end</span>
568 240: <span class="ruby-keyword kw">end</span>
569 241: <span class="ruby-keyword kw">end</span>
570 </pre>
571 </div>
572 </div>
573 </div>
574
575 <div id="method-M000014" class="method-detail">
576 <a name="M000014"></a>
577
578 <div class="method-heading">
579 <a href="#M000014" class="method-signature">
580 <span class="method-name">set_config</span><span class="method-args">(hash)</span>
581 </a>
582 </div>
583
584 <div class="method-description">
585 <p>
586 Sets <a href="GLoc.html">GLoc</a> configuration values.
587 </p>
588 <p><a class="source-toggle" href="#"
589 onclick="toggleCode('M000014-source');return false;">[Source]</a></p>
590 <div class="method-source-code" id="M000014-source">
591 <pre>
592 <span class="ruby-comment cmt"># File lib/gloc.rb, line 244</span>
593 244: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">set_config</span>(<span class="ruby-identifier">hash</span>)
594 245: <span class="ruby-constant">CONFIG</span>.<span class="ruby-identifier">merge!</span> <span class="ruby-identifier">hash</span>
595 246: <span class="ruby-keyword kw">end</span>
596 </pre>
597 </div>
598 </div>
599 </div>
600
601 <div id="method-M000015" class="method-detail">
602 <a name="M000015"></a>
603
604 <div class="method-heading">
605 <a href="#M000015" class="method-signature">
606 <span class="method-name">set_kcode</span><span class="method-args">(charset=nil)</span>
607 </a>
608 </div>
609
610 <div class="method-description">
611 <p>
612 Sets the $KCODE global variable according to a specified charset, or else
613 the current default charset for the default language.
614 </p>
615 <p><a class="source-toggle" href="#"
616 onclick="toggleCode('M000015-source');return false;">[Source]</a></p>
617 <div class="method-source-code" id="M000015-source">
618 <pre>
619 <span class="ruby-comment cmt"># File lib/gloc.rb, line 250</span>
620 250: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">set_kcode</span>(<span class="ruby-identifier">charset</span>=<span class="ruby-keyword kw">nil</span>)
621 251: <span class="ruby-identifier">_charset_required</span>
622 252: <span class="ruby-identifier">charset</span> <span class="ruby-operator">||=</span> <span class="ruby-identifier">get_charset</span>(<span class="ruby-identifier">current_language</span>)
623 253: <span class="ruby-identifier">$KCODE</span>= <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">charset</span>
624 254: <span class="ruby-keyword kw">when</span> <span class="ruby-constant">UTF_8</span> <span class="ruby-keyword kw">then</span> <span class="ruby-value str">'u'</span>
625 255: <span class="ruby-keyword kw">when</span> <span class="ruby-constant">SHIFT_JIS</span> <span class="ruby-keyword kw">then</span> <span class="ruby-value str">'s'</span>
626 256: <span class="ruby-keyword kw">when</span> <span class="ruby-constant">EUC_JP</span> <span class="ruby-keyword kw">then</span> <span class="ruby-value str">'e'</span>
627 257: <span class="ruby-keyword kw">else</span> <span class="ruby-value str">'n'</span>
628 258: <span class="ruby-keyword kw">end</span>
629 259: <span class="ruby-identifier">_verbose_msg</span> {<span class="ruby-node">&quot;$KCODE set to #{$KCODE}&quot;</span>}
630 260: <span class="ruby-keyword kw">end</span>
631 </pre>
632 </div>
633 </div>
634 </div>
635
636 <div id="method-M000016" class="method-detail">
637 <a name="M000016"></a>
638
639 <div class="method-heading">
640 <a href="#M000016" class="method-signature">
641 <span class="method-name">similar_language</span><span class="method-args">(lang)</span>
642 </a>
643 </div>
644
645 <div class="method-description">
646 <p>
647 Tries to find a valid language that is similar to the argument passed. Eg.
648 :en, :en_au, :EN_US are all similar languages. Returns <tt>nil</tt> if no
649 similar languages are found.
650 </p>
651 <p><a class="source-toggle" href="#"
652 onclick="toggleCode('M000016-source');return false;">[Source]</a></p>
653 <div class="method-source-code" id="M000016-source">
654 <pre>
655 <span class="ruby-comment cmt"># File lib/gloc.rb, line 265</span>
656 265: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">similar_language</span>(<span class="ruby-identifier">lang</span>)
657 266: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">nil</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">lang</span>.<span class="ruby-identifier">nil?</span>
658 267: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">lang</span>.<span class="ruby-identifier">to_sym</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">valid_language?</span>(<span class="ruby-identifier">lang</span>)
659 268: <span class="ruby-comment cmt"># Check lowercase without dashes</span>
660 269: <span class="ruby-identifier">lang</span>= <span class="ruby-identifier">lang</span>.<span class="ruby-identifier">to_s</span>.<span class="ruby-identifier">downcase</span>.<span class="ruby-identifier">gsub</span>(<span class="ruby-value str">'-'</span>,<span class="ruby-value str">'_'</span>)
661 270: <span class="ruby-keyword kw">return</span> <span class="ruby-constant">LOWERCASE_LANGUAGES</span>[<span class="ruby-identifier">lang</span>] <span class="ruby-keyword kw">if</span> <span class="ruby-constant">LOWERCASE_LANGUAGES</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">lang</span>)
662 271: <span class="ruby-comment cmt"># Check without dialect</span>
663 272: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">lang</span>.<span class="ruby-identifier">to_s</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/^([a-z]+?)[^a-z].*/</span>
664 273: <span class="ruby-identifier">lang</span>= <span class="ruby-identifier">$1</span>
665 274: <span class="ruby-keyword kw">return</span> <span class="ruby-constant">LOWERCASE_LANGUAGES</span>[<span class="ruby-identifier">lang</span>] <span class="ruby-keyword kw">if</span> <span class="ruby-constant">LOWERCASE_LANGUAGES</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">lang</span>)
666 275: <span class="ruby-keyword kw">end</span>
667 276: <span class="ruby-comment cmt"># Check other dialects</span>
668 277: <span class="ruby-identifier">lang</span>= <span class="ruby-node">&quot;#{lang}_&quot;</span>
669 278: <span class="ruby-constant">LOWERCASE_LANGUAGES</span>.<span class="ruby-identifier">keys</span>.<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">k</span><span class="ruby-operator">|</span> <span class="ruby-keyword kw">return</span> <span class="ruby-constant">LOWERCASE_LANGUAGES</span>[<span class="ruby-identifier">k</span>] <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">k</span>.<span class="ruby-identifier">starts_with?</span>(<span class="ruby-identifier">lang</span>)}
670 279: <span class="ruby-comment cmt"># Nothing found</span>
671 280: <span class="ruby-keyword kw">nil</span>
672 281: <span class="ruby-keyword kw">end</span>
673 </pre>
674 </div>
675 </div>
676 </div>
677
678 <div id="method-M000018" class="method-detail">
679 <a name="M000018"></a>
680
681 <div class="method-heading">
682 <a href="#M000018" class="method-signature">
683 <span class="method-name">valid_language?</span><span class="method-args">(language)</span>
684 </a>
685 </div>
686
687 <div class="method-description">
688 <p>
689 Returns <tt>true</tt> if there are any localized strings for a specified
690 language. Note that although <tt>set_langauge nil</tt> is perfectly valid,
691 <tt>nil</tt> is not a valid language.
692 </p>
693 <p><a class="source-toggle" href="#"
694 onclick="toggleCode('M000018-source');return false;">[Source]</a></p>
695 <div class="method-source-code" id="M000018-source">
696 <pre>
697 <span class="ruby-comment cmt"># File lib/gloc.rb, line 290</span>
698 290: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">valid_language?</span>(<span class="ruby-identifier">language</span>)
699 291: <span class="ruby-constant">LOCALIZED_STRINGS</span>.<span class="ruby-identifier">has_key?</span> <span class="ruby-identifier">language</span>.<span class="ruby-identifier">to_sym</span> <span class="ruby-keyword kw">rescue</span> <span class="ruby-keyword kw">false</span>
700 292: <span class="ruby-keyword kw">end</span>
701 </pre>
702 </div>
703 </div>
704 </div>
705
706 <div id="method-M000017" class="method-detail">
707 <a name="M000017"></a>
708
709 <div class="method-heading">
710 <a href="#M000017" class="method-signature">
711 <span class="method-name">valid_languages</span><span class="method-args">()</span>
712 </a>
713 </div>
714
715 <div class="method-description">
716 <p>
717 Returns an array of (currently) valid languages (ie. languages for which
718 localized data exists).
719 </p>
720 <p><a class="source-toggle" href="#"
721 onclick="toggleCode('M000017-source');return false;">[Source]</a></p>
722 <div class="method-source-code" id="M000017-source">
723 <pre>
724 <span class="ruby-comment cmt"># File lib/gloc.rb, line 284</span>
725 284: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">valid_languages</span>
726 285: <span class="ruby-constant">LOCALIZED_STRINGS</span>.<span class="ruby-identifier">keys</span>
727 286: <span class="ruby-keyword kw">end</span>
728 </pre>
729 </div>
730 </div>
731 </div>
732
733 <h3 class="section-bar">Public Instance methods</h3>
734
735 <div id="method-M000002" class="method-detail">
736 <a name="M000002"></a>
737
738 <div class="method-heading">
739 <a href="#M000002" class="method-signature">
740 <span class="method-name">current_language</span><span class="method-args">()</span>
741 </a>
742 </div>
743
744 <div class="method-description">
745 <p>
746 Returns the instance-level current language, or if not set, returns the
747 class-level current language.
748 </p>
749 <p><a class="source-toggle" href="#"
750 onclick="toggleCode('M000002-source');return false;">[Source]</a></p>
751 <div class="method-source-code" id="M000002-source">
752 <pre>
753 <span class="ruby-comment cmt"># File lib/gloc.rb, line 77</span>
754 77: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">current_language</span>
755 78: <span class="ruby-ivar">@gloc_language</span> <span class="ruby-operator">||</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">class</span>.<span class="ruby-identifier">current_language</span>
756 79: <span class="ruby-keyword kw">end</span>
757 </pre>
758 </div>
759 </div>
760 </div>
761
762
763 </div>
764
765
766 </div>
767
768
769 <div id="validator-badges">
770 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
771 </div>
772
773 </body>
774 </html> No newline at end of file
@@ -0,0 +1,160
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>Module: GLoc::ClassMethods</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="classHeader">
50 <table class="header-table">
51 <tr class="top-aligned-row">
52 <td><strong>Module</strong></td>
53 <td class="class-name-in-header">GLoc::ClassMethods</td>
54 </tr>
55 <tr class="top-aligned-row">
56 <td><strong>In:</strong></td>
57 <td>
58 <a href="../../files/lib/gloc_rb.html">
59 lib/gloc.rb
60 </a>
61 <br />
62 </td>
63 </tr>
64
65 </table>
66 </div>
67 <!-- banner header -->
68
69 <div id="bodyContent">
70
71
72
73 <div id="contextContent">
74
75 <div id="description">
76 <p>
77 All classes/modules that include <a href="../GLoc.html">GLoc</a> will also
78 gain these class methods. Notice that the <a
79 href="InstanceMethods.html">GLoc::InstanceMethods</a> module is also
80 included.
81 </p>
82
83 </div>
84
85
86 </div>
87
88 <div id="method-list">
89 <h3 class="section-bar">Methods</h3>
90
91 <div class="name-list">
92 <a href="#M000019">current_language</a>&nbsp;&nbsp;
93 </div>
94 </div>
95
96 </div>
97
98
99 <!-- if includes -->
100 <div id="includes">
101 <h3 class="section-bar">Included Modules</h3>
102
103 <div id="includes-list">
104 <span class="include-name"><a href="InstanceMethods.html">::GLoc::InstanceMethods</a></span>
105 </div>
106 </div>
107
108 <div id="section">
109
110
111
112
113
114
115
116
117 <!-- if method_list -->
118 <div id="methods">
119 <h3 class="section-bar">Public Instance methods</h3>
120
121 <div id="method-M000019" class="method-detail">
122 <a name="M000019"></a>
123
124 <div class="method-heading">
125 <a href="#M000019" class="method-signature">
126 <span class="method-name">current_language</span><span class="method-args">()</span>
127 </a>
128 </div>
129
130 <div class="method-description">
131 <p>
132 Returns the current language, or if not set, returns the <a
133 href="../GLoc.html">GLoc</a> current language.
134 </p>
135 <p><a class="source-toggle" href="#"
136 onclick="toggleCode('M000019-source');return false;">[Source]</a></p>
137 <div class="method-source-code" id="M000019-source">
138 <pre>
139 <span class="ruby-comment cmt"># File lib/gloc.rb, line 89</span>
140 89: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">current_language</span>
141 90: <span class="ruby-ivar">@gloc_language</span> <span class="ruby-operator">||</span> <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">current_language</span>
142 91: <span class="ruby-keyword kw">end</span>
143 </pre>
144 </div>
145 </div>
146 </div>
147
148
149 </div>
150
151
152 </div>
153
154
155 <div id="validator-badges">
156 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
157 </div>
158
159 </body>
160 </html> No newline at end of file
@@ -0,0 +1,323
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>Module: GLoc::Helpers</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="classHeader">
50 <table class="header-table">
51 <tr class="top-aligned-row">
52 <td><strong>Module</strong></td>
53 <td class="class-name-in-header">GLoc::Helpers</td>
54 </tr>
55 <tr class="top-aligned-row">
56 <td><strong>In:</strong></td>
57 <td>
58 <a href="../../files/lib/gloc-helpers_rb.html">
59 lib/gloc-helpers.rb
60 </a>
61 <br />
62 </td>
63 </tr>
64
65 </table>
66 </div>
67 <!-- banner header -->
68
69 <div id="bodyContent">
70
71
72
73 <div id="contextContent">
74
75 <div id="description">
76 <p>
77 These helper methods will be included in the <a
78 href="InstanceMethods.html">InstanceMethods</a> module.
79 </p>
80
81 </div>
82
83
84 </div>
85
86 <div id="method-list">
87 <h3 class="section-bar">Methods</h3>
88
89 <div class="name-list">
90 <a href="#M000026">l_YesNo</a>&nbsp;&nbsp;
91 <a href="#M000020">l_age</a>&nbsp;&nbsp;
92 <a href="#M000021">l_date</a>&nbsp;&nbsp;
93 <a href="#M000022">l_datetime</a>&nbsp;&nbsp;
94 <a href="#M000023">l_datetime_short</a>&nbsp;&nbsp;
95 <a href="#M000028">l_lang_name</a>&nbsp;&nbsp;
96 <a href="#M000024">l_strftime</a>&nbsp;&nbsp;
97 <a href="#M000025">l_time</a>&nbsp;&nbsp;
98 <a href="#M000027">l_yesno</a>&nbsp;&nbsp;
99 </div>
100 </div>
101
102 </div>
103
104
105 <!-- if includes -->
106
107 <div id="section">
108
109
110
111
112
113
114
115
116 <!-- if method_list -->
117 <div id="methods">
118 <h3 class="section-bar">Public Instance methods</h3>
119
120 <div id="method-M000026" class="method-detail">
121 <a name="M000026"></a>
122
123 <div class="method-heading">
124 <a href="#M000026" class="method-signature">
125 <span class="method-name">l_YesNo</span><span class="method-args">(value)</span>
126 </a>
127 </div>
128
129 <div class="method-description">
130 <p><a class="source-toggle" href="#"
131 onclick="toggleCode('M000026-source');return false;">[Source]</a></p>
132 <div class="method-source-code" id="M000026-source">
133 <pre>
134 <span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 12</span>
135 12: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_YesNo</span>(<span class="ruby-identifier">value</span>) <span class="ruby-identifier">l</span>(<span class="ruby-identifier">value</span> <span class="ruby-value">? </span><span class="ruby-operator">:</span><span class="ruby-identifier">general_text_Yes</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">:general_text_No</span>) <span class="ruby-keyword kw">end</span>
136 </pre>
137 </div>
138 </div>
139 </div>
140
141 <div id="method-M000020" class="method-detail">
142 <a name="M000020"></a>
143
144 <div class="method-heading">
145 <a href="#M000020" class="method-signature">
146 <span class="method-name">l_age</span><span class="method-args">(age)</span>
147 </a>
148 </div>
149
150 <div class="method-description">
151 <p><a class="source-toggle" href="#"
152 onclick="toggleCode('M000020-source');return false;">[Source]</a></p>
153 <div class="method-source-code" id="M000020-source">
154 <pre>
155 <span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 6</span>
156 6: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_age</span>(<span class="ruby-identifier">age</span>) <span class="ruby-identifier">lwr</span> <span class="ruby-operator">:</span><span class="ruby-identifier">general_fmt_age</span>, <span class="ruby-identifier">age</span> <span class="ruby-keyword kw">end</span>
157 </pre>
158 </div>
159 </div>
160 </div>
161
162 <div id="method-M000021" class="method-detail">
163 <a name="M000021"></a>
164
165 <div class="method-heading">
166 <a href="#M000021" class="method-signature">
167 <span class="method-name">l_date</span><span class="method-args">(date)</span>
168 </a>
169 </div>
170
171 <div class="method-description">
172 <p><a class="source-toggle" href="#"
173 onclick="toggleCode('M000021-source');return false;">[Source]</a></p>
174 <div class="method-source-code" id="M000021-source">
175 <pre>
176 <span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 7</span>
177 7: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_date</span>(<span class="ruby-identifier">date</span>) <span class="ruby-identifier">l_strftime</span> <span class="ruby-identifier">date</span>, <span class="ruby-identifier">:general_fmt_date</span> <span class="ruby-keyword kw">end</span>
178 </pre>
179 </div>
180 </div>
181 </div>
182
183 <div id="method-M000022" class="method-detail">
184 <a name="M000022"></a>
185
186 <div class="method-heading">
187 <a href="#M000022" class="method-signature">
188 <span class="method-name">l_datetime</span><span class="method-args">(date)</span>
189 </a>
190 </div>
191
192 <div class="method-description">
193 <p><a class="source-toggle" href="#"
194 onclick="toggleCode('M000022-source');return false;">[Source]</a></p>
195 <div class="method-source-code" id="M000022-source">
196 <pre>
197 <span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 8</span>
198 8: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_datetime</span>(<span class="ruby-identifier">date</span>) <span class="ruby-identifier">l_strftime</span> <span class="ruby-identifier">date</span>, <span class="ruby-identifier">:general_fmt_datetime</span> <span class="ruby-keyword kw">end</span>
199 </pre>
200 </div>
201 </div>
202 </div>
203
204 <div id="method-M000023" class="method-detail">
205 <a name="M000023"></a>
206
207 <div class="method-heading">
208 <a href="#M000023" class="method-signature">
209 <span class="method-name">l_datetime_short</span><span class="method-args">(date)</span>
210 </a>
211 </div>
212
213 <div class="method-description">
214 <p><a class="source-toggle" href="#"
215 onclick="toggleCode('M000023-source');return false;">[Source]</a></p>
216 <div class="method-source-code" id="M000023-source">
217 <pre>
218 <span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 9</span>
219 9: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_datetime_short</span>(<span class="ruby-identifier">date</span>) <span class="ruby-identifier">l_strftime</span> <span class="ruby-identifier">date</span>, <span class="ruby-identifier">:general_fmt_datetime_short</span> <span class="ruby-keyword kw">end</span>
220 </pre>
221 </div>
222 </div>
223 </div>
224
225 <div id="method-M000028" class="method-detail">
226 <a name="M000028"></a>
227
228 <div class="method-heading">
229 <a href="#M000028" class="method-signature">
230 <span class="method-name">l_lang_name</span><span class="method-args">(lang, display_lang=nil)</span>
231 </a>
232 </div>
233
234 <div class="method-description">
235 <p><a class="source-toggle" href="#"
236 onclick="toggleCode('M000028-source');return false;">[Source]</a></p>
237 <div class="method-source-code" id="M000028-source">
238 <pre>
239 <span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 15</span>
240 15: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_lang_name</span>(<span class="ruby-identifier">lang</span>, <span class="ruby-identifier">display_lang</span>=<span class="ruby-keyword kw">nil</span>)
241 16: <span class="ruby-identifier">ll</span> <span class="ruby-identifier">display_lang</span> <span class="ruby-operator">||</span> <span class="ruby-identifier">current_language</span>, <span class="ruby-node">&quot;general_lang_#{lang}&quot;</span>
242 17: <span class="ruby-keyword kw">end</span>
243 </pre>
244 </div>
245 </div>
246 </div>
247
248 <div id="method-M000024" class="method-detail">
249 <a name="M000024"></a>
250
251 <div class="method-heading">
252 <a href="#M000024" class="method-signature">
253 <span class="method-name">l_strftime</span><span class="method-args">(date,fmt)</span>
254 </a>
255 </div>
256
257 <div class="method-description">
258 <p><a class="source-toggle" href="#"
259 onclick="toggleCode('M000024-source');return false;">[Source]</a></p>
260 <div class="method-source-code" id="M000024-source">
261 <pre>
262 <span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 10</span>
263 10: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_strftime</span>(<span class="ruby-identifier">date</span>,<span class="ruby-identifier">fmt</span>) <span class="ruby-identifier">date</span>.<span class="ruby-identifier">strftime</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">fmt</span>) <span class="ruby-keyword kw">end</span>
264 </pre>
265 </div>
266 </div>
267 </div>
268
269 <div id="method-M000025" class="method-detail">
270 <a name="M000025"></a>
271
272 <div class="method-heading">
273 <a href="#M000025" class="method-signature">
274 <span class="method-name">l_time</span><span class="method-args">(time)</span>
275 </a>
276 </div>
277
278 <div class="method-description">
279 <p><a class="source-toggle" href="#"
280 onclick="toggleCode('M000025-source');return false;">[Source]</a></p>
281 <div class="method-source-code" id="M000025-source">
282 <pre>
283 <span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 11</span>
284 11: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_time</span>(<span class="ruby-identifier">time</span>) <span class="ruby-identifier">l_strftime</span> <span class="ruby-identifier">time</span>, <span class="ruby-identifier">:general_fmt_time</span> <span class="ruby-keyword kw">end</span>
285 </pre>
286 </div>
287 </div>
288 </div>
289
290 <div id="method-M000027" class="method-detail">
291 <a name="M000027"></a>
292
293 <div class="method-heading">
294 <a href="#M000027" class="method-signature">
295 <span class="method-name">l_yesno</span><span class="method-args">(value)</span>
296 </a>
297 </div>
298
299 <div class="method-description">
300 <p><a class="source-toggle" href="#"
301 onclick="toggleCode('M000027-source');return false;">[Source]</a></p>
302 <div class="method-source-code" id="M000027-source">
303 <pre>
304 <span class="ruby-comment cmt"># File lib/gloc-helpers.rb, line 13</span>
305 13: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_yesno</span>(<span class="ruby-identifier">value</span>) <span class="ruby-identifier">l</span>(<span class="ruby-identifier">value</span> <span class="ruby-value">? </span><span class="ruby-operator">:</span><span class="ruby-identifier">general_text_yes</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">:general_text_no</span>) <span class="ruby-keyword kw">end</span>
306 </pre>
307 </div>
308 </div>
309 </div>
310
311
312 </div>
313
314
315 </div>
316
317
318 <div id="validator-badges">
319 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
320 </div>
321
322 </body>
323 </html> No newline at end of file
@@ -0,0 +1,364
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>Module: GLoc::InstanceMethods</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="classHeader">
50 <table class="header-table">
51 <tr class="top-aligned-row">
52 <td><strong>Module</strong></td>
53 <td class="class-name-in-header">GLoc::InstanceMethods</td>
54 </tr>
55 <tr class="top-aligned-row">
56 <td><strong>In:</strong></td>
57 <td>
58 <a href="../../files/lib/gloc_rb.html">
59 lib/gloc.rb
60 </a>
61 <br />
62 </td>
63 </tr>
64
65 </table>
66 </div>
67 <!-- banner header -->
68
69 <div id="bodyContent">
70
71
72
73 <div id="contextContent">
74
75 <div id="description">
76 <p>
77 This module will be included in both instances and classes of <a
78 href="../GLoc.html">GLoc</a> includees. It is also included as class
79 methods in the <a href="../GLoc.html">GLoc</a> module itself.
80 </p>
81
82 </div>
83
84
85 </div>
86
87 <div id="method-list">
88 <h3 class="section-bar">Methods</h3>
89
90 <div class="name-list">
91 <a href="#M000029">l</a>&nbsp;&nbsp;
92 <a href="#M000034">l_has_string?</a>&nbsp;&nbsp;
93 <a href="#M000030">ll</a>&nbsp;&nbsp;
94 <a href="#M000031">ltry</a>&nbsp;&nbsp;
95 <a href="#M000032">lwr</a>&nbsp;&nbsp;
96 <a href="#M000033">lwr_</a>&nbsp;&nbsp;
97 <a href="#M000035">set_language</a>&nbsp;&nbsp;
98 <a href="#M000036">set_language_if_valid</a>&nbsp;&nbsp;
99 </div>
100 </div>
101
102 </div>
103
104
105 <!-- if includes -->
106 <div id="includes">
107 <h3 class="section-bar">Included Modules</h3>
108
109 <div id="includes-list">
110 <span class="include-name"><a href="Helpers.html">Helpers</a></span>
111 </div>
112 </div>
113
114 <div id="section">
115
116
117
118
119
120
121
122
123 <!-- if method_list -->
124 <div id="methods">
125 <h3 class="section-bar">Public Instance methods</h3>
126
127 <div id="method-M000029" class="method-detail">
128 <a name="M000029"></a>
129
130 <div class="method-heading">
131 <a href="#M000029" class="method-signature">
132 <span class="method-name">l</span><span class="method-args">(symbol, *arguments)</span>
133 </a>
134 </div>
135
136 <div class="method-description">
137 <p>
138 Returns a localized string.
139 </p>
140 <p><a class="source-toggle" href="#"
141 onclick="toggleCode('M000029-source');return false;">[Source]</a></p>
142 <div class="method-source-code" id="M000029-source">
143 <pre>
144 <span class="ruby-comment cmt"># File lib/gloc.rb, line 18</span>
145 18: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">symbol</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
146 19: <span class="ruby-keyword kw">return</span> <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">_l</span>(<span class="ruby-identifier">symbol</span>,<span class="ruby-identifier">current_language</span>,<span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
147 20: <span class="ruby-keyword kw">end</span>
148 </pre>
149 </div>
150 </div>
151 </div>
152
153 <div id="method-M000034" class="method-detail">
154 <a name="M000034"></a>
155
156 <div class="method-heading">
157 <a href="#M000034" class="method-signature">
158 <span class="method-name">l_has_string?</span><span class="method-args">(symbol)</span>
159 </a>
160 </div>
161
162 <div class="method-description">
163 <p>
164 Returns <tt>true</tt> if a localized string with the specified key exists.
165 </p>
166 <p><a class="source-toggle" href="#"
167 onclick="toggleCode('M000034-source');return false;">[Source]</a></p>
168 <div class="method-source-code" id="M000034-source">
169 <pre>
170 <span class="ruby-comment cmt"># File lib/gloc.rb, line 48</span>
171 48: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">l_has_string?</span>(<span class="ruby-identifier">symbol</span>)
172 49: <span class="ruby-keyword kw">return</span> <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">_l_has_string?</span>(<span class="ruby-identifier">symbol</span>,<span class="ruby-identifier">current_language</span>)
173 50: <span class="ruby-keyword kw">end</span>
174 </pre>
175 </div>
176 </div>
177 </div>
178
179 <div id="method-M000030" class="method-detail">
180 <a name="M000030"></a>
181
182 <div class="method-heading">
183 <a href="#M000030" class="method-signature">
184 <span class="method-name">ll</span><span class="method-args">(lang, symbol, *arguments)</span>
185 </a>
186 </div>
187
188 <div class="method-description">
189 <p>
190 Returns a localized string in a specified language. This does not effect
191 <tt>current_language</tt>.
192 </p>
193 <p><a class="source-toggle" href="#"
194 onclick="toggleCode('M000030-source');return false;">[Source]</a></p>
195 <div class="method-source-code" id="M000030-source">
196 <pre>
197 <span class="ruby-comment cmt"># File lib/gloc.rb, line 24</span>
198 24: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">ll</span>(<span class="ruby-identifier">lang</span>, <span class="ruby-identifier">symbol</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
199 25: <span class="ruby-keyword kw">return</span> <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">_l</span>(<span class="ruby-identifier">symbol</span>,<span class="ruby-identifier">lang</span>.<span class="ruby-identifier">to_sym</span>,<span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
200 26: <span class="ruby-keyword kw">end</span>
201 </pre>
202 </div>
203 </div>
204 </div>
205
206 <div id="method-M000031" class="method-detail">
207 <a name="M000031"></a>
208
209 <div class="method-heading">
210 <a href="#M000031" class="method-signature">
211 <span class="method-name">ltry</span><span class="method-args">(possible_key)</span>
212 </a>
213 </div>
214
215 <div class="method-description">
216 <p>
217 Returns a localized string if the argument is a Symbol, else just returns
218 the argument.
219 </p>
220 <p><a class="source-toggle" href="#"
221 onclick="toggleCode('M000031-source');return false;">[Source]</a></p>
222 <div class="method-source-code" id="M000031-source">
223 <pre>
224 <span class="ruby-comment cmt"># File lib/gloc.rb, line 29</span>
225 29: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">ltry</span>(<span class="ruby-identifier">possible_key</span>)
226 30: <span class="ruby-identifier">possible_key</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Symbol</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">l</span>(<span class="ruby-identifier">possible_key</span>) <span class="ruby-operator">:</span> <span class="ruby-identifier">possible_key</span>
227 31: <span class="ruby-keyword kw">end</span>
228 </pre>
229 </div>
230 </div>
231 </div>
232
233 <div id="method-M000032" class="method-detail">
234 <a name="M000032"></a>
235
236 <div class="method-heading">
237 <a href="#M000032" class="method-signature">
238 <span class="method-name">lwr</span><span class="method-args">(symbol, *arguments)</span>
239 </a>
240 </div>
241
242 <div class="method-description">
243 <p>
244 Uses the default <a href="../GLoc.html">GLoc</a> rule to return a localized
245 string. See lwr_() for more info.
246 </p>
247 <p><a class="source-toggle" href="#"
248 onclick="toggleCode('M000032-source');return false;">[Source]</a></p>
249 <div class="method-source-code" id="M000032-source">
250 <pre>
251 <span class="ruby-comment cmt"># File lib/gloc.rb, line 35</span>
252 35: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">lwr</span>(<span class="ruby-identifier">symbol</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
253 36: <span class="ruby-identifier">lwr_</span>(<span class="ruby-identifier">:default</span>, <span class="ruby-identifier">symbol</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
254 37: <span class="ruby-keyword kw">end</span>
255 </pre>
256 </div>
257 </div>
258 </div>
259
260 <div id="method-M000033" class="method-detail">
261 <a name="M000033"></a>
262
263 <div class="method-heading">
264 <a href="#M000033" class="method-signature">
265 <span class="method-name">lwr_</span><span class="method-args">(rule, symbol, *arguments)</span>
266 </a>
267 </div>
268
269 <div class="method-description">
270 <p>
271 Uses a <em>rule</em> to return a localized string. A rule is a function
272 that uses specified arguments to return a localization key prefix. The
273 prefix is appended to the localization key originally specified, to create
274 a new key which is then used to lookup a localized string.
275 </p>
276 <p><a class="source-toggle" href="#"
277 onclick="toggleCode('M000033-source');return false;">[Source]</a></p>
278 <div class="method-source-code" id="M000033-source">
279 <pre>
280 <span class="ruby-comment cmt"># File lib/gloc.rb, line 43</span>
281 43: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">lwr_</span>(<span class="ruby-identifier">rule</span>, <span class="ruby-identifier">symbol</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
282 44: <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">_l</span>(<span class="ruby-node">&quot;#{symbol}#{GLoc::_l_rule(rule,current_language).call(*arguments)}&quot;</span>,<span class="ruby-identifier">current_language</span>,<span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
283 45: <span class="ruby-keyword kw">end</span>
284 </pre>
285 </div>
286 </div>
287 </div>
288
289 <div id="method-M000035" class="method-detail">
290 <a name="M000035"></a>
291
292 <div class="method-heading">
293 <a href="#M000035" class="method-signature">
294 <span class="method-name">set_language</span><span class="method-args">(language)</span>
295 </a>
296 </div>
297
298 <div class="method-description">
299 <p>
300 Sets the current language for this instance/class. Setting the language of
301 a class effects all instances unless the instance has its own language
302 defined.
303 </p>
304 <p><a class="source-toggle" href="#"
305 onclick="toggleCode('M000035-source');return false;">[Source]</a></p>
306 <div class="method-source-code" id="M000035-source">
307 <pre>
308 <span class="ruby-comment cmt"># File lib/gloc.rb, line 54</span>
309 54: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">set_language</span>(<span class="ruby-identifier">language</span>)
310 55: <span class="ruby-ivar">@gloc_language</span>= <span class="ruby-identifier">language</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-value">? </span><span class="ruby-keyword kw">nil</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">language</span>.<span class="ruby-identifier">to_sym</span>
311 56: <span class="ruby-keyword kw">end</span>
312 </pre>
313 </div>
314 </div>
315 </div>
316
317 <div id="method-M000036" class="method-detail">
318 <a name="M000036"></a>
319
320 <div class="method-heading">
321 <a href="#M000036" class="method-signature">
322 <span class="method-name">set_language_if_valid</span><span class="method-args">(language)</span>
323 </a>
324 </div>
325
326 <div class="method-description">
327 <p>
328 Sets the current language if the language passed is a valid language. If
329 the language was valid, this method returns <tt>true</tt> else it will
330 return <tt>false</tt>. Note that <tt>nil</tt> is not a valid language. See
331 <a href="InstanceMethods.html#M000035">set_language</a>(language) for more
332 info.
333 </p>
334 <p><a class="source-toggle" href="#"
335 onclick="toggleCode('M000036-source');return false;">[Source]</a></p>
336 <div class="method-source-code" id="M000036-source">
337 <pre>
338 <span class="ruby-comment cmt"># File lib/gloc.rb, line 62</span>
339 62: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">set_language_if_valid</span>(<span class="ruby-identifier">language</span>)
340 63: <span class="ruby-keyword kw">if</span> <span class="ruby-constant">GLoc</span>.<span class="ruby-identifier">valid_language?</span>(<span class="ruby-identifier">language</span>)
341 64: <span class="ruby-identifier">set_language</span>(<span class="ruby-identifier">language</span>)
342 65: <span class="ruby-keyword kw">true</span>
343 66: <span class="ruby-keyword kw">else</span>
344 67: <span class="ruby-keyword kw">false</span>
345 68: <span class="ruby-keyword kw">end</span>
346 69: <span class="ruby-keyword kw">end</span>
347 </pre>
348 </div>
349 </div>
350 </div>
351
352
353 </div>
354
355
356 </div>
357
358
359 <div id="validator-badges">
360 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
361 </div>
362
363 </body>
364 </html> No newline at end of file
@@ -0,0 +1,1
1 Sun May 28 15:21:13 E. Australia Standard Time 2006
@@ -0,0 +1,153
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>File: CHANGELOG</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="fileHeader">
50 <h1>CHANGELOG</h1>
51 <table class="header-table">
52 <tr class="top-aligned-row">
53 <td><strong>Path:</strong></td>
54 <td>CHANGELOG
55 </td>
56 </tr>
57 <tr class="top-aligned-row">
58 <td><strong>Last Update:</strong></td>
59 <td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
60 </tr>
61 </table>
62 </div>
63 <!-- banner header -->
64
65 <div id="bodyContent">
66
67
68
69 <div id="contextContent">
70
71 <div id="description">
72 <h2>Version 1.1 (28 May 2006)</h2>
73 <ul>
74 <li>The charset for each and/or all languages can now be easily configured.
75
76 </li>
77 <li>Added a ActionController filter that auto-detects the client language.
78
79 </li>
80 <li>The rake task &quot;sort&quot; now merges lines that match 100%, and warns
81 if duplicate keys are found.
82
83 </li>
84 <li>Rule support. Create flexible rules to handle issues such as pluralization.
85
86 </li>
87 <li>Massive speed and stability improvements to development mode.
88
89 </li>
90 <li>Added Russian strings. (Thanks to Evgeny Lineytsev)
91
92 </li>
93 <li>Complete RDoc documentation.
94
95 </li>
96 <li>Improved helpers.
97
98 </li>
99 <li><a href="../classes/GLoc.html">GLoc</a> now configurable via get_config and
100 set_config
101
102 </li>
103 <li>Added an option to tell <a href="../classes/GLoc.html">GLoc</a> to output
104 various verbose information.
105
106 </li>
107 <li>More useful functions such as set_language_if_valid, similar_language
108
109 </li>
110 <li><a href="../classes/GLoc.html">GLoc</a>&#8217;s entire internal state can
111 now be backed up and restored.
112
113 </li>
114 </ul>
115 <h2>Version 1.0 (17 April 2006)</h2>
116 <ul>
117 <li>Initial public release.
118
119 </li>
120 </ul>
121
122 </div>
123
124
125 </div>
126
127
128 </div>
129
130
131 <!-- if includes -->
132
133 <div id="section">
134
135
136
137
138
139
140
141
142 <!-- if method_list -->
143
144
145 </div>
146
147
148 <div id="validator-badges">
149 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
150 </div>
151
152 </body>
153 </html> No newline at end of file
@@ -0,0 +1,480
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>File: README</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="fileHeader">
50 <h1>README</h1>
51 <table class="header-table">
52 <tr class="top-aligned-row">
53 <td><strong>Path:</strong></td>
54 <td>README
55 </td>
56 </tr>
57 <tr class="top-aligned-row">
58 <td><strong>Last Update:</strong></td>
59 <td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
60 </tr>
61 </table>
62 </div>
63 <!-- banner header -->
64
65 <div id="bodyContent">
66
67
68
69 <div id="contextContent">
70
71 <div id="description">
72 <h1>About</h1>
73 <h3>Preface</h3>
74 <p>
75 I originally started designing this on weekends and after work in 2005. We
76 started to become very interested in Rails at work and I wanted to get some
77 experience with ruby with before we started using it full-time. I
78 didn&#8217;t have very many ideas for anything interesting to create so,
79 because we write a lot of multilingual webapps at my company, I decided to
80 write a localization library. That way if my little hobby project developed
81 into something decent, I could at least put it to good use. And here we are
82 in 2006, my little hobby project has come a long way and become quite a
83 useful piece of software. Not only do I use it in production sites I write
84 at work, but I also prefer it to other existing alternatives. Therefore I
85 have decided to make it publicly available, and I hope that other
86 developers will find it useful too.
87 </p>
88 <h3>About</h3>
89 <p>
90 <a href="../classes/GLoc.html">GLoc</a> is a localization library. It
91 doesn&#8217;t aim to do everything l10n-related that you can imagine, but
92 what it does, it does very well. It was originally designed as a Rails
93 plugin, but can also be used for plain ruby projects. Here are a list of
94 its main features:
95 </p>
96 <ul>
97 <li>Lightweight and efficient.
98
99 </li>
100 <li>Uses file-based string bundles. Strings can also be set directly.
101
102 </li>
103 <li>Intelligent, cascading language configuration.
104
105 </li>
106 <li>Create flexible rules to handle issues such as pluralization.
107
108 </li>
109 <li>Includes a ActionController filter that auto-detects the client language.
110
111 </li>
112 <li>Works perfectly with Rails Engines and allows strings to be overridden just
113 as easily as controllers, models, etc.
114
115 </li>
116 <li>Automatically localizes Rails functions such as distance_in_minutes,
117 select_month etc
118
119 </li>
120 <li>Supports different charsets. You can even specify the encoding to use for
121 each language seperately.
122
123 </li>
124 <li>Special Rails mods/helpers.
125
126 </li>
127 </ul>
128 <h3>What does <a href="../classes/GLoc.html">GLoc</a> mean?</h3>
129 <p>
130 If you&#8217;re wondering about the name &quot;<a
131 href="../classes/GLoc.html">GLoc</a>&quot;, I&#8217;m sure you&#8217;re not
132 alone. This project was originally just called &quot;Localization&quot;
133 which was a bit too common, so when I decided to release it I decided to
134 call it &quot;Golly&#8217;s Localization Library&quot; instead (Golly is my
135 nickname), and that was long and boring so I then abbreviated that to
136 &quot;<a href="../classes/GLoc.html">GLoc</a>&quot;. What a fun story!!
137 </p>
138 <h3>Localization helpers</h3>
139 <p>
140 This also includes a few helpers for common situations such as displaying
141 localized date, time, &quot;yes&quot; or &quot;no&quot;, etc.
142 </p>
143 <h3>Rails Localization</h3>
144 <p>
145 At the moment, unless you manually remove the <tt>require
146 &#8216;gloc-rails-text&#8217;</tt> line from init.rb, this plugin overrides
147 certain Rails functions to provide multilingual versions. This
148 automatically localizes functions such as select_date(),
149 distance_of_time_in_words() and more&#8230; The strings can be found in
150 lang/*.yml. NOTE: This is not complete. Timezones and countries are not
151 currently localized.
152 </p>
153 <h1>Usage</h1>
154 <h3>Quickstart</h3>
155 <p>
156 Windows users will need to first install iconv. <a
157 href="http://wiki.rubyonrails.com/rails/pages/iconv">wiki.rubyonrails.com/rails/pages/iconv</a>
158 </p>
159 <ul>
160 <li>Create a dir &quot;#{RAILS_ROOT}/lang&quot;
161
162 </li>
163 <li>Create a file &quot;#{RAILS_ROOT}/lang/en.yml&quot; and write your strings.
164 The format is &quot;key: string&quot;. Save it as UTF-8. If you save it in
165 a different encoding, add a key called file_charset (eg.
166 &quot;file_charset: iso-2022-jp&quot;)
167
168 </li>
169 <li>Put the following in config/environment.rb and change the values as you see
170 fit. The following example is for an app that uses English and Japanese,
171 with Japanese being the default.
172
173 <pre>
174 GLoc.set_config :default_language =&gt; :ja
175 GLoc.clear_strings_except :en, :ja
176 GLoc.set_kcode
177 GLoc.load_localized_strings
178 </pre>
179 </li>
180 <li>Add &#8216;include <a href="../classes/GLoc.html">GLoc</a>&#8217; to all
181 classes that will use localization. This is added to most Rails classes
182 automatically.
183
184 </li>
185 <li>Optionally, you can set the language for models and controllers by simply
186 inserting <tt>set_language :en</tt> in classes and/or methods.
187
188 </li>
189 <li>To use localized strings, replace text such as <tt>&quot;Welcome&quot;</tt>
190 with <tt>l(:welcome_string_key)</tt>, and <tt>&quot;Hello
191 #{name}.&quot;</tt> with <tt>l(:hello_string_key, name)</tt>. (Of course
192 the strings will need to exist in your string bundle.)
193
194 </li>
195 </ul>
196 <p>
197 There is more functionality provided by this plugin, that is not
198 demonstrated above. Please read the API summary for details.
199 </p>
200 <h3>API summary</h3>
201 <p>
202 The following methods are added as both class methods and instance methods
203 to modules/classes that include <a href="../classes/GLoc.html">GLoc</a>.
204 They are also available as class methods of <a
205 href="../classes/GLoc.html">GLoc</a>.
206 </p>
207 <pre>
208 current_language # Returns the current language
209 l(symbol, *arguments) # Returns a localized string
210 ll(lang, symbol, *arguments) # Returns a localized string in a specific language
211 ltry(possible_key) # Returns a localized string if passed a Symbol, else returns the same argument passed
212 lwr(symbol, *arguments) # Uses the default rule to return a localized string.
213 lwr_(rule, symbol, *arguments) # Uses a specified rule to return a localized string.
214 l_has_string?(symbol) # Checks if a localized string exists
215 set_language(language) # Sets the language for the current class or class instance
216 set_language_if_valid(lang) # Sets the current language if the language passed is a valid language
217 </pre>
218 <p>
219 The <a href="../classes/GLoc.html">GLoc</a> module also defines the
220 following class methods:
221 </p>
222 <pre>
223 add_localized_strings(lang, symbol_hash, override=true) # Adds a hash of localized strings
224 backup_state(clear=false) # Creates a backup of GLoc's internal state and optionally clears everything too
225 clear_strings(*languages) # Removes localized strings from memory
226 clear_strings_except(*languages) # Removes localized strings from memory except for those of certain specified languages
227 get_charset(lang) # Returns the charset used to store localized strings in memory
228 get_config(key) # Returns a GLoc configuration value (see below)
229 load_localized_strings(dir=nil, override=true) # Loads localized strings from all YML files in a given directory
230 restore_state(state) # Restores a backup of GLoc's internal state
231 set_charset(new_charset, *langs) # Sets the charset used to internally store localized strings
232 set_config(hash) # Sets GLoc configuration values (see below)
233 set_kcode(charset=nil) # Sets the $KCODE global variable
234 similar_language(language) # Tries to find a valid language that is similar to the argument passed
235 valid_languages # Returns an array of (currently) valid languages (ie. languages for which localized data exists)
236 valid_language?(language) # Checks whether any localized strings are in memory for a given language
237 </pre>
238 <p>
239 <a href="../classes/GLoc.html">GLoc</a> uses the following configuration
240 items. They can be accessed via <tt>get_config</tt> and
241 <tt>set_config</tt>.
242 </p>
243 <pre>
244 :default_cookie_name
245 :default_language
246 :default_param_name
247 :raise_string_not_found_errors
248 :verbose
249 </pre>
250 <p>
251 The <a href="../classes/GLoc.html">GLoc</a> module is automatically
252 included in the following classes:
253 </p>
254 <pre>
255 ActionController::Base
256 ActionMailer::Base
257 ActionView::Base
258 ActionView::Helpers::InstanceTag
259 ActiveRecord::Base
260 ActiveRecord::Errors
261 ApplicationHelper
262 Test::Unit::TestCase
263 </pre>
264 <p>
265 The <a href="../classes/GLoc.html">GLoc</a> module also defines the
266 following controller filters:
267 </p>
268 <pre>
269 autodetect_language_filter
270 </pre>
271 <p>
272 <a href="../classes/GLoc.html">GLoc</a> also makes the following change to
273 Rails:
274 </p>
275 <ul>
276 <li>Views for ActionMailer are now #{view_name}_#{language}.rb rather than just
277 #{view_name}.rb
278
279 </li>
280 <li>All ActiveRecord validation class methods now accept a localized string key
281 (symbol) as a :message value.
282
283 </li>
284 <li><a
285 href="../classes/ActiveRecord/Errors.html#M000039">ActiveRecord::Errors.add</a>
286 now accepts symbols as valid message values. At runtime these symbols are
287 converted to localized strings using the current_language of the base
288 record.
289
290 </li>
291 <li><a
292 href="../classes/ActiveRecord/Errors.html#M000039">ActiveRecord::Errors.add</a>
293 now accepts arrays as arguments so that printf-style strings can be
294 generated at runtime. This also applies to the validates_* class methods.
295
296 <pre>
297 Eg. validates_xxxxxx_of :name, :message =&gt; ['Your name must be at least %d characters.', MIN_LEN]
298 Eg. validates_xxxxxx_of :name, :message =&gt; [:user_error_validation_name_too_short, MIN_LEN]
299 </pre>
300 </li>
301 <li>Instances of ActiveView inherit their current_language from the controller
302 (or mailer) creating them.
303
304 </li>
305 </ul>
306 <p>
307 This plugin also adds the following rake tasks:
308 </p>
309 <pre>
310 * gloc:sort - Sorts the keys in the lang ymls (also accepts a DIR argument)
311 </pre>
312 <h3>Cascading language configuration</h3>
313 <p>
314 The language can be set at three levels:
315 </p>
316 <pre>
317 1. The default # GLoc.get_config :default_language
318 2. Class level # class A; set_language :de; end
319 3. Instance level # b= B.new; b.set_language :zh
320 </pre>
321 <p>
322 Instance level has the highest priority and the default has the lowest.
323 </p>
324 <p>
325 Because <a href="../classes/GLoc.html">GLoc</a> is included at class level
326 too, it becomes easy to associate languages with contexts. For example:
327 </p>
328 <pre>
329 class Student
330 set_language :en
331 def say_hello
332 puts &quot;We say #{l :hello} but our teachers say #{Teacher.l :hello}&quot;
333 end
334 end
335 </pre>
336 <h3>Rules</h3>
337 <p>
338 There are often situations when depending on the value of one or more
339 variables, the surrounding text changes. The most common case of this is
340 pluralization. Rather than hardcode these rules, they are completely
341 definable by the user so that the user can eaasily accomodate for more
342 complicated grammatical rules such as those found in Russian and Polish (or
343 so I hear). To define a rule, simply include a string in the string bundle
344 whose key begins with &quot;<em>gloc_rule</em>&quot; and then write ruby
345 code as the value. The ruby code will be converted to a Proc when the
346 string bundle is first read, and should return a prefix that will be
347 appended to the string key at runtime to point to a new string. Make sense?
348 Probably not&#8230; Please look at the following example and I am sure it
349 will all make sense.
350 </p>
351 <p>
352 Simple example (string bundle / en.yml)
353 </p>
354 <pre>
355 _gloc_rule_default: ' |n| n==1 ? &quot;_single&quot; : &quot;_plural&quot; '
356 man_count_plural: There are %d men.
357 man_count_single: There is 1 man.
358 </pre>
359 <p>
360 Simple example (code)
361 </p>
362 <pre>
363 lwr(:man_count, 1) # =&gt; There is 1 man.
364 lwr(:man_count, 8) # =&gt; There are 8 men.
365 </pre>
366 <p>
367 To use rules other than the default simply call lwr_ instead of lwr, and
368 specify the rule.
369 </p>
370 <p>
371 Example 2 (string bundle / en.yml)
372 </p>
373 <pre>
374 _gloc_rule_default: ' |n| n==1 ? &quot;_single&quot; : &quot;_plural&quot; '
375 _gloc_rule_custom: ' |n| return &quot;_none&quot; if n==0; return &quot;_heaps&quot; if n&gt;100; n==1 ? &quot;_single&quot; : &quot;_plural&quot; '
376 man_count_none: There are no men.
377 man_count_heaps: There are heaps of men!!
378 man_count_plural: There are %d men.
379 man_count_single: There is 1 man.
380 </pre>
381 <p>
382 Example 2 (code)
383 </p>
384 <pre>
385 lwr_(:custom, :man_count, 0) # =&gt; There are no men.
386 lwr_(:custom, :man_count, 1) # =&gt; There is 1 man.
387 lwr_(:custom, :man_count, 8) # =&gt; There are 8 men.
388 lwr_(:custom, :man_count, 150) # =&gt; There are heaps of men!!
389 </pre>
390 <h3>Helpers</h3>
391 <p>
392 <a href="../classes/GLoc.html">GLoc</a> includes the following helpers:
393 </p>
394 <pre>
395 l_age(age) # Returns a localized version of an age. eg &quot;3 years old&quot;
396 l_date(date) # Returns a date in a localized format
397 l_datetime(date) # Returns a date+time in a localized format
398 l_datetime_short(date) # Returns a date+time in a localized short format.
399 l_lang_name(l,dl=nil) # Returns the name of a language (you must supply your own strings)
400 l_strftime(date,fmt) # Formats a date/time in a localized format.
401 l_time(date) # Returns a time in a localized format
402 l_YesNo(value) # Returns localized string of &quot;Yes&quot; or &quot;No&quot; depending on the arg
403 l_yesno(value) # Returns localized string of &quot;yes&quot; or &quot;no&quot; depending on the arg
404 </pre>
405 <h3>Rails localization</h3>
406 <p>
407 Not all of Rails is covered but the following functions are:
408 </p>
409 <pre>
410 distance_of_time_in_words
411 select_day
412 select_month
413 select_year
414 add_options
415 </pre>
416 <h1>FAQ</h1>
417 <h4>How do I use it in engines?</h4>
418 <p>
419 Simply put this in your init_engine.rb
420 </p>
421 <pre>
422 GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
423 </pre>
424 <p>
425 That way your engines strings will be loaded when the engine is started.
426 Just simply make sure that you load your application strings after you
427 start your engines to safely override any engine strings.
428 </p>
429 <h4>Why am I getting an Iconv::IllegalSequence error when calling <a href="../classes/GLoc.html#M000013">GLoc.set_charset</a>?</h4>
430 <p>
431 By default <a href="../classes/GLoc.html">GLoc</a> loads all of its default
432 strings at startup. For example, calling <tt>set_charset
433 &#8216;iso-2022-jp&#8217;</tt> will cause this error because Russian
434 strings are loaded by default, and the Russian strings use characters that
435 cannot be expressed in the ISO-2022-JP charset. Before calling
436 <tt>set_charset</tt> you should call <tt>clear_strings_except</tt> to
437 remove strings from any languages that you will not be using.
438 Alternatively, you can simply specify the language(s) as follows,
439 <tt>set_charset &#8216;iso-2022-jp&#8217;, :ja</tt>.
440 </p>
441 <h4>How do I make <a href="../classes/GLoc.html">GLoc</a> ignore StringNotFoundErrors?</h4>
442 <p>
443 Disable it as follows:
444 </p>
445 <pre>
446 GLoc.set_config :raise_string_not_found_errors =&gt; false
447 </pre>
448
449 </div>
450
451
452 </div>
453
454
455 </div>
456
457
458 <!-- if includes -->
459
460 <div id="section">
461
462
463
464
465
466
467
468
469 <!-- if method_list -->
470
471
472 </div>
473
474
475 <div id="validator-badges">
476 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
477 </div>
478
479 </body>
480 </html> No newline at end of file
@@ -0,0 +1,107
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>File: gloc-helpers.rb</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="fileHeader">
50 <h1>gloc-helpers.rb</h1>
51 <table class="header-table">
52 <tr class="top-aligned-row">
53 <td><strong>Path:</strong></td>
54 <td>lib/gloc-helpers.rb
55 </td>
56 </tr>
57 <tr class="top-aligned-row">
58 <td><strong>Last Update:</strong></td>
59 <td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
60 </tr>
61 </table>
62 </div>
63 <!-- banner header -->
64
65 <div id="bodyContent">
66
67
68
69 <div id="contextContent">
70
71 <div id="description">
72 <p>
73 Copyright &#169; 2005-2006 David Barri
74 </p>
75
76 </div>
77
78
79 </div>
80
81
82 </div>
83
84
85 <!-- if includes -->
86
87 <div id="section">
88
89
90
91
92
93
94
95
96 <!-- if method_list -->
97
98
99 </div>
100
101
102 <div id="validator-badges">
103 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
104 </div>
105
106 </body>
107 </html> No newline at end of file
@@ -0,0 +1,115
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>File: gloc-internal.rb</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="fileHeader">
50 <h1>gloc-internal.rb</h1>
51 <table class="header-table">
52 <tr class="top-aligned-row">
53 <td><strong>Path:</strong></td>
54 <td>lib/gloc-internal.rb
55 </td>
56 </tr>
57 <tr class="top-aligned-row">
58 <td><strong>Last Update:</strong></td>
59 <td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
60 </tr>
61 </table>
62 </div>
63 <!-- banner header -->
64
65 <div id="bodyContent">
66
67
68
69 <div id="contextContent">
70
71 <div id="description">
72 <p>
73 Copyright &#169; 2005-2006 David Barri
74 </p>
75
76 </div>
77
78 <div id="requires-list">
79 <h3 class="section-bar">Required files</h3>
80
81 <div class="name-list">
82 iconv&nbsp;&nbsp;
83 gloc-version&nbsp;&nbsp;
84 </div>
85 </div>
86
87 </div>
88
89
90 </div>
91
92
93 <!-- if includes -->
94
95 <div id="section">
96
97
98
99
100
101
102
103
104 <!-- if method_list -->
105
106
107 </div>
108
109
110 <div id="validator-badges">
111 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
112 </div>
113
114 </body>
115 </html> No newline at end of file
@@ -0,0 +1,114
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>File: gloc-rails-text.rb</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="fileHeader">
50 <h1>gloc-rails-text.rb</h1>
51 <table class="header-table">
52 <tr class="top-aligned-row">
53 <td><strong>Path:</strong></td>
54 <td>lib/gloc-rails-text.rb
55 </td>
56 </tr>
57 <tr class="top-aligned-row">
58 <td><strong>Last Update:</strong></td>
59 <td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
60 </tr>
61 </table>
62 </div>
63 <!-- banner header -->
64
65 <div id="bodyContent">
66
67
68
69 <div id="contextContent">
70
71 <div id="description">
72 <p>
73 Copyright &#169; 2005-2006 David Barri
74 </p>
75
76 </div>
77
78 <div id="requires-list">
79 <h3 class="section-bar">Required files</h3>
80
81 <div class="name-list">
82 date&nbsp;&nbsp;
83 </div>
84 </div>
85
86 </div>
87
88
89 </div>
90
91
92 <!-- if includes -->
93
94 <div id="section">
95
96
97
98
99
100
101
102
103 <!-- if method_list -->
104
105
106 </div>
107
108
109 <div id="validator-badges">
110 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
111 </div>
112
113 </body>
114 </html> No newline at end of file
@@ -0,0 +1,114
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>File: gloc-rails.rb</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="fileHeader">
50 <h1>gloc-rails.rb</h1>
51 <table class="header-table">
52 <tr class="top-aligned-row">
53 <td><strong>Path:</strong></td>
54 <td>lib/gloc-rails.rb
55 </td>
56 </tr>
57 <tr class="top-aligned-row">
58 <td><strong>Last Update:</strong></td>
59 <td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
60 </tr>
61 </table>
62 </div>
63 <!-- banner header -->
64
65 <div id="bodyContent">
66
67
68
69 <div id="contextContent">
70
71 <div id="description">
72 <p>
73 Copyright &#169; 2005-2006 David Barri
74 </p>
75
76 </div>
77
78 <div id="requires-list">
79 <h3 class="section-bar">Required files</h3>
80
81 <div class="name-list">
82 gloc&nbsp;&nbsp;
83 </div>
84 </div>
85
86 </div>
87
88
89 </div>
90
91
92 <!-- if includes -->
93
94 <div id="section">
95
96
97
98
99
100
101
102
103 <!-- if method_list -->
104
105
106 </div>
107
108
109 <div id="validator-badges">
110 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
111 </div>
112
113 </body>
114 </html> No newline at end of file
@@ -0,0 +1,107
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>File: gloc-ruby.rb</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="fileHeader">
50 <h1>gloc-ruby.rb</h1>
51 <table class="header-table">
52 <tr class="top-aligned-row">
53 <td><strong>Path:</strong></td>
54 <td>lib/gloc-ruby.rb
55 </td>
56 </tr>
57 <tr class="top-aligned-row">
58 <td><strong>Last Update:</strong></td>
59 <td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
60 </tr>
61 </table>
62 </div>
63 <!-- banner header -->
64
65 <div id="bodyContent">
66
67
68
69 <div id="contextContent">
70
71 <div id="description">
72 <p>
73 Copyright &#169; 2005-2006 David Barri
74 </p>
75
76 </div>
77
78
79 </div>
80
81
82 </div>
83
84
85 <!-- if includes -->
86
87 <div id="section">
88
89
90
91
92
93
94
95
96 <!-- if method_list -->
97
98
99 </div>
100
101
102 <div id="validator-badges">
103 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
104 </div>
105
106 </body>
107 </html> No newline at end of file
@@ -0,0 +1,101
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>File: gloc-version.rb</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="fileHeader">
50 <h1>gloc-version.rb</h1>
51 <table class="header-table">
52 <tr class="top-aligned-row">
53 <td><strong>Path:</strong></td>
54 <td>lib/gloc-version.rb
55 </td>
56 </tr>
57 <tr class="top-aligned-row">
58 <td><strong>Last Update:</strong></td>
59 <td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
60 </tr>
61 </table>
62 </div>
63 <!-- banner header -->
64
65 <div id="bodyContent">
66
67
68
69 <div id="contextContent">
70
71
72
73 </div>
74
75
76 </div>
77
78
79 <!-- if includes -->
80
81 <div id="section">
82
83
84
85
86
87
88
89
90 <!-- if method_list -->
91
92
93 </div>
94
95
96 <div id="validator-badges">
97 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
98 </div>
99
100 </body>
101 </html> No newline at end of file
@@ -0,0 +1,116
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <title>File: gloc.rb</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
13 // <![CDATA[
14
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17 }
18
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
24 else
25 return false;
26
27 elemStyle = elem.style;
28
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
31 } else {
32 elemStyle.display = "none"
33 }
34
35 return true;
36 }
37
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
41 // ]]>
42 </script>
43
44 </head>
45 <body>
46
47
48
49 <div id="fileHeader">
50 <h1>gloc.rb</h1>
51 <table class="header-table">
52 <tr class="top-aligned-row">
53 <td><strong>Path:</strong></td>
54 <td>lib/gloc.rb
55 </td>
56 </tr>
57 <tr class="top-aligned-row">
58 <td><strong>Last Update:</strong></td>
59 <td>Sun May 28 15:19:38 E. Australia Standard Time 2006</td>
60 </tr>
61 </table>
62 </div>
63 <!-- banner header -->
64
65 <div id="bodyContent">
66
67
68
69 <div id="contextContent">
70
71 <div id="description">
72 <p>
73 Copyright &#169; 2005-2006 David Barri
74 </p>
75
76 </div>
77
78 <div id="requires-list">
79 <h3 class="section-bar">Required files</h3>
80
81 <div class="name-list">
82 yaml&nbsp;&nbsp;
83 gloc-internal&nbsp;&nbsp;
84 gloc-helpers&nbsp;&nbsp;
85 </div>
86 </div>
87
88 </div>
89
90
91 </div>
92
93
94 <!-- if includes -->
95
96 <div id="section">
97
98
99
100
101
102
103
104
105 <!-- if method_list -->
106
107
108 </div>
109
110
111 <div id="validator-badges">
112 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
113 </div>
114
115 </body>
116 </html> No newline at end of file
@@ -0,0 +1,37
1
2 <?xml version="1.0" encoding="iso-8859-1"?>
3 <!DOCTYPE html
4 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
7 <!--
8
9 Classes
10
11 -->
12 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
13 <head>
14 <title>Classes</title>
15 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
16 <link rel="stylesheet" href="rdoc-style.css" type="text/css" />
17 <base target="docwin" />
18 </head>
19 <body>
20 <div id="index">
21 <h1 class="section-bar">Classes</h1>
22 <div id="index-entries">
23 <a href="classes/ActionController/Filters/ClassMethods.html">ActionController::Filters::ClassMethods</a><br />
24 <a href="classes/ActionMailer/Base.html">ActionMailer::Base</a><br />
25 <a href="classes/ActionView/Base.html">ActionView::Base</a><br />
26 <a href="classes/ActionView/Helpers/DateHelper.html">ActionView::Helpers::DateHelper</a><br />
27 <a href="classes/ActionView/Helpers/InstanceTag.html">ActionView::Helpers::InstanceTag</a><br />
28 <a href="classes/ActiveRecord/Errors.html">ActiveRecord::Errors</a><br />
29 <a href="classes/ActiveRecord/Validations/ClassMethods.html">ActiveRecord::Validations::ClassMethods</a><br />
30 <a href="classes/GLoc.html">GLoc</a><br />
31 <a href="classes/GLoc/ClassMethods.html">GLoc::ClassMethods</a><br />
32 <a href="classes/GLoc/Helpers.html">GLoc::Helpers</a><br />
33 <a href="classes/GLoc/InstanceMethods.html">GLoc::InstanceMethods</a><br />
34 </div>
35 </div>
36 </body>
37 </html> No newline at end of file
@@ -0,0 +1,35
1
2 <?xml version="1.0" encoding="iso-8859-1"?>
3 <!DOCTYPE html
4 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
7 <!--
8
9 Files
10
11 -->
12 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
13 <head>
14 <title>Files</title>
15 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
16 <link rel="stylesheet" href="rdoc-style.css" type="text/css" />
17 <base target="docwin" />
18 </head>
19 <body>
20 <div id="index">
21 <h1 class="section-bar">Files</h1>
22 <div id="index-entries">
23 <a href="files/CHANGELOG.html">CHANGELOG</a><br />
24 <a href="files/README.html">README</a><br />
25 <a href="files/lib/gloc-helpers_rb.html">lib/gloc-helpers.rb</a><br />
26 <a href="files/lib/gloc-internal_rb.html">lib/gloc-internal.rb</a><br />
27 <a href="files/lib/gloc-rails-text_rb.html">lib/gloc-rails-text.rb</a><br />
28 <a href="files/lib/gloc-rails_rb.html">lib/gloc-rails.rb</a><br />
29 <a href="files/lib/gloc-ruby_rb.html">lib/gloc-ruby.rb</a><br />
30 <a href="files/lib/gloc-version_rb.html">lib/gloc-version.rb</a><br />
31 <a href="files/lib/gloc_rb.html">lib/gloc.rb</a><br />
32 </div>
33 </div>
34 </body>
35 </html> No newline at end of file
@@ -0,0 +1,72
1
2 <?xml version="1.0" encoding="iso-8859-1"?>
3 <!DOCTYPE html
4 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
7 <!--
8
9 Methods
10
11 -->
12 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
13 <head>
14 <title>Methods</title>
15 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
16 <link rel="stylesheet" href="rdoc-style.css" type="text/css" />
17 <base target="docwin" />
18 </head>
19 <body>
20 <div id="index">
21 <h1 class="section-bar">Methods</h1>
22 <div id="index-entries">
23 <a href="classes/ActiveRecord/Errors.html#M000039">add (ActiveRecord::Errors)</a><br />
24 <a href="classes/GLoc.html#M000004">add_localized_strings (GLoc)</a><br />
25 <a href="classes/ActionController/Filters/ClassMethods.html#M000001">autodetect_language_filter (ActionController::Filters::ClassMethods)</a><br />
26 <a href="classes/GLoc.html#M000005">backup_state (GLoc)</a><br />
27 <a href="classes/GLoc.html#M000006">clear_strings (GLoc)</a><br />
28 <a href="classes/GLoc.html#M000007">clear_strings_except (GLoc)</a><br />
29 <a href="classes/GLoc/ClassMethods.html#M000019">current_language (GLoc::ClassMethods)</a><br />
30 <a href="classes/GLoc.html#M000003">current_language (GLoc)</a><br />
31 <a href="classes/GLoc.html#M000002">current_language (GLoc)</a><br />
32 <a href="classes/ActionView/Helpers/InstanceTag.html#M000045">current_language (ActionView::Helpers::InstanceTag)</a><br />
33 <a href="classes/ActiveRecord/Errors.html#M000040">current_language (ActiveRecord::Errors)</a><br />
34 <a href="classes/ActionView/Helpers/DateHelper.html#M000041">distance_of_time_in_words (ActionView::Helpers::DateHelper)</a><br />
35 <a href="classes/GLoc.html#M000008">get_charset (GLoc)</a><br />
36 <a href="classes/GLoc.html#M000009">get_config (GLoc)</a><br />
37 <a href="classes/GLoc/InstanceMethods.html#M000029">l (GLoc::InstanceMethods)</a><br />
38 <a href="classes/GLoc/Helpers.html#M000026">l_YesNo (GLoc::Helpers)</a><br />
39 <a href="classes/GLoc/Helpers.html#M000020">l_age (GLoc::Helpers)</a><br />
40 <a href="classes/GLoc/Helpers.html#M000021">l_date (GLoc::Helpers)</a><br />
41 <a href="classes/GLoc/Helpers.html#M000022">l_datetime (GLoc::Helpers)</a><br />
42 <a href="classes/GLoc/Helpers.html#M000023">l_datetime_short (GLoc::Helpers)</a><br />
43 <a href="classes/GLoc/InstanceMethods.html#M000034">l_has_string? (GLoc::InstanceMethods)</a><br />
44 <a href="classes/GLoc/Helpers.html#M000028">l_lang_name (GLoc::Helpers)</a><br />
45 <a href="classes/GLoc/Helpers.html#M000024">l_strftime (GLoc::Helpers)</a><br />
46 <a href="classes/GLoc/Helpers.html#M000025">l_time (GLoc::Helpers)</a><br />
47 <a href="classes/GLoc/Helpers.html#M000027">l_yesno (GLoc::Helpers)</a><br />
48 <a href="classes/GLoc/InstanceMethods.html#M000030">ll (GLoc::InstanceMethods)</a><br />
49 <a href="classes/GLoc.html#M000010">load_gloc_default_localized_strings (GLoc)</a><br />
50 <a href="classes/GLoc.html#M000011">load_localized_strings (GLoc)</a><br />
51 <a href="classes/GLoc/InstanceMethods.html#M000031">ltry (GLoc::InstanceMethods)</a><br />
52 <a href="classes/GLoc/InstanceMethods.html#M000032">lwr (GLoc::InstanceMethods)</a><br />
53 <a href="classes/GLoc/InstanceMethods.html#M000033">lwr_ (GLoc::InstanceMethods)</a><br />
54 <a href="classes/ActionView/Base.html#M000046">new (ActionView::Base)</a><br />
55 <a href="classes/GLoc.html#M000012">restore_state (GLoc)</a><br />
56 <a href="classes/ActionView/Helpers/DateHelper.html#M000042">select_day (ActionView::Helpers::DateHelper)</a><br />
57 <a href="classes/ActionView/Helpers/DateHelper.html#M000043">select_month (ActionView::Helpers::DateHelper)</a><br />
58 <a href="classes/ActionView/Helpers/DateHelper.html#M000044">select_year (ActionView::Helpers::DateHelper)</a><br />
59 <a href="classes/GLoc.html#M000013">set_charset (GLoc)</a><br />
60 <a href="classes/GLoc.html#M000014">set_config (GLoc)</a><br />
61 <a href="classes/GLoc.html#M000015">set_kcode (GLoc)</a><br />
62 <a href="classes/GLoc/InstanceMethods.html#M000035">set_language (GLoc::InstanceMethods)</a><br />
63 <a href="classes/GLoc/InstanceMethods.html#M000036">set_language_if_valid (GLoc::InstanceMethods)</a><br />
64 <a href="classes/GLoc.html#M000016">similar_language (GLoc)</a><br />
65 <a href="classes/GLoc.html#M000018">valid_language? (GLoc)</a><br />
66 <a href="classes/GLoc.html#M000017">valid_languages (GLoc)</a><br />
67 <a href="classes/ActiveRecord/Validations/ClassMethods.html#M000037">validates_length_of (ActiveRecord::Validations::ClassMethods)</a><br />
68 <a href="classes/ActiveRecord/Validations/ClassMethods.html#M000038">validates_size_of (ActiveRecord::Validations::ClassMethods)</a><br />
69 </div>
70 </div>
71 </body>
72 </html> No newline at end of file
@@ -0,0 +1,24
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html
3 PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
5
6 <!--
7
8 GLoc Localization Library Documentation
9
10 -->
11 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
12 <head>
13 <title>GLoc Localization Library Documentation</title>
14 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
15 </head>
16 <frameset rows="20%, 80%">
17 <frameset cols="25%,35%,45%">
18 <frame src="fr_file_index.html" title="Files" name="Files" />
19 <frame src="fr_class_index.html" name="Classes" />
20 <frame src="fr_method_index.html" name="Methods" />
21 </frameset>
22 <frame src="files/README.html" name="docwin" />
23 </frameset>
24 </html> No newline at end of file
@@ -0,0 +1,208
1
2 body {
3 font-family: Verdana,Arial,Helvetica,sans-serif;
4 font-size: 90%;
5 margin: 0;
6 margin-left: 40px;
7 padding: 0;
8 background: white;
9 }
10
11 h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
12 h1 { font-size: 150%; }
13 h2,h3,h4 { margin-top: 1em; }
14
15 a { background: #eef; color: #039; text-decoration: none; }
16 a:hover { background: #039; color: #eef; }
17
18 /* Override the base stylesheet's Anchor inside a table cell */
19 td > a {
20 background: transparent;
21 color: #039;
22 text-decoration: none;
23 }
24
25 /* and inside a section title */
26 .section-title > a {
27 background: transparent;
28 color: #eee;
29 text-decoration: none;
30 }
31
32 /* === Structural elements =================================== */
33
34 div#index {
35 margin: 0;
36 margin-left: -40px;
37 padding: 0;
38 font-size: 90%;
39 }
40
41
42 div#index a {
43 margin-left: 0.7em;
44 }
45
46 div#index .section-bar {
47 margin-left: 0px;
48 padding-left: 0.7em;
49 background: #ccc;
50 font-size: small;
51 }
52
53
54 div#classHeader, div#fileHeader {
55 width: auto;
56 color: white;
57 padding: 0.5em 1.5em 0.5em 1.5em;
58 margin: 0;
59 margin-left: -40px;
60 border-bottom: 3px solid #006;
61 }
62
63 div#classHeader a, div#fileHeader a {
64 background: inherit;
65 color: white;
66 }
67
68 div#classHeader td, div#fileHeader td {
69 background: inherit;
70 color: white;
71 }
72
73
74 div#fileHeader {
75 background: #057;
76 }
77
78 div#classHeader {
79 background: #048;
80 }
81
82
83 .class-name-in-header {
84 font-size: 180%;
85 font-weight: bold;
86 }
87
88
89 div#bodyContent {
90 padding: 0 1.5em 0 1.5em;
91 }
92
93 div#description {
94 padding: 0.5em 1.5em;
95 background: #efefef;
96 border: 1px dotted #999;
97 }
98
99 div#description h1,h2,h3,h4,h5,h6 {
100 color: #125;;
101 background: transparent;
102 }
103
104 div#validator-badges {
105 text-align: center;
106 }
107 div#validator-badges img { border: 0; }
108
109 div#copyright {
110 color: #333;
111 background: #efefef;
112 font: 0.75em sans-serif;
113 margin-top: 5em;
114 margin-bottom: 0;
115 padding: 0.5em 2em;
116 }
117
118
119 /* === Classes =================================== */
120
121 table.header-table {
122 color: white;
123 font-size: small;
124 }
125
126 .type-note {
127 font-size: small;
128 color: #DEDEDE;
129 }
130
131 .xxsection-bar {
132 background: #eee;
133 color: #333;
134 padding: 3px;
135 }
136
137 .section-bar {
138 color: #333;
139 border-bottom: 1px solid #999;
140 margin-left: -20px;
141 }
142
143
144 .section-title {
145 background: #79a;
146 color: #eee;
147 padding: 3px;
148 margin-top: 2em;
149 margin-left: -30px;
150 border: 1px solid #999;
151 }
152
153 .top-aligned-row { vertical-align: top }
154 .bottom-aligned-row { vertical-align: bottom }
155
156 /* --- Context section classes ----------------------- */
157
158 .context-row { }
159 .context-item-name { font-family: monospace; font-weight: bold; color: black; }
160 .context-item-value { font-size: small; color: #448; }
161 .context-item-desc { color: #333; padding-left: 2em; }
162
163 /* --- Method classes -------------------------- */
164 .method-detail {
165 background: #efefef;
166 padding: 0;
167 margin-top: 0.5em;
168 margin-bottom: 1em;
169 border: 1px dotted #ccc;
170 }
171 .method-heading {
172 color: black;
173 background: #ccc;
174 border-bottom: 1px solid #666;
175 padding: 0.2em 0.5em 0 0.5em;
176 }
177 .method-signature { color: black; background: inherit; }
178 .method-name { font-weight: bold; }
179 .method-args { font-style: italic; }
180 .method-description { padding: 0 0.5em 0 0.5em; }
181
182 /* --- Source code sections -------------------- */
183
184 a.source-toggle { font-size: 90%; }
185 div.method-source-code {
186 background: #262626;
187 color: #ffdead;
188 margin: 1em;
189 padding: 0.5em;
190 border: 1px dashed #999;
191 overflow: hidden;
192 }
193
194 div.method-source-code pre { color: #ffdead; overflow: hidden; }
195
196 /* --- Ruby keyword styles --------------------- */
197
198 .standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
199
200 .ruby-constant { color: #7fffd4; background: transparent; }
201 .ruby-keyword { color: #00ffff; background: transparent; }
202 .ruby-ivar { color: #eedd82; background: transparent; }
203 .ruby-operator { color: #00ffee; background: transparent; }
204 .ruby-identifier { color: #ffdead; background: transparent; }
205 .ruby-node { color: #ffa07a; background: transparent; }
206 .ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
207 .ruby-regexp { color: #ffa07a; background: transparent; }
208 .ruby-value { color: #7fffd4; background: transparent; } No newline at end of file
@@ -0,0 +1,11
1 # Copyright (c) 2005-2006 David Barri
2
3 require 'gloc'
4 require 'gloc-ruby'
5 require 'gloc-rails'
6 require 'gloc-rails-text'
7 require 'gloc-config'
8
9 require 'gloc-dev' if ENV['RAILS_ENV'] == 'development'
10
11 GLoc.load_gloc_default_localized_strings
@@ -0,0 +1,16
1 # Copyright (c) 2005-2006 David Barri
2
3 module GLoc
4
5 private
6
7 CONFIG= {} unless const_defined?(:CONFIG)
8 unless CONFIG.frozen?
9 CONFIG[:default_language] ||= :en
10 CONFIG[:default_param_name] ||= 'lang'
11 CONFIG[:default_cookie_name] ||= 'lang'
12 CONFIG[:raise_string_not_found_errors]= true unless CONFIG.has_key?(:raise_string_not_found_errors)
13 CONFIG[:verbose] ||= false
14 end
15
16 end
@@ -0,0 +1,97
1 # Copyright (c) 2005-2006 David Barri
2
3 puts "GLoc v#{GLoc::VERSION} running in development mode. Strings can be modified at runtime."
4
5 module GLoc
6 class << self
7
8 alias :actual_add_localized_strings :add_localized_strings
9 def add_localized_strings(lang, symbol_hash, override=true, strings_charset=nil)
10 _verbose_msg {"dev::add_localized_strings #{lang}, [#{symbol_hash.size}], #{override}, #{strings_charset ? strings_charset : 'nil'}"}
11 STATE.push [:hash, lang, {}.merge(symbol_hash), override, strings_charset]
12 _force_refresh
13 end
14
15 alias :actual_load_localized_strings :load_localized_strings
16 def load_localized_strings(dir=nil, override=true)
17 _verbose_msg {"dev::load_localized_strings #{dir ? dir : 'nil'}, #{override}"}
18 STATE.push [:dir, dir, override]
19 _get_lang_file_list(dir).each {|filename| FILES[filename]= nil}
20 end
21
22 alias :actual_clear_strings :clear_strings
23 def clear_strings(*languages)
24 _verbose_msg {"dev::clear_strings #{languages.map{|l|l.to_s}.join(', ')}"}
25 STATE.push [:clear, languages.clone]
26 _force_refresh
27 end
28
29 alias :actual_clear_strings_except :clear_strings_except
30 def clear_strings_except(*languages)
31 _verbose_msg {"dev::clear_strings_except #{languages.map{|l|l.to_s}.join(', ')}"}
32 STATE.push [:clear_except, languages.clone]
33 _force_refresh
34 end
35
36 # Replace methods
37 [:_l, :_l_rule, :_l_has_string?, :similar_language, :valid_languages, :valid_language?].each do |m|
38 class_eval <<-EOB
39 alias :actual_#{m} :#{m}
40 def #{m}(*args)
41 _assert_gloc_strings_up_to_date
42 actual_#{m}(*args)
43 end
44 EOB
45 end
46
47 #-------------------------------------------------------------------------
48 private
49
50 STATE= []
51 FILES= {}
52
53 def _assert_gloc_strings_up_to_date
54 changed= @@force_refresh
55
56 # Check if any lang files have changed
57 unless changed
58 FILES.each_pair {|f,mtime|
59 changed ||= (File.stat(f).mtime != mtime)
60 }
61 end
62
63 return unless changed
64 puts "GLoc reloading strings..."
65 @@force_refresh= false
66
67 # Update file timestamps
68 FILES.each_key {|f|
69 FILES[f]= File.stat(f).mtime
70 }
71
72 # Reload strings
73 actual_clear_strings
74 STATE.each {|s|
75 case s[0]
76 when :dir then actual_load_localized_strings s[1], s[2]
77 when :hash then actual_add_localized_strings s[1], s[2], s[3], s[4]
78 when :clear then actual_clear_strings(*s[1])
79 when :clear_except then actual_clear_strings_except(*s[1])
80 else raise "Invalid state id: '#{s[0]}'"
81 end
82 }
83 _verbose_msg :stats
84 end
85
86 @@force_refresh= false
87 def _force_refresh
88 @@force_refresh= true
89 end
90
91 alias :super_get_internal_state_vars :_get_internal_state_vars
92 def _get_internal_state_vars
93 super_get_internal_state_vars + [ STATE, FILES ]
94 end
95
96 end
97 end
@@ -0,0 +1,20
1 # Copyright (c) 2005-2006 David Barri
2
3 module GLoc
4 # These helper methods will be included in the InstanceMethods module.
5 module Helpers
6 def l_age(age) lwr :general_fmt_age, age end
7 def l_date(date) l_strftime date, :general_fmt_date end
8 def l_datetime(date) l_strftime date, :general_fmt_datetime end
9 def l_datetime_short(date) l_strftime date, :general_fmt_datetime_short end
10 def l_strftime(date,fmt) date.strftime l(fmt) end
11 def l_time(time) l_strftime time, :general_fmt_time end
12 def l_YesNo(value) l(value ? :general_text_Yes : :general_text_No) end
13 def l_yesno(value) l(value ? :general_text_yes : :general_text_no) end
14
15 def l_lang_name(lang, display_lang=nil)
16 ll display_lang || current_language, "general_lang_#{lang}"
17 end
18
19 end
20 end
@@ -0,0 +1,134
1 # Copyright (c) 2005-2006 David Barri
2
3 require 'iconv'
4 require 'gloc-version'
5
6 module GLoc
7 class GLocError < StandardError #:nodoc:
8 end
9 class InvalidArgumentsError < GLocError #:nodoc:
10 end
11 class InvalidKeyError < GLocError #:nodoc:
12 end
13 class RuleNotFoundError < GLocError #:nodoc:
14 end
15 class StringNotFoundError < GLocError #:nodoc:
16 end
17
18 class << self
19 private
20
21 def _add_localized_data(lang, symbol_hash, override, target) #:nodoc:
22 lang= lang.to_sym
23 if override
24 target[lang] ||= {}
25 target[lang].merge!(symbol_hash)
26 else
27 symbol_hash.merge!(target[lang]) if target[lang]
28 target[lang]= symbol_hash
29 end
30 end
31
32 def _add_localized_strings(lang, symbol_hash, override=true, strings_charset=nil) #:nodoc:
33 _charset_required
34
35 # Convert all incoming strings to the gloc charset
36 if strings_charset
37 Iconv.open(get_charset(lang), strings_charset) do |i|
38 symbol_hash.each_pair {|k,v| symbol_hash[k]= i.iconv(v)}
39 end
40 end
41
42 # Convert rules
43 rules= {}
44 old_kcode= $KCODE
45 begin
46 $KCODE= 'u'
47 Iconv.open(UTF_8, get_charset(lang)) do |i|
48 symbol_hash.each {|k,v|
49 if /^_gloc_rule_(.+)$/ =~ k.to_s
50 v= i.iconv(v) if v
51 v= '""' if v.nil?
52 rules[$1.to_sym]= eval "Proc.new do #{v} end"
53 end
54 }
55 end
56 ensure
57 $KCODE= old_kcode
58 end
59 rules.keys.each {|k| symbol_hash.delete "_gloc_rule_#{k}".to_sym}
60
61 # Add new localized data
62 LOWERCASE_LANGUAGES[lang.to_s.downcase]= lang
63 _add_localized_data(lang, symbol_hash, override, LOCALIZED_STRINGS)
64 _add_localized_data(lang, rules, override, RULES)
65 end
66
67 def _charset_required #:nodoc:
68 set_charset UTF_8 unless CONFIG[:internal_charset]
69 end
70
71 def _get_internal_state_vars
72 [ CONFIG, LOCALIZED_STRINGS, RULES, LOWERCASE_LANGUAGES ]
73 end
74
75 def _get_lang_file_list(dir) #:nodoc:
76 dir= File.join(RAILS_ROOT,'lang') if dir.nil?
77 Dir[File.join(dir,'*.{yaml,yml}')]
78 end
79
80 def _l(symbol, language, *arguments) #:nodoc:
81 symbol= symbol.to_sym if symbol.is_a?(String)
82 raise InvalidKeyError.new("Symbol or String expected as key.") unless symbol.kind_of?(Symbol)
83
84 translation= LOCALIZED_STRINGS[language][symbol] rescue nil
85 if translation.nil?
86 raise StringNotFoundError.new("There is no key called '#{symbol}' in the #{language} strings.") if CONFIG[:raise_string_not_found_errors]
87 translation= symbol.to_s
88 end
89
90 begin
91 return translation % arguments
92 rescue => e
93 raise InvalidArgumentsError.new("Translation value #{translation.inspect} with arguments #{arguments.inspect} caused error '#{e.message}'")
94 end
95 end
96
97 def _l_has_string?(symbol,lang) #:nodoc:
98 symbol= symbol.to_sym if symbol.is_a?(String)
99 LOCALIZED_STRINGS[lang].has_key?(symbol.to_sym) rescue false
100 end
101
102 def _l_rule(symbol,lang) #:nodoc:
103 symbol= symbol.to_sym if symbol.is_a?(String)
104 raise InvalidKeyError.new("Symbol or String expected as key.") unless symbol.kind_of?(Symbol)
105
106 r= RULES[lang][symbol] rescue nil
107 raise RuleNotFoundError.new("There is no rule called '#{symbol}' in the #{lang} rules.") if r.nil?
108 r
109 end
110
111 def _verbose_msg(type=nil)
112 return unless CONFIG[:verbose]
113 x= case type
114 when :stats
115 x= valid_languages.map{|l| ":#{l}(#{LOCALIZED_STRINGS[l].size}/#{RULES[l].size})"}.sort.join(', ')
116 "Current stats -- #{x}"
117 else
118 yield
119 end
120 puts "[GLoc] #{x}"
121 end
122
123 public :_l, :_l_has_string?, :_l_rule
124 end
125
126 private
127
128 unless const_defined?(:LOCALIZED_STRINGS)
129 LOCALIZED_STRINGS= {}
130 RULES= {}
131 LOWERCASE_LANGUAGES= {}
132 end
133
134 end
@@ -0,0 +1,137
1 # Copyright (c) 2005-2006 David Barri
2
3 require 'date'
4
5 module ActionView #:nodoc:
6 module Helpers #:nodoc:
7 module DateHelper
8
9 unless const_defined?(:LOCALIZED_HELPERS)
10 LOCALIZED_HELPERS= true
11 LOCALIZED_MONTHNAMES = {}
12 LOCALIZED_ABBR_MONTHNAMES = {}
13 end
14
15 # This method uses <tt>current_language</tt> to return a localized string.
16 def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false)
17 from_time = from_time.to_time if from_time.respond_to?(:to_time)
18 to_time = to_time.to_time if to_time.respond_to?(:to_time)
19 distance_in_minutes = (((to_time - from_time).abs)/60).round
20 distance_in_seconds = ((to_time - from_time).abs).round
21
22 case distance_in_minutes
23 when 0..1
24 return (distance_in_minutes==0) ? l(:actionview_datehelper_time_in_words_minute_less_than) : l(:actionview_datehelper_time_in_words_minute_single) unless include_seconds
25 case distance_in_seconds
26 when 0..5 then lwr(:actionview_datehelper_time_in_words_second_less_than, 5)
27 when 6..10 then lwr(:actionview_datehelper_time_in_words_second_less_than, 10)
28 when 11..20 then lwr(:actionview_datehelper_time_in_words_second_less_than, 20)
29 when 21..40 then l(:actionview_datehelper_time_in_words_minute_half)
30 when 41..59 then l(:actionview_datehelper_time_in_words_minute_less_than)
31 else l(:actionview_datehelper_time_in_words_minute)
32 end
33
34 when 2..45 then lwr(:actionview_datehelper_time_in_words_minute, distance_in_minutes)
35 when 46..90 then l(:actionview_datehelper_time_in_words_hour_about_single)
36 when 90..1440 then lwr(:actionview_datehelper_time_in_words_hour_about, (distance_in_minutes.to_f / 60.0).round)
37 when 1441..2880 then lwr(:actionview_datehelper_time_in_words_day, 1)
38 else lwr(:actionview_datehelper_time_in_words_day, (distance_in_minutes / 1440).round)
39 end
40 end
41
42 # This method has been modified so that a localized string can be appended to the day numbers.
43 def select_day(date, options = {})
44 day_options = []
45 prefix = l :actionview_datehelper_select_day_prefix
46
47 1.upto(31) do |day|
48 day_options << ((date && (date.kind_of?(Fixnum) ? date : date.day) == day) ?
49 %(<option value="#{day}" selected="selected">#{day}#{prefix}</option>\n) :
50 %(<option value="#{day}">#{day}#{prefix}</option>\n)
51 )
52 end
53
54 select_html(options[:field_name] || 'day', day_options, options[:prefix], options[:include_blank], options[:discard_type], options[:disabled])
55 end
56
57 # This method has been modified so that
58 # * the month names are localized.
59 # * it uses options: <tt>:min_date</tt>, <tt>:max_date</tt>, <tt>:start_month</tt>, <tt>:end_month</tt>
60 # * a localized string can be appended to the month numbers when the <tt>:use_month_numbers</tt> option is specified.
61 def select_month(date, options = {})
62 unless LOCALIZED_MONTHNAMES.has_key?(current_language)
63 LOCALIZED_MONTHNAMES[current_language] = [''] + l(:actionview_datehelper_select_month_names).split(',')
64 LOCALIZED_ABBR_MONTHNAMES[current_language] = [''] + l(:actionview_datehelper_select_month_names_abbr).split(',')
65 end
66
67 month_options = []
68 month_names = options[:use_short_month] ? LOCALIZED_ABBR_MONTHNAMES[current_language] : LOCALIZED_MONTHNAMES[current_language]
69
70 if options.has_key?(:min_date) && options.has_key?(:max_date)
71 if options[:min_date].year == options[:max_date].year
72 start_month, end_month = options[:min_date].month, options[:max_date].month
73 end
74 end
75 start_month = (options[:start_month] || 1) unless start_month
76 end_month = (options[:end_month] || 12) unless end_month
77 prefix = l :actionview_datehelper_select_month_prefix
78
79 start_month.upto(end_month) do |month_number|
80 month_name = if options[:use_month_numbers]
81 "#{month_number}#{prefix}"
82 elsif options[:add_month_numbers]
83 month_number.to_s + ' - ' + month_names[month_number]
84 else
85 month_names[month_number]
86 end
87
88 month_options << ((date && (date.kind_of?(Fixnum) ? date : date.month) == month_number) ?
89 %(<option value="#{month_number}" selected="selected">#{month_name}</option>\n) :
90 %(<option value="#{month_number}">#{month_name}</option>\n)
91 )
92 end
93
94 select_html(options[:field_name] || 'month', month_options, options[:prefix], options[:include_blank], options[:discard_type], options[:disabled])
95 end
96
97 # This method has been modified so that
98 # * it uses options: <tt>:min_date</tt>, <tt>:max_date</tt>
99 # * a localized string can be appended to the years numbers.
100 def select_year(date, options = {})
101 year_options = []
102 y = date ? (date.kind_of?(Fixnum) ? (y = (date == 0) ? Date.today.year : date) : date.year) : Date.today.year
103
104 start_year = options.has_key?(:min_date) ? options[:min_date].year : (options[:start_year] || y-5)
105 end_year = options.has_key?(:max_date) ? options[:max_date].year : (options[:end_year] || y+5)
106 step_val = start_year < end_year ? 1 : -1
107 prefix = l :actionview_datehelper_select_year_prefix
108
109 start_year.step(end_year, step_val) do |year|
110 year_options << ((date && (date.kind_of?(Fixnum) ? date : date.year) == year) ?
111 %(<option value="#{year}" selected="selected">#{year}#{prefix}</option>\n) :
112 %(<option value="#{year}">#{year}#{prefix}</option>\n)
113 )
114 end
115
116 select_html(options[:field_name] || 'year', year_options, options[:prefix], options[:include_blank], options[:discard_type], options[:disabled])
117 end
118
119 end
120
121 # The private method <tt>add_options</tt> is overridden so that "Please select" is localized.
122 class InstanceTag
123 private
124
125 def add_options(option_tags, options, value = nil)
126 option_tags = "<option value=\"\"></option>\n" + option_tags if options[:include_blank]
127
128 if value.blank? && options[:prompt]
129 ("<option value=\"\">#{options[:prompt].kind_of?(String) ? options[:prompt] : l(:actionview_instancetag_blank_option)}</option>\n") + option_tags
130 else
131 option_tags
132 end
133 end
134
135 end
136 end
137 end
@@ -0,0 +1,230
1 # Copyright (c) 2005-2006 David Barri
2
3 require 'gloc'
4
5 module ActionController #:nodoc:
6 class Base #:nodoc:
7 include GLoc
8 end
9 module Filters #:nodoc:
10 module ClassMethods
11
12 # This filter attempts to auto-detect the clients desired language.
13 # It first checks the params, then a cookie and then the HTTP_ACCEPT_LANGUAGE
14 # request header. If a language is found to match or be similar to a currently
15 # valid language, then it sets the current_language of the controller.
16 #
17 # class ExampleController < ApplicationController
18 # set_language :en
19 # autodetect_language_filter :except => 'monkey', :on_no_lang => :lang_not_autodetected_callback
20 # autodetect_language_filter :only => 'monkey', :check_cookie => 'monkey_lang', :check_accept_header => false
21 # ...
22 # def lang_not_autodetected_callback
23 # redirect_to somewhere
24 # end
25 # end
26 #
27 # The <tt>args</tt> for this filter are exactly the same the arguments of
28 # <tt>before_filter</tt> with the following exceptions:
29 # * <tt>:check_params</tt> -- If false, then params will not be checked for a language.
30 # If a String, then this will value will be used as the name of the param.
31 # * <tt>:check_cookie</tt> -- If false, then the cookie will not be checked for a language.
32 # If a String, then this will value will be used as the name of the cookie.
33 # * <tt>:check_accept_header</tt> -- If false, then HTTP_ACCEPT_LANGUAGE will not be checked for a language.
34 # * <tt>:on_set_lang</tt> -- You can specify the name of a callback function to be called when the language
35 # is successfully detected and set. The param must be a Symbol or a String which is the name of the function.
36 # The callback function must accept one argument (the language) and must be instance level.
37 # * <tt>:on_no_lang</tt> -- You can specify the name of a callback function to be called when the language
38 # couldn't be detected automatically. The param must be a Symbol or a String which is the name of the function.
39 # The callback function must be instance level.
40 #
41 # You override the default names of the param or cookie by calling <tt>GLoc.set_config :default_param_name => 'new_param_name'</tt>
42 # and <tt>GLoc.set_config :default_cookie_name => 'new_cookie_name'</tt>.
43 def autodetect_language_filter(*args)
44 options= args.last.is_a?(Hash) ? args.last : {}
45 x= 'Proc.new { |c| l= nil;'
46 # :check_params
47 unless (v= options.delete(:check_params)) == false
48 name= v ? ":#{v}" : 'GLoc.get_config(:default_param_name)'
49 x << "l ||= GLoc.similar_language(c.params[#{name}]);"
50 end
51 # :check_cookie
52 unless (v= options.delete(:check_cookie)) == false
53 name= v ? ":#{v}" : 'GLoc.get_config(:default_cookie_name)'
54 x << "l ||= GLoc.similar_language(c.send(:cookies)[#{name}]);"
55 end
56 # :check_accept_header
57 unless options.delete(:check_accept_header) == false
58 x << %<
59 unless l
60 a= c.request.env['HTTP_ACCEPT_LANGUAGE'].split(/,|;/) rescue nil
61 a.each {|x| l ||= GLoc.similar_language(x)} if a
62 end; >
63 end
64 # Set language
65 x << 'ret= true;'
66 x << 'if l; c.set_language(l); c.headers[\'Content-Language\']= l.to_s; '
67 if options.has_key?(:on_set_lang)
68 x << "ret= c.#{options.delete(:on_set_lang)}(l);"
69 end
70 if options.has_key?(:on_no_lang)
71 x << "else; ret= c.#{options.delete(:on_no_lang)};"
72 end
73 x << 'end; ret }'
74
75 # Create filter
76 block= eval x
77 before_filter(*args, &block)
78 end
79
80 end
81 end
82 end
83
84 # ==============================================================================
85
86 module ActionMailer #:nodoc:
87 # In addition to including GLoc, <tt>render_message</tt> is also overridden so
88 # that mail templates contain the current language at the end of the file.
89 # Eg. <tt>deliver_hello</tt> will render <tt>hello_en.rhtml</tt>.
90 class Base
91 include GLoc
92 private
93 alias :render_message_without_gloc :render_message
94 def render_message(method_name, body)
95 render_message_without_gloc("#{method_name}_#{current_language}", body)
96 end
97 end
98 end
99
100 # ==============================================================================
101
102 module ActionView #:nodoc:
103 # <tt>initialize</tt> is overridden so that new instances of this class inherit
104 # the current language of the controller.
105 class Base
106 include GLoc
107
108 alias :initialize_without_gloc :initialize
109 def initialize(base_path = nil, assigns_for_first_render = {}, controller = nil)
110 initialize_without_gloc(base_path, assigns_for_first_render, controller)
111 set_language controller.current_language unless controller.nil?
112 end
113 end
114
115 module Helpers #:nodoc:
116 class InstanceTag
117 include GLoc
118 # Inherits the current language from the template object.
119 def current_language
120 @template_object.current_language
121 end
122 end
123 end
124 end
125
126 # ==============================================================================
127
128 module ActiveRecord #:nodoc:
129 class Base #:nodoc:
130 include GLoc
131 end
132
133 class Errors
134 include GLoc
135 alias :add_without_gloc :add
136 # The GLoc version of this method provides two extra features
137 # * If <tt>msg</tt> is a string, it will be considered a GLoc string key.
138 # * If <tt>msg</tt> is an array, the first element will be considered
139 # the string and the remaining elements will be considered arguments for the
140 # string. Eg. <tt>['Hi %s.','John']</tt>
141 def add(attribute, msg= @@default_error_messages[:invalid])
142 if msg.is_a?(Array)
143 args= msg.clone
144 msg= args.shift
145 args= nil if args.empty?
146 end
147 msg= ltry(msg)
148 msg= msg % args unless args.nil?
149 add_without_gloc(attribute, msg)
150 end
151 # Inherits the current language from the base record.
152 def current_language
153 @base.current_language
154 end
155 end
156
157 module Validations #:nodoc:
158 module ClassMethods
159 # The default Rails version of this function creates an error message and then
160 # passes it to ActiveRecord.Errors.
161 # The GLoc version of this method, sends an array to ActiveRecord.Errors that will
162 # be turned into a string by ActiveRecord.Errors which in turn allows for the message
163 # of this validation function to be a GLoc string key.
164 def validates_length_of(*attrs)
165 # Merge given options with defaults.
166 options = {
167 :too_long => ActiveRecord::Errors.default_error_messages[:too_long],
168 :too_short => ActiveRecord::Errors.default_error_messages[:too_short],
169 :wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_length]
170 }.merge(DEFAULT_VALIDATION_OPTIONS)
171 options.update(attrs.pop.symbolize_keys) if attrs.last.is_a?(Hash)
172
173 # Ensure that one and only one range option is specified.
174 range_options = ALL_RANGE_OPTIONS & options.keys
175 case range_options.size
176 when 0
177 raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
178 when 1
179 # Valid number of options; do nothing.
180 else
181 raise ArgumentError, 'Too many range options specified. Choose only one.'
182 end
183
184 # Get range option and value.
185 option = range_options.first
186 option_value = options[range_options.first]
187
188 case option
189 when :within, :in
190 raise ArgumentError, ":#{option} must be a Range" unless option_value.is_a?(Range)
191
192 too_short = [options[:too_short] , option_value.begin]
193 too_long = [options[:too_long] , option_value.end ]
194
195 validates_each(attrs, options) do |record, attr, value|
196 if value.nil? or value.split(//).size < option_value.begin
197 record.errors.add(attr, too_short)
198 elsif value.split(//).size > option_value.end
199 record.errors.add(attr, too_long)
200 end
201 end
202 when :is, :minimum, :maximum
203 raise ArgumentError, ":#{option} must be a nonnegative Integer" unless option_value.is_a?(Integer) and option_value >= 0
204
205 # Declare different validations per option.
206 validity_checks = { :is => "==", :minimum => ">=", :maximum => "<=" }
207 message_options = { :is => :wrong_length, :minimum => :too_short, :maximum => :too_long }
208
209 message = [(options[:message] || options[message_options[option]]) , option_value]
210
211 validates_each(attrs, options) do |record, attr, value|
212 if value.kind_of?(String)
213 record.errors.add(attr, message) unless !value.nil? and value.split(//).size.method(validity_checks[option])[option_value]
214 else
215 record.errors.add(attr, message) unless !value.nil? and value.size.method(validity_checks[option])[option_value]
216 end
217 end
218 end
219 end
220
221 alias_method :validates_size_of, :validates_length_of
222 end
223 end
224 end
225
226 # ==============================================================================
227
228 module ApplicationHelper #:nodoc:
229 include GLoc
230 end
@@ -0,0 +1,7
1 # Copyright (c) 2005-2006 David Barri
2
3 module Test # :nodoc:
4 module Unit # :nodoc:
5 class TestCase # :nodoc:
6 include GLoc
7 end; end; end
@@ -0,0 +1,12
1 module GLoc
2 module VERSION #:nodoc:
3 MAJOR = 1
4 MINOR = 1
5 TINY = nil
6
7 STRING= [MAJOR, MINOR, TINY].delete_if{|x|x.nil?}.join('.')
8 def self.to_s; STRING end
9 end
10 end
11
12 puts "NOTICE: You are using a dev version of GLoc." if GLoc::VERSION::TINY == 'DEV' No newline at end of file
@@ -0,0 +1,294
1 # Copyright (c) 2005-2006 David Barri
2
3 require 'yaml'
4 require 'gloc-internal'
5 require 'gloc-helpers'
6
7 module GLoc
8 UTF_8= 'utf-8'
9 SHIFT_JIS= 'sjis'
10 EUC_JP= 'euc-jp'
11
12 # This module will be included in both instances and classes of GLoc includees.
13 # It is also included as class methods in the GLoc module itself.
14 module InstanceMethods
15 include Helpers
16
17 # Returns a localized string.
18 def l(symbol, *arguments)
19 return GLoc._l(symbol,current_language,*arguments)
20 end
21
22 # Returns a localized string in a specified language.
23 # This does not effect <tt>current_language</tt>.
24 def ll(lang, symbol, *arguments)
25 return GLoc._l(symbol,lang.to_sym,*arguments)
26 end
27
28 # Returns a localized string if the argument is a Symbol, else just returns the argument.
29 def ltry(possible_key)
30 possible_key.is_a?(Symbol) ? l(possible_key) : possible_key
31 end
32
33 # Uses the default GLoc rule to return a localized string.
34 # See lwr_() for more info.
35 def lwr(symbol, *arguments)
36 lwr_(:default, symbol, *arguments)
37 end
38
39 # Uses a <em>rule</em> to return a localized string.
40 # A rule is a function that uses specified arguments to return a localization key prefix.
41 # The prefix is appended to the localization key originally specified, to create a new key which
42 # is then used to lookup a localized string.
43 def lwr_(rule, symbol, *arguments)
44 GLoc._l("#{symbol}#{GLoc::_l_rule(rule,current_language).call(*arguments)}",current_language,*arguments)
45 end
46
47 # Returns <tt>true</tt> if a localized string with the specified key exists.
48 def l_has_string?(symbol)
49 return GLoc._l_has_string?(symbol,current_language)
50 end
51
52 # Sets the current language for this instance/class.
53 # Setting the language of a class effects all instances unless the instance has its own language defined.
54 def set_language(language)
55 @gloc_language= language.nil? ? nil : language.to_sym
56 end
57
58 # Sets the current language if the language passed is a valid language.
59 # If the language was valid, this method returns <tt>true</tt> else it will return <tt>false</tt>.
60 # Note that <tt>nil</tt> is not a valid language.
61 # See set_language(language) for more info.
62 def set_language_if_valid(language)
63 if GLoc.valid_language?(language)
64 set_language(language)
65 true
66 else
67 false
68 end
69 end
70 end
71
72 #---------------------------------------------------------------------------
73 # Instance
74
75 include ::GLoc::InstanceMethods
76 # Returns the instance-level current language, or if not set, returns the class-level current language.
77 def current_language
78 @gloc_language || self.class.current_language
79 end
80
81 #---------------------------------------------------------------------------
82 # Class
83
84 # All classes/modules that include GLoc will also gain these class methods.
85 # Notice that the GLoc::InstanceMethods module is also included.
86 module ClassMethods
87 include ::GLoc::InstanceMethods
88 # Returns the current language, or if not set, returns the GLoc current language.
89 def current_language
90 @gloc_language || GLoc.current_language
91 end
92 end
93
94 def self.included(target) #:nodoc:
95 super
96 class << target
97 include ::GLoc::ClassMethods
98 end
99 end
100
101 #---------------------------------------------------------------------------
102 # GLoc module
103
104 class << self
105 include ::GLoc::InstanceMethods
106
107 # Returns the default language
108 def current_language
109 GLoc::CONFIG[:default_language]
110 end
111
112 # Adds a collection of localized strings to the in-memory string store.
113 def add_localized_strings(lang, symbol_hash, override=true, strings_charset=nil)
114 _verbose_msg {"Adding #{symbol_hash.size} #{lang} strings."}
115 _add_localized_strings(lang, symbol_hash, override, strings_charset)
116 _verbose_msg :stats
117 end
118
119 # Creates a backup of the internal state of GLoc (ie. strings, langs, rules, config)
120 # and optionally clears everything.
121 def backup_state(clear=false)
122 s= _get_internal_state_vars.map{|o| o.clone}
123 _get_internal_state_vars.each{|o| o.clear} if clear
124 s
125 end
126
127 # Removes all localized strings from memory, either of a certain language (or languages),
128 # or entirely.
129 def clear_strings(*languages)
130 if languages.empty?
131 _verbose_msg {"Clearing all strings"}
132 LOCALIZED_STRINGS.clear
133 LOWERCASE_LANGUAGES.clear
134 else
135 languages.each {|l|
136 _verbose_msg {"Clearing :#{l} strings"}
137 l= l.to_sym
138 LOCALIZED_STRINGS.delete l
139 LOWERCASE_LANGUAGES.each_pair {|k,v| LOWERCASE_LANGUAGES.delete k if v == l}
140 }
141 end
142 end
143 alias :_clear_strings :clear_strings
144
145 # Removes all localized strings from memory, except for those of certain specified languages.
146 def clear_strings_except(*languages)
147 clear= (LOCALIZED_STRINGS.keys - languages)
148 _clear_strings(*clear) unless clear.empty?
149 end
150
151 # Returns the charset used to store localized strings in memory.
152 def get_charset(lang)
153 CONFIG[:internal_charset_per_lang][lang] || CONFIG[:internal_charset]
154 end
155
156 # Returns a GLoc configuration value.
157 def get_config(key)
158 CONFIG[key]
159 end
160
161 # Loads the localized strings that are included in the GLoc library.
162 def load_gloc_default_localized_strings(override=false)
163 GLoc.load_localized_strings "#{File.dirname(__FILE__)}/../lang", override
164 end
165
166 # Loads localized strings from all yml files in the specifed directory.
167 def load_localized_strings(dir=nil, override=true)
168 _charset_required
169 _get_lang_file_list(dir).each {|filename|
170
171 # Load file
172 raw_hash = YAML::load(File.read(filename))
173 raw_hash={} unless raw_hash.kind_of?(Hash)
174 filename =~ /([^\/\\]+)\.ya?ml$/
175 lang = $1.to_sym
176 file_charset = raw_hash['file_charset'] || UTF_8
177
178 # Convert string keys to symbols
179 dest_charset= get_charset(lang)
180 _verbose_msg {"Reading file #{filename} [charset: #{file_charset} --> #{dest_charset}]"}
181 symbol_hash = {}
182 Iconv.open(dest_charset, file_charset) do |i|
183 raw_hash.each {|key, value|
184 symbol_hash[key.to_sym] = i.iconv(value)
185 }
186 end
187
188 # Add strings to repos
189 _add_localized_strings(lang, symbol_hash, override)
190 }
191 _verbose_msg :stats
192 end
193
194 # Restores a backup of GLoc's internal state that was made with backup_state.
195 def restore_state(state)
196 _get_internal_state_vars.each do |o|
197 o.clear
198 o.send o.respond_to?(:merge!) ? :merge! : :concat, state.shift
199 end
200 end
201
202 # Sets the charset used to internally store localized strings.
203 # You can set the charset to use for a specific language or languages,
204 # or if none are specified the charset for ALL localized strings will be set.
205 def set_charset(new_charset, *langs)
206 CONFIG[:internal_charset_per_lang] ||= {}
207
208 # Convert symbol shortcuts
209 if new_charset.is_a?(Symbol)
210 new_charset= case new_charset
211 when :utf8, :utf_8 then UTF_8
212 when :sjis, :shift_jis, :shiftjis then SHIFT_JIS
213 when :eucjp, :euc_jp then EUC_JP
214 else new_charset.to_s
215 end
216 end
217
218 # Convert existing strings
219 (langs.empty? ? LOCALIZED_STRINGS.keys : langs).each do |lang|
220 cur_charset= get_charset(lang)
221 if cur_charset && new_charset != cur_charset
222 _verbose_msg {"Converting :#{lang} strings from #{cur_charset} to #{new_charset}"}
223 Iconv.open(new_charset, cur_charset) do |i|
224 bundle= LOCALIZED_STRINGS[lang]
225 bundle.each_pair {|k,v| bundle[k]= i.iconv(v)}
226 end
227 end
228 end
229
230 # Set new charset value
231 if langs.empty?
232 _verbose_msg {"Setting GLoc charset for all languages to #{new_charset}"}
233 CONFIG[:internal_charset]= new_charset
234 CONFIG[:internal_charset_per_lang].clear
235 else
236 langs.each do |lang|
237 _verbose_msg {"Setting GLoc charset for :#{lang} strings to #{new_charset}"}
238 CONFIG[:internal_charset_per_lang][lang]= new_charset
239 end
240 end
241 end
242
243 # Sets GLoc configuration values.
244 def set_config(hash)
245 CONFIG.merge! hash
246 end
247
248 # Sets the $KCODE global variable according to a specified charset, or else the
249 # current default charset for the default language.
250 def set_kcode(charset=nil)
251 _charset_required
252 charset ||= get_charset(current_language)
253 $KCODE= case charset
254 when UTF_8 then 'u'
255 when SHIFT_JIS then 's'
256 when EUC_JP then 'e'
257 else 'n'
258 end
259 _verbose_msg {"$KCODE set to #{$KCODE}"}
260 end
261
262 # Tries to find a valid language that is similar to the argument passed.
263 # Eg. :en, :en_au, :EN_US are all similar languages.
264 # Returns <tt>nil</tt> if no similar languages are found.
265 def similar_language(lang)
266 return nil if lang.nil?
267 return lang.to_sym if valid_language?(lang)
268 # Check lowercase without dashes
269 lang= lang.to_s.downcase.gsub('-','_')
270 return LOWERCASE_LANGUAGES[lang] if LOWERCASE_LANGUAGES.has_key?(lang)
271 # Check without dialect
272 if lang.to_s =~ /^([a-z]+?)[^a-z].*/
273 lang= $1
274 return LOWERCASE_LANGUAGES[lang] if LOWERCASE_LANGUAGES.has_key?(lang)
275 end
276 # Check other dialects
277 lang= "#{lang}_"
278 LOWERCASE_LANGUAGES.keys.each {|k| return LOWERCASE_LANGUAGES[k] if k.starts_with?(lang)}
279 # Nothing found
280 nil
281 end
282
283 # Returns an array of (currently) valid languages (ie. languages for which localized data exists).
284 def valid_languages
285 LOCALIZED_STRINGS.keys
286 end
287
288 # Returns <tt>true</tt> if there are any localized strings for a specified language.
289 # Note that although <tt>set_langauge nil</tt> is perfectly valid, <tt>nil</tt> is not a valid language.
290 def valid_language?(language)
291 LOCALIZED_STRINGS.has_key? language.to_sym rescue false
292 end
293 end
294 end
@@ -0,0 +1,30
1 namespace :gloc do
2 desc 'Sorts the keys in the lang ymls'
3 task :sort do
4 dir = ENV['DIR'] || '{.,vendor/plugins/*}/lang'
5 puts "Processing directory #{dir}"
6 files = Dir.glob(File.join(dir,'*.{yaml,yml}'))
7 puts 'No files found.' if files.empty?
8 files.each {|file|
9 puts "Sorting file: #{file}"
10 header = []
11 content = IO.readlines(file)
12 content.each {|line| line.gsub!(/[\s\r\n\t]+$/,'')}
13 content.delete_if {|line| line==''}
14 tmp= []
15 content.each {|x| tmp << x unless tmp.include?(x)}
16 content= tmp
17 header << content.shift if !content.empty? && content[0] =~ /^file_charset:/
18 content.sort!
19 filebak = "#{file}.bak"
20 File.rename file, filebak
21 File.open(file, 'w') {|fout| fout << header.join("\n") << content.join("\n") << "\n"}
22 File.delete filebak
23 # Report duplicates
24 count= {}
25 content.map {|x| x.gsub(/:.+$/, '') }.each {|x| count[x] ||= 0; count[x] += 1}
26 count.delete_if {|k,v|v==1}
27 puts count.keys.sort.map{|x|" WARNING: Duplicate key '#{x}' (#{count[x]} occurances)"}.join("\n") unless count.empty?
28 }
29 end
30 end No newline at end of file
@@ -0,0 +1,118
1 # Copyright (c) 2005-2006 David Barri
2
3 $LOAD_PATH.push File.join(File.dirname(__FILE__),'..','lib')
4 require "#{File.dirname(__FILE__)}/../../../../test/test_helper"
5 require "#{File.dirname(__FILE__)}/../init"
6
7 class GLocRailsTestController < ActionController::Base
8 autodetect_language_filter :only => :auto, :on_set_lang => :called_when_set, :on_no_lang => :called_when_bad
9 autodetect_language_filter :only => :auto2, :check_accept_header => false, :check_params => 'xx'
10 autodetect_language_filter :only => :auto3, :check_cookie => false
11 autodetect_language_filter :only => :auto4, :check_cookie => 'qwe', :check_params => false
12 def rescue_action(e) raise e end
13 def auto; render :text => 'auto'; end
14 def auto2; render :text => 'auto'; end
15 def auto3; render :text => 'auto'; end
16 def auto4; render :text => 'auto'; end
17 attr_accessor :callback_set, :callback_bad
18 def called_when_set(l) @callback_set ||= 0; @callback_set += 1 end
19 def called_when_bad; @callback_bad ||= 0; @callback_bad += 1 end
20 end
21
22 class GLocRailsTest < Test::Unit::TestCase
23
24 def setup
25 @lstrings = GLoc::LOCALIZED_STRINGS.clone
26 @old_config= GLoc::CONFIG.clone
27 begin_new_request
28 end
29
30 def teardown
31 GLoc.clear_strings
32 GLoc::LOCALIZED_STRINGS.merge! @lstrings
33 GLoc::CONFIG.merge! @old_config
34 end
35
36 def begin_new_request
37 @controller = GLocRailsTestController.new
38 @request = ActionController::TestRequest.new
39 @response = ActionController::TestResponse.new
40 end
41
42 def test_autodetect_language
43 GLoc::CONFIG[:default_language]= :def
44 GLoc::CONFIG[:default_param_name] = 'plang'
45 GLoc::CONFIG[:default_cookie_name] = 'clang'
46 GLoc.clear_strings
47 GLoc.add_localized_strings :en, :a => 'a'
48 GLoc.add_localized_strings :en_au, :a => 'a'
49 GLoc.add_localized_strings :en_US, :a => 'a'
50 GLoc.add_localized_strings :Ja, :a => 'a'
51 GLoc.add_localized_strings :ZH_HK, :a => 'a'
52
53 # default
54 subtest_autodetect_language :def, nil, nil, nil
55 subtest_autodetect_language :def, 'its', 'all', 'bullshit,man;q=zxc'
56 # simple
57 subtest_autodetect_language :en_au, 'en_au', nil, nil
58 subtest_autodetect_language :en_US, nil, 'en_us', nil
59 subtest_autodetect_language :Ja, nil, nil, 'ja'
60 # priority
61 subtest_autodetect_language :Ja, 'ja', 'en_us', 'qwe_ja,zh,monkey_en;q=0.5'
62 subtest_autodetect_language :en_US, 'why', 'en_us', 'qwe_ja,zh,monkey_en;q=0.5'
63 subtest_autodetect_language :Ja, nil, nil, 'qwe_en,JA,zh,monkey_en;q=0.5'
64 # dashes to underscores in accept string
65 subtest_autodetect_language :en_au, 'monkey', nil, 'de,EN-Au'
66 # remove dialect
67 subtest_autodetect_language :en, nil, 'en-bullshit', nil
68 subtest_autodetect_language :en, 'monkey', nil, 'de,EN-NZ,ja'
69 # different dialect
70 subtest_autodetect_language :ZH_HK, 'zh', nil, 'de,EN-NZ,ja'
71 subtest_autodetect_language :ZH_HK, 'monkey', 'zh', 'de,EN-NZ,ja'
72
73 # Check param/cookie names use defaults
74 GLoc::CONFIG[:default_param_name] = 'p_lang'
75 GLoc::CONFIG[:default_cookie_name] = 'c_lang'
76 # :check_params
77 subtest_autodetect_language :def, 'en_au', nil, nil
78 subtest_autodetect_language :en_au, {:p_lang => 'en_au'}, nil, nil
79 # :check_cookie
80 subtest_autodetect_language :def, nil, 'en_us', nil
81 subtest_autodetect_language :en_US, nil, {:c_lang => 'en_us'}, nil
82 GLoc::CONFIG[:default_param_name] = 'plang'
83 GLoc::CONFIG[:default_cookie_name] = 'clang'
84
85 # autodetect_language_filter :only => :auto2, :check_accept_header => false, :check_params => 'xx'
86 subtest_autodetect_language :def, 'ja', nil, 'en_US', :auto2
87 subtest_autodetect_language :Ja, {:xx => 'ja'}, nil, 'en_US', :auto2
88 subtest_autodetect_language :en_au, 'ja', 'en_au', 'en_US', :auto2
89
90 # autodetect_language_filter :only => :auto3, :check_cookie => false
91 subtest_autodetect_language :Ja, 'ja', 'en_us', 'qwe_ja,zh,monkey_en;q=0.5', :auto3
92 subtest_autodetect_language :ZH_HK, 'hehe', 'en_us', 'qwe_ja,zh,monkey_en;q=0.5', :auto3
93
94 # autodetect_language_filter :only => :auto4, :check_cookie => 'qwe', :check_params => false
95 subtest_autodetect_language :def, 'ja', 'en_us', nil, :auto4
96 subtest_autodetect_language :ZH_HK, 'ja', 'en_us', 'qwe_ja,zh,monkey_en;q=0.5', :auto4
97 subtest_autodetect_language :en_US, 'ja', {:qwe => 'en_us'}, 'ja', :auto4
98 end
99
100 def subtest_autodetect_language(expected,params,cookie,accept, action=:auto)
101 begin_new_request
102 params= {'plang' => params} if params.is_a?(String)
103 params ||= {}
104 if cookie
105 cookie={'clang' => cookie} unless cookie.is_a?(Hash)
106 cookie.each_pair {|k,v| @request.cookies[k.to_s]= CGI::Cookie.new(k.to_s,v)}
107 end
108 @request.env['HTTP_ACCEPT_LANGUAGE']= accept
109 get action, params
110 assert_equal expected, @controller.current_language
111 if action == :auto
112 s,b = expected != :def ? [1,nil] : [nil,1]
113 assert_equal s, @controller.callback_set
114 assert_equal b, @controller.callback_bad
115 end
116 end
117
118 end No newline at end of file
@@ -0,0 +1,433
1 # Copyright (c) 2005-2006 David Barri
2
3 $LOAD_PATH.push File.join(File.dirname(__FILE__),'..','lib')
4 require 'gloc'
5 require 'gloc-ruby'
6 require 'gloc-config'
7 require 'gloc-rails-text'
8 require File.join(File.dirname(__FILE__),'lib','rails-time_ext') unless 3.respond_to?(:days)
9 require File.join(File.dirname(__FILE__),'lib','rails-string_ext') unless ''.respond_to?(:starts_with?)
10 #require 'gloc-dev'
11
12 class LClass; include GLoc; end
13 class LClass2 < LClass; end
14 class LClass_en < LClass2; set_language :en; end
15 class LClass_ja < LClass2; set_language :ja; end
16 # class LClass_forced_au < LClass; set_language :en; force_language :en_AU; set_language :ja; end
17
18 class GLocTest < Test::Unit::TestCase
19 include GLoc
20 include ActionView::Helpers::DateHelper
21
22 def setup
23 @l1 = LClass.new
24 @l2 = LClass.new
25 @l3 = LClass.new
26 @l1.set_language :ja
27 @l2.set_language :en
28 @l3.set_language 'en_AU'
29 @gloc_state= GLoc.backup_state true
30 GLoc::CONFIG.merge!({
31 :default_param_name => 'lang',
32 :default_cookie_name => 'lang',
33 :default_language => :ja,
34 :raise_string_not_found_errors => true,
35 :verbose => false,
36 })
37 end
38
39 def teardown
40 GLoc.restore_state @gloc_state
41 end
42
43 #---------------------------------------------------------------------------
44
45 def test_basic
46 assert_localized_value [nil, @l1, @l2, @l3], nil, :in_both_langs
47
48 GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
49
50 assert_localized_value [nil, @l1], 'enにもjaにもある', :in_both_langs
51 assert_localized_value [nil, @l1], '日本語のみ', :ja_only
52 assert_localized_value [nil, @l1], nil, :en_only
53
54 assert_localized_value @l2, 'This is in en+ja', :in_both_langs
55 assert_localized_value @l2, nil, :ja_only
56 assert_localized_value @l2, 'English only', :en_only
57
58 assert_localized_value @l3, "Thiz in en 'n' ja", :in_both_langs
59 assert_localized_value @l3, nil, :ja_only
60 assert_localized_value @l3, 'Aussie English only bro', :en_only
61
62 @l3.set_language :en
63 assert_localized_value @l3, 'This is in en+ja', :in_both_langs
64 assert_localized_value @l3, nil, :ja_only
65 assert_localized_value @l3, 'English only', :en_only
66
67 assert_localized_value nil, 'enにもjaにもある', :in_both_langs
68 assert_localized_value nil, '日本語のみ', :ja_only
69 assert_localized_value nil, nil, :en_only
70 end
71
72 def test_load_twice_with_override
73 GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
74 GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang2')
75
76 assert_localized_value [nil, @l1], '更新された', :in_both_langs
77 assert_localized_value [nil, @l1], '日本語のみ', :ja_only
78 assert_localized_value [nil, @l1], nil, :en_only
79 assert_localized_value [nil, @l1], nil, :new_en
80 assert_localized_value [nil, @l1], '新たな日本語ストリング', :new_ja
81
82 assert_localized_value @l2, 'This is in en+ja', :in_both_langs
83 assert_localized_value @l2, nil, :ja_only
84 assert_localized_value @l2, 'overriden dude', :en_only
85 assert_localized_value @l2, 'This is a new English string', :new_en
86 assert_localized_value @l2, nil, :new_ja
87
88 assert_localized_value @l3, "Thiz in en 'n' ja", :in_both_langs
89 assert_localized_value @l3, nil, :ja_only
90 assert_localized_value @l3, 'Aussie English only bro', :en_only
91 end
92
93 def test_load_twice_without_override
94 GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
95 GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang2'), false
96
97 assert_localized_value [nil, @l1], 'enにもjaにもある', :in_both_langs
98 assert_localized_value [nil, @l1], '日本語のみ', :ja_only
99 assert_localized_value [nil, @l1], nil, :en_only
100 assert_localized_value [nil, @l1], nil, :new_en
101 assert_localized_value [nil, @l1], '新たな日本語ストリング', :new_ja
102
103 assert_localized_value @l2, 'This is in en+ja', :in_both_langs
104 assert_localized_value @l2, nil, :ja_only
105 assert_localized_value @l2, 'English only', :en_only
106 assert_localized_value @l2, 'This is a new English string', :new_en
107 assert_localized_value @l2, nil, :new_ja
108
109 assert_localized_value @l3, "Thiz in en 'n' ja", :in_both_langs
110 assert_localized_value @l3, nil, :ja_only
111 assert_localized_value @l3, 'Aussie English only bro', :en_only
112 end
113
114 def test_add_localized_strings
115 assert_localized_value nil, nil, :add
116 assert_localized_value nil, nil, :ja_only
117 GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
118 assert_localized_value nil, nil, :add
119 assert_localized_value nil, '日本語のみ', :ja_only
120 GLoc.add_localized_strings 'en', {:ja_only => 'bullshit'}, true
121 GLoc.add_localized_strings 'en', {:ja_only => 'bullshit'}, false
122 assert_localized_value nil, nil, :add
123 assert_localized_value nil, '日本語のみ', :ja_only
124 GLoc.add_localized_strings 'ja', {:ja_only => 'bullshit', :add => '123'}, false
125 assert_localized_value nil, '123', :add
126 assert_localized_value nil, '日本語のみ', :ja_only
127 GLoc.add_localized_strings 'ja', {:ja_only => 'bullshit', :add => '234'}
128 assert_localized_value nil, '234', :add
129 assert_localized_value nil, 'bullshit', :ja_only
130 end
131
132 def test_class_set_language
133 GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
134
135 @l1 = LClass_ja.new
136 @l2 = LClass_en.new
137 @l3 = LClass_en.new
138
139 assert_localized_value @l1, 'enにもjaにもある', :in_both_langs
140 assert_localized_value @l2, 'This is in en+ja', :in_both_langs
141 assert_localized_value @l3, 'This is in en+ja', :in_both_langs
142
143 @l3.set_language 'en_AU'
144
145 assert_localized_value @l1, 'enにもjaにもある', :in_both_langs
146 assert_localized_value @l2, 'This is in en+ja', :in_both_langs
147 assert_localized_value @l3, "Thiz in en 'n' ja", :in_both_langs
148 end
149
150 def test_ll
151 GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
152
153 assert_equal 'enにもjaにもある', ll('ja',:in_both_langs)
154 assert_equal 'enにもjaにもある', GLoc::ll('ja',:in_both_langs)
155 assert_equal 'enにもjaにもある', LClass_en.ll('ja',:in_both_langs)
156 assert_equal 'enにもjaにもある', LClass_ja.ll('ja',:in_both_langs)
157
158 assert_equal 'This is in en+ja', ll('en',:in_both_langs)
159 assert_equal 'This is in en+ja', GLoc::ll('en',:in_both_langs)
160 assert_equal 'This is in en+ja', LClass_en.ll('en',:in_both_langs)
161 assert_equal 'This is in en+ja', LClass_ja.ll('en',:in_both_langs)
162 end
163
164 def test_lsym
165 GLoc.load_localized_strings File.join(File.dirname(__FILE__),'lang')
166 assert_equal 'enにもjaにもある', LClass_ja.ltry(:in_both_langs)
167 assert_equal 'hello', LClass_ja.ltry('hello')
168 assert_equal nil, LClass_ja.ltry(nil)
169 end
170
171 # def test_forced
172 # assert_equal :en_AU, LClass_forced_au.current_language
173 # a= LClass_forced_au.new
174 # a.set_language :ja
175 # assert_equal :en_AU, a.current_language
176 # a.force_language :ja
177 # assert_equal :ja, a.current_language
178 # assert_equal :en_AU, LClass_forced_au.current_language
179 # end
180
181 def test_pluralization
182 GLoc.add_localized_strings :en, :_gloc_rule_default => %[|n| case n; when 0 then '_none'; when 1 then '_single'; else '_many'; end], :a_single => '%d man', :a_many => '%d men', :a_none => 'No men'
183 GLoc.add_localized_strings :en, :_gloc_rule_asd => %[|n| n<10 ? '_few' : '_heaps'], :a_few => 'a few men (%d)', :a_heaps=> 'soo many men'
184 set_language :en
185
186 assert_equal 'No men', lwr(:a, 0)
187 assert_equal '1 man', lwr(:a, 1)
188 assert_equal '3 men', lwr(:a, 3)
189 assert_equal '20 men', lwr(:a, 20)
190
191 assert_equal 'a few men (0)', lwr_(:asd, :a, 0)
192 assert_equal 'a few men (1)', lwr_(:asd, :a, 1)
193 assert_equal 'a few men (3)', lwr_(:asd, :a, 3)
194 assert_equal 'soo many men', lwr_(:asd, :a, 12)
195 assert_equal 'soo many men', lwr_(:asd, :a, 20)
196
197 end
198
199 def test_distance_in_words
200 load_default_strings
201 [
202 [20.seconds, 'less than a minute', '1分以内', 'меньше минуты'],
203 [80.seconds, '1 minute', '1分', '1 минуту'],
204 [3.seconds, 'less than 5 seconds', '5秒以内', 'менее 5 секунд', true],
205 [9.seconds, 'less than 10 seconds', '10秒以内', 'менее 10 секунд', true],
206 [16.seconds, 'less than 20 seconds', '20秒以内', 'менее 20 секунд', true],
207 [35.seconds, 'half a minute', '約30秒', 'полминуты', true],
208 [50.seconds, 'less than a minute', '1分以内', 'меньше минуты', true],
209 [1.1.minutes, '1 minute', '1分', '1 минуту'],
210 [2.1.minutes, '2 minutes', '2分', '2 минуты'],
211 [4.1.minutes, '4 minutes', '4分', '4 минуты'],
212 [5.1.minutes, '5 minutes', '5分', '5 минут'],
213 [1.1.hours, 'about an hour', '約1時間', 'около часа'],
214 [3.1.hours, 'about 3 hours', '約3時間', 'около 3 часов'],
215 [9.1.hours, 'about 9 hours', '約9時間', 'около 9 часов'],
216 [1.1.days, '1 day', '1日間', '1 день'],
217 [2.1.days, '2 days', '2日間', '2 дня'],
218 [4.days, '4 days', '4日間', '4 дня'],
219 [6.days, '6 days', '6日間', '6 дней'],
220 [11.days, '11 days', '11日間', '11 дней'],
221 [12.days, '12 days', '12日間', '12 дней'],
222 [15.days, '15 days', '15日間', '15 дней'],
223 [20.days, '20 days', '20日間', '20 дней'],
224 [21.days, '21 days', '21日間', '21 день'],
225 [22.days, '22 days', '22日間', '22 дня'],
226 [25.days, '25 days', '25日間', '25 дней'],
227 ].each do |a|
228 t, en, ja, ru = a
229 inc_sec= (a.size == 5) ? a[-1] : false
230 set_language :en
231 assert_equal en, distance_of_time_in_words(t,0,inc_sec)
232 set_language :ja
233 assert_equal ja, distance_of_time_in_words(t,0,inc_sec)
234 set_language :ru
235 assert_equal ru, distance_of_time_in_words(t,0,inc_sec)
236 end
237 end
238
239 def test_age
240 load_default_strings
241 [
242 [1, '1 yr', '1歳', '1 год'],
243 [22, '22 yrs', '22歳', '22 года'],
244 [27, '27 yrs', '27歳', '27 лет'],
245 ].each do |a, en, ja, ru|
246 set_language :en
247 assert_equal en, l_age(a)
248 set_language :ja
249 assert_equal ja, l_age(a)
250 set_language :ru
251 assert_equal ru, l_age(a)
252 end
253 end
254
255 def test_yesno
256 load_default_strings
257 set_language :en
258 assert_equal 'yes', l_yesno(true)
259 assert_equal 'no', l_yesno(false)
260 assert_equal 'Yes', l_YesNo(true)
261 assert_equal 'No', l_YesNo(false)
262 end
263
264 def test_all_languages_have_values_for_helpers
265 load_default_strings
266 t= Time.local(2000, 9, 15, 11, 23, 57)
267 GLoc.valid_languages.each {|l|
268 set_language l
269 0.upto(120) {|n| l_age(n)}
270 l_date(t)
271 l_datetime(t)
272 l_datetime_short(t)
273 l_time(t)
274 [true,false].each{|v| l_YesNo(v); l_yesno(v) }
275 }
276 end
277
278 def test_similar_languages
279 GLoc.add_localized_strings :en, :a => 'a'
280 GLoc.add_localized_strings :en_AU, :a => 'a'
281 GLoc.add_localized_strings :ja, :a => 'a'
282 GLoc.add_localized_strings :zh_tw, :a => 'a'
283
284 assert_equal :en, GLoc.similar_language(:en)
285 assert_equal :en, GLoc.similar_language('en')
286 assert_equal :ja, GLoc.similar_language(:ja)
287 assert_equal :ja, GLoc.similar_language('ja')
288 # lowercase + dashes to underscores
289 assert_equal :en, GLoc.similar_language('EN')
290 assert_equal :en, GLoc.similar_language(:EN)
291 assert_equal :en_AU, GLoc.similar_language(:EN_Au)
292 assert_equal :en_AU, GLoc.similar_language('eN-Au')
293 # remove dialect
294 assert_equal :ja, GLoc.similar_language(:ja_Au)
295 assert_equal :ja, GLoc.similar_language('JA-ASDF')
296 assert_equal :ja, GLoc.similar_language('jA_ASD_ZXC')
297 # different dialect
298 assert_equal :zh_tw, GLoc.similar_language('ZH')
299 assert_equal :zh_tw, GLoc.similar_language('ZH_HK')
300 assert_equal :zh_tw, GLoc.similar_language('ZH-BUL')
301 # non matching
302 assert_equal nil, GLoc.similar_language('WW')
303 assert_equal nil, GLoc.similar_language('WW_AU')
304 assert_equal nil, GLoc.similar_language('WW-AU')
305 assert_equal nil, GLoc.similar_language('eZ_en')
306 assert_equal nil, GLoc.similar_language('AU-ZH')
307 end
308
309 def test_clear_strings_and_similar_langs
310 GLoc.add_localized_strings :en, :a => 'a'
311 GLoc.add_localized_strings :en_AU, :a => 'a'
312 GLoc.add_localized_strings :ja, :a => 'a'
313 GLoc.add_localized_strings :zh_tw, :a => 'a'
314 GLoc.clear_strings :en, :ja
315 assert_equal nil, GLoc.similar_language('ja')
316 assert_equal :en_AU, GLoc.similar_language('en')
317 assert_equal :zh_tw, GLoc.similar_language('ZH_HK')
318 GLoc.clear_strings
319 assert_equal nil, GLoc.similar_language('ZH_HK')
320 end
321
322 def test_lang_name
323 GLoc.add_localized_strings :en, :general_lang_en => 'English', :general_lang_ja => 'Japanese'
324 GLoc.add_localized_strings :ja, :general_lang_en => '英語', :general_lang_ja => '日本語'
325 set_language :en
326 assert_equal 'Japanese', l_lang_name(:ja)
327 assert_equal 'English', l_lang_name('en')
328 set_language :ja
329 assert_equal '日本語', l_lang_name('ja')
330 assert_equal '英語', l_lang_name(:en)
331 end
332
333 def test_charset_change_all
334 load_default_strings
335 GLoc.add_localized_strings :ja2, :a => 'a'
336 GLoc.valid_languages # Force refresh if in dev mode
337 GLoc.class_eval 'LOCALIZED_STRINGS[:ja2]= LOCALIZED_STRINGS[:ja].clone'
338
339 [:ja, :ja2].each do |l|
340 set_language l
341 assert_equal 'はい', l_yesno(true)
342 assert_equal "E381AFE38184", l_yesno(true).unpack('H*')[0].upcase
343 end
344
345 GLoc.set_charset 'sjis'
346 assert_equal 'sjis', GLoc.get_charset(:ja)
347 assert_equal 'sjis', GLoc.get_charset(:ja2)
348
349 [:ja, :ja2].each do |l|
350 set_language l
351 assert_equal "82CD82A2", l_yesno(true).unpack('H*')[0].upcase
352 end
353 end
354
355 def test_charset_change_single
356 load_default_strings
357 GLoc.add_localized_strings :ja2, :a => 'a'
358 GLoc.add_localized_strings :ja3, :a => 'a'
359 GLoc.valid_languages # Force refresh if in dev mode
360 GLoc.class_eval 'LOCALIZED_STRINGS[:ja2]= LOCALIZED_STRINGS[:ja].clone'
361 GLoc.class_eval 'LOCALIZED_STRINGS[:ja3]= LOCALIZED_STRINGS[:ja].clone'
362
363 [:ja, :ja2, :ja3].each do |l|
364 set_language l
365 assert_equal 'はい', l_yesno(true)
366 assert_equal "E381AFE38184", l_yesno(true).unpack('H*')[0].upcase
367 end
368
369 GLoc.set_charset 'sjis', :ja
370 assert_equal 'sjis', GLoc.get_charset(:ja)
371 assert_equal 'utf-8', GLoc.get_charset(:ja2)
372 assert_equal 'utf-8', GLoc.get_charset(:ja3)
373
374 set_language :ja
375 assert_equal "82CD82A2", l_yesno(true).unpack('H*')[0].upcase
376 set_language :ja2
377 assert_equal "E381AFE38184", l_yesno(true).unpack('H*')[0].upcase
378 set_language :ja3
379 assert_equal "E381AFE38184", l_yesno(true).unpack('H*')[0].upcase
380
381 GLoc.set_charset 'euc-jp', :ja, :ja3
382 assert_equal 'euc-jp', GLoc.get_charset(:ja)
383 assert_equal 'utf-8', GLoc.get_charset(:ja2)
384 assert_equal 'euc-jp', GLoc.get_charset(:ja3)
385
386 set_language :ja
387 assert_equal "A4CFA4A4", l_yesno(true).unpack('H*')[0].upcase
388 set_language :ja2
389 assert_equal "E381AFE38184", l_yesno(true).unpack('H*')[0].upcase
390 set_language :ja3
391 assert_equal "A4CFA4A4", l_yesno(true).unpack('H*')[0].upcase
392 end
393
394 def test_set_language_if_valid
395 GLoc.add_localized_strings :en, :a => 'a'
396 GLoc.add_localized_strings :zh_tw, :a => 'a'
397
398 assert set_language_if_valid('en')
399 assert_equal :en, current_language
400
401 assert set_language_if_valid('zh_tw')
402 assert_equal :zh_tw, current_language
403
404 assert !set_language_if_valid(nil)
405 assert_equal :zh_tw, current_language
406
407 assert !set_language_if_valid('ja')
408 assert_equal :zh_tw, current_language
409
410 assert set_language_if_valid(:en)
411 assert_equal :en, current_language
412 end
413
414 #===========================================================================
415 protected
416
417 def assert_localized_value(objects,expected,key)
418 objects = [objects] unless objects.kind_of?(Array)
419 objects.each {|object|
420 o = object || GLoc
421 assert_equal !expected.nil?, o.l_has_string?(key)
422 if expected.nil?
423 assert_raise(GLoc::StringNotFoundError) {o.l(key)}
424 else
425 assert_equal expected, o.l(key)
426 end
427 }
428 end
429
430 def load_default_strings
431 GLoc.load_localized_strings File.join(File.dirname(__FILE__),'..','lang')
432 end
433 end No newline at end of file
@@ -0,0 +1,2
1 in_both_langs: This is in en+ja
2 en_only: English only No newline at end of file
@@ -0,0 +1,2
1 in_both_langs: Thiz in en 'n' ja
2 en_only: Aussie English only bro No newline at end of file
@@ -0,0 +1,2
1 in_both_langs: enにもjaにもある
2 ja_only: 日本語のみ No newline at end of file
@@ -0,0 +1,2
1 en_only: overriden dude
2 new_en: This is a new English string No newline at end of file
@@ -0,0 +1,2
1 in_both_langs: 更新された
2 new_ja: 新たな日本語ストリング No newline at end of file
@@ -0,0 +1,23
1 module ActiveSupport #:nodoc:
2 module CoreExtensions #:nodoc:
3 module String #:nodoc:
4 # Additional string tests.
5 module StartsEndsWith
6 # Does the string start with the specified +prefix+?
7 def starts_with?(prefix)
8 prefix = prefix.to_s
9 self[0, prefix.length] == prefix
10 end
11
12 # Does the string end with the specified +suffix+?
13 def ends_with?(suffix)
14 suffix = suffix.to_s
15 self[-suffix.length, suffix.length] == suffix
16 end
17 end
18 end
19 end
20 end
21 class String
22 include ActiveSupport::CoreExtensions::String::StartsEndsWith
23 end No newline at end of file
@@ -0,0 +1,76
1 module ActiveSupport #:nodoc:
2 module CoreExtensions #:nodoc:
3 module Numeric #:nodoc:
4 # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
5 #
6 # If you need precise date calculations that doesn't just treat months as 30 days, then have
7 # a look at Time#advance.
8 #
9 # Some of these methods are approximations, Ruby's core
10 # Date[http://stdlib.rubyonrails.org/libdoc/date/rdoc/index.html] and
11 # Time[http://stdlib.rubyonrails.org/libdoc/time/rdoc/index.html] should be used for precision
12 # date and time arithmetic
13 module Time
14 def seconds
15 self
16 end
17 alias :second :seconds
18
19 def minutes
20 self * 60
21 end
22 alias :minute :minutes
23
24 def hours
25 self * 60.minutes
26 end
27 alias :hour :hours
28
29 def days
30 self * 24.hours
31 end
32 alias :day :days
33
34 def weeks
35 self * 7.days
36 end
37 alias :week :weeks
38
39 def fortnights
40 self * 2.weeks
41 end
42 alias :fortnight :fortnights
43
44 def months
45 self * 30.days
46 end
47 alias :month :months
48
49 def years
50 (self * 365.25.days).to_i
51 end
52 alias :year :years
53
54 # Reads best without arguments: 10.minutes.ago
55 def ago(time = ::Time.now)
56 time - self
57 end
58
59 # Reads best with argument: 10.minutes.until(time)
60 alias :until :ago
61
62 # Reads best with argument: 10.minutes.since(time)
63 def since(time = ::Time.now)
64 time + self
65 end
66
67 # Reads best without arguments: 10.minutes.from_now
68 alias :from_now :since
69 end
70 end
71 end
72 end
73
74 class Numeric #:nodoc:
75 include ActiveSupport::CoreExtensions::Numeric::Time
76 end
@@ -1,77 +1,154
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class AccountController < ApplicationController
19 19 layout 'base'
20 helper :custom_fields
21 include CustomFieldsHelper
20 22
21 23 # prevents login action to be filtered by check_if_login_required application scope filter
22 skip_before_filter :check_if_login_required, :only => :login
23 before_filter :require_login, :except => [:show, :login]
24 skip_before_filter :check_if_login_required, :only => [:login, :lost_password, :register]
25 before_filter :require_login, :except => [:show, :login, :lost_password, :register]
24 26
27 # Show user's account
25 28 def show
26 29 @user = User.find(params[:id])
27 30 end
28 31
29 32 # Login request and validation
30 33 def login
31 34 if request.get?
32 session[:user] = nil
35 # Logout user
36 self.logged_in_user = nil
33 37 else
34 logged_in_user = User.try_to_login(params[:login], params[:password])
35 if logged_in_user
36 session[:user] = logged_in_user
38 # Authenticate user
39 user = User.try_to_login(params[:login], params[:password])
40 if user
41 self.logged_in_user = user
37 42 redirect_back_or_default :controller => 'account', :action => 'my_page'
38 43 else
39 flash[:notice] = _('Invalid user/password')
44 flash[:notice] = l(:notice_account_invalid_creditentials)
40 45 end
41 46 end
42 47 end
43
44 # Log out current user and redirect to welcome page
45 def logout
46 session[:user] = nil
47 redirect_to(:controller => '')
48 end
49 48
50 def my_page
51 @user = session[:user]
52 @reported_issues = Issue.find(:all, :conditions => ["author_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
53 @assigned_issues = Issue.find(:all, :conditions => ["assigned_to_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
54 end
55
56 # Edit current user's account
57 def my_account
58 @user = User.find(session[:user].id)
59 if request.post? and @user.update_attributes(@params[:user])
60 flash[:notice] = 'Account was successfully updated.'
61 session[:user] = @user
49 # Log out current user and redirect to welcome page
50 def logout
51 self.logged_in_user = nil
52 redirect_to :controller => ''
53 end
54
55 # Show logged in user's page
56 def my_page
57 @user = self.logged_in_user
58 @reported_issues = Issue.find(:all, :conditions => ["author_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
59 @assigned_issues = Issue.find(:all, :conditions => ["assigned_to_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
60 end
61
62 # Edit logged in user's account
63 def my_account
64 @user = self.logged_in_user
65 if request.post? and @user.update_attributes(@params[:user])
62 66 set_localization
63 end
64 end
67 flash[:notice] = l(:notice_account_updated)
68 self.logged_in_user.reload
69 end
70 end
65 71
66 # Change current user's password
72 # Change logged in user's password
67 73 def change_password
68 @user = User.find(session[:user].id)
74 @user = self.logged_in_user
69 75 if @user.check_password?(@params[:password])
70 76 @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
71 flash[:notice] = 'Password was successfully updated.' if @user.save
77 flash[:notice] = l(:notice_account_password_updated) if @user.save
72 78 else
73 flash[:notice] = 'Wrong password'
79 flash[:notice] = l(:notice_account_wrong_password)
74 80 end
75 81 render :action => 'my_account'
76 end
82 end
83
84 # Enable user to choose a new password
85 def lost_password
86 if params[:token]
87 @token = Token.find_by_action_and_value("recovery", params[:token])
88 redirect_to :controller => '' and return unless @token and !@token.expired?
89 @user = @token.user
90 if request.post?
91 @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
92 if @user.save
93 @token.destroy
94 flash[:notice] = l(:notice_account_password_updated)
95 redirect_to :action => 'login'
96 return
97 end
98 end
99 render :template => "account/password_recovery"
100 return
101 else
102 if request.post?
103 user = User.find_by_mail(params[:mail])
104 flash[:notice] = l(:notice_account_unknown_email) and return unless user
105 token = Token.new(:user => user, :action => "recovery")
106 if token.save
107 Mailer.set_language_if_valid(Localization.lang)
108 Mailer.deliver_lost_password(token)
109 flash[:notice] = l(:notice_account_lost_email_sent)
110 redirect_to :action => 'login'
111 return
112 end
113 end
114 end
115 end
116
117 # User self-registration
118 def register
119 redirect_to :controller => '' and return if $RDM_SELF_REGISTRATION == false
120 if params[:token]
121 token = Token.find_by_action_and_value("register", params[:token])
122 redirect_to :controller => '' and return unless token and !token.expired?
123 user = token.user
124 redirect_to :controller => '' and return unless user.status == User::STATUS_REGISTERED
125 user.status = User::STATUS_ACTIVE
126 if user.save
127 token.destroy
128 flash[:notice] = l(:notice_account_activated)
129 redirect_to :action => 'login'
130 return
131 end
132 else
133 if request.get?
134 @user = User.new(:language => $RDM_DEFAULT_LANG)
135 @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
136 else
137 @user = User.new(params[:user])
138 @user.admin = false
139 @user.login = params[:user][:login]
140 @user.status = User::STATUS_REGISTERED
141 @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
142 @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
143 @user.custom_values = @custom_values
144 token = Token.new(:user => @user, :action => "register")
145 if @user.save and token.save
146 Mailer.set_language_if_valid(Localization.lang)
147 Mailer.deliver_register(token)
148 flash[:notice] = l(:notice_account_register_done)
149 redirect_to :controller => ''
150 end
151 end
152 end
153 end
77 154 end
@@ -1,96 +1,111
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class ApplicationController < ActionController::Base
19 19 before_filter :check_if_login_required, :set_localization
20 20
21 def logged_in_user=(user)
22 @logged_in_user = user
23 session[:user_id] = (user ? user.id : nil)
24 end
25
26 def logged_in_user
27 if session[:user_id]
28 @logged_in_user ||= User.find(session[:user_id], :include => :memberships)
29 else
30 nil
31 end
32 end
33
21 34 # check if login is globally required to access the application
22 35 def check_if_login_required
23 require_login if RDM_LOGIN_REQUIRED
36 require_login if $RDM_LOGIN_REQUIRED
24 37 end
25 38
26 39 def set_localization
27 40 Localization.lang = begin
28 if session[:user]
29 session[:user].language
41 if self.logged_in_user and Localization.langs.keys.include? self.logged_in_user.language
42 self.logged_in_user.language
30 43 elsif request.env['HTTP_ACCEPT_LANGUAGE']
31 44 accept_lang = HTTPUtils.parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.split('-').first
32 if Localization.langs.collect{ |l| l[1] }.include? accept_lang
45 if Localization.langs.keys.include? accept_lang
33 46 accept_lang
34 47 end
35 48 end
36 49 rescue
37 50 nil
38 end || RDM_DEFAULT_LANG
51 end || $RDM_DEFAULT_LANG
52
53 set_language_if_valid(Localization.lang)
54
39 55 end
40 56
41 57 def require_login
42 unless session[:user]
58 unless self.logged_in_user
43 59 store_location
44 60 redirect_to(:controller => "account", :action => "login")
61 return false
45 62 end
63 true
46 64 end
47 65
48 66 def require_admin
49 if session[:user].nil?
50 store_location
51 redirect_to(:controller => "account", :action => "login")
52 else
53 unless session[:user].admin?
54 flash[:notice] = "Acces not allowed"
55 redirect_to(:controller => "projects", :action => "list")
56 end
67 return unless require_login
68 unless self.logged_in_user.admin?
69 flash[:notice] = "Acces denied"
70 redirect_to:controller => ''
71 return false
57 72 end
73 true
58 74 end
59 75
60 76 # authorizes the user for the requested action.
61 77 def authorize
62 78 # check if action is allowed on public projects
63 79 if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ @params[:controller], @params[:action] ]
64 80 return true
65 end
66 # if user not logged in, redirect to login form
67 unless session[:user]
68 store_location
69 redirect_to(:controller => "account", :action => "login")
70 return false
71 end
72 # if logged in, check if authorized
73 if session[:user].admin? or Permission.allowed_to_role( "%s/%s" % [ @params[:controller], @params[:action] ], session[:user].role_for_project(@project.id) )
81 end
82 # if action is not public, force login
83 return unless require_login
84 # admin is always authorized
85 return true if self.logged_in_user.admin?
86 # if not admin, check membership permission
87 @user_membership ||= Member.find(:first, :conditions => ["user_id=? and project_id=?", self.logged_in_user.id, @project.id])
88 if @user_membership and Permission.allowed_to_role( "%s/%s" % [ @params[:controller], @params[:action] ], @user_membership.role_id )
74 89 return true
75 90 end
76 91 flash[:notice] = "Acces denied"
77 redirect_to(:controller => "")
92 redirect_to :controller => ''
78 93 false
79 94 end
80 95
81 96 # store current uri in session.
82 97 # return to this location by calling redirect_back_or_default
83 98 def store_location
84 99 session[:return_to] = @request.request_uri
85 100 end
86 101
87 102 # move to the last store_location call or to the passed default one
88 103 def redirect_back_or_default(default)
89 104 if session[:return_to].nil?
90 105 redirect_to default
91 106 else
92 107 redirect_to_url session[:return_to]
93 108 session[:return_to] = nil
94 109 end
95 110 end
96 111 end No newline at end of file
@@ -1,58 +1,69
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class CustomFieldsController < ApplicationController
19 layout 'base'
20 before_filter :require_admin
21
19 layout 'base'
20 before_filter :require_admin
21
22 22 def index
23 23 list
24 24 render :action => 'list'
25 25 end
26 26
27 27 def list
28 @custom_field_pages, @custom_fields = paginate :custom_fields, :per_page => 10
28 @custom_field_pages, @custom_fields = paginate :custom_fields, :per_page => 15
29 29 end
30
30
31 31 def new
32 if request.get?
33 @custom_field = CustomField.new
34 else
35 @custom_field = CustomField.new(params[:custom_field])
36 if @custom_field.save
37 flash[:notice] = 'CustomField was successfully created.'
38 redirect_to :action => 'list'
32 case params[:type]
33 when "IssueCustomField"
34 @custom_field = IssueCustomField.new(params[:custom_field])
35 @custom_field.trackers = Tracker.find(params[:tracker_ids]) if params[:tracker_ids]
36 when "UserCustomField"
37 @custom_field = UserCustomField.new(params[:custom_field])
38 when "ProjectCustomField"
39 @custom_field = ProjectCustomField.new(params[:custom_field])
40 else
41 redirect_to :action => 'list'
42 return
43 end
44 if request.post? and @custom_field.save
45 redirect_to :action => 'list'
46 end
47 @trackers = Tracker.find(:all)
48 end
49
50 def edit
51 @custom_field = CustomField.find(params[:id])
52 if request.post? and @custom_field.update_attributes(params[:custom_field])
53 if @custom_field.is_a? IssueCustomField
54 @custom_field.trackers = params[:tracker_ids] ? Tracker.find(params[:tracker_ids]) : []
39 55 end
40 end
41 end
42
43 def edit
44 @custom_field = CustomField.find(params[:id])
45 if request.post? and @custom_field.update_attributes(params[:custom_field])
46 flash[:notice] = 'CustomField was successfully updated.'
47 redirect_to :action => 'list'
48 end
49 end
56 flash[:notice] = 'Custom field was successfully updated.'
57 redirect_to :action => 'list'
58 end
59 @trackers = Tracker.find(:all)
60 end
50 61
51 62 def destroy
52 63 CustomField.find(params[:id]).destroy
53 64 redirect_to :action => 'list'
54 65 rescue
55 66 flash[:notice] = "Unable to delete custom field"
56 67 redirect_to :action => 'list'
57 end
68 end
58 69 end
@@ -1,65 +1,65
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class DocumentsController < ApplicationController
19 19 layout 'base'
20 20 before_filter :find_project, :authorize
21 21
22 22 def show
23 23 end
24 24
25 25 def edit
26 26 @categories = Enumeration::get_values('DCAT')
27 27 if request.post? and @document.update_attributes(params[:document])
28 28 flash[:notice] = 'Document was successfully updated.'
29 29 redirect_to :action => 'show', :id => @document
30 30 end
31 31 end
32 32
33 33 def destroy
34 34 @document.destroy
35 35 redirect_to :controller => 'projects', :action => 'list_documents', :id => @project
36 36 end
37 37
38 38 def download
39 39 @attachment = @document.attachments.find(params[:attachment_id])
40 40 @attachment.increment_download
41 41 send_file @attachment.diskfile, :filename => @attachment.filename
42 42 end
43 43
44 44 def add_attachment
45 45 # Save the attachment
46 46 if params[:attachment][:file].size > 0
47 47 @attachment = @document.attachments.build(params[:attachment])
48 @attachment.author_id = session[:user].id unless session[:user].nil?
48 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
49 49 @attachment.save
50 50 end
51 51 render :action => 'show'
52 52 end
53 53
54 54 def destroy_attachment
55 55 @document.attachments.find(params[:attachment_id]).destroy
56 56 render :action => 'show'
57 57 end
58 58
59 59 private
60 60 def find_project
61 61 @document = Document.find(params[:id])
62 62 @project = @document.project
63 63 end
64 64
65 65 end
@@ -1,102 +1,100
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class IssuesController < ApplicationController
19 19 layout 'base'
20 20 before_filter :find_project, :authorize
21 21
22 22 helper :custom_fields
23 23 include CustomFieldsHelper
24 24
25 25 def show
26 @status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", session[:user].role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if session[:user]
26 @status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user
27 @custom_values = @issue.custom_values.find(:all, :include => :custom_field)
27 28 end
28 29
29 def edit
30 @trackers = Tracker.find(:all)
30 def edit
31 31 @priorities = Enumeration::get_values('IPRI')
32 32
33 33 if request.get?
34 @custom_values = @project.custom_fields_for_issues.collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
34 @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) }
35 35 else
36 36 # Retrieve custom fields and values
37 @custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x, :value => params["custom_fields"][x.id.to_s]) }
38
37 @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
39 38 @issue.custom_values = @custom_values
40 if @issue.update_attributes(params[:issue])
39 @issue.attributes = params[:issue]
40 if @issue.save
41 41 flash[:notice] = 'Issue was successfully updated.'
42 42 redirect_to :action => 'show', :id => @issue
43 43 end
44 44 end
45 45 end
46 46
47 47 def change_status
48 48 @history = @issue.histories.build(params[:history])
49 @status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", session[:user].role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if session[:user]
49 @status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user
50 50
51 51 if params[:confirm]
52 unless session[:user].nil?
53 @history.author = session[:user]
54 end
52 @history.author_id = self.logged_in_user.id if self.logged_in_user
53
55 54 if @history.save
56 55 @issue.status = @history.status
57 56 @issue.fixed_version_id = (params[:issue][:fixed_version_id])
58 57 @issue.assigned_to_id = (params[:issue][:assigned_to_id])
59 58 if @issue.save
60 59 flash[:notice] = 'Issue was successfully updated.'
61 60 Mailer.deliver_issue_change_status(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
62 61 redirect_to :action => 'show', :id => @issue
63 62 end
64 63 end
65 64 end
66 65 @assignable_to = @project.members.find(:all, :include => :user).collect{ |m| m.user }
67 66
68 67 end
69 68
70 69 def destroy
71 70 @issue.destroy
72 71 redirect_to :controller => 'projects', :action => 'list_issues', :id => @project
73 72 end
74 73
75 74 def add_attachment
76 75 # Save the attachment
77 76 if params[:attachment][:file].size > 0
78 77 @attachment = @issue.attachments.build(params[:attachment])
79 @attachment.author_id = session[:user].id unless session[:user].nil?
78 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
80 79 @attachment.save
81 80 end
82 81 redirect_to :action => 'show', :id => @issue
83 82 end
84 83
85 84 def destroy_attachment
86 85 @issue.attachments.find(params[:attachment_id]).destroy
87 86 redirect_to :action => 'show', :id => @issue
88 87 end
89
90 # Send the file in stream mode
91 def download
92 @attachment = @issue.attachments.find(params[:attachment_id])
93 send_file @attachment.diskfile, :filename => @attachment.filename
94 end
95
88
89 # Send the file in stream mode
90 def download
91 @attachment = @issue.attachments.find(params[:attachment_id])
92 send_file @attachment.diskfile, :filename => @attachment.filename
93 end
94
96 95 private
97 def find_project
96 def find_project
98 97 @issue = Issue.find(params[:id])
99 @project = @issue.project
100 end
101
98 @project = @issue.project
99 end
102 100 end
@@ -1,282 +1,292
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class ProjectsController < ApplicationController
19 19 layout 'base'
20 20 before_filter :find_project, :authorize, :except => [ :index, :list, :add ]
21 21 before_filter :require_admin, :only => [ :add, :destroy ]
22 22
23 23 helper :sort
24 24 include SortHelper
25 25 helper :search_filter
26 26 include SearchFilterHelper
27 27 helper :custom_fields
28 28 include CustomFieldsHelper
29 29
30 30 def index
31 31 list
32 32 render :action => 'list'
33 33 end
34 34
35 35 # Lists public projects
36 36 def list
37 37 sort_init 'name', 'asc'
38 38 sort_update
39 39 @project_count = Project.count(["is_public=?", true])
40 40 @project_pages = Paginator.new self, @project_count,
41 41 15,
42 42 @params['page']
43 43 @projects = Project.find :all, :order => sort_clause,
44 44 :conditions => ["is_public=?", true],
45 45 :limit => @project_pages.items_per_page,
46 46 :offset => @project_pages.current.offset
47 47 end
48 48
49 49 # Add a new project
50 50 def add
51 @custom_fields = CustomField::find_all
52 @root_projects = Project::find(:all, :conditions => "parent_id is null")
51 @custom_fields = IssueCustomField.find(:all)
52 @root_projects = Project.find(:all, :conditions => "parent_id is null")
53 53 @project = Project.new(params[:project])
54 if request.post?
55 @project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
54 if request.get?
55 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project) }
56 else
57 @project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
58 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
59 @project.custom_values = @custom_values
56 60 if @project.save
57 61 flash[:notice] = 'Project was successfully created.'
58 62 redirect_to :controller => 'admin', :action => 'projects'
59 63 end
60 64 end
61 65 end
62 66
63 # Show @project
67 # Show @project
64 68 def show
69 @custom_values = @project.custom_values.find(:all, :include => :custom_field)
65 70 @members = @project.members.find(:all, :include => [:user, :role])
66 71 @subprojects = @project.children if @project.children_count > 0
67 @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
72 @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
73 @trackers = Tracker.find(:all)
68 74 end
69 75
70 76 def settings
71 77 @root_projects = Project::find(:all, :conditions => ["parent_id is null and id <> ?", @project.id])
72 @custom_fields = CustomField::find_all
78 @custom_fields = IssueCustomField::find_all
73 79 @issue_category ||= IssueCategory.new
74 80 @member ||= @project.members.new
75 81 @roles = Role.find_all
76 82 @users = User.find_all - @project.members.find(:all, :include => :user).collect{|m| m.user }
83 @custom_values = ProjectCustomField.find(:all).collect { |x| @project.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
77 84 end
78 85
79 86 # Edit @project
80 87 def edit
81 88 if request.post?
82 @project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
89 @project.custom_fields = IssueCustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
90 if params[:custom_fields]
91 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
92 @project.custom_values = @custom_values
93 end
83 94 if @project.update_attributes(params[:project])
84 95 flash[:notice] = 'Project was successfully updated.'
85 96 redirect_to :action => 'settings', :id => @project
86 97 else
87 98 settings
88 99 render :action => 'settings'
89 100 end
90 101 end
91 102 end
92
93 # Delete @project
94 def destroy
103
104 # Delete @project
105 def destroy
95 106 if request.post? and params[:confirm]
96 107 @project.destroy
97 108 redirect_to :controller => 'admin', :action => 'projects'
98 109 end
99 end
110 end
100 111
101 # Add a new issue category to @project
102 def add_issue_category
103 if request.post?
104 @issue_category = @project.issue_categories.build(params[:issue_category])
105 if @issue_category.save
106 redirect_to :action => 'settings', :id => @project
107 else
112 # Add a new issue category to @project
113 def add_issue_category
114 if request.post?
115 @issue_category = @project.issue_categories.build(params[:issue_category])
116 if @issue_category.save
117 redirect_to :action => 'settings', :id => @project
118 else
108 119 settings
109 120 render :action => 'settings'
110 end
111 end
112 end
121 end
122 end
123 end
113 124
114 # Add a new version to @project
115 def add_version
116 @version = @project.versions.build(params[:version])
117 if request.post? and @version.save
125 # Add a new version to @project
126 def add_version
127 @version = @project.versions.build(params[:version])
128 if request.post? and @version.save
118 129 redirect_to :action => 'settings', :id => @project
119 end
120 end
130 end
131 end
121 132
122 # Add a new member to @project
123 def add_member
133 # Add a new member to @project
134 def add_member
124 135 @member = @project.members.build(params[:member])
125 if request.post?
126 if @member.save
136 if request.post?
137 if @member.save
127 138 flash[:notice] = 'Member was successfully added.'
128 redirect_to :action => 'settings', :id => @project
129 else
139 redirect_to :action => 'settings', :id => @project
140 else
130 141 settings
131 142 render :action => 'settings'
132 143 end
133 end
134 end
144 end
145 end
135 146
136 # Show members list of @project
137 def list_members
138 @members = @project.members
139 end
147 # Show members list of @project
148 def list_members
149 @members = @project.members
150 end
140 151
141 # Add a new document to @project
142 def add_document
143 @categories = Enumeration::get_values('DCAT')
144 @document = @project.documents.build(params[:document])
145 if request.post?
152 # Add a new document to @project
153 def add_document
154 @categories = Enumeration::get_values('DCAT')
155 @document = @project.documents.build(params[:document])
156 if request.post?
146 157 # Save the attachment
147 if params[:attachment][:file].size > 0
148 @attachment = @document.attachments.build(params[:attachment])
149 @attachment.author_id = session[:user].id unless session[:user].nil?
150 end
151 if @document.save
152 redirect_to :action => 'list_documents', :id => @project
153 end
154 end
155 end
156
157 # Show documents list of @project
158 def list_documents
159 @documents = @project.documents
160 end
158 if params[:attachment][:file].size > 0
159 @attachment = @document.attachments.build(params[:attachment])
160 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
161 end
162 if @document.save
163 redirect_to :action => 'list_documents', :id => @project
164 end
165 end
166 end
167
168 # Show documents list of @project
169 def list_documents
170 @documents = @project.documents
171 end
161 172
162 # Add a new issue to @project
163 def add_issue
164 @trackers = Tracker.find(:all)
165 @priorities = Enumeration::get_values('IPRI')
166 if request.get?
167 @issue = @project.issues.build
168 @custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x) }
169 else
170 # Create the issue and set the author
171 @issue = @project.issues.build(params[:issue])
172 @issue.author = session[:user] unless session[:user].nil?
173 # Create the document if a file was sent
174 if params[:attachment][:file].size > 0
175 @attachment = @issue.attachments.build(params[:attachment])
176 @attachment.author_id = session[:user].id unless session[:user].nil?
177 end
178 @custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x, :value => params["custom_fields"][x.id.to_s]) }
179 @issue.custom_values = @custom_values
180 if @issue.save
173 # Add a new issue to @project
174 def add_issue
175 @tracker = Tracker.find(params[:tracker_id])
176 @priorities = Enumeration::get_values('IPRI')
177 @issue = Issue.new(:project => @project, :tracker => @tracker)
178 if request.get?
179 @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) }
180 else
181 @issue.attributes = params[:issue]
182 @issue.author_id = self.logged_in_user.id if self.logged_in_user
183 # Create the document if a file was sent
184 if params[:attachment][:file].size > 0
185 @attachment = @issue.attachments.build(params[:attachment])
186 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
187 end
188 @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
189 @issue.custom_values = @custom_values
190 if @issue.save
181 191 flash[:notice] = "Issue was successfully added."
182 Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
183 redirect_to :action => 'list_issues', :id => @project
184 end
185 end
186 end
187
192 Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
193 redirect_to :action => 'list_issues', :id => @project
194 end
195 end
196 end
197
188 198 # Show filtered/sorted issues list of @project
189 199 def list_issues
190 200 sort_init 'issues.id', 'desc'
191 201 sort_update
192 202
193 203 search_filter_init_list_issues
194 204 search_filter_update if params[:set_filter] or request.post?
195 205
196 206 @issue_count = Issue.count(:include => [:status, :project], :conditions => search_filter_clause)
197 207 @issue_pages = Paginator.new self, @issue_count, 15, @params['page']
198 @issues = Issue.find :all, :order => sort_clause,
208 @issues = Issue.find :all, :order => sort_clause,
199 209 :include => [ :author, :status, :tracker, :project ],
200 210 :conditions => search_filter_clause,
201 211 :limit => @issue_pages.items_per_page,
202 :offset => @issue_pages.current.offset
212 :offset => @issue_pages.current.offset
203 213 end
204 214
205 215 # Export filtered/sorted issues list to CSV
206 216 def export_issues_csv
207 217 sort_init 'issues.id', 'desc'
208 218 sort_update
209 219
210 220 search_filter_init_list_issues
211 221
212 222 @issues = Issue.find :all, :order => sort_clause,
213 223 :include => [ :author, :status, :tracker, :project ],
214 224 :conditions => search_filter_clause
215 225
216 226 export = StringIO.new
217 227 CSV::Writer.generate(export, ',') do |csv|
218 228 csv << %w(Id Status Tracker Subject Author Created Updated)
219 229 @issues.each do |issue|
220 230 csv << [issue.id, issue.status.name, issue.tracker.name, issue.subject, issue.author.display_name, _('(time)', issue.created_on), _('(time)', issue.updated_on)]
221 231 end
222 232 end
223 233 export.rewind
224 234 send_data(export.read,
225 235 :type => 'text/csv; charset=utf-8; header=present',
226 236 :filename => 'export.csv')
227 237 end
228
229 # Add a news to @project
230 def add_news
231 @news = @project.news.build(params[:news])
232 if request.post?
233 @news.author = session[:user] unless session[:user].nil?
234 if @news.save
235 redirect_to :action => 'list_news', :id => @project
236 end
237 end
238 end
239 238
240 # Show news list of @project
239 # Add a news to @project
240 def add_news
241 @news = News.new(:project => @project)
242 if request.post?
243 @news.attributes = params[:news]
244 @news.author_id = self.logged_in_user.id if self.logged_in_user
245 if @news.save
246 redirect_to :action => 'list_news', :id => @project
247 end
248 end
249 end
250
251 # Show news list of @project
241 252 def list_news
242 253 @news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "news.created_on DESC"
243 254 end
244
255
245 256 def add_file
246 257 if request.post?
247 258 # Save the attachment
248 259 if params[:attachment][:file].size > 0
249 260 @attachment = @project.versions.find(params[:version_id]).attachments.build(params[:attachment])
250 @attachment.author_id = session[:user].id unless session[:user].nil?
261 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
251 262 if @attachment.save
252 263 redirect_to :controller => 'projects', :action => 'list_files', :id => @project
253 264 end
254 265 end
255 266 end
256 267 @versions = @project.versions
257 268 end
258 269
259 270 def list_files
260 271 @versions = @project.versions
261 272 end
262 273
263 274 # Show changelog of @project
264 275 def changelog
265 276 @fixed_issues = @project.issues.find(:all,
266 277 :include => [ :fixed_version, :status, :tracker ],
267 278 :conditions => [ "issue_statuses.is_closed=? and trackers.is_in_chlog=? and issues.fixed_version_id is not null", true, true]
268 279 )
269 280 end
270 281
271 282 private
272 # Find project of id params[:id]
273 # if not found, redirect to project list
274 # used as a before_filter
275 def find_project
276 @project = Project.find(params[:id])
277 rescue
278 flash[:notice] = 'Project not found.'
279 redirect_to :action => 'list'
280 end
281
283 # Find project of id params[:id]
284 # if not found, redirect to project list
285 # used as a before_filter
286 def find_project
287 @project = Project.find(params[:id])
288 rescue
289 flash[:notice] = 'Project not found.'
290 redirect_to :action => 'list'
291 end
282 292 end
@@ -1,77 +1,88
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class UsersController < ApplicationController
19 19 layout 'base'
20 20 before_filter :require_admin
21 21
22 22 helper :sort
23 23 include SortHelper
24 helper :custom_fields
25 include CustomFieldsHelper
24 26
25 27 def index
26 28 list
27 29 render :action => 'list'
28 30 end
29 31
30 32 def list
31 33 sort_init 'login', 'asc'
32 34 sort_update
33 35 @user_count = User.count
34 36 @user_pages = Paginator.new self, @user_count,
35 37 15,
36 38 @params['page']
37 39 @users = User.find :all,:order => sort_clause,
38 40 :limit => @user_pages.items_per_page,
39 41 :offset => @user_pages.current.offset
40 42 end
41 43
42 44 def add
43 45 if request.get?
44 @user = User.new
46 @user = User.new(:language => $RDM_DEFAULT_LANG)
47 @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
45 48 else
46 49 @user = User.new(params[:user])
47 50 @user.admin = params[:user][:admin] || false
48 51 @user.login = params[:user][:login]
49 52 @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
53 @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
54 @user.custom_values = @custom_values
50 55 if @user.save
51 56 flash[:notice] = 'User was successfully created.'
52 57 redirect_to :action => 'list'
53 58 end
54 59 end
55 60 end
56 61
57 62 def edit
58 63 @user = User.find(params[:id])
59 if request.post?
64 if request.get?
65 @custom_values = UserCustomField.find(:all).collect { |x| @user.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
66 else
60 67 @user.admin = params[:user][:admin] if params[:user][:admin]
61 68 @user.login = params[:user][:login] if params[:user][:login]
62 69 @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless params[:password].nil? or params[:password].empty?
70 if params[:custom_fields]
71 @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
72 @user.custom_values = @custom_values
73 end
63 74 if @user.update_attributes(params[:user])
64 75 flash[:notice] = 'User was successfully updated.'
65 76 redirect_to :action => 'list'
66 77 end
67 78 end
68 79 end
69 80
70 81 def destroy
71 82 User.find(params[:id]).destroy
72 83 redirect_to :action => 'list'
73 84 rescue
74 85 flash[:notice] = "Unable to delete user"
75 86 redirect_to :action => 'list'
76 87 end
77 88 end
@@ -1,26 +1,25
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class WelcomeController < ApplicationController
19 layout 'base'
20
21 def index
19 layout 'base'
20
21 def index
22 22 @news = News.latest
23 23 @projects = Project.latest
24 end
25
24 end
26 25 end
@@ -1,65 +1,93
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 module ApplicationHelper
19 19
20 def loggedin?
21 session[:user]
22 end
20 # return current logged in user or nil
21 def loggedin?
22 @logged_in_user
23 end
24
25 # return true if user is loggend in and is admin, otherwise false
26 def admin_loggedin?
27 @logged_in_user and @logged_in_user.admin?
28 end
23 29
24 def admin_loggedin?
25 session[:user] && session[:user].admin
26 end
27
28 def authorize_for(controller, action)
30 def authorize_for(controller, action)
29 31 # check if action is allowed on public projects
30 32 if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ controller, action ]
31 33 return true
32 end
34 end
33 35 # check if user is authorized
34 if session[:user] and (session[:user].admin? or Permission.allowed_to_role( "%s/%s" % [ controller, action ], session[:user].role_for_project(@project.id) ) )
35 return true
36 end
37 return false
38 end
39
40 def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
41 link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller], options[:action])
42 end
43
44 # Display a link to user's account page
45 def link_to_user(user)
46 link_to user.display_name, :controller => 'account', :action => 'show', :id => user
47 end
48
36 if @logged_in_user and (@logged_in_user.admin? or Permission.allowed_to_role( "%s/%s" % [ controller, action ], @logged_in_user.role_for_project(@project.id) ) )
37 return true
38 end
39 return false
40 end
41
42 # Display a link if user is authorized
43 def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
44 link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller], options[:action])
45 end
46
47 # Display a link to user's account page
48 def link_to_user(user)
49 link_to user.display_name, :controller => 'account', :action => 'show', :id => user
50 end
51
49 52 def format_date(date)
50 53 _('(date)', date) if date
51 54 end
52 55
53 56 def format_time(time)
54 57 _('(time)', time) if time
55 58 end
56 59
57 60 def pagination_links_full(paginator, options={}, html_options={})
58 61 html =''
59 62 html << link_to(('&#171; ' + _('Previous') ), { :page => paginator.current.previous }) + ' ' if paginator.current.previous
60 63 html << (pagination_links(paginator, options, html_options) || '')
61 64 html << ' ' + link_to((_('Next') + ' &#187;'), { :page => paginator.current.next }) if paginator.current.next
62 65 html
63 66 end
64
67
68 def error_messages_for(object_name, options = {})
69 options = options.symbolize_keys
70 object = instance_variable_get("@#{object_name}")
71 if object && !object.errors.empty?
72 # build full_messages here with controller current language
73 full_messages = []
74 object.errors.each do |attr, msg|
75 next if msg.nil?
76 if attr == "base"
77 full_messages << l(msg)
78 else
79 full_messages << "&#171; " + (l_has_string?("field_" + attr) ? l("field_" + attr) : object.class.human_attribute_name(attr)) + " &#187; " + l(msg)
80 end
81 end
82 content_tag("div",
83 content_tag(
84 options[:header_tag] || "h2", lwr(:gui_validation_error, object.errors.count) + " :"
85 ) +
86 content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
87 "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
88 )
89 else
90 ""
91 end
92 end
65 93 end
@@ -1,36 +1,64
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 module CustomFieldsHelper
19 def custom_field_tag(custom_value)
20
21 custom_field = custom_value.custom_field
22
23 field_name = "custom_fields[#{custom_field.id}]"
24
25 case custom_field.typ
26 when 0 .. 2
27 text_field_tag field_name, custom_value.value
28 when 3
29 check_box field_name
30 when 4
31 select_tag field_name,
32 options_for_select(custom_field.possible_values.split('|'),
33 custom_value.value)
34 end
35 end
19
20 def custom_field_tag(custom_value)
21 custom_field = custom_value.custom_field
22 field_name = "custom_fields[#{custom_field.id}]"
23 case custom_field.field_format
24 when "string", "int", "date"
25 text_field_tag field_name, custom_value.value
26 when "text"
27 text_area_tag field_name, custom_value.value, :cols => 60, :rows => 3
28 when "bool"
29 check_box_tag(field_name, "1", custom_value.value == "1") +
30 hidden_field_tag(field_name, "0")
31 when "list"
32 select_tag field_name,
33 "<option></option>" + options_for_select(custom_field.possible_values.split('|'),
34 custom_value.value)
35 end
36 end
37
38 def custom_field_label_tag(custom_value)
39 content_tag "label", custom_value.custom_field.name +
40 (custom_value.custom_field.is_required? ? " <span class=\"required\">*</span>" : "")
41 end
42
43 def custom_field_tag_with_label(custom_value)
44 case custom_value.custom_field.field_format
45 when "bool"
46 custom_field_tag(custom_value) + " " + custom_field_label_tag(custom_value)
47 else
48 custom_field_label_tag(custom_value) + "<br />" + custom_field_tag(custom_value)
49 end
50 end
51
52 def show_value(custom_value)
53 case custom_value.custom_field.field_format
54 when "bool"
55 l_YesNo(custom_value.value == "1")
56 else
57 custom_value.value
58 end
59 end
60
61 def custom_field_formats_for_select
62 CustomField::FIELD_FORMATS.keys.collect { |k| [ l(CustomField::FIELD_FORMATS[k]), k ] }
63 end
36 64 end
@@ -1,81 +1,81
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require "digest/md5"
19 19
20 20 class Attachment < ActiveRecord::Base
21 21 belongs_to :container, :polymorphic => true
22 22 belongs_to :author, :class_name => "User", :foreign_key => "author_id"
23 23
24 24 validates_presence_of :filename
25 25
26 26 def file=(incomming_file)
27 27 unless incomming_file.nil?
28 28 @temp_file = incomming_file
29 29 if @temp_file.size > 0
30 30 self.filename = sanitize_filename(@temp_file.original_filename)
31 31 self.disk_filename = DateTime.now.strftime("%y%m%d%H%M%S") + "_" + self.filename
32 32 self.content_type = @temp_file.content_type
33 33 self.filesize = @temp_file.size
34 34 end
35 35 end
36 36 end
37 37
38 38 # Copy temp file to its final location
39 39 def before_save
40 40 if @temp_file && (@temp_file.size > 0)
41 41 logger.debug("saving '#{self.diskfile}'")
42 42 File.open(diskfile, "wb") do |f|
43 43 f.write(@temp_file.read)
44 44 end
45 45 self.digest = Digest::MD5.hexdigest(File.read(diskfile))
46 46 end
47 47 end
48 48
49 49 # Deletes file on the disk
50 50 def after_destroy
51 51 if self.filename?
52 52 File.delete(diskfile) if File.exist?(diskfile)
53 53 end
54 54 end
55 55
56 56 # Returns file's location on disk
57 57 def diskfile
58 "#{RDM_STORAGE_PATH}/#{self.disk_filename}"
58 "#{$RDM_STORAGE_PATH}/#{self.disk_filename}"
59 59 end
60 60
61 61 def increment_download
62 62 increment!(:downloads)
63 63 end
64 64
65 65 # returns last created projects
66 66 def self.most_downloaded
67 67 find(:all, :limit => 5, :order => "downloads DESC")
68 68 end
69 69
70 70 private
71 71 def sanitize_filename(value)
72 72 # get only the filename, not the whole path
73 73 just_filename = value.gsub(/^.*(\\|\/)/, '')
74 74 # NOTE: File.basename doesn't work right with Windows paths on Unix
75 75 # INCORRECT: just_filename = File.basename(value.gsub('\\\\', '/'))
76 76
77 77 # Finally, replace all non alphanumeric, underscore or periods with underscore
78 78 @filename = just_filename.gsub(/[^\w\.\-]/,'_')
79 79 end
80 80
81 81 end
@@ -1,38 +1,42
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class CustomField < ActiveRecord::Base
19 has_many :custom_values, :dependent => true
19 20
20 has_and_belongs_to_many :projects
21 has_many :custom_values, :dependent => true
22 has_many :issues, :through => :issue_custom_values
21 FIELD_FORMATS = { "list" => :label_list,
22 "date" => :label_date,
23 "bool" => :label_boolean,
24 "int" => :label_integer,
25 "string" => :label_string,
26 "text" => :label_text
27 }.freeze
23 28
24 validates_presence_of :name, :typ
25 validates_uniqueness_of :name
29 validates_presence_of :name, :field_format
30 validates_uniqueness_of :name
31 validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
32 validates_presence_of :possible_values, :if => Proc.new { |field| field.field_format == "list" }
26 33
27 TYPES = [
28 [ "Integer", 0 ],
29 [ "String", 1 ],
30 [ "Date", 2 ],
31 [ "Boolean", 3 ],
32 [ "List", 4 ]
33 ].freeze
34
35 def self.for_all
36 find(:all, :conditions => ["is_for_all=?", true])
37 end
38 end
34 # to move in project_custom_field
35 def self.for_all
36 find(:all, :conditions => ["is_for_all=?", true])
37 end
38
39 def type_name
40 nil
41 end
42 end
@@ -1,41 +1,43
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class CustomValue < ActiveRecord::Base
19 belongs_to :issue
20 belongs_to :custom_field
21
19 belongs_to :custom_field
20 belongs_to :customized, :polymorphic => true
21
22 22 protected
23 23 def validate
24 errors.add(custom_field.name, "can't be blank") if custom_field.is_required? and value.empty?
25 errors.add(custom_field.name, "is not valid") unless custom_field.regexp.empty? or value =~ Regexp.new(custom_field.regexp)
26
27 case custom_field.typ
28 when 0
29 errors.add(custom_field.name, "must be an integer") unless value =~ /^[0-9]*$/
30 when 1
31 errors.add(custom_field.name, "is too short") if custom_field.min_length > 0 and value.length < custom_field.min_length and value.length > 0
32 errors.add(custom_field.name, "is too long") if custom_field.max_length > 0 and value.length > custom_field.max_length
33 when 2
34 errors.add(custom_field.name, "must be a valid date") unless value =~ /^(\d+)\/(\d+)\/(\d+)$/ or value.empty?
35 when 3
36
37 when 4
38 errors.add(custom_field.name, "is not a valid value") unless custom_field.possible_values.split('|').include? value or value.empty?
39 end
24 # errors are added to customized object unless it's nil
25 object = customized || self
26
27 object.errors.add(custom_field.name, :activerecord_error_blank) if custom_field.is_required? and value.empty?
28 object.errors.add(custom_field.name, :activerecord_error_invalid) unless custom_field.regexp.empty? or value =~ Regexp.new(custom_field.regexp)
29
30 object.errors.add(custom_field.name, :activerecord_error_too_short) if custom_field.min_length > 0 and value.length < custom_field.min_length and value.length > 0
31 object.errors.add(custom_field.name, :activerecord_error_too_long) if custom_field.max_length > 0 and value.length > custom_field.max_length
32
33 case custom_field.field_format
34 when "int"
35 object.errors.add(custom_field.name, :activerecord_error_not_a_number) unless value =~ /^[0-9]*$/
36 when "date"
37 object.errors.add(custom_field.name, :activerecord_error_invalid) unless value =~ /^(\d+)\/(\d+)\/(\d+)$/ or value.empty?
38 when "list"
39 object.errors.add(custom_field.name, :activerecord_error_inclusion) unless custom_field.possible_values.split('|').include? value or value.empty?
40 end
40 41 end
41 end
42 end
43
@@ -1,24 +1,24
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Document < ActiveRecord::Base
19 19 belongs_to :project
20 20 belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
21 21 has_many :attachments, :as => :container, :dependent => true
22 22
23 validates_presence_of :title
23 validates_presence_of :project, :title, :category
24 24 end
@@ -1,55 +1,59
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Issue < ActiveRecord::Base
19 19
20 20 belongs_to :project
21 21 belongs_to :tracker
22 22 belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
23 23 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
24 24 belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
25 25 belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
26 26 belongs_to :priority, :class_name => 'Enumeration', :foreign_key => 'priority_id'
27 27 belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
28 28
29 29 has_many :histories, :class_name => 'IssueHistory', :dependent => true, :order => "issue_histories.created_on DESC", :include => :status
30 30 has_many :attachments, :as => :container, :dependent => true
31 31
32 has_many :custom_values, :dependent => true
32 has_many :custom_values, :dependent => true, :as => :customized
33 33 has_many :custom_fields, :through => :custom_values
34 34
35 validates_presence_of :subject, :descr, :priority, :tracker, :author
35 validates_presence_of :subject, :description, :priority, :tracker, :author
36 validates_associated :custom_values, :on => :update
36 37
37 38 # set default status for new issues
39 def before_validation
40 self.status = IssueStatus.default if new_record?
41 end
42
38 43 def before_create
39 self.status = IssueStatus.default
40 build_history
44 build_history
41 45 end
42 46
43 47 def long_id
44 48 "%05d" % self.id
45 49 end
46 50
47 51 private
48 52 # Creates an history for the issue
49 53 def build_history
50 54 @history = self.histories.build
51 55 @history.status = self.status
52 56 @history.author = self.author
53 57 end
54 58
55 59 end
@@ -1,36 +1,50
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Mailer < ActionMailer::Base
19 19
20 def issue_change_status(issue)
21 # Sends to all project members
22 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
23 @from = 'redmine@somenet.foo'
24 @subject = "Issue ##{issue.id} has been updated"
25 @body['issue'] = issue
26 end
27
28 def issue_add(issue)
29 # Sends to all project members
30 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
31 @from = 'redmine@somenet.foo'
32 @subject = "Issue ##{issue.id} has been reported"
33 @body['issue'] = issue
34 end
35
20 def issue_change_status(issue)
21 # Sends to all project members
22 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
23 @from = 'redmine@somenet.foo'
24 @subject = "Issue ##{issue.id} has been updated"
25 @body['issue'] = issue
26 end
27
28 def issue_add(issue)
29 # Sends to all project members
30 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
31 @from = 'redmine@somenet.foo'
32 @subject = "Issue ##{issue.id} has been reported"
33 @body['issue'] = issue
34 end
35
36 def lost_password(token)
37 @recipients = token.user.mail
38 @from = 'redmine@somenet.foo'
39 @subject = "redMine password"
40 @body['token'] = token
41 end
42
43 def register(token)
44 @recipients = token.user.mail
45 @from = 'redmine@somenet.foo'
46 @subject = "redMine account activation"
47 @body['token'] = token
48 end
49
36 50 end
@@ -1,28 +1,28
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class News < ActiveRecord::Base
19 19 belongs_to :project
20 20 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
21 21
22 validates_presence_of :title, :shortdescr, :descr
22 validates_presence_of :title, :description
23 23
24 24 # returns last created news
25 25 def self.latest
26 26 find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
27 27 end
28 28 end
@@ -1,63 +1,63
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Permission < ActiveRecord::Base
19 19 has_and_belongs_to_many :roles
20 20
21 validates_presence_of :controller, :action, :descr
21 validates_presence_of :controller, :action, :description
22 22
23 23 GROUPS = {
24 24 100 => "Project",
25 25 200 => "Membres",
26 26 300 => "Versions",
27 27 400 => "Issue categories",
28 28 1000 => "Issues",
29 29 1100 => "News",
30 30 1200 => "Documents",
31 31 1300 => "Files",
32 32 }.freeze
33 33
34 34 @@cached_perms_for_public = nil
35 35 @@cached_perms_for_roles = nil
36 36
37 37 def name
38 38 self.controller + "/" + self.action
39 39 end
40 40
41 41 def group_id
42 42 (self.sort / 100)*100
43 43 end
44 44
45 45 def self.allowed_to_public(action)
46 46 @@cached_perms_for_public ||= find(:all, :conditions => ["is_public=?", true]).collect {|p| "#{p.controller}/#{p.action}"}
47 47 @@cached_perms_for_public.include? action
48 48 end
49 49
50 50 def self.allowed_to_role(action, role)
51 51 @@cached_perms_for_roles ||=
52 52 begin
53 53 perms = {}
54 54 find(:all, :include => :roles).each {|p| perms.store "#{p.controller}/#{p.action}", p.roles.collect {|r| r.id } }
55 55 perms
56 56 end
57 57 @@cached_perms_for_roles[action] and @@cached_perms_for_roles[action].include? role
58 58 end
59 59
60 60 def self.allowed_to_role_expired
61 61 @@cached_perms_for_roles = nil
62 62 end
63 63 end
@@ -1,48 +1,52
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Project < ActiveRecord::Base
19 has_many :versions, :dependent => true, :order => "versions.effective_date DESC"
20 has_many :members, :dependent => true
21 has_many :users, :through => :members
22 has_many :issues, :dependent => true, :order => "issues.created_on DESC", :include => :status
23 has_many :documents, :dependent => true
24 has_many :news, :dependent => true, :include => :author
25 has_many :issue_categories, :dependent => true
26 has_and_belongs_to_many :custom_fields
27 acts_as_tree :order => "name", :counter_cache => true
28
29 validates_presence_of :name, :descr
30 validates_uniqueness_of :name
31
32 # returns 5 last created projects
33 def self.latest
34 find(:all, :limit => 5, :order => "created_on DESC")
35 end
36
37 # Returns an array of all custom fields enabled for project issues
38 # (explictly associated custom fields and custom fields enabled for all projects)
39 def custom_fields_for_issues
40 (CustomField.for_all + custom_fields).uniq
41 end
42
19 has_many :versions, :dependent => true, :order => "versions.effective_date DESC, versions.name DESC"
20 has_many :members, :dependent => true
21 has_many :users, :through => :members
22 has_many :custom_values, :dependent => true, :as => :customized
23 has_many :issues, :dependent => true, :order => "issues.created_on DESC", :include => :status
24 has_many :documents, :dependent => true
25 has_many :news, :dependent => true, :include => :author
26 has_many :issue_categories, :dependent => true, :order => "issue_categories.name"
27 has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_projects', :association_foreign_key => 'custom_field_id'
28 acts_as_tree :order => "name", :counter_cache => true
29
30 validates_presence_of :name, :description
31 validates_uniqueness_of :name
32 validates_associated :custom_values, :on => :update
33
34 # returns 5 last created projects
35 def self.latest
36 find(:all, :limit => 5, :order => "created_on DESC")
37 end
38
39 # Returns an array of all custom fields enabled for project issues
40 # (explictly associated custom fields and custom fields enabled for all projects)
41 def custom_fields_for_issues(tracker)
42 tracker.custom_fields.find(:all, :include => :projects,
43 :conditions => ["is_for_all=? or project_id=?", true, self.id])
44 #(CustomField.for_all + custom_fields).uniq
45 end
46
43 47 protected
44 48 def validate
45 49 errors.add(parent_id, " must be a root project") if parent and parent.parent
46 50 errors.add_to_base("A project with subprojects can't be a subproject") if parent and projects_count > 0
47 51 end
48 52 end
@@ -1,34 +1,35
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Tracker < ActiveRecord::Base
19 19 before_destroy :check_integrity
20 20 has_many :issues
21 21 has_many :workflows, :dependent => true
22
22 has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_trackers', :association_foreign_key => 'custom_field_id'
23
23 24 validates_presence_of :name
24 25 validates_uniqueness_of :name
25 26
26 27 def name
27 28 _ self.attributes['name']
28 29 end
29 30
30 31 private
31 32 def check_integrity
32 33 raise "Can't delete tracker" if Issue.find(:first, :conditions => ["tracker_id=?", self.id])
33 34 end
34 35 end
@@ -1,77 +1,114
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require "digest/sha1"
19 19
20 20 class User < ActiveRecord::Base
21 21 has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :dependent => true
22
22 has_many :custom_values, :dependent => true, :as => :customized
23 belongs_to :auth_source
24
23 25 attr_accessor :password, :password_confirmation
24 26 attr_accessor :last_before_login_on
25 27 # Prevents unauthorized assignments
26 28 attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
27 29
28 30 validates_presence_of :login, :firstname, :lastname, :mail
29 31 validates_uniqueness_of :login, :mail
30 32 # Login must contain lettres, numbers, underscores only
31 33 validates_format_of :login, :with => /^[a-z0-9_]+$/i
32 34 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
33 35 # Password length between 4 and 12
34 36 validates_length_of :password, :in => 4..12, :allow_nil => true
35 37 validates_confirmation_of :password, :allow_nil => true
38 validates_associated :custom_values, :on => :update
39
40 # Account statuses
41 STATUS_ACTIVE = 1
42 STATUS_REGISTERED = 2
43 STATUS_LOCKED = 3
36 44
37 45 def before_save
38 46 # update hashed_password if password was set
39 47 self.hashed_password = User.hash_password(self.password) if self.password
40 48 end
41 49
42 50 # Returns the user that matches provided login and password, or nil
43 51 def self.try_to_login(login, password)
44 user = find(:first, :conditions => ["login=? and hashed_password=? and locked=?", login, User.hash_password(password), false])
52 user = find(:first, :conditions => ["login=?", login])
45 53 if user
46 user.last_before_login_on = user.last_login_on
47 user.update_attribute(:last_login_on, Time.now)
48 end
54 # user is already in local database
55 return nil if !user.active?
56 if user.auth_source
57 # user has an external authentication method
58 return nil unless user.auth_source.authenticate(login, password)
59 else
60 # local authentication
61 return nil unless User.hash_password(password) == user.hashed_password
62 end
63 else
64 # user is not yet registered, try to authenticate with available sources
65 attrs = AuthSource.authenticate(login, password)
66 if attrs
67 onthefly = new(*attrs)
68 onthefly.login = login
69 onthefly.language = $RDM_DEFAULT_LANG
70 if onthefly.save
71 user = find(:first, :conditions => ["login=?", login])
72 end
73 end
74 end
75 user.update_attribute(:last_login_on, Time.now) if user
49 76 user
77
78 rescue => text
79 raise text
50 80 end
51 81
52 82 # Return user's full name for display
53 83 def display_name
54 84 firstname + " " + lastname
55 85 end
86
87 def active?
88 self.status == STATUS_ACTIVE
89 end
90
91 def locked?
92 self.status == STATUS_LOCKED
93 end
56 94
57 95 def check_password?(clear_password)
58 96 User.hash_password(clear_password) == self.hashed_password
59 97 end
60
61 98
62 99 def role_for_project(project_id)
63 100 @role_for_projects ||=
64 101 begin
65 102 roles = {}
66 103 self.memberships.each { |m| roles.store m.project_id, m.role_id }
67 104 roles
68 105 end
69 106 @role_for_projects[project_id]
70 107 end
71 108
72 109 private
73 110 # Return password digest
74 111 def self.hash_password(clear_password)
75 112 Digest::SHA1.hexdigest(clear_password || "")
76 113 end
77 114 end
@@ -1,13 +1,25
1 <div class="box">
2 <h2><%=_('Please login') %></h2>
1 <center>
2 <div class="box login">
3 <h2><%= image_tag 'login' %>&nbsp;&nbsp;<%=l(:label_please_login)%></h2>
3 4
4 <%= start_form_tag :action=> "login" %>
5 <p><label for="login"><%=_ 'Login' %>:</label><br/>
6 <%= text_field_tag 'login', nil, :size => 25 %></p>
7
8 <p><label for="user_password"><%=_ 'Password' %>:</label><br/>
9 <%= password_field_tag 'password', nil, :size => 25 %></p>
5 <%= start_form_tag :action=> "login" %>
6 <table cellpadding="4">
7 <tr>
8 <td><label for="login"><%=l(:field_login)%>:</label></td>
9 <td><%= text_field_tag 'login', nil, :size => 25 %></td>
10 </tr>
11 <tr>
12 <td><label for="password"><%=l(:field_password)%>:</label></td>
13 <td><%= password_field_tag 'password', nil, :size => 25 %></td>
14 </tr>
15 </table>
16
17 &nbsp;
10 18
11 <p><input type="submit" name="login" value="<%=_ 'Log in' %> &#187;" class="primary" /></p>
12 <%= end_form_tag %>
13 </div> No newline at end of file
19 <p><center><input type="submit" name="login" value="<%=l(:button_login)%> &#187;" class="primary" /></center></p>
20 <%= end_form_tag %>
21 <br />
22 <% unless $RDM_SELF_REGISTRATION == false %><%= link_to l(:label_register), :action => 'register' %> |<% end %>
23 <%= link_to l(:label_password_lost), :action => 'lost_password' %>
24 </div>
25 </center> No newline at end of file
@@ -1,55 +1,55
1 <h2><%=_('My account')%></h2>
1 <h2><%=l(:label_my_account)%></h2>
2 2
3 <p><%=_('Login')%>: <strong><%= @user.login %></strong><br />
4 <%=_('Created on')%>: <%= format_time(@user.created_on) %>,
5 <%=_('Last update')%>: <%= format_time(@user.updated_on) %></p>
3 <p><%=l(:field_login)%>: <strong><%= @user.login %></strong><br />
4 <%=l(:field_created_on)%>: <%= format_time(@user.created_on) %>,
5 <%=l(:field_updated_on)%>: <%= format_time(@user.updated_on) %></p>
6 6
7 7 <%= error_messages_for 'user' %>
8 8
9 9 <div class="splitcontentleft">
10 10 <div class="box">
11 <h3><%=_('Information')%></h3>
11 <h3><%=l(:label_information_plural)%></h3>
12 12 &nbsp;
13 13 <%= start_form_tag :action => 'my_account' %>
14 14
15 15 <!--[form:user]-->
16 <p><label for="user_firstname"><%=_('Firstname')%> <span class="required">*</span></label><br/>
16 <p><label for="user_firstname"><%=l(:field_firstname)%> <span class="required">*</span></label><br/>
17 17 <%= text_field 'user', 'firstname' %></p>
18 18
19 <p><label for="user_lastname"><%=_('Lastname')%> <span class="required">*</span></label><br/>
19 <p><label for="user_lastname"><%=l(:field_lastname)%> <span class="required">*</span></label><br/>
20 20 <%= text_field 'user', 'lastname' %></p>
21 21
22 <p><label for="user_mail"><%=_('Mail')%> <span class="required">*</span></label><br/>
23 <%= text_field 'user', 'mail' %></p>
22 <p><label for="user_mail"><%=l(:field_mail)%> <span class="required">*</span></label><br/>
23 <%= text_field 'user', 'mail' %></p>
24 24
25 <p><label for="user_language"><%=_('Language')%></label><br/>
26 <%= select("user", "language", Localization.langs) %></p>
25 <p><label for="user_language"><%=l(:field_language)%></label><br/>
26 <%= select("user", "language", Localization.langs.invert) %></p>
27 27 <!--[eoform:user]-->
28 28
29 <p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=_('Mail notifications')%></label></p>
29 <p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=l(:field_mail_notification)%></label></p>
30 30
31 <center><%= submit_tag _('Save') %></center>
31 <center><%= submit_tag l(:button_save) %></center>
32 32 <%= end_form_tag %>
33 33 </div>
34 34 </div>
35 35
36 36
37 37 <div class="splitcontentright">
38 38 <div class="box">
39 <h3><%=_('Password')%></h3>
39 <h3><%=l(:field_password)%></h3>
40 40 &nbsp;
41 41 <%= start_form_tag :action => 'change_password' %>
42 42
43 <p><label for="password"><%=_('Password')%> <span class="required">*</span></label><br/>
43 <p><label for="password"><%=l(:field_password)%> <span class="required">*</span></label><br/>
44 44 <%= password_field_tag 'password', nil, :size => 25 %></p>
45 45
46 <p><label for="new_password"><%=_('New password')%> <span class="required">*</span></label><br/>
46 <p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label><br/>
47 47 <%= password_field_tag 'new_password', nil, :size => 25 %></p>
48 48
49 <p><label for="new_password_confirmation"><%=_('Confirmation')%> <span class="required">*</span></label><br/>
49 <p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label><br/>
50 50 <%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>
51 51
52 <center><%= submit_tag _('Save') %></center>
52 <center><%= submit_tag l(:button_save) %></center>
53 53 <%= end_form_tag %>
54 54 </div>
55 55 </div> No newline at end of file
@@ -1,19 +1,22
1 <h2><%=_('My page') %></h2>
1 <h2><%=l(:label_my_page)%></h2>
2 2
3 3 <p>
4 <%=_('Welcome')%> <b><%= @user.firstname %></b><br />
5 4 <% unless @user.last_before_login_on.nil? %>
6 <%=_('Last login')%>: <%= format_time(@user.last_before_login_on) %>
5 <%=l(:label_last_login)%>: <%= format_time(@user.last_before_login_on) %>
7 6 <% end %>
8 7 </p>
9 8
10 9 <div class="splitcontentleft">
11 <h3><%=_('Reported issues')%></h3>
10 <h3><%=l(:label_reported_issues)%></h3>
12 11 <%= render :partial => 'issues/list_simple', :locals => { :issues => @reported_issues } %>
13 <%= "<p>(Last #{@reported_issues.length} updated)</p>" if @reported_issues.length > 0 %>
12 <% if @reported_issues.length > 0 %>
13 <p><%=lwr(:label_last_updates, @reported_issues.length)%></p>
14 <% end %>
14 15 </div>
15 16 <div class="splitcontentright">
16 <h3><%=_('Assigned to me')%></h3>
17 <h3><%=l(:label_assigned_to_me_issues)%></h3>
17 18 <%= render :partial => 'issues/list_simple', :locals => { :issues => @assigned_issues } %>
18 <%= "<p>(Last #{@assigned_issues.length} updated)</p>" if @assigned_issues.length > 0 %>
19 <% if @assigned_issues.length > 0 %>
20 <p><%=lwr(:label_last_updates, @assigned_issues.length)%></p>
21 <% end %>
19 22 </div> No newline at end of file
@@ -1,19 +1,19
1 1 <h2><%= @user.display_name %></h2>
2 2
3 3 <p>
4 4 <%= mail_to @user.mail %><br />
5 <%=_('Registered on')%>: <%= format_date(@user.created_on) %>
5 <%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %>
6 6 </p>
7 7
8 <h3><%=_('Projects')%></h3>
8 <h3><%=l(:label_project_plural)%></h3>
9 9 <p>
10 10 <% for membership in @user.memberships %>
11 11 <%= membership.project.name %> (<%= membership.role.name %>, <%= format_date(membership.created_on) %>)
12 12 <br />
13 13 <% end %>
14 14 </p>
15 15
16 <h3><%=_('Activity')%></h3>
16 <h3><%=l(:label_activity)%></h3>
17 17 <p>
18 <%=_('Reported issues')%>: <%= Issue.count( [ "author_id=?", @user.id]) %>
18 <%=l(:label_reported_issues)%>: <%= Issue.count(["author_id=?", @user.id]) %>
19 19 </p> No newline at end of file
@@ -1,45 +1,50
1 <h2><%=_('Administration')%></h2>
1 <h2><%=l(:label_administration)%></h2>
2 2
3 3 <p>
4 4 <%= image_tag "projects" %>
5 <%= link_to _('Projects'), :controller => 'admin', :action => 'projects' %> |
6 <%= link_to _('New'), :controller => 'projects', :action => 'add' %>
5 <%= link_to l(:label_project_plural), :controller => 'admin', :action => 'projects' %> |
6 <%= link_to l(:label_new), :controller => 'projects', :action => 'add' %>
7 7 </p>
8 8
9 9 <p>
10 10 <%= image_tag "users" %>
11 <%= link_to _('Users'), :controller => 'users' %> |
12 <%= link_to _('New'), :controller => 'users', :action => 'add' %>
11 <%= link_to l(:label_user_plural), :controller => 'users' %> |
12 <%= link_to l(:label_new), :controller => 'users', :action => 'add' %>
13 13 </p>
14 14
15 15 <p>
16 16 <%= image_tag "role" %>
17 <%= link_to _('Roles and permissions'), :controller => 'roles' %>
17 <%= link_to l(:label_role_and_permissions), :controller => 'roles' %>
18 18 </p>
19 19
20 20 <p>
21 21 <%= image_tag "tracker" %>
22 <%= link_to _('Trackers'), :controller => 'trackers' %> |
23 <%= link_to _('Custom fields'), :controller => 'custom_fields' %>
22 <%= link_to l(:label_tracker_plural), :controller => 'trackers' %> |
23 <%= link_to l(:label_custom_field_plural), :controller => 'custom_fields' %>
24 24 </p>
25 25
26 26 <p>
27 27 <%= image_tag "workflow" %>
28 <%= link_to _('Issue Statuses'), :controller => 'issue_statuses' %> |
29 <%= link_to _('Workflow'), :controller => 'roles', :action => 'workflow' %>
28 <%= link_to l(:label_issue_status_plural), :controller => 'issue_statuses' %> |
29 <%= link_to l(:label_workflow), :controller => 'roles', :action => 'workflow' %>
30 30 </p>
31 31
32 32 <p>
33 33 <%= image_tag "options" %>
34 <%= link_to _('Enumerations'), :controller => 'enumerations' %>
34 <%= link_to l(:label_enumerations), :controller => 'enumerations' %>
35 35 </p>
36 36
37 37 <p>
38 38 <%= image_tag "mailer" %>
39 <%= link_to _('Mail notifications'), :controller => 'admin', :action => 'mail_options' %>
39 <%= link_to l(:field_mail_notification), :controller => 'admin', :action => 'mail_options' %>
40 </p>
41
42 <p>
43 <%= image_tag "login" %>
44 <%= link_to l(:label_authentication), :controller => 'auth_sources' %>
40 45 </p>
41 46
42 47 <p>
43 48 <%= image_tag "help" %>
44 <%= link_to _('Information'), :controller => 'admin', :action => 'info' %>
49 <%= link_to l(:label_information_plural), :controller => 'admin', :action => 'info' %>
45 50 </p> No newline at end of file
@@ -1,10 +1,10
1 1 <h2><%=_('Information')%></h2>
2 2
3 <p><%=_('Version')%>: <strong><%= RDM_APP_NAME %> <%= RDM_APP_VERSION %></strong></p>
3 <p><%=l(:field_version)%>: <strong><%= RDM_APP_NAME %> <%= RDM_APP_VERSION %></strong></p>
4 4
5 Environment:
5 <%=l(:label_environment)%>:
6 6 <ul>
7 7 <% Rails::Info.properties.each do |name, value| %>
8 8 <li><%= name %>: <%= value %></li>
9 9 <% end %>
10 10 </ul> No newline at end of file
@@ -1,16 +1,16
1 <h2><%=_('Mail notifications')%></h2>
1 <h2><%=l(:field_mail_notification)%></h2>
2 2
3 <p><%=_('Select actions for which mail notification should be enabled.')%></p>
3 <p><%=l(:text_select_mail_notifications)%></p>
4 4
5 5 <%= start_form_tag ({}, :id => 'mail_options_form')%>
6 6 <% for action in @actions %>
7 7 <%= check_box_tag "action_ids[]", action.id, action.mail_enabled? %>
8 <%= action.descr %><br />
8 <%= action.description %><br />
9 9 <% end %>
10 10 <br />
11 11 <p>
12 <a href="javascript:checkAll('mail_options_form', true)"><%=_('Check all')%></a> |
13 <a href="javascript:checkAll('mail_options_form', false)"><%=_('Uncheck all')%></a>
12 <a href="javascript:checkAll('mail_options_form', true)"><%=l(:button_check_all)%></a> |
13 <a href="javascript:checkAll('mail_options_form', false)"><%=l(:button_uncheck_all)%></a>
14 14 </p>
15 <%= submit_tag _('Save') %>
15 <%= submit_tag l(:button_save) %>
16 16 <%= end_form_tag %> No newline at end of file
@@ -1,32 +1,32
1 <h2><%=_('Projects')%></h2>
1 <h2><%=l(:label_project_plural)%></h2>
2 2
3 3 <table width="100%" cellspacing="1" cellpadding="2" class="listTableContent">
4 4 <tr class="ListHead">
5 <%= sort_header_tag('name', :caption => _('Project')) %>
6 <th><%=_('Description')%></th>
7 <th><%=_('Public')%></th>
8 <th><%=_('Subprojects')%></th>
9 <%= sort_header_tag('created_on', :caption => _('Created on')) %>
5 <%= sort_header_tag('name', :caption => l(:label_project)) %>
6 <th><%=l(:field_description)%></th>
7 <th><%=l(:field_is_public)%></th>
8 <th><%=l(:label_subproject_plural)%></th>
9 <%= sort_header_tag('created_on', :caption => l(:field_created_on)) %>
10 10 <th></th>
11 11 </tr>
12 12
13 13 <% for project in @projects %>
14 14 <tr class="<%= cycle("odd", "even") %>">
15 15 <td><%= link_to project.name, :controller => 'projects', :action => 'settings', :id => project %>
16 <td><%= project.descr %>
16 <td><%= project.description %>
17 17 <td align="center"><%= image_tag 'true' if project.is_public? %>
18 18 <td align="center"><%= project.projects_count %>
19 19 <td align="center"><%= format_date(project.created_on) %>
20 20 <td align="center">
21 21 <%= start_form_tag({:controller => 'projects', :action => 'destroy', :id => project}) %>
22 <%= submit_tag _('Delete'), :class => "button-small" %>
22 <%= submit_tag l(:button_delete), :class => "button-small" %>
23 23 <%= end_form_tag %>
24 24 </td>
25 25 </tr>
26 26 <% end %>
27 27 </table>
28 28
29 29 <p><%= pagination_links_full @project_pages %>
30 30 [ <%= @project_pages.current.first_item %> - <%= @project_pages.current.last_item %> / <%= @project_count %> ]</p>
31 31
32 <p><%= link_to ('&#187; ' + _('New project')), :controller => 'projects', :action => 'add' %></p> No newline at end of file
32 <p><%= link_to ('&#187; ' + l(:label_project_new)), :controller => 'projects', :action => 'add' %></p> No newline at end of file
@@ -1,26 +1,53
1 1 <%= error_messages_for 'custom_field' %>
2 2
3 3 <!--[form:custom_field]-->
4 <p><label for="custom_field_name"><%=_('Name')%></label><br/>
5 <%= text_field 'custom_field', 'name' %></p>
4 <div class="box">
5 <p><label for="custom_field_name"><%=l(:field_name)%></label> <span class="required">*</span><br/>
6 <%= text_field 'custom_field', 'name' %></p>
6 7
7 <p><label for="custom_field_typ"><%=_('Type')%></label><br/>
8 <%= select("custom_field", "typ", CustomField::TYPES) %></p>
8 <p><label for="custom_field_typ"><%=l(:field_field_format)%></label><br/>
9 <%= select("custom_field", "field_format", custom_field_formats_for_select) %></p>
9 10
10 <p><%= check_box 'custom_field', 'is_required' %>
11 <label for="custom_field_is_required"><%=_('Required')%></label></p>
12
13 <p><%= check_box 'custom_field', 'is_for_all' %>
14 <label for="custom_field_is_for_all"><%=_('For all projects')%></label></p>
15
16 <p><label for="custom_field_min_length"><%=_('Min - max length')%></label> (<%=_('0 means no restriction')%>)<br/>
11 <p><label for="custom_field_min_length"><%=l(:label_min_max_length)%></label> (<%=l(:text_min_max_length_info)%>)<br/>
17 12 <%= text_field 'custom_field', 'min_length', :size => 5 %> -
18 13 <%= text_field 'custom_field', 'max_length', :size => 5 %></p>
19 14
20 <p><label for="custom_field_regexp"><%=_('Regular expression pattern')%></label> (eg. ^[A-Z0-9]+$)<br/>
15 <p><label for="custom_field_regexp"><%=l(:field_regexp)%></label> (<%=l(:text_regexp_info)%>)<br/>
21 16 <%= text_field 'custom_field', 'regexp', :size => 50 %></p>
22 17
23 <p><label for="custom_field_possible_values"><%=_('Possible values')%></label> (separator: |)<br/>
24 <%= text_area 'custom_field', 'possible_values', :rows => 5, :cols => 60 %></p>
18 <p><label for="custom_field_possible_values"><%=l(:field_possible_values)%></label> (<%=l(:text_possible_values_info)%>)<br/>
19 <%= text_area 'custom_field', 'possible_values', :rows => 5, :cols => 60 %></p>
20 </div>
25 21 <!--[eoform:custom_field]-->
26 22
23 <div class="box">
24 <% case type.to_s
25 when "IssueCustomField" %>
26
27 <fieldset><legend><%=l(:label_tracker_plural)%></legend>
28 <% for tracker in @trackers %>
29 <input type="checkbox"
30 name="tracker_ids[]"
31 value="<%= tracker.id %>"
32 <%if @custom_field.trackers.include? tracker%>checked="checked"<%end%>
33 > <%= tracker.name %>
34 <% end %></fieldset>
35 &nbsp;
36
37 <p><%= check_box 'custom_field', 'is_required' %>
38 <label for="custom_field_is_required"><%=l(:field_is_required)%></label></p>
39
40 <p><%= check_box 'custom_field', 'is_for_all' %>
41 <label for="custom_field_is_for_all"><%=l(:field_is_for_all)%></label></p>
42
43 <% when "UserCustomField" %>
44 <p><%= check_box 'custom_field', 'is_required' %>
45 <label for="custom_field_is_required"><%=l(:field_is_required)%></label></p>
46
47 <% when "ProjectCustomField" %>
48 <p><%= check_box 'custom_field', 'is_required' %>
49 <label for="custom_field_is_required"><%=l(:field_is_required)%></label></p>
50
51
52 <% end %>
53 </div>
@@ -1,6 +1,6
1 <h2><%=_('Custom field')%></h2>
1 <h2><%=l(:label_custom_field)%> (<%=l(@custom_field.type_name)%>)</h2>
2 2
3 3 <%= start_form_tag :action => 'edit', :id => @custom_field %>
4 <%= render :partial => 'form' %>
5 <%= submit_tag _('Save') %>
4 <%= render :partial => 'form', :locals => { :type => @custom_field.type } %>
5 <%= submit_tag l(:button_save) %>
6 6 <%= end_form_tag %>
@@ -1,32 +1,37
1 <h2><%=_('Custom fields')%></h2>
1 <h2><%=l(:label_custom_field_plural)%></h2>
2 2
3 3 <table border="0" cellspacing="1" cellpadding="2" class="listTableContent">
4 4 <tr class="ListHead">
5 <th><%=_('Name')%></th>
6 <th><%=_('Type')%></th>
7 <th><%=_('Required')%></th>
8 <th><%=_('For all projects')%></th>
5 <th><%=l(:field_name)%></th>
6 <th><%=l(:field_type)%></th>
7 <th><%=l(:field_field_format)%></th>
8 <th><%=l(:field_is_required)%></th>
9 <th><%=l(:field_is_for_all)%></th>
9 10 <th><%=_('Used by')%></th>
10 11 <th></th>
11 12 </tr>
12 13 <% for custom_field in @custom_fields %>
13 14 <tr class="<%= cycle("odd", "even") %>">
14 15 <td><%= link_to custom_field.name, :action => 'edit', :id => custom_field %></td>
15 <td align="center"><%= CustomField::TYPES[custom_field.typ][0] %></td>
16 <td align="center"><%= l(custom_field.type_name) %></td>
17 <td align="center"><%= l(CustomField::FIELD_FORMATS[custom_field.field_format]) %></td>
16 18 <td align="center"><%= image_tag 'true' if custom_field.is_required? %></td>
17 19 <td align="center"><%= image_tag 'true' if custom_field.is_for_all? %></td>
18 <td align="center"><%= custom_field.projects.count.to_s + ' ' + _('Project') + '(s)' unless custom_field.is_for_all? %></td>
20 <td align="center"><%= custom_field.projects.count.to_s + ' ' + lwr(:label_project, custom_field.projects.count) if custom_field.is_a? IssueCustomField and !custom_field.is_for_all? %></td>
19 21 <td align="center">
20 22 <%= start_form_tag :action => 'destroy', :id => custom_field %>
21 <%= submit_tag _('Delete'), :class => "button-small" %>
23 <%= submit_tag l(:button_delete), :class => "button-small" %>
22 24 <%= end_form_tag %> </td>
23 25 </tr>
24 26 <% end %>
25 27 </table>
26 28
27 <%= link_to ('&#171; ' + _('Previous')), { :page => @custom_field_pages.current.previous } if @custom_field_pages.current.previous %>
28 <%= link_to (_('Next') + ' &#187;'), { :page => @custom_field_pages.current.next } if @custom_field_pages.current.next %>
29 <%= pagination_links_full @custom_field_pages %>
29 30
30 31 <br />
31
32 <%= link_to ('&#187; ' + _('New custom field')), :action => 'new' %>
32 <%=l(:label_custom_field_new)%>:
33 <ul>
34 <li><%= link_to l(:label_issue_plural), :action => 'new', :type => 'IssueCustomField' %></li>
35 <li><%= link_to l(:label_project_plural), :action => 'new', :type => 'ProjectCustomField' %></li>
36 <li><%= link_to l(:label_user_plural), :action => 'new', :type => 'UserCustomField' %></li>
37 </ul>
@@ -1,7 +1,8
1 <h2><%=_('New custom field')%></h2>
1 <h2><%=l(:label_custom_field_new)%> (<%=l(@custom_field.type_name)%>)</h2>
2 2
3 3 <%= start_form_tag :action => 'new' %>
4 <%= render :partial => 'form' %>
5 <%= submit_tag _('Create') %>
4 <%= render :partial => 'form', :locals => { :type => @custom_field.type } %>
5 <%= hidden_field_tag 'type', @custom_field.type %>
6 <%= submit_tag l(:button_save) %>
6 7 <%= end_form_tag %>
7 8
@@ -1,15 +1,15
1 1 <%= error_messages_for 'document' %>
2 2
3 3 <!--[form:document]-->
4 <p><label for="document_category_id"><%=_('Category')%></label><br />
4 <p><label for="document_category_id"><%=l(:field_category)%></label><br />
5 5 <select name="document[category_id]">
6 <%= options_from_collection_for_select @categories, "id", "name",@document.category_id %>
6 <%= options_from_collection_for_select @categories, "id", "name", @document.category_id %>
7 7 </select></p>
8 8
9 <p><label for="document_title"><%=_('Title')%> <span class="required">*</span></label><br />
9 <p><label for="document_title"><%=l(:field_title)%> <span class="required">*</span></label><br />
10 10 <%= text_field 'document', 'title', :size => 60 %></p>
11 11
12 <p><label for="document_descr"><%=_('Description')%> <span class="required">*</span></label><br />
13 <%= text_area 'document', 'descr', :cols => 60, :rows => 5 %></p>
12 <p><label for="document_description"><%=l(:field_description)%> <span class="required">*</span></label><br />
13 <%= text_area 'document', 'description', :cols => 60, :rows => 5 %></p>
14 14 <!--[eoform:document]-->
15 15
@@ -1,47 +1,47
1 1 <h2><%= @document.title %></h2>
2 2
3 <strong><%=_('Description')%>:</strong> <%= @document.descr %><br />
3 <strong><%=_('Description')%>:</strong> <%= @document.description %><br />
4 4 <strong><%=_('Category')%>:</strong> <%= @document.category.name %><br />
5 5 <br />
6 6
7 7 <% if authorize_for('documents', 'edit') %>
8 8 <%= start_form_tag ({ :controller => 'documents', :action => 'edit', :id => @document }, :method => 'get' ) %>
9 9 <%= submit_tag _('Edit') %>
10 10 <%= end_form_tag %>
11 11 <% end %>
12 12
13 13 <% if authorize_for('documents', 'destroy') %>
14 14 <%= start_form_tag ({ :controller => 'documents', :action => 'destroy', :id => @document } ) %>
15 15 <%= submit_tag _('Delete') %>
16 16 <%= end_form_tag %>
17 17 <% end %>
18 18
19 19 <br /><br />
20 20
21 21 <table border="0" cellspacing="1" cellpadding="2" width="100%">
22 22 <% for attachment in @document.attachments %>
23 23 <tr style="background-color:#CEE1ED">
24 24 <td><%= link_to attachment.filename, :action => 'download', :id => @document, :attachment_id => attachment %></td>
25 25 <td align="center"><%= format_date(attachment.created_on) %></td>
26 26 <td align="center"><%= attachment.author.display_name %></td>
27 27 <td><%= human_size(attachment.filesize) %><br /><%= attachment.downloads %> <%=_('download')%>(s)</td>
28 28
29 29 <% if authorize_for('documents', 'destroy_attachment') %>
30 30 <td align="center">
31 31 <%= start_form_tag :action => 'destroy_attachment', :id => @document, :attachment_id => attachment %>
32 32 <%= submit_tag _('Delete'), :class => "button-small" %>
33 33 <%= end_form_tag %>
34 34 </tr>
35 35 <% end %>
36 36
37 37 <% end %>
38 38 </table>
39 39 <br />
40 40
41 41 <% if authorize_for('documents', 'add_attachment') %>
42 42 <%= start_form_tag ({ :controller => 'documents', :action => 'add_attachment', :id => @document }, :multipart => true) %>
43 43 <%=_('Add file')%><br /><%= file_field 'attachment', 'file' %>
44 44 <%= submit_tag _('Add') %>
45 45 <%= end_form_tag %>
46 46 <% end %>
47 47
@@ -1,29 +1,32
1 1 <h2><%=_('Issue')%> #<%= @issue.id %>: <%= @issue.subject %></h2>
2 2
3 3 <%= error_messages_for 'history' %>
4 4 <%= start_form_tag :action => 'change_status', :id => @issue %>
5 5
6 6 <%= hidden_field_tag 'confirm', 1 %>
7 7 <%= hidden_field 'history', 'status_id' %>
8
8
9 <div class="box">
9 10 <p><%=_('New status')%>: <b><%= @history.status.name %></b></p>
10 11
11 12 <div>
12 13 <p><label for="issue_assigned_to_id"><%=_('Assigned to')%></label><br/>
13 14 <select name="issue[assigned_to_id]">
14 15 <option value=""></option>
15 16 <%= options_from_collection_for_select @assignable_to, "id", "display_name", @issue.assigned_to_id %></p>
16 17 </select></p>
17 18 </div>
18 19
19 20 <p><label for="issue_fixed_version"><%=_('Fixed in version')%></label><br/>
20 21 <select name="issue[fixed_version_id]">
21 22 <option value="">--none--</option>
22 23 <%= options_from_collection_for_select @issue.project.versions, "id", "name", @issue.fixed_version_id %>
23 24 </select></p>
24 25
25 26 <p><label for="history_notes"><%=_('Notes')%></label><br />
26 27 <%= text_area 'history', 'notes', :cols => 60, :rows => 10 %></p>
28 </div>
29
27 30
28 31 <%= submit_tag _('Save') %>
29 32 <%= end_form_tag %>
@@ -1,62 +1,53
1 <h2><%=_('Issue')%> #<%= @issue.id %></h2>
1 <h2><%=_@issue.tracker.name%> #<%= @issue.id %> - <%= @issue.subject %></h2>
2 2
3 3 <%= error_messages_for 'issue' %>
4 4 <%= start_form_tag :action => 'edit', :id => @issue %>
5 5
6 <div class="box">
6 7 <!--[form:issue]-->
7 8 <p><%=_('Status')%>: <b><%= @issue.status.name %></b></p>
8 9
9 <div style="float:left;margin-right:10px;">
10 <p><label for="issue_tracker_id"><%=_('Tracker')%> <span class="required">*</span></label><br/>
11 <select name="issue[tracker_id]">
12 <%= options_from_collection_for_select @trackers, "id", "name", @issue.tracker_id %></p>
13 </select></p>
14 </div>
15
16 10 <div style="float:left;margin-right:10px;">
17 11 <p><label for="issue_priority_id"><%=_('Priority')%> <span class="required">*</span></label><br/>
18 12 <select name="issue[priority_id]">
19 13 <%= options_from_collection_for_select @priorities, "id", "name", @issue.priority_id %></p>
20 14 </select></p>
21 15 </div>
22 16
23 17 <div style="float:left;margin-right:10px;">
24 18 <p><label for="issue_assigned_to_id"><%=_('Assigned to')%></label><br/>
25 19 <select name="issue[assigned_to_id]">
26 20 <option value=""></option>
27 21 <%= options_from_collection_for_select @issue.project.members, "user_id", "name", @issue.assigned_to_id %></p>
28 22 </select></p>
29 23 </div>
30 24
31 25 <div>
32 26 <p><label for="issue_category_id"><%=_('Category')%></label><br/>
33 27 <select name="issue[category_id]">
34 28 <option value=""></option>
35 29 <%= options_from_collection_for_select @project.issue_categories, "id", "name", @issue.category_id %></p>
36 30 </select></p>
37 31 </div>
38 32
39 33 <p><label for="issue_subject"><%=_('Subject')%></label><span class="required">*</span><br/>
40 34 <%= text_field 'issue', 'subject', :size => 60 %></p>
41 35
42 <p><label for="issue_descr"><%=_('Description')%></label><span class="required">*</span><br/>
43 <%= text_area 'issue', 'descr', :cols => 60, :rows => 10 %></p>
36 <p><label for="issue_description"><%=_('Description')%></label><span class="required">*</span><br/>
37 <%= text_area 'issue', 'description', :cols => 60, :rows => 10 %></p>
44 38
45
46 <% for custom_value in @custom_values %>
47 <p><%= content_tag "label", custom_value.custom_field.name %>
48 <% if custom_value.custom_field.is_required? %><span class="required">*</span><% end %>
49 <br />
50 <%= custom_field_tag custom_value %></p>
39 <% for custom_value in @custom_values %>
40 <p><%= custom_field_tag_with_label custom_value %></p>
51 41 <% end %>
52 42
53
54 43 <p><label for="issue_fixed_version"><%=_('Fixed in version')%></label><br/>
55 44 <select name="issue[fixed_version_id]">
56 45 <option value="">--none--</option>
57 46 <%= options_from_collection_for_select @project.versions, "id", "name", @issue.fixed_version_id %>
58 47 </select></p>
48
59 49 <!--[eoform:issue]-->
50 </div>
60 51
61 <center><%= submit_tag _('Save') %></center>
52 <%= submit_tag _('Save') %>
62 53 <%= end_form_tag %>
@@ -1,90 +1,93
1 1
2 <h2><%=_('Issue')%> #<%= @issue.id %> - <%= @issue.subject %></h2>
2 <h2><%=_(@issue.tracker.name)%> #<%= @issue.id %> - <%= @issue.subject %></h2>
3 3
4 4 <div class="box">
5 <p><b><%=_('Tracker')%>:</b> <%= @issue.tracker.name %></p>
5 <p><b><%=_('Status')%>:</b> <%= @issue.status.name %></p>
6 6 <p><b><%=_('Priority')%>:</b> <%= @issue.priority.name %></p>
7 7 <p><b><%=_('Category')%>:</b> <%= @issue.category.name unless @issue.category_id.nil? %></p>
8 <p><b><%=_('Status')%>:</b> <%= @issue.status.name %></p>
9 8 <p><b><%=_('Author')%>:</b> <%= @issue.author.display_name %></p>
10 9 <p><b><%=_('Assigned to')%>:</b> <%= @issue.assigned_to.display_name unless @issue.assigned_to.nil? %></p>
11 10
12 11 <p><b><%=_('Subject')%>:</b> <%= @issue.subject %></p>
13 <p><b><%=_('Description')%>:</b> <%= simple_format auto_link @issue.descr %></p>
12 <p><b><%=_('Description')%>:</b> <%= simple_format auto_link @issue.description %></p>
14 13 <p><b><%=_('Created on')%>:</b> <%= format_date(@issue.created_on) %></p>
15 14
15 <% for custom_value in @custom_values %>
16 <p><b><%= custom_value.custom_field.name %></b>: <%= show_value custom_value %></p>
17 <% end %>
18
16 19 <% if authorize_for('issues', 'edit') %>
17 20 <%= start_form_tag ({:controller => 'issues', :action => 'edit', :id => @issue}, :method => "get" ) %>
18 21 <%= submit_tag _('Edit') %>
19 22 <%= end_form_tag %>
20 23 &nbsp;&nbsp;
21 24 <% end %>
22 25
23 26 <% if authorize_for('issues', 'change_status') and @status_options and !@status_options.empty? %>
24 27 <%= start_form_tag ({:controller => 'issues', :action => 'change_status', :id => @issue}) %>
25 28 <label for="history_status_id"><%=_('Change status')%>:</label>
26 29 <select name="history[status_id]">
27 30 <%= options_from_collection_for_select @status_options, "id", "name" %>
28 31 </select>
29 32 <%= submit_tag _ "Update..." %>
30 33 <%= end_form_tag %>
31 34 &nbsp;&nbsp;
32 35 <% end %>
33 36
34 37 <% if authorize_for('issues', 'destroy') %>
35 38 <%= start_form_tag ({:controller => 'issues', :action => 'destroy', :id => @issue} ) %>
36 39 <%= submit_tag _ "Delete" %>
37 40 <%= end_form_tag %>
38 41 &nbsp;&nbsp;
39 42 <% end %>
40 43
41 44 </div>
42 45
43 46
44 47 <div class="splitcontentleft">
45 48 <div class="box">
46 49 <h3><%=_('History')%></h3>
47 50 <table width="100%">
48 51 <% for history in @issue.histories.find(:all, :include => :author) %>
49 52 <tr>
50 53 <td><%= format_date(history.created_on) %></td>
51 54 <td><%= history.author.display_name %></td>
52 55 <td><b><%= history.status.name %></b></td>
53 56 </tr>
54 57 <% if history.notes? %>
55 58 <tr><td colspan=3><div class="notes"><%= history.notes %></td></tr>
56 59 <% end %>
57 60 <% end %>
58 61 </table>
59 62 </div>
60 63 </div>
61 64
62 65 <div class="splitcontentright">
63 66 <div class="box">
64 67 <h3><%=_('Attachments')%></h3>
65 68 <table width="100%">
66 69 <% for attachment in @issue.attachments %>
67 70 <tr>
68 71 <td><%= link_to attachment.filename, :action => 'download', :id => @issue, :attachment_id => attachment %> (<%= human_size(attachment.filesize) %>)</td>
69 72 <td><%= format_date(attachment.created_on) %></td>
70 73 <td><%= attachment.author.display_name %></td>
71 74 <% if authorize_for('issues', 'destroy_attachment') %>
72 75 <td>
73 76 <%= start_form_tag :action => 'destroy_attachment', :id => @issue, :attachment_id => attachment %>
74 77 <%= submit_tag _('Delete'), :class => "button-small" %>
75 78 <%= end_form_tag %>
76 79 </td>
77 80 <% end %>
78 81 </tr>
79 82 <% end %>
80 83 </table>
81 84 <br />
82 85 <% if authorize_for('issues', 'add_attachment') %>
83 86 <%= start_form_tag ({ :controller => 'issues', :action => 'add_attachment', :id => @issue }, :multipart => true) %>
84 87 <%=_('Add file')%>: <%= file_field 'attachment', 'file' %>
85 88 <%= submit_tag _('Add') %>
86 89 <%= end_form_tag %>
87 90 <% end %>
88 91 </div>
89 92 </div>
90 93
@@ -1,89 +1,134
1 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2 2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
3 3 <head>
4 <title>redMine</title>
4 <title><%= $RDM_HEADER_TITLE %></title>
5 5 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
6 6 <meta name="description" content="redMine" />
7 7 <meta name="keywords" content="issue,bug,tracker" />
8 8 <%= stylesheet_link_tag "application" %>
9 <%= stylesheet_link_tag "menu" %>
9 10 <%= stylesheet_link_tag "rails" %>
10 11 <%= javascript_include_tag :defaults %>
12 <%= javascript_include_tag 'menu' %>
13
14 <script type='text/javascript'>
15 var menu_contenu=' \
16 <div id="menuAdmin" class="menu" onmouseover="menuMouseover(event)"> \
17 <a class="menuItem" href="\/admin\/projects" onmouseover="menuItemMouseover(event,\'menuProjects\');"><span class="menuItemText"><%=_('Projects')%><\/span><span class="menuItemArrow">&#9654;<\/span><\/a> \
18 <a class="menuItem" href="\/users" onmouseover="menuItemMouseover(event,\'menuUsers\');"><span class="menuItemText"><%=_('Users')%><\/span><span class="menuItemArrow">&#9654;<\/span><\/a> \
19 <a class="menuItem" href="\/roles"><%=_('Roles and permissions')%><\/a> \
20 <a class="menuItem" href="\/trackers" onmouseover="menuItemMouseover(event,\'menuTrackers\');"><span class="menuItemText"><%=_('Trackers')%><\/span><span class="menuItemArrow">&#9654;<\/span><\/a> \
21 <a class="menuItem" href="\/custom_fields"><%=_('Custom fields')%><\/a> \
22 <a class="menuItem" href="\/enumerations"><%=_('Enumerations')%><\/a> \
23 <a class="menuItem" href="\/admin\/mail_options"><%=_('Mail notifications')%><\/a> \
24 <a class="menuItem" href="\/auth_sources"><%=l(:label_authentication)%><\/a> \
25 <a class="menuItem" href="\/admin\/info"><%=_('Information')%><\/a> \
26 <\/div> \
27 <div id="menuTrackers" class="menu"> \
28 <a class="menuItem" href="\/issue_statuses"><%=_('Issue Statuses')%><\/a> \
29 <a class="menuItem" href="\/roles\/workflow"><%=_('Workflow')%><\/a> \
30 <\/div> \
31 <div id="menuProjects" class="menu"><a class="menuItem" href="\/projects\/add"><%=_('New')%><\/a><\/div> \
32 <div id="menuUsers" class="menu"><a class="menuItem" href="\/users\/add"><%=_('New')%><\/a><\/div> \
33 \
34 <% unless @project.nil? || @project.id.nil? %> \
35 <div id="menuProject" class="menu" onmouseover="menuMouseover(event)"> \
36 <%= link_to _('Issues'), {:controller => 'projects', :action => 'list_issues', :id => @project }, :class => "menuItem" %> \
37 <%= link_to _('Reports'), {:controller => 'reports', :action => 'issue_report', :id => @project }, :class => "menuItem" %> \
38 <%= link_to _('News'), {:controller => 'projects', :action => 'list_news', :id => @project }, :class => "menuItem" %> \
39 <%= link_to _('Change log'), {:controller => 'projects', :action => 'changelog', :id => @project }, :class => "menuItem" %> \
40 <%= link_to _('Documents'), {:controller => 'projects', :action => 'list_documents', :id => @project }, :class => "menuItem" %> \
41 <%= link_to _('Members'), {:controller => 'projects', :action => 'list_members', :id => @project }, :class => "menuItem" %> \
42 <%= link_to _('Files'), {:controller => 'projects', :action => 'list_files', :id => @project }, :class => "menuItem" %> \
43 <%= link_to_if_authorized _('Settings'), {:controller => 'projects', :action => 'settings', :id => @project }, :class => "menuItem" %> \
44 <\/div> \
45 <% end %> \
46 ';
47 </script>
48
11 49 </head>
12 50
13 51 <body>
14 52 <div id="container" >
15 53
16 54 <div id="header">
17 55 <div style="float: left;">
18 <h1><%= RDM_APP_NAME %></h1>
19 <h2>Project management</h2>
56 <h1><%= $RDM_HEADER_TITLE %></h1>
57 <h2><%= $RDM_HEADER_SUBTITLE %></h2>
20 58 </div>
21 59 <div style="float: right; padding-right: 1em; padding-top: 0.2em;">
22 <% unless session[:user].nil? %><small><%=_('Logged as')%> <b><%= session[:user].login %></b></small><% end %>
60 <% if loggedin? %><small><%=l(:label_logged_as)%> <b><%= @logged_in_user.login %></b></small><% end %>
23 61 </div>
24 62 </div>
25 63
26 64 <div id="navigation">
27 65 <ul>
28 <li class="selected"><%= link_to _('Home'), { :controller => '' }, :class => "picHome" %></li>
29 <li><%= link_to _('My page'), { :controller => 'account', :action => 'my_page'}, :class => "picUserPage" %></li>
30 <li><%= link_to _('Projects'), { :controller => 'projects' }, :class => "picProject" %></li>
66 <li class="selected"><%= link_to l(:label_home), { :controller => '' }, :class => "picHome" %></li>
67 <li><%= link_to l(:label_my_page), { :controller => 'account', :action => 'my_page'}, :class => "picUserPage" %></li>
68 <li><%= link_to l(:label_project_plural), { :controller => 'projects' }, :class => "picProject" %></li>
31 69
32 <% unless session[:user].nil? %>
33 <li><%= link_to _('My account'), { :controller => 'account', :action => 'my_account' }, :class => "picUser" %></li>
34 <% end %>
70 <% unless @project.nil? || @project.id.nil? %>
71 <li><%= link_to @project.name, { :controller => 'projects', :action => 'show', :id => @project }, :class => "picProject", :onmouseover => "buttonMouseover(event, 'menuProject');" %></li>
72 <% end %>
35 73
36 <% if admin_loggedin? %>
37 <li><%= link_to _('Administration'), { :controller => 'admin' }, :class => "picAdmin" %></li>
38 <% end %>
74 <% if loggedin? %>
75 <li><%= link_to l(:label_my_account), { :controller => 'account', :action => 'my_account' }, :class => "picUser" %></li>
76 <% end %>
39 77
40 <li class="right"><%= link_to _('Help'), { :controller => 'help', :ctrl => @params[:controller], :page => @params[:action] }, :target => "new", :class => "picHelp" %></li>
41 <% if session[:user].nil? %>
42 <li class="right"><%= link_to _('Log in'), { :controller => 'account', :action => 'login' }, :class => "picUser" %></li>
43 <% else %>
44 <li class="right"><%= link_to _('Logout'), { :controller => 'account', :action => 'logout' }, :class => "picUser" %></li>
45 <% end %>
46 </ul>
47
78 <% if admin_loggedin? %>
79 <li><%= link_to l(:label_administration), { :controller => 'admin' }, :class => "picAdmin", :onmouseover => "buttonMouseover(event, 'menuAdmin');" %></li>
80 <% end %>
81
82 <li class="right"><%= link_to l(:label_help), { :controller => 'help', :ctrl => @params[:controller], :page => @params[:action] }, :target => "new", :class => "picHelp" %></li>
83
84 <% if loggedin? %>
85 <li class="right"><%= link_to l(:label_logout), { :controller => 'account', :action => 'logout' }, :class => "picUser" %></li>
86 <% else %>
87 <li class="right"><%= link_to l(:label_login), { :controller => 'account', :action => 'login' }, :class => "picUser" %></li>
88 <% end %>
89 </ul>
48 90 </div>
91 <script type='text/javascript'>if(document.getElementById) {document.write(menu_contenu);}</script>
49 92
50 93 <div id="subcontent">
51 94
52 95 <% unless @project.nil? || @project.id.nil? %>
53 96 <h2><%= @project.name %></h2>
54 97 <ul class="menublock">
55 98 <li><%= link_to _('Overview'), :controller => 'projects', :action => 'show', :id => @project %></li>
56 99 <li><%= link_to _('Issues'), :controller => 'projects', :action => 'list_issues', :id => @project %></li>
57 100 <li><%= link_to _('Reports'), :controller => 'reports', :action => 'issue_report', :id => @project %></li>
58 101 <li><%= link_to _('News'), :controller => 'projects', :action => 'list_news', :id => @project %></li>
59 102 <li><%= link_to _('Change log'), :controller => 'projects', :action => 'changelog', :id => @project %></li>
60 103 <li><%= link_to _('Documents'), :controller => 'projects', :action => 'list_documents', :id => @project %></li>
61 104 <li><%= link_to _('Members'), :controller => 'projects', :action => 'list_members', :id => @project %></li>
62 105 <li><%= link_to _('Files'), :controller => 'projects', :action => 'list_files', :id => @project %></li>
63 106 <li><%= link_to_if_authorized _('Settings'), :controller => 'projects', :action => 'settings', :id => @project %></li>
64 107 </ul>
65 108 <% end %>
66 109
67 <% unless session[:user].nil? %>
110 <% if loggedin? and @logged_in_user.memberships.length > 0 %>
68 111 <h2><%=_('My projects') %></h2>
69 112 <ul class="menublock">
70 <% for membership in session[:user].memberships %>
113 <% for membership in @logged_in_user.memberships %>
71 114 <li><%= link_to membership.project.name, :controller => 'projects', :action => 'show', :id => membership.project %></li>
72 115 <% end %>
73 116 </ul>
74 <% end %>
75
117 <% end %>
76 118 </div>
77 119
78 120 <div id="content">
79 121 <% if flash[:notice] %><p style="color: green"><%= flash[:notice] %></p><% end %>
80 122 <%= @content_for_layout %>
81 123 </div>
82 124
83 125 <div id="footer">
84 <p><a href="http://redmine.org/" target="_new"><%= RDM_APP_NAME %></a> <%= RDM_APP_VERSION %></p>
126 <p>
127 <%= auto_link $RDM_FOOTER_SIG %> |
128 <a href="http://redmine.org/" target="_new"><%= RDM_APP_NAME %></a> <%= RDM_APP_VERSION %>
129 </p>
85 130 </div>
86 131
87 132 </div>
88 133 </body>
89 134 </html> No newline at end of file
@@ -1,6 +1,6
1 1 <%=_('Issue')%> #<%= issue.id %> - <%= issue.subject %>
2 2 <%=_('Author')%>: <%= issue.author.display_name %>
3 3
4 <%= issue.descr %>
4 <%= issue.description %>
5 5
6 http://<%= RDM_HOST_NAME %>/issues/show/<%= issue.id %> No newline at end of file
6 http://<%= $RDM_HOST_NAME %>/issues/show/<%= issue.id %> No newline at end of file
1 NO CONTENT: file renamed from redmine/app/views/mailer/issue_add.rhtml to redmine/app/views/mailer/issue_add_en.rhtml
1 NO CONTENT: file renamed from redmine/app/views/mailer/issue_change_status.rhtml to redmine/app/views/mailer/issue_change_status_en.rhtml
@@ -1,13 +1,13
1 1 <%= error_messages_for 'news' %>
2 2
3 3 <!--[form:news]-->
4 4 <p><label for="news_title"><%=_('Title')%></label> <span class="required">*</span><br/>
5 5 <%= text_field 'news', 'title', :size => 60 %></p>
6 6
7 <p><label for="news_shortdescr"><%=_('Summary')%> <span class="required">*</span></label><br/>
8 <%= text_area 'news', 'shortdescr', :cols => 60, :rows => 2 %></p>
7 <p><label for="news_summary"><%=_('Summary')%></label><br/>
8 <%= text_area 'news', 'summary', :cols => 60, :rows => 2 %></p>
9 9
10 <p><label for="news_descr"><%=_('Description')%> <span class="required">*</span></label><br/>
11 <%= text_area 'news', 'descr', :cols => 60, :rows => 10 %></p>
10 <p><label for="news_description"><%=_('Description')%> <span class="required">*</span></label><br/>
11 <%= text_area 'news', 'description', :cols => 60, :rows => 10 %></p>
12 12 <!--[eoform:news]-->
13 13
@@ -1,10 +1,10
1 1 <h2><%= @news.title %></h2>
2 2
3 3 <p>
4 <b><%=_('Summary')%></b>: <%= @news.shortdescr %><br />
4 <b><%=_('Summary')%></b>: <%= @news.summary %><br />
5 5 <b><%=_('By')%></b>: <%= @news.author.display_name %><br />
6 6 <b><%=_('Date')%></b>: <%= format_time(@news.created_on) %>
7 7 </p>
8 8
9 <%= simple_format auto_link @news.descr %>
9 <%= simple_format auto_link @news.description %>
10 10
@@ -1,36 +1,41
1 1 <%= error_messages_for 'project' %>
2 2
3 <div class="box">
3 4 <!--[form:project]-->
4 5 <p><label for="project_name"><%=_('Name')%> <span class="required">*</span></label><br/>
5 6 <%= text_field 'project', 'name' %></p>
6 7
7 <% if session[:user].admin %>
8 <% if admin_loggedin? %>
8 9 <p><label for="project_parent_id"><%=_('Subproject of')%></label><br/>
9 10 <select name="project[parent_id]">
10 11 <option value=""></option>
11 12 <%= options_from_collection_for_select @root_projects, "id", "name", @project.parent_id %>
12 13 </select></p>
13 14 <% end %>
14 15
15 <p><label for="project_descr"><%=_('Description')%> <span class="required">*</span></label><br/>
16 <%= text_area 'project', 'descr', :cols => 60, :rows => 3 %></p>
16 <p><label for="project_description"><%=_('Description')%> <span class="required">*</span></label><br/>
17 <%= text_area 'project', 'description', :cols => 60, :rows => 3 %></p>
17 18
18 19 <p><label for="project_homepage"><%=_('Homepage')%></label><br/>
19 20 <%= text_field 'project', 'homepage', :size => 40 %></p>
20 21
21 22 <p><%= check_box 'project', 'is_public' %>
22 23 <label for="project_is_public"><%=_('Public')%></label></p>
23
24
25 <% for custom_value in @custom_values %>
26 <p><%= custom_field_tag_with_label custom_value %></p>
27 <% end %>
28
24 29 <fieldset><legend><%=_('Custom fields')%></legend>
25 30 <% for custom_field in @custom_fields %>
26 31 <input type="checkbox"
27 32
28 33 name="custom_field_ids[]"
29 34 value="<%= custom_field.id %>"
30 35 <%if @project.custom_fields.include? custom_field%>checked="checked"<%end%>
31 36 > <%= custom_field.name %>
32 37
33 38 <% end %></fieldset>
34 <br />
35
39
40 </div>
36 41 <!--[eoform:project]-->
@@ -1,7 +1,6
1 1 <h2><%=_('New project')%></h2>
2 2
3 3 <%= start_form_tag :action => 'add' %>
4 4 <%= render :partial => 'form' %>
5 5 <%= submit_tag _('Create') %>
6 6 <%= end_form_tag %>
7
@@ -1,26 +1,26
1 1 <h2><%=_('New document')%></h2>
2 2
3 3 <%= error_messages_for 'document' %>
4 4 <%= start_form_tag( { :action => 'add_document', :id => @project }, :multipart => true) %>
5 5
6 6 <!--[form:document]-->
7 7 <p><label for="document_category_id"><%=_('Category')%></label><br />
8 8 <select name="document[category_id]">
9 9 <%= options_from_collection_for_select @categories, "id", "name",@document.category_id %>
10 10 </select></p>
11 11
12 12 <p><label for="document_title"><%=_('Title')%> <span class="required">*</span></label><br />
13 13 <%= text_field 'document', 'title', :size => 60 %></p>
14 14
15 <p><label for="document_descr"><%=_('Description')%> <span class="required">*</span></label><br />
16 <%= text_area 'document', 'descr', :cols => 60, :rows => 5 %></p>
15 <p><label for="document_description"><%=_('Description')%> <span class="required">*</span></label><br />
16 <%= text_area 'document', 'description', :cols => 60, :rows => 5 %></p>
17 17
18 18 <p><label for="attachment_file"><%=_('File')%></label><br/>
19 19 <%= file_field 'attachment', 'file' %></p>
20 20
21 21 <!--[eoform:document]-->
22 22
23 23 <%= submit_tag _('Create') %>
24 24 <%= end_form_tag %>
25 25
26 26
@@ -1,62 +1,51
1 <h2><%=_('New issue')%></h2>
1 <h2><%=_('New issue')%>: <%=_(@tracker.name)%></h2>
2 2
3 3 <%= start_form_tag( { :action => 'add_issue', :id => @project }, :multipart => true) %>
4 4 <%= error_messages_for 'issue' %>
5 5
6 <div class="box">
6 7 <!--[form:issue]-->
7
8 <div style="float:left;margin-right:10px;">
9 <p><label for="issue_tracker_id"><%=_('Tracker')%> <span class="required">*</span></label><br/>
10 <select name="issue[tracker_id]">
11 <%= options_from_collection_for_select @trackers, "id", "name", @issue.tracker_id %></p>
12 </select></p>
13 </div>
8
9 <%= hidden_field_tag 'tracker_id', @tracker.id %>
14 10
15 11 <div style="float:left;margin-right:10px;">
16 12 <p><label for="issue_priority_id"><%=_('Priority')%> <span class="required">*</span></label><br/>
17 13 <select name="issue[priority_id]">
18 14 <%= options_from_collection_for_select @priorities, "id", "name", @issue.priority_id %></p>
19 15 </select></p>
20 16 </div>
21 17
22 18 <div style="float:left;margin-right:10px;">
23 19 <p><label for="issue_assigned_to_id"><%=_('Assigned to')%></label><br/>
24 20 <select name="issue[assigned_to_id]">
25 21 <option value=""></option>
26 22 <%= options_from_collection_for_select @issue.project.members, "user_id", "name", @issue.assigned_to_id %></p>
27 23 </select></p>
28 24 </div>
29 25
30 26 <div>
31 27 <p><label for="issue_category_id"><%=_('Category')%></label><br/>
32 28 <select name="issue[category_id]">
33 <option value=""></option>
34 <%= options_from_collection_for_select @project.issue_categories, "id", "name", @issue.category_id %></p>
29 <option value=""></option><%= options_from_collection_for_select @project.issue_categories, "id", "name", @issue.category_id %>
35 30 </select></p>
36 31 </div>
37 32
38 33 <p><label for="issue_subject"><%=_('Subject')%> <span class="required">*</span></label><br/>
39 34 <%= text_field 'issue', 'subject', :size => 80 %></p>
40 35
41 <p><label for="issue_descr"><%=_('Description')%> <span class="required">*</span></label><br/>
42 <%= text_area 'issue', 'descr', :cols => 60, :rows => 10 %></p>
43
36 <p><label for="issue_description"><%=_('Description')%> <span class="required">*</span></label><br/>
37 <%= text_area 'issue', 'description', :cols => 60, :rows => 10 %></p>
44 38
45 <% for custom_value in @custom_values %>
46 <div style="float:left;margin-right:10px;">
47 <p><%= content_tag "label", custom_value.custom_field.name %>
48 <% if custom_value.custom_field.is_required? %><span class="required">*</span><% end %>
49 <br />
50 <%= custom_field_tag custom_value %></p>
51 </div>
39 <% for custom_value in @custom_values %>
40 <p><%= custom_field_tag_with_label custom_value %></p>
52 41 <% end %>
53 42
54 <div style="clear: both;">
55 43 <p><label for="attachment_file"><%=_('Attachment')%></label><br/>
56 44 <%= file_field 'attachment', 'file' %></p>
57 </div>
58 45
59 46 <!--[eoform:issue]-->
47 </div>
48
60 49
61 50 <%= submit_tag _('Create') %>
62 51 <%= end_form_tag %> No newline at end of file
@@ -1,12 +1,12
1 1 <h2><%=_('Change log')%></h2>
2 2
3 3 <% fixed_issues = @fixed_issues.group_by {|i| i.fixed_version } %>
4 4 <% fixed_issues.each do |version, issues| %>
5 5 <p><strong><%= version.name %></strong> - <%= format_date(version.effective_date) %><br />
6 <%=h version.descr %></p>
6 <%=h version.description %></p>
7 7 <ul>
8 8 <% issues.each do |i| %>
9 9 <li><%= link_to i.long_id, :controller => 'issues', :action => 'show', :id => i %> [<%= i.tracker.name %>]: <%= i.subject %></li>
10 10 <% end %>
11 11 </ul>
12 12 <% end %>
@@ -1,20 +1,20
1 1 <h2><%=_('Public projects')%></h2>
2 2
3 3 <table width="100%" cellspacing="1" cellpadding="2" class="listTableContent">
4 4 <tr class="ListHead">
5 5 <%= sort_header_tag('name', :caption => _('Project')) %>
6 6 <th>Description</th>
7 7 <%= sort_header_tag('created_on', :caption => _('Created on')) %>
8 8 </tr>
9 9
10 10 <% for project in @projects %>
11 11 <tr class="<%= cycle("odd", "even") %>">
12 12 <td><%= link_to project.name, :action => 'show', :id => project %>
13 <td><%= project.descr %>
13 <td><%= project.description %>
14 14 <td align="center"><%= format_date(project.created_on) %>
15 15 </tr>
16 16 <% end %>
17 17 </table>
18 18
19 19 <%= pagination_links_full @project_pages %>
20 20 [ <%= @project_pages.current.first_item %> - <%= @project_pages.current.last_item %> / <%= @project_count %> ] No newline at end of file
@@ -1,21 +1,21
1 1 <h2><%=_('Documents')%></h2>
2 2
3 3 <% documents = @documents.group_by {|d| d.category } %>
4 4 <% documents.each do |category, docs| %>
5 5 <h3><%= category.name %></h3>
6 6 <ul>
7 7 <% docs.each do |d| %>
8 8 <li>
9 9 <b><%= link_to d.title, :controller => 'documents', :action => 'show', :id => d %></b>
10 10 <br />
11 <%=_('Desciption')%>: <%= d.descr %><br />
11 <%=_('Desciption')%>: <%= d.description %><br />
12 12 <%= format_time(d.created_on) %>
13 13 </li>
14 14
15 15 <% end %>
16 16 </ul>
17 17 <% end %>
18 18
19 19 <p>
20 20 <%= link_to_if_authorized '&#187; ' + _('New'), :controller => 'projects', :action => 'add_document', :id => @project %>
21 21 </p>
@@ -1,60 +1,56
1 1 <h2><%=_('Issues')%></h2>
2 2
3 3 <form method="post" class="noborder">
4 4 <table cellpadding=2>
5 5 <tr>
6 6 <td><small><%=_('Status')%>:</small><br /><%= search_filter_tag 'status_id', :class => 'select-small' %></td>
7 7 <td><small><%=_('Tracker')%>:</small><br /><%= search_filter_tag 'tracker_id', :class => 'select-small' %></td>
8 8 <td><small><%=_('Priority')%>:</small><br /><%= search_filter_tag 'priority_id', :class => 'select-small' %></td>
9 9 <td><small><%=_('Category')%>:</small><br /><%= search_filter_tag 'category_id', :class => 'select-small' %></td>
10 <td><small><%=_('Fixed in version')%>:</small><br /><%= search_filter_tag 'fixed_version_id', :class => 'select-small' %></td>
10 11 <td><small><%=_('Assigned to')%>:</small><br /><%= search_filter_tag 'assigned_to_id', :class => 'select-small' %></td>
11 12 <td><small><%=_('Subprojects')%>:</small><br /><%= search_filter_tag 'subproject_id', :class => 'select-small' %></td>
12 13
13 14 <td valign="bottom">
14 15 <%= submit_tag _('Apply filter'), :class => 'button-small' %>
15 16 <%= end_form_tag %>
16 17
17 18 <%= start_form_tag %>
18 19 <%= submit_tag _('Reset'), :class => 'button-small' %>
19 20 <%= end_form_tag %>
20 21 </td>
21 22 </tr>
22 23 </table>
23 24 &nbsp;
24 25 <table border="0" cellspacing="1" cellpadding="2" class="listTableContent">
25 26
26 27 <tr><td colspan="7" align="right">
27 28 <small><%= link_to 'Export to CSV', :action => 'export_issues_csv', :id => @project.id %></small>
28 29 </td></tr>
29 30
30 31 <tr class="ListHead">
31 32 <%= sort_header_tag('issues.id', :caption => '#') %>
32 33 <%= sort_header_tag('issue_statuses.name', :caption => _('Status')) %>
33 34 <%= sort_header_tag('issues.tracker_id', :caption => _('Tracker')) %>
34 35 <th><%=_('Subject')%></th>
35 36 <%= sort_header_tag('users.lastname', :caption => _('Author')) %>
36 37 <%= sort_header_tag('issues.created_on', :caption => _('Created on')) %>
37 38 <%= sort_header_tag('issues.updated_on', :caption => _('Last update')) %>
38 39 </tr>
39 40
40 41 <% for issue in @issues %>
41 42 <tr bgcolor="#<%= issue.status.html_color %>">
42 43 <td align="center"><%= link_to issue.long_id, :controller => 'issues', :action => 'show', :id => issue %></td>
43 44 <td align="center"><%= issue.status.name %></td>
44 45 <td align="center"><%= issue.tracker.name %></td>
45 46 <td><%= link_to issue.subject, :controller => 'issues', :action => 'show', :id => issue %></td>
46 47 <td align="center"><%= issue.author.display_name %></td>
47 48 <td align="center"><%= format_time(issue.created_on) %></td>
48 49 <td align="center"><%= format_time(issue.updated_on) %></td>
49 50 </tr>
50 51 <% end %>
51 52 </table>
52 53 <p>
53 54 <%= pagination_links_full @issue_pages %>
54 55 [ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]
55 </p>
56
57
58 <p>
59 <%= link_to_if_authorized '&#187; ' + _('Report an issue'), :controller => 'projects', :action => 'add_issue', :id => @project %>
60 </p> No newline at end of file
56 </p> No newline at end of file
@@ -1,17 +1,17
1 1 <h2><%=_('News')%></h2>
2 2
3 3 <% for news in @news %>
4 4 <p>
5 5 <b><%= news.title %></b> <small>(<%= link_to_user news.author %> <%= format_time(news.created_on) %>)</small>
6 6 <%= link_to_if_authorized image_tag('edit_small'), :controller => 'news', :action => 'edit', :id => news %>
7 7 <%= link_to_if_authorized image_tag('delete'), { :controller => 'news', :action => 'destroy', :id => news }, :confirm => 'Are you sure?' %>
8 8 <br />
9 <%= news.shortdescr %>
9 <%= news.summary %>
10 10 <small>[<%= link_to _('Read...'), :controller => 'news', :action => 'show', :id => news %>]</small>
11 11 </p>
12 12 <% end %>
13 13
14 14 <%= pagination_links_full @news_pages %>
15 15 <p>
16 16 <%= link_to_if_authorized '&#187; ' + _('Add'), :controller => 'projects', :action => 'add_news', :id => @project %>
17 17 </p>
@@ -1,105 +1,105
1 1 <h2><%=_('Settings')%></h2>
2 2
3 <div class="box">
4 3 <%= start_form_tag :action => 'edit', :id => @project %>
5 4 <%= render :partial => 'form' %>
6 5 <center><%= submit_tag _('Save') %></center>
7 6 <%= end_form_tag %>
8 </div>
7
8 &nbsp;
9 9
10 10 <div class="box">
11 11 <h3><%=_('Members')%></h3>
12 12 <%= error_messages_for 'member' %>
13 13 <table>
14 14 <% for member in @project.members.find(:all, :include => :user) %>
15 15 <% unless member.new_record? %>
16 16 <tr>
17 17 <td><%= member.user.display_name %></td>
18 18 <td>
19 19 <%= start_form_tag :controller => 'members', :action => 'edit', :id => member %>
20 20 <select name="member[role_id]">
21 21 <%= options_from_collection_for_select @roles, "id", "name", member.role_id %>
22 22 </select>
23 23 </td>
24 24 <td>
25 25 <%= submit_tag _('Save'), :class => "button-small" %>
26 26 <%= end_form_tag %>
27 27 </td>
28 28 <td>
29 29 <%= start_form_tag :controller => 'members', :action => 'destroy', :id => member %>
30 30 <%= submit_tag _('Delete'), :class => "button-small" %>
31 31 <%= end_form_tag %>
32 32 </td>
33 33 </tr>
34 34 <% end %>
35 35 <% end %>
36 36 </table>
37 37 <hr />
38 38 <label><%=_('New member')%></label><br/>
39 39 <%= start_form_tag :controller => 'projects', :action => 'add_member', :id => @project %>
40 40 <select name="member[user_id]">
41 41 <%= options_from_collection_for_select @users, "id", "display_name", @member.user_id %>
42 42 </select>
43 43 <select name="member[role_id]">
44 44 <%= options_from_collection_for_select @roles, "id", "name", @member.role_id %>
45 45 </select>
46 46 <%= submit_tag _('Add') %>
47 47 <%= end_form_tag %>
48 48 </div>
49 49
50 50 <div class="box">
51 51 <h3><%=_('Versions')%></h3>
52 52
53 53 <table>
54 54 <% for version in @project.versions %>
55 55 <tr>
56 56 <td><%= link_to version.name, :controller => 'versions', :action => 'edit', :id => version %></td>
57 <td><%=h version.descr %></td>
57 <td><%=h version.description %></td>
58 58 <td>
59 59 <%= start_form_tag :controller => 'versions', :action => 'destroy', :id => version %>
60 60 <%= submit_tag _('Delete'), :class => "button-small" %>
61 61 <%= end_form_tag %>
62 62 </td>
63 63 </tr>
64 64 <% end %>
65 65 </table>
66 66 <hr />
67 67 <%= start_form_tag ({ :controller => 'projects', :action => 'add_version', :id => @project }, :method => 'get' ) %>
68 68 <%= submit_tag _('New version...') %>
69 69 <%= end_form_tag %>
70 70 </div>
71 71
72 72
73 73 <div class="box">
74 74 <h3><%=_('Issue categories')%></h3>
75 75 <table>
76 76 <% for @category in @project.issue_categories %>
77 77 <% unless @category.new_record? %>
78 78 <tr>
79 79 <td>
80 80 <%= start_form_tag :controller => 'issue_categories', :action => 'edit', :id => @category %>
81 81 <%= text_field 'category', 'name', :size => 25 %>
82 82 </td>
83 83 <td>
84 84 <%= submit_tag _('Save'), :class => "button-small" %>
85 85 <%= end_form_tag %>
86 86 </td>
87 87 <td>
88 88 <%= start_form_tag :controller => 'issue_categories', :action => 'destroy', :id => @category %>
89 89 <%= submit_tag _('Delete'), :class => "button-small" %>
90 90 <%= end_form_tag %>
91 91 </td>
92 92 </tr>
93 93 <% end %>
94 94 <% end %>
95 95 </table>
96 96 <hr />
97 97
98 98 <%= start_form_tag :action => 'add_issue_category', :id => @project %>
99 99 <%= error_messages_for 'issue_category' %>
100 100 <label for="issue_category_name"><%=_('New category')%></label><br/>
101 101 <%= text_field 'issue_category', 'name', :size => 25 %>
102 102 <%= submit_tag _('Create') %>
103 103 <%= end_form_tag %>
104 104
105 105 </div>
@@ -1,62 +1,73
1 1 <h2><%=_('Overview')%></h2>
2 2
3 3 <div class="splitcontentleft">
4 <%= @project.descr %>
4 <%= @project.description %>
5 5 <ul>
6 6 <li><%=_('Homepage')%>: <%= link_to @project.homepage, @project.homepage %></li>
7 7 <li><%=_('Created on')%>: <%= format_date(@project.created_on) %></li>
8 <% for custom_value in @custom_values %>
9 <% if !custom_value.value.empty? %>
10 <li><%= custom_value.custom_field.name%>: <%= custom_value.value%></li>
11 <% end %>
12 <% end %>
8 13 </ul>
9 14
10 15 <div class="box">
11 16 <h3><%= image_tag "tracker" %> <%=_('Trackers')%></h3>
12 17 <ul>
13 <% for tracker in Tracker.find_all %>
18 <% for tracker in @trackers %>
14 19 <li><%= link_to tracker.name, :controller => 'projects', :action => 'list_issues', :id => @project,
15 20 :set_filter => 1,
16 21 "tracker_id" => tracker.id %>:
17 22 <%= Issue.count(:conditions => ["project_id=? and tracker_id=? and issue_statuses.is_closed=?", @project.id, tracker.id, false], :include => :status) %> <%=_('open')%>
18 23 </li>
19 24 <% end %>
20 25 </ul>
21 <%= link_to_if_authorized '&#187; ' + _('Report an issue'), :controller => 'projects', :action => 'add_issue', :id => @project %>
22 <br />
26 <% if authorize_for 'projects', 'add_issue' %>
27 &#187; <%=_('Report an issue')%>:
28 <ul>
29 <% @trackers.each do |tracker| %>
30 <li><%= link_to _(tracker.name), :controller => 'projects', :action => 'add_issue', :id => @project, :tracker_id => tracker %></li>
31 <% end %>
32 </ul>
33 <% end %>
23 34 <center><small>[ <%= link_to _('View all issues'), :controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1 %> ]</small></center>
24 35 </div>
25 36 </div>
26 37
27 38 <div class="splitcontentright">
28 39 <div class="box">
29 40 <h3><%= image_tag "users" %> <%=_('Members')%></h3>
30 41 <% for member in @members %>
31 42 <%= link_to_user member.user %> (<%= member.role.name %>)<br />
32 43 <% end %>
33 44 </div>
34 45
35 46 <% if @subprojects %>
36 47 <div class="box">
37 48 <h3><%= image_tag "projects" %> <%=_('Subprojects')%></h3>
38 49 <% for subproject in @subprojects %>
39 50 <%= link_to subproject.name, :action => 'show', :id => subproject %><br />
40 51 <% end %>
41 52 </div>
42 53 <% end %>
43 54
44 55 <div class="box">
45 56 <h3><%=_('Latest news')%></h3>
46 57 <% for news in @news %>
47 58 <p>
48 59 <b><%= news.title %></b> <small>(<%= link_to_user news.author %> <%= format_time(news.created_on) %>)</small><br />
49 <%= news.shortdescr %>
60 <%= news.summary %>
50 61 <small>[<%= link_to _('Read...'), :controller => 'news', :action => 'show', :id => news %>]</small>
51 62 </p>
52 63 <hr />
53 64 <% end %>
54 65 <center><small>[ <%= link_to _('View all news'), :controller => 'projects', :action => 'list_news', :id => @project %> ]</small></center>
55 66 </div>
56 67 </div>
57 68
58 69
59 70
60 71
61 72
62 73
@@ -1,22 +1,23
1 1 <%= error_messages_for 'role' %>
2 2
3 <div class="box">
3 4 <!--[form:role]-->
4 5 <p><label for="role_name"><%=_('Name')%> <span class="required">*</span></label><br />
5 6 <%= text_field 'role', 'name' %></p>
6 7
7 8 <strong><%=_('Permissions')%></strong>
8 9 <% permissions = @permissions.group_by {|p| p.group_id } %>
9 10 <% permissions.keys.sort.each do |group_id| %>
10 11 <fieldset><legend><%= _(Permission::GROUPS[group_id]) %></legend>
11 12 <% permissions[group_id].each do |p| %>
12 13 <div style="width:200px;float:left;"><%= check_box_tag "permission_ids[]", p.id, (@role.permissions.include? p) %>
13 <%= _(p.descr) %>
14 <%= _(p.description) %>
14 15 </div>
15 16 <% end %>
16 17 </fieldset>
17 18 <% end %>
18 19 <br />
19 20 <a href="javascript:checkAll('role_form', true)"><%=_('Check all')%></a> |
20 21 <a href="javascript:checkAll('role_form', false)"><%=_('Uncheck all')%></a><br />
21 22 <!--[eoform:role]-->
22
23 </div>
@@ -1,10 +1,10
1 1 <%= error_messages_for 'tracker' %>
2 2
3 3 <!--[form:tracker]-->
4 <p><label for="tracker_name"><%=_('Name')%></label><br/>
4 <p><label for="tracker_name"><%=_('Name')%></label> <span class="required">*</span><br/>
5 5 <%= text_field 'tracker', 'name' %></p>
6 6
7 7 <p><%= check_box 'tracker', 'is_in_chlog' %>
8 8 <label for="tracker_is_in_chlog"><%=_('View issues in change log')%></label></p>
9 9 <!--[eoform:tracker]-->
10 10
@@ -1,31 +1,37
1 1 <%= error_messages_for 'user' %>
2 2
3 <div class="box">
3 4 <!--[form:user]-->
4 <p><label for="user_login"><%=_('Login')%></label><br/>
5 <p><label for="user_login"><%=_('Login')%></label> <span class="required">*</span><br/>
5 6 <%= text_field 'user', 'login', :size => 25 %></p>
6 7
7 <p><label for="password"><%=_('Password')%></label><br/>
8 <p><label for="password"><%=_('Password')%></label> <span class="required">*</span><br/>
8 9 <%= password_field_tag 'password', nil, :size => 25 %></p>
9 10
10 <p><label for="password_confirmation"><%=_('Confirmation')%></label><br/>
11 <p><label for="password_confirmation"><%=_('Confirmation')%></label> <span class="required">*</span><br/>
11 12 <%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
12 13
13 <p><label for="user_firstname"><%=_('Firstname')%></label><br/>
14 <p><label for="user_firstname"><%=_('Firstname')%></label> <span class="required">*</span><br/>
14 15 <%= text_field 'user', 'firstname' %></p>
15 16
16 <p><label for="user_lastname"><%=_('Lastname')%></label><br/>
17 <p><label for="user_lastname"><%=_('Lastname')%></label> <span class="required">*</span><br/>
17 18 <%= text_field 'user', 'lastname' %></p>
18 19
19 <p><label for="user_mail"><%=_('Mail')%></label><br/>
20 <p><label for="user_mail"><%=_('Mail')%></label> <span class="required">*</span><br/>
20 21 <%= text_field 'user', 'mail' %></p>
21 22
22 23 <p><label for="user_language"><%=_('Language')%></label><br/>
23 <%= select("user", "language", Localization.langs) %></p>
24 <%= select("user", "language", Localization.langs.invert) %></p>
25
26 <% for custom_value in @custom_values %>
27 <p><%= custom_field_tag_with_label custom_value %></p>
28 <% end %>
29
30 <div style="clear: both;"></div>
24 31
25 32 <p><%= check_box 'user', 'admin' %> <label for="user_admin"><%=_('Administrator')%></label></p>
26 33
27 34 <p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=_('Mail notifications')%></label></p>
28 35
29 <p><%= check_box 'user', 'locked' %> <label for="user_locked"><%=_('Locked')%></label></p>
30 36 <!--[eoform:user]-->
31
37 </div>
@@ -1,46 +1,46
1 1 <h2><%=_('Users')%></h2>
2 2
3 3 <table border="0" cellspacing="1" cellpadding="2" class="listTableContent">
4 4 <tr class="ListHead">
5 5 <%= sort_header_tag('login', :caption => _('Login')) %>
6 6 <%= sort_header_tag('firstname', :caption => _('Firstname')) %>
7 7 <%= sort_header_tag('lastname', :caption => _('Lastname')) %>
8 8 <th><%=_('Mail')%></th>
9 9 <%= sort_header_tag('admin', :caption => _('Admin')) %>
10 <%= sort_header_tag('locked', :caption => _('Locked')) %>
10 <%= sort_header_tag('status', :caption => _('Status')) %>
11 11 <%= sort_header_tag('created_on', :caption => _('Created on')) %>
12 12 <%= sort_header_tag('last_login_on', :caption => _('Last login')) %>
13 13 <th></th>
14 14 </tr>
15 15 <% for user in @users %>
16 16 <tr class="<%= cycle("odd", "even") %>">
17 17 <td><%= link_to user.login, :action => 'edit', :id => user %></td>
18 18 <td><%= user.firstname %></td>
19 19 <td><%= user.lastname %></td>
20 20 <td><%= user.mail %></td>
21 21 <td align="center"><%= image_tag 'true' if user.admin? %></td>
22 22 <td align="center"><%= image_tag 'locked' if user.locked? %></td>
23 23 <td align="center"><%= format_time(user.created_on) %></td>
24 24 <td align="center"><%= format_time(user.last_login_on) unless user.last_login_on.nil? %></td>
25 25 <td align="center">
26 26 <%= start_form_tag :action => 'edit', :id => user %>
27 27 <% if user.locked? %>
28 <%= hidden_field_tag 'user[locked]', 0 %>
28 <%= hidden_field_tag 'user[status]', User::STATUS_ACTIVE %>
29 29 <%= submit_tag _('Unlock'), :class => "button-small" %>
30 30 <% else %>
31 <%= hidden_field_tag 'user[locked]', 1 %>
31 <%= hidden_field_tag 'user[status]', User::STATUS_LOCKED %>
32 32 <%= submit_tag _('Lock'), :class => "button-small" %>
33 33 <% end %>
34 34 <%= end_form_tag %>
35 35 </td>
36 36 </tr>
37 37 <% end %>
38 38 </table>
39 39
40 40 <p><%= pagination_links_full @user_pages %>
41 41 [ <%= @user_pages.current.first_item %> - <%= @user_pages.current.last_item %> / <%= @user_count %> ]
42 42 </p>
43 43
44 44 <p>
45 45 <%= link_to '&#187; ' + _('New user'), :action => 'add' %>
46 46 </p> No newline at end of file
@@ -1,13 +1,13
1 1 <%= error_messages_for 'version' %>
2 2
3 3 <!--[form:version]-->
4 4 <p><label for="version_name"><%=_('Version')%></label> <span class="required">*</span><br/>
5 5 <%= text_field 'version', 'name', :size => 20 %></p>
6 6
7 <p><label for="version_descr"><%=_('Description')%></label><br/>
8 <%= text_field 'version', 'descr', :size => 60 %></p>
7 <p><label for="version_description"><%=_('Description')%></label><br/>
8 <%= text_field 'version', 'description', :size => 60 %></p>
9 9
10 10 <p><label for="version_effective_date"><%=_('Date')%></label><br/>
11 11 <%= date_select 'version', 'effective_date' %></p>
12 12 <!--[eoform:version]-->
13 13
@@ -1,30 +1,31
1 1 <div class="splitcontentleft">
2 <h2><%=_('Welcome')%> !</h2>
3
2 <h2><%= $RDM_WELCOME_TITLE || _('Welcome') %> !</h2>
3 <p><%= $RDM_WELCOME_TEXT %></p>
4
4 5 <div class="box">
5 6 <h3><%=_('Latest news')%></h3>
6 7 <% for news in @news %>
7 8 <p>
8 9 <b><%= news.title %></b> (<%= link_to_user news.author %> <%= format_time(news.created_on) %> - <%= news.project.name %>)<br />
9 <%= news.shortdescr %><br />
10 <%= news.summary %><br />
10 11 [<%= link_to 'Read...', :controller => 'news', :action => 'show', :id => news %>]
11 12 </p>
12 13 <hr />
13 14 <% end %>
14 15 </div>
15 16 </div>
16 17
17 18 <div class="splitcontentright">
18 19 <div class="box">
19 20 <h3><%=_('Latest projects')%></h3>
20 21 <ul>
21 22 <% for project in @projects %>
22 23 <li>
23 24 <%= link_to project.name, :controller => 'projects', :action => 'show', :id => project %> (added <%= format_time(project.created_on) %>)<br />
24 <%= project.descr %>
25 <%= project.description %>
25 26 </li>
26 27 <% end %>
27 28 </ul>
28 29 </div>
29 30
30 31 </div>
@@ -1,85 +1,134
1 1 # Be sure to restart your web server when you modify this file.
2 2
3 3 # Uncomment below to force Rails into production mode when
4 4 # you don't control web/app server and can't set it the proper way
5 5 # ENV['RAILS_ENV'] ||= 'production'
6 6
7 7 # Bootstrap the Rails environment, frameworks, and default configuration
8 8 require File.join(File.dirname(__FILE__), 'boot')
9 9
10 10 Rails::Initializer.run do |config|
11 11 # Settings in config/environments/* take precedence those specified here
12 12
13 13 # Skip frameworks you're not going to use
14 14 # config.frameworks -= [ :action_web_service, :action_mailer ]
15 15
16 16 # Add additional load paths for your own custom dirs
17 17 # config.load_paths += %W( #{RAILS_ROOT}/extras )
18 18
19 19 # Force all environments to use the same logger level
20 20 # (by default production uses :info, the others :debug)
21 21 # config.log_level = :debug
22 22
23 23 # Use the database for sessions instead of the file system
24 24 # (create the session table with 'rake create_sessions_table')
25 25 # config.action_controller.session_store = :active_record_store
26 26
27 27 # Enable page/fragment caching by setting a file-based store
28 28 # (remember to create the caching directory and make it readable to the application)
29 29 # config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache"
30 30
31 31 # Activate observers that should always be running
32 32 # config.active_record.observers = :cacher, :garbage_collector
33 33
34 34 # Make Active Record use UTC-base instead of local time
35 35 # config.active_record.default_timezone = :utc
36 36
37 37 # Use Active Record's schema dumper instead of SQL when creating the test database
38 38 # (enables use of different database adapters for development and test environments)
39 39 # config.active_record.schema_format = :ruby
40 40
41 41 # See Rails::Configuration for more options
42 42
43 43 # SMTP server configuration
44 44 config.action_mailer.server_settings = {
45 45 :address => "127.0.0.1",
46 46 :port => 25,
47 47 :domain => "somenet.foo",
48 48 :authentication => :login,
49 49 :user_name => "redmine",
50 50 :password => "redmine",
51 51 }
52 52
53 53 config.action_mailer.perform_deliveries = true
54 54
55 55 # Tell ActionMailer not to deliver emails to the real world.
56 56 # The :test delivery method accumulates sent emails in the
57 57 # ActionMailer::Base.deliveries array.
58 58 #config.action_mailer.delivery_method = :test
59 59 config.action_mailer.delivery_method = :smtp
60 60 end
61 61
62 62 # Add new inflection rules using the following format
63 63 # (all these examples are active by default):
64 64 # Inflector.inflections do |inflect|
65 65 # inflect.plural /^(ox)$/i, '\1en'
66 66 # inflect.singular /^(ox)en/i, '\1'
67 67 # inflect.irregular 'person', 'people'
68 68 # inflect.uncountable %w( fish sheep )
69 69 # end
70 70
71 # Include your application configuration below
72
73 # application name
74 RDM_APP_NAME = "redMine"
75 # application version
76 RDM_APP_VERSION = "0.2.0"
71 if File.exist? File.join(File.dirname(__FILE__), 'config_custom.rb')
72 begin
73 print "=> Loading config_custom.rb... "
74 require File.join(File.dirname(__FILE__), 'config_custom')
75 puts "done."
76 rescue Exception => detail
77 puts
78 puts detail
79 puts detail.backtrace.join("\n")
80 puts "=> Error in config_custom.rb. Check your configuration."
81 exit
82 end
83 end
84
85 # IMPORTANT !!! DO NOT MODIFY PARAMETERS HERE
86 # Instead, rename config_custom.example.rb to config_custom.rb
87 # and set your own configuration in that file
88 # Parameters defined in config_custom.rb override those defined below
89
77 90 # application host name
78 RDM_HOST_NAME = "somenet.foo"
91 $RDM_HOST_NAME ||= "localhost:3000"
79 92 # file storage path
80 RDM_STORAGE_PATH = "#{RAILS_ROOT}/files"
93 $RDM_STORAGE_PATH ||= "#{RAILS_ROOT}/files"
81 94 # if RDM_LOGIN_REQUIRED is set to true, login is required to access the application
82 RDM_LOGIN_REQUIRED = false
95 $RDM_LOGIN_REQUIRED ||= false
83 96 # default langage
84 RDM_DEFAULT_LANG = 'en'
85
97 $RDM_DEFAULT_LANG ||= 'en'
98
99 # page title
100 $RDM_HEADER_TITLE ||= "redMine"
101 # page sub-title
102 $RDM_HEADER_SUBTITLE ||= "Project management"
103 # footer signature
104 $RDM_FOOTER_SIG = "admin@somenet.foo"
105
106 # application name
107 RDM_APP_NAME = "redMine"
108 # application version
109 RDM_APP_VERSION = "0.3.0"
110
111 ActiveRecord::Errors.default_error_messages = {
112 :inclusion => "activerecord_error_inclusion",
113 :exclusion => "activerecord_error_exclusion",
114 :invalid => "activerecord_error_invalid",
115 :confirmation => "activerecord_error_confirmation",
116 :accepted => "activerecord_error_accepted",
117 :empty => "activerecord_error_empty",
118 :blank => "activerecord_error_blank",
119 :too_long => "activerecord_error_too_long",
120 :too_short => "activerecord_error_too_short",
121 :wrong_length => "activerecord_error_wrong_length",
122 :taken => "activerecord_error_taken",
123 :not_a_number => "activerecord_error_not_a_number"
124 }
125
126 ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "<span class=\"fieldWithErrors\">#{html_tag}</span>" }
127
128 GLoc.set_config :default_language => $RDM_DEFAULT_LANG
129 GLoc.clear_strings
130 GLoc.set_kcode
131 GLoc.load_localized_strings
132 GLoc.set_config(:raise_string_not_found_errors => false)
133
134
@@ -1,15 +1,16
1 1 # Settings specified here will take precedence over those in config/environment.rb
2 2
3 3 # The test environment is used exclusively to run your application's
4 4 # test suite. You never need to work with it otherwise. Remember that
5 5 # your test database is "scratch space" for the test suite and is wiped
6 6 # and recreated between test runs. Don't rely on the data there!
7 7 config.cache_classes = true
8 8
9 9 # Log error messages when you accidentally call methods on nil.
10 10 config.whiny_nils = true
11 11
12 12 # Show full error reports and disable caching
13 13 config.action_controller.consider_all_requests_local = true
14 14 config.action_controller.perform_caching = false
15 15
16 config.action_mailer.delivery_method = :test
@@ -1,34 +1,62
1 1 == redMine changelog
2 2
3 3 redMine - project management software
4 4 Copyright (C) 2006 Jean-Philippe Lang
5 5 http://redmine.org/
6 6
7 7
8 == xx/xx/2006 v0.3.0
9
10 * user authentication against multiple LDAP
11 * token based "lost password" functionality
12 * user self-registration functionality (optional)
13 * custom fields now available for issues, users and projects
14 * new custom field format "text" (textarea)
15 * project & administration drop down menus in navigation bar
16 * error messages internationalization
17 * Localization plugin replaced with GLoc 1.1.0
18 * new filter in issues list: "Fixed version"
19 * colored background for active filters on issues list
20 * custom configuration is now defined in config/config_custom.rb
21 * user object no more stored in session (only user_id)
22 * news summary field is no longer required
23 * Fixed: boolean custom field not working
24 * Fixed: error messages for custom fields are not displayed
25 * Fixed: custom fields values are not validated on issue update
26 * Fixed: user unable to choose an empty value for 'List' custom fields
27 * Fixed: no issue categories sorting
28 * Fixed: incorrect versions sorting
29
30
31 == 07/12/2006 - v0.2.2
32
33 * Fixed: bug in "issues list"
34
35
8 36 == 07/09/2006 - v0.2.1
9 37
10 38 * new databases supported: Oracle, PostgreSQL, SQL Server
11 39 * projects/subprojects hierarchy (1 level of subprojects only)
12 40 * environment information display in admin/info
13 41 * more filter options in issues list (rev6)
14 42 * default language based on browser settings (Accept-Language HTTP header)
15 43 * issues list exportable to CSV (rev6)
16 44 * simple_format and auto_link on long text fields
17 45 * more data validations
18 46 * Fixed: error when all mail notifications are unchecked in admin/mail_options
19 47 * Fixed: all project news are displayed on project summary
20 48 * Fixed: Can't change user password in users/edit
21 49 * Fixed: Error on tables creation with PostgreSQL (rev5)
22 50 * Fixed: SQL error in "issue reports" view with PostgreSQL (rev5)
23 51
24 52
25 53 == 06/25/2006 - v0.1.0
26 54
27 55 * multiple users/multiple projects
28 56 * role based access control
29 57 * issue tracking system
30 58 * fully customizable workflow
31 59 * documents/files repository
32 60 * email notifications on issue creation and update
33 61 * multilanguage support (except for error messages):english, french, spanish
34 62 * online manual in french (unfinished) No newline at end of file
@@ -1,69 +1,59
1 1 == redMine installation
2 2
3 3 redMine - project management software
4 4 Copyright (C) 2006 Jean-Philippe Lang
5 5 http://redmine.org/
6 6
7 7
8 8 == Requirements
9 9
10 10 * Ruby on Rails 1.1
11 11 * a database (see compatibility below)
12 12 * (recommended) Apache/Lighttpd with FCGI support
13 13
14 14 Supported databases:
15 15
16 16 * MySQL (tested with MySQL 5)
17 17 * PostgreSQL (tested with PostgreSQL 8.1)
18 18 * Oracle (tested with Oracle 10g)
19 19 * SQL Server (tested with SQL Server 2005)
20 20 * SQLite (tested with SQLite 3)
21 21
22 22
23 23 == Installation
24 24
25 25 1. Uncompress program archive:
26 26 tar zxvf <filename>
27 27
28 28 2. Create an empty database: "redmine" for example
29 29
30 30 3. Configure database parameters in config/database.yml
31 31 for "production" environment (default database is MySQL)
32 32
33 33 4. Create the database structure. Under application main directory:
34 34 rake migrate RAILS_ENV="production"
35 35 It will create tables and default configuration data
36 36
37 37 5. Test the installation by running WEBrick web server:
38 38 ruby script/server -e production
39 39
40 40 Once WEBrick has started, point your browser to http://localhost:3000/
41 41 You should now see the application welcome page
42 42
43 43 6. Use default administrator account to log in:
44 44 login: admin
45 45 password: admin
46 46
47 47 7. Setup Apache or Lighttpd with fastcgi for best performance.
48 48
49 49
50 50 == Configuration
51 51
52 You can setup a few things in config/environment.rb:
52 A sample configuration file is provided: "config/config_custom.example.rb"
53 Rename it to config_custom.rb and edit parameters.
53 54 Don't forget to restart the application after any change.
54 55
55 56
56 57 config.action_mailer.server_settings: SMTP server configuration
57 58 config.action_mailer.perform_deliveries: set to false to disable mail delivering
58 59
59 RDM_HOST_NAME: hostname used to provide urls in notification mails
60
61 RDM_STORAGE_PATH: path for all attachments storage (default: "#{RAILS_ROOT}/files")
62 "#{RAILS_ROOT}/" represents application main directory
63
64 RDM_LOGIN_REQUIRED: set to true if you want to force users to login to access
65 any part of the application (default: false)
66
67 RDM_DEFAULT_LANG: default language for anonymous users: 'en' (default), 'es', 'fr' available
68
69
@@ -1,4 +1,6
1 1 Localization.define('en', 'English') do |l|
2 2 l.store '(date)', lambda { |t| t.strftime('%m/%d/%Y') }
3 3 l.store '(time)', lambda { |t| t.strftime('%m/%d/%Y %I:%M%p') }
4
5 l.store '%d errors', ['1 error', '%d errors']
4 6 end No newline at end of file
@@ -1,324 +1,352
1 1 Localization.define('fr', 'Français') do |l|
2 2
3 3 # trackers
4 4 l.store 'Bug', 'Anomalie'
5 5 l.store 'Feature request', 'Evolution'
6 6 l.store 'Support request', 'Assistance'
7 7 # issue statuses
8 8 l.store 'New', 'Nouveau'
9 9 l.store 'Assigned', 'Assignée'
10 10 l.store 'Resolved', 'Résolue'
11 11 l.store 'Closed', 'Fermée'
12 12 l.store 'Rejected', 'Rejetée'
13 13 l.store 'Feedback', 'Commentaire'
14 14 # filters
15 15 l.store '[All]', '[Tous]'
16 16 l.store '[Open]', '[Ouvert]'
17 17 l.store '[None]', '[Aucun]'
18 18
19 19 # issue priorities
20 20 l.store 'Issue priorities', 'Priorités des demandes'
21 21 l.store 'Low', 'Bas'
22 22 l.store 'Normal', 'Normal'
23 23 l.store 'High', 'Haut'
24 24 l.store 'Urgent', 'Urgent'
25 25 l.store 'Immediate', 'Immédiat'
26 26 # document categories
27 27 l.store 'Document categories', 'Catégories de documents'
28 28 l.store 'Uncategorized', 'Sans catégorie'
29 29 l.store 'User documentation', 'Documentation utilisateur'
30 l.store 'Technical documentation', 'Documentation technique'
30 l.store 'Technical documentation', 'Documentation technique'
31 # custom fields formats
32 l.store 'String', 'Chaîne'
33 l.store 'Integer', 'Entier'
34 l.store 'Date', 'Date'
35 l.store 'Boolean', 'Booléen'
36 l.store 'List', 'Liste'
31 37 # dates
32 38 l.store '(date)', lambda { |t| t.strftime('%d/%m/%Y') }
33 39 l.store '(time)', lambda { |t| t.strftime('%d/%m/%Y %H:%M') }
34 40
35 # ./script/../config/../app/views/account/login.rhtml
41
42 # error messages
43 l.store '%d errors', ['1 erreur', '%d erreurs']
44
45 l.store "is not included in the list", "n'est pas inclus dans la liste"
46 l.store "is reserved", "est réservé"
47 l.store "is invalid", "n'est pas valide"
48 l.store "doesn't match confirmation", "ne correspond pas à la confirmation"
49 l.store "must be accepted", "doit être accepté"
50 l.store "can't be empty", "ne doit pas être vide"
51 l.store "can't be blank", "doit être renseigné"
52 l.store "is too long", "est trop long"
53 l.store "is too short", "est trop court"
54 l.store "is the wrong length", "n'est pas de la bonne longueur"
55 l.store "has already been taken", "est déjà utilisé"
56 l.store "is not a number", "doit être un nombre"
57
58 # notice messages
59 l.store 'Invalid user/password', 'Identifiant/Mot de passe invalide'
36 60
37 61 # ./script/../config/../app/views/account/my_account.rhtml
38 62 l.store 'My account', 'Mon compte'
39 63 l.store 'Login', 'Identifiant'
40 64 l.store 'Created on', 'Crée le'
41 65 l.store 'Last update', 'Mis à jour'
42 66 l.store 'Information', 'Informations'
43 67 l.store 'Firstname', 'Prénom'
44 68 l.store 'Lastname', 'Nom'
45 69 l.store 'Mail', 'Mail'
46 70 l.store 'Language', 'Langue'
47 71 l.store 'Mail notifications', 'Notifications par mail'
48 72 l.store 'Save', 'Valider'
49 73 l.store 'Password', 'Mot de passe'
50 74 l.store 'New password', 'Nouveau mot de passe'
51 75 l.store 'Confirmation', 'Confirmation'
52 76
53 77 # ./script/../config/../app/views/account/my_page.rhtml
54 78 l.store 'My page', 'Ma page'
55 79 l.store 'Welcome', 'Bienvenue'
56 80 l.store 'Last login', 'Dernière connexion'
57 81 l.store 'Reported issues', 'Demandes soumises'
58 82 l.store 'Assigned to me', 'Demandes qui me sont assignées'
59 83
60 84 # ./script/../config/../app/views/account/login.rhtml
61 85 l.store 'Please login', 'Identification'
86 l.store 'Register', "S'enregistrer"
87 l.store 'Password lost', 'Mot de passe perdu'
88 l.store 'Submit', 'Soumettre'
62 89
63 90 # ./script/../config/../app/views/account/show.rhtml
64 91 l.store 'Registered on', 'Inscrit le'
65 92 l.store 'Projects', 'Projets'
66 93 l.store 'Activity', 'Activité'
67 94
68 95 # ./script/../config/../app/views/admin/index.rhtml
69 96 l.store 'Administration', 'Administration'
70 97 l.store 'Users', 'Utilisateurs'
71 98 l.store 'Roles and permissions', 'Rôles et permissions'
72 99 l.store 'Trackers', 'Trackers'
73 100 l.store 'Custom fields', 'Champs personnalisés'
74 101 l.store 'Issue Statuses', 'Statuts des demandes'
75 102 l.store 'Workflow', 'Workflow'
76 103 l.store 'Enumerations', 'Listes de valeurs'
77 104
78 105 # ./script/../config/../app/views/admin/info.rhtml
79 106 l.store 'Version', 'Version'
80 107 l.store 'Database', 'Base de données'
81 108
82 109 # ./script/../config/../app/views/admin/mail_options.rhtml
83 110 l.store 'Select actions for which mail notification should be enabled.', 'Sélectionner les actions pour lesquelles la notification par mail doit être activée.'
84 111 l.store 'Check all', 'Cocher tout'
85 112 l.store 'Uncheck all', 'Décocher tout'
86 113
87 114 # ./script/../config/../app/views/admin/projects.rhtml
88 115 l.store 'Project', 'Projet'
89 116 l.store 'Description', 'Description'
90 117 l.store 'Public', 'Public'
91 118 l.store 'Delete', 'Supprimer'
92 119 l.store 'Previous', 'Précédent'
93 120 l.store 'Next', 'Suivant'
94 121
95 122 # ./script/../config/../app/views/custom_fields/edit.rhtml
96 123 l.store 'Custom field', 'Champ personnalisé'
97 124
98 125 # ./script/../config/../app/views/custom_fields/list.rhtml
99 126 l.store 'Name', 'Nom'
127 l.store 'For', 'Pour'
100 128 l.store 'Type', 'Type'
101 129 l.store 'Required', 'Obligatoire'
102 130 l.store 'For all projects', 'Pour tous les projets'
103 131 l.store 'Used by', 'Utilisé par'
104 132
105 133 # ./script/../config/../app/views/custom_fields/new.rhtml
106 134 l.store 'New custom field', 'Nouveau champ personnalisé'
107 135 l.store 'Create', 'Créer'
108 136
109 137 # ./script/../config/../app/views/custom_fields/_form.rhtml
110 138 l.store '0 means no restriction', '0 pour aucune restriction'
111 139 l.store 'Regular expression pattern', 'Expression régulière'
112 140 l.store 'Possible values', 'Valeurs possibles'
113 141
114 142 # ./script/../config/../app/views/documents/edit.rhtml
115 143 l.store 'Document', 'Document'
116 144
117 145 # ./script/../config/../app/views/documents/show.rhtml
118 146 l.store 'Category', 'Catégorie'
119 147 l.store 'Edit', 'Modifier'
120 148 l.store 'download', 'téléchargement'
121 149 l.store 'Add file', 'Ajouter le fichier'
122 150 l.store 'Add', 'Ajouter'
123 151
124 152 # ./script/../config/../app/views/documents/_form.rhtml
125 153 l.store 'Title', 'Titre'
126 154
127 155 # ./script/../config/../app/views/enumerations/edit.rhtml
128 156
129 157 # ./script/../config/../app/views/enumerations/list.rhtml
130 158
131 159 # ./script/../config/../app/views/enumerations/new.rhtml
132 160 l.store 'New enumeration', 'Nouvelle valeur'
133 161
134 162 # ./script/../config/../app/views/enumerations/_form.rhtml
135 163
136 164 # ./script/../config/../app/views/issues/change_status.rhtml
137 165 l.store 'Issue', 'Demande'
138 166 l.store 'New status', 'Nouveau statut'
139 167 l.store 'Assigned to', 'Assigné à'
140 168 l.store 'Fixed in version', 'Version corrigée'
141 169 l.store 'Notes', 'Remarques'
142 170
143 171 # ./script/../config/../app/views/issues/edit.rhtml
144 172 l.store 'Status', 'Statut'
145 173 l.store 'Tracker', 'Tracker'
146 174 l.store 'Priority', 'Priorité'
147 175 l.store 'Subject', 'Sujet'
148 176
149 177 # ./script/../config/../app/views/issues/show.rhtml
150 178 l.store 'Author', 'Auteur'
151 179 l.store 'Change status', 'Changer le statut'
152 180 l.store 'History', 'Historique'
153 181 l.store 'Attachments', 'Fichiers'
154 182 l.store 'Update...', 'Changer...'
155 183
156 184 # ./script/../config/../app/views/issues/_list_simple.rhtml
157 185 l.store 'No issue', 'Aucune demande'
158 186
159 187 # ./script/../config/../app/views/issue_categories/edit.rhtml
160 188
161 189 # ./script/../config/../app/views/issue_categories/_form.rhtml
162 190
163 191 # ./script/../config/../app/views/issue_statuses/edit.rhtml
164 192 l.store 'Issue status', 'Statut de demande'
165 193
166 194 # ./script/../config/../app/views/issue_statuses/list.rhtml
167 195 l.store 'Issue statuses', 'Statuts de demande'
168 196 l.store 'Default status', 'Statut par défaut'
169 197 l.store 'Issue closed', 'Demande fermée'
170 198 l.store 'Color', 'Couleur'
171 199
172 200 # ./script/../config/../app/views/issue_statuses/new.rhtml
173 201 l.store 'New issue status', 'Nouveau statut'
174 202
175 203 # ./script/../config/../app/views/issue_statuses/_form.rhtml
176 204
177 205 # ./script/../config/../app/views/layouts/base.rhtml
178 206 l.store 'Home', 'Accueil'
179 207 l.store 'Help', 'Aide'
180 208 l.store 'Log in', 'Connexion'
181 209 l.store 'Logout', 'Déconnexion'
182 210 l.store 'Overview', 'Aperçu'
183 211 l.store 'Issues', 'Demandes'
184 212 l.store 'Reports', 'Rapports'
185 213 l.store 'News', 'Annonces'
186 214 l.store 'Change log', 'Historique'
187 215 l.store 'Documents', 'Documents'
188 216 l.store 'Members', 'Membres'
189 217 l.store 'Files', 'Fichiers'
190 218 l.store 'Settings', 'Configuration'
191 219 l.store 'My projects', 'Mes projets'
192 220 l.store 'Logged as', 'Connecté en tant que'
193 221
194 222 # ./script/../config/../app/views/mailer/issue_add.rhtml
195 223
196 224 # ./script/../config/../app/views/mailer/issue_change_status.rhtml
197 225
198 226 # ./script/../config/../app/views/mailer/_issue.rhtml
199 227
200 228 # ./script/../config/../app/views/news/edit.rhtml
201 229
202 230 # ./script/../config/../app/views/news/show.rhtml
203 231 l.store 'Summary', 'Résumé'
204 232 l.store 'By', 'Par'
205 233 l.store 'Date', 'Date'
206 234
207 235 # ./script/../config/../app/views/news/_form.rhtml
208 236
209 237 # ./script/../config/../app/views/projects/add.rhtml
210 238 l.store 'New project', 'Nouveau projet'
211 239
212 240 # ./script/../config/../app/views/projects/add_document.rhtml
213 241 l.store 'New document', 'Nouveau document'
214 242 l.store 'File', 'Fichier'
215 243
216 244 # ./script/../config/../app/views/projects/add_issue.rhtml
217 245 l.store 'New issue', 'Nouvelle demande'
218 246 l.store 'Attachment', 'Fichier'
219 247
220 248 # ./script/../config/../app/views/projects/add_news.rhtml
221 249
222 250 # ./script/../config/../app/views/projects/add_version.rhtml
223 251 l.store 'New version', 'Nouvelle version'
224 252
225 253 # ./script/../config/../app/views/projects/changelog.rhtml
226 254
227 255 # ./script/../config/../app/views/projects/destroy.rhtml
228 256 l.store 'Are you sure you want to delete project', 'Êtes-vous sûr de vouloir supprimer le projet'
229 257
230 258 # ./script/../config/../app/views/projects/list.rhtml
231 259 l.store 'Public projects', 'Projets publics'
232 260
233 261 # ./script/../config/../app/views/projects/list_documents.rhtml
234 262 l.store 'Desciption', 'Description'
235 263
236 264 # ./script/../config/../app/views/projects/list_files.rhtml
237 265 l.store 'Files', 'Fichiers'
238 266 l.store 'New file', 'Nouveau fichier'
239 267
240 268 # ./script/../config/../app/views/projects/list_issues.rhtml
241 269 l.store 'Subprojects', 'Sous-projets'
242 270 l.store 'Apply filter', 'Appliquer'
243 271 l.store 'Reset', 'Annuler'
244 272 l.store 'Report an issue', 'Nouvelle demande'
245 273
246 274 # ./script/../config/../app/views/projects/list_members.rhtml
247 275 l.store 'Project members', 'Membres du projet'
248 276
249 277 # ./script/../config/../app/views/projects/list_news.rhtml
250 278 l.store 'Read...', 'Lire...'
251 279
252 280 # ./script/../config/../app/views/projects/settings.rhtml
253 281 l.store 'New member', 'Nouveau membre'
254 282 l.store 'Versions', 'Versions'
255 283 l.store 'New version...', 'Nouvelle version...'
256 284 l.store 'Issue categories', 'Catégories des demandes'
257 285 l.store 'New category', 'Nouvelle catégorie'
258 286
259 287 # ./script/../config/../app/views/projects/show.rhtml
260 288 l.store 'Homepage', 'Site web'
261 289 l.store 'open', 'ouverte(s)'
262 290 l.store 'View all issues', 'Voir toutes les demandes'
263 291 l.store 'View all news', 'Voir toutes les annonces'
264 292 l.store 'Latest news', 'Dernières annonces'
265 293
266 294 # ./script/../config/../app/views/projects/_form.rhtml
267 295
268 296 # ./script/../config/../app/views/reports/issue_report.rhtml
269 297 l.store 'Issues by tracker', 'Demandes par tracker'
270 298 l.store 'Issues by priority', 'Demandes par priorité'
271 299 l.store 'Issues by category', 'Demandes par catégorie'
272 300
273 301 # ./script/../config/../app/views/reports/_simple.rhtml
274 302 l.store 'Open', 'Ouverte'
275 303 l.store 'Total', 'Total'
276 304
277 305 # ./script/../config/../app/views/roles/edit.rhtml
278 306 l.store 'Role', 'Rôle'
279 307
280 308 # ./script/../config/../app/views/roles/list.rhtml
281 309 l.store 'Roles', 'Rôles'
282 310
283 311 # ./script/../config/../app/views/roles/new.rhtml
284 312 l.store 'New role', 'Nouveau rôle'
285 313
286 314 # ./script/../config/../app/views/roles/workflow.rhtml
287 315 l.store 'Workflow setup', 'Configuration du workflow'
288 316 l.store 'Select a workflow to edit', 'Sélectionner un workflow à mettre à jour'
289 317 l.store 'New statuses allowed', 'Nouveaux statuts autorisés'
290 318
291 319 # ./script/../config/../app/views/roles/_form.rhtml
292 320 l.store 'Permissions', 'Permissions'
293 321
294 322 # ./script/../config/../app/views/trackers/edit.rhtml
295 323
296 324 # ./script/../config/../app/views/trackers/list.rhtml
297 325 l.store 'View issues in change log', 'Demandes affichées dans l\'historique'
298 326
299 327 # ./script/../config/../app/views/trackers/new.rhtml
300 328 l.store 'New tracker', 'Nouveau tracker'
301 329
302 330 # ./script/../config/../app/views/trackers/_form.rhtml
303 331
304 332 # ./script/../config/../app/views/users/add.rhtml
305 333 l.store 'New user', 'Nouvel utilisateur'
306 334
307 335 # ./script/../config/../app/views/users/edit.rhtml
308 336 l.store 'User', 'Utilisateur'
309 337
310 338 # ./script/../config/../app/views/users/list.rhtml
311 339 l.store 'Admin', 'Admin'
312 340 l.store 'Locked', 'Verrouillé'
313 341
314 342 # ./script/../config/../app/views/users/_form.rhtml
315 343 l.store 'Administrator', 'Administrateur'
316 344
317 345 # ./script/../config/../app/views/versions/edit.rhtml
318 346
319 347 # ./script/../config/../app/views/versions/_form.rhtml
320 348
321 349 # ./script/../config/../app/views/welcome/index.rhtml
322 350 l.store 'Latest projects', 'Derniers projets'
323 351
324 352 end
1 NO CONTENT: file renamed from redmine/public/images/logout.png to redmine/public/images/alert.png, binary diff hidden
1 NO CONTENT: file renamed from redmine/public/images/Copie de help.png to redmine/public/images/login.png, binary diff hidden
@@ -1,331 +1,354
1 1 /* andreas08 - an open source xhtml/css website layout by Andreas Viklund - http://andreasviklund.com . Free to use in any way and for any purpose as long as the proper credits are given to the original designer. Version: 1.0, November 28, 2005 */
2 2 /* Edited by Jean-Philippe Lang *>
3 3 /**************** Body and tag styles ****************/
4 4
5 5
6 6 #header * {margin:0; padding:0;}
7 7 p, ul, ol, li {margin:0; padding:0;}
8 8
9 9
10 10 body{
11 11 font:76% Verdana,Tahoma,Arial,sans-serif;
12 12 line-height:1.4em;
13 13 text-align:center;
14 14 color:#303030;
15 15 background:#e8eaec;
16 16 }
17 17
18
18 19 a{
19 20 color:#467aa7;
20 21 font-weight:bold;
21 22 text-decoration:none;
22 23 background-color:inherit;
23 24 }
24 25
25 26 a:hover{color:#2a5a8a; text-decoration:none; background-color:inherit;}
26 27 a img{border:none;}
27 28
28 29 p{padding:0 0 1em 0;}
29 30 p form{margin-top:0; margin-bottom:20px;}
30 31
31 32 img.left,img.center,img.right{padding:4px; border:1px solid #a0a0a0;}
32 33 img.left{float:left; margin:0 12px 5px 0;}
33 34 img.center{display:block; margin:0 auto 5px auto;}
34 35 img.right{float:right; margin:0 0 5px 12px;}
35 36
36 37 /**************** Header and navigation styles ****************/
37 38
38 39 #container{
39 40 width:100%;
40 41 min-width: 800px;
41 42 margin:5px auto;
42 43 padding:1px 0;
43 44 text-align:left;
44 45 background:#ffffff;
45 46 color:#303030;
46 47 border:2px solid #a0a0a0;
47 48 }
48 49
49 50 #header{
50 51 height:5.5em;
51 52 /*width:758px;*/
52 53 margin:0 1px 1px 1px;
53 54 background:#467aa7;
54 55 color:#ffffff;
55 56 }
56 57
57 58 #header h1{
58 59 padding:14px 0 0 20px;
59 60 font-size:2.4em;
60 61 background-color:inherit;
61 62 color:#fff; /*rgb(152, 26, 33);*/
62 63 letter-spacing:-2px;
63 64 font-weight:normal;
64 65 }
65 66
66 67 #header h2{
67 68 margin:10px 0 0 40px;
68 69 font-size:1.4em;
69 70 background-color:inherit;
70 71 color:#f0f2f4;
71 72 letter-spacing:-1px;
72 73 font-weight:normal;
73 74 }
74 75
75 76 #navigation{
76 77 height:2.2em;
77 78 line-height:2.2em;
78 79 /*width:758px;*/
79 80 margin:0 1px;
80 81 background:#578bb8;
81 82 color:#ffffff;
82 83 }
83 84
84 85 #navigation li{
85 86 float:left;
86 87 list-style-type:none;
87 88 border-right:1px solid #ffffff;
88 89 white-space:nowrap;
89 90 }
90 91
91 92 #navigation li.right {
92 93 float:right;
93 94 list-style-type:none;
94 95 border-right:0;
95 96 border-left:1px solid #ffffff;
96 97 white-space:nowrap;
97 98 }
98 99
99 100 #navigation li a{
100 101 display:block;
101 102 padding:0px 10px 0px 22px;
102 103 font-size:0.8em;
103 104 font-weight:normal;
104 105 /*text-transform:uppercase;*/
105 106 text-decoration:none;
106 107 background-color:inherit;
107 108 color: #ffffff;
108 109 }
109 110
110 111 * html #navigation a {width:1%;}
111 112
112 113 #navigation .selected,#navigation a:hover{
113 114 color:#ffffff;
114 115 text-decoration:none;
115 116 background-color: #80b0da;
116 117 }
117 118
118 119 /**************** Icons links *******************/
119 120 .picHome { background: url(../images/home.png) no-repeat 4px 50%; }
120 121 .picUser { background: url(../images/user.png) no-repeat 4px 50%; }
121 122 .picUserPage { background: url(../images/user_page.png) no-repeat 4px 50%; }
122 123 .picAdmin { background: url(../images/admin.png) no-repeat 4px 50%; }
123 124 .picProject { background: url(../images/projects.png) no-repeat 4px 50%; }
124 125 .picLogout { background: url(../images/logout.png) no-repeat 4px 50%; }
125 126 .picHelp { background: url(../images/help.png) no-repeat 4px 50%; }
126 127
127 128 /**************** Content styles ****************/
128 129
129 130 #content{
130 131 /*float:right;*/
131 132 /*width:530px;*/
132 133 width: auto;
133 134 min-height: 500px;
134 135 font-size:0.9em;
135 136 padding:20px 10px 10px 20px;
136 137 /*position: absolute;*/
137 138 margin: 0 0 0 140px;
138 139 border-left: 1px dashed #c0c0c0;
139
140 140 }
141 141
142 142 #content h2{
143 143 display:block;
144 144 margin:0 0 16px 0;
145 145 font-size:1.7em;
146 146 font-weight:normal;
147 147 letter-spacing:-1px;
148 148 color:#505050;
149 149 background-color:inherit;
150 150 }
151 151
152 152 #content h2 a{font-weight:normal;}
153 153 #content h3{margin:0 0 5px 0; font-size:1.4em; letter-spacing:-1px;}
154 154 #content a:hover,#subcontent a:hover{text-decoration:underline;}
155 155 #content ul,#content ol{margin:0 5px 16px 35px;}
156 156 #content dl{margin:0 5px 10px 25px;}
157 157 #content dt{font-weight:bold; margin-bottom:5px;}
158 158 #content dd{margin:0 0 10px 15px;}
159 159
160 160
161 161 /***********************************************/
162 162
163 163 /*
164 164 form{
165 165 padding:15px;
166 166 margin:0 0 20px 0;
167 167 border:1px solid #c0c0c0;
168 168 background-color:#CEE1ED;
169 169 width:600px;
170 170 }
171 171 */
172 172
173 173 form {
174 174 display: inline;
175 175 }
176 176
177 177 .noborder {
178 178 border:0px;
179 179 background-color:#fff;
180 180 width:100%;
181 181 }
182 182
183 textarea {
184 padding:0;
185 margin:0;
186 }
187
183 188 input {
184 189 vertical-align: top;
185 190 }
186 191
187 192 input.button-small
188 193 {
189 194 font-size: 0.8em;
190 195 }
191 196
192 197 select.select-small
193 198 {
194 font-size: 0.8em;
199 border: 1px solid #7F9DB9;
200 padding: 1px;
201 font-size: 0.8em;
202 }
203
204 .active-filter
205 {
206 background-color: #F9FA9E;
207
195 208 }
196 209
197 210 label {
198 211 font-weight: bold;
199 212 font-size: 1em;
200 213 }
201 214
202 215 fieldset {
203 216 border:1px solid #7F9DB9;
217 padding: 6px;
218 }
219
220 legend {
221 color: #505050;
222
204 223 }
205 224
206 225 .required {
207 226 color: #bb0000;
208 227 }
209 228
210 229 table.listTableContent {
211 230 /*margin: 2em 2em 2em 0; */
212 231 border:1px solid #c0c0c0;
213 232 width:99%;
214 233 }
215 234
216 235 table.listTableContent td {
217 236 margin: 2px;
218 237
219 238 }
220 239
221 240 tr.ListHead {
222 241 background-color:#467aa7;
223 242 color:#FFFFFF;
224 243 text-align:center;
225 244 }
226 245
227 246 tr.ListHead a {
228 247 color:#FFFFFF;
229 248 text-decoration:underline;
230 249 }
231 250
232 251 tr.odd {
233 252 background-color: #C1E2F7;
234 253 }
235 254 tr.even {
236 255 background-color:#CEE1ED;
237 256 }
238 257
239 258 hr { border:0px; border-bottom:1px dashed #000000; }
240 259
241 260
242 261 /**************** Sidebar styles ****************/
243 262
244 263 #subcontent{
245 264 float:left;
246 265 clear:both;
247 266 width:130px;
248 267 padding:20px 20px 10px 5px;
249 268 line-height:1.4em;
250 269 }
251 270
252 271 #subcontent h2{
253 272 display:block;
254 273 margin:0 0 15px 0;
255 274 font-size:1.6em;
256 275 font-weight:normal;
257 276 text-align:left;
258 277 letter-spacing:-1px;
259 278 color:#505050;
260 279 background-color:inherit;
261 280 }
262 281
263 282 #subcontent p{margin:0 0 16px 0; font-size:0.9em;}
264 283
265 284 /**************** Menublock styles ****************/
266 285
267 286 .menublock{margin:0 0 20px 8px; font-size:0.9em;}
268 287 .menublock li{list-style:none; display:block; padding:1px; margin-bottom:0px;}
269 288 .menublock li a{font-weight:bold; text-decoration:none;}
270 289 .menublock li a:hover{text-decoration:none;}
271 290 .menublock li ul{margin:3px 0 3px 15px; font-size:1em; font-weight:normal;}
272 291 .menublock li ul li{margin-bottom:0;}
273 292 .menublock li ul a{font-weight:normal;}
274 293
275 294 /**************** Searchbar styles ****************/
276 295
277 296 #searchbar{margin:0 0 20px 0;}
278 297 #searchbar form fieldset{margin-left:10px; border:0 solid;}
279 298
280 299 #searchbar #s{
281 300 height:1.2em;
282 301 width:110px;
283 302 margin:0 5px 0 0;
284 303 border:1px solid #a0a0a0;
285 304 }
286 305
287 306 #searchbar #searchbutton{
288 307 width:auto;
289 308 padding:0 1px;
290 309 border:1px solid #808080;
291 310 font-size:0.9em;
292 311 text-align:center;
293 312 }
294 313
295 314 /**************** Footer styles ****************/
296 315
297 316 #footer{
298 317 clear:both;
299 318 /*width:758px;*/
300 319 padding:5px 0;
301 320 margin:0 1px;
302 321 font-size:0.9em;
303 322 color:#f0f0f0;
304 323 background:#467aa7;
305 324 }
306 325
307 326 #footer p{padding:0; margin:0; text-align:center;}
308 327 #footer a{color:#f0f0f0; background-color:inherit; font-weight:bold;}
309 328 #footer a:hover{color:#ffffff; background-color:inherit; text-decoration: underline;}
310 329
311 330 /**************** Misc classes and styles ****************/
312 331
313 332 .splitcontentleft{float:left; width:49%;}
314 333 .splitcontentright{float:right; width:49%;}
315 334 .clear{clear:both;}
316 335 .small{font-size:0.8em;line-height:1.4em;padding:0 0 0 0;}
317 336 .hide{display:none;}
318 337 .textcenter{text-align:center;}
319 338 .textright{text-align:right;}
320 339 .important{color:#f02025; background-color:inherit; font-weight:bold;}
321 340
322 341 .box{
323 342 margin:0 0 20px 0;
324 343 padding:10px;
325 344 border:1px solid #c0c0c0;
326 345 background-color:#fafbfc;
327 346 color:#505050;
328 347 line-height:1.5em;
329 348 }
330 349
350 .login {
351 width: 50%;
352 text-align: left;
353 }
331 354
@@ -1,56 +1,57
1 1
2 2 .fieldWithErrors {
3 3 padding: 2px;
4 margin: 0px;
4 5 background-color: red;
5 6 display: table;
6 7 }
7 8
8 9 #errorExplanation {
9 10 width: 400px;
10 border: 2px solid red;
11 border: 0;
11 12 padding: 7px;
12 padding-bottom: 12px;
13 margin-bottom: 20px;
14 background-color: #f0f0f0;
13 padding-bottom: 3px;
14 margin-bottom: 0px;
15 /*background-color: #f0f0f0;*/
15 16 }
16 17
17 18 #errorExplanation h2 {
18 19 text-align: left;
19 20 font-weight: bold;
20 padding: 5px 5px 5px 15px;
21 font-size: 12px;
21 padding: 5px 5px 10px 26px;
22 font-size: 1em;
22 23 margin: -7px;
23 background-color: #c00;
24 color: #fff;
24 background: url(../images/alert.png) no-repeat 6px 6px;
25 25 }
26 26
27 27 #errorExplanation p {
28 28 color: #333;
29 29 margin-bottom: 0;
30 30 padding: 5px;
31 31 }
32 32
33 33 #errorExplanation ul li {
34 font-size: 12px;
35 list-style: square;
34 font-size: 1em;
35 list-style: none;
36 margin-left: -16px;
36 37 }
37 38
38 39 div.uploadStatus {
39 40 margin: 5px;
40 41 }
41 42
42 43 div.progressBar {
43 44 margin: 5px;
44 45 }
45 46
46 47 div.progressBar div.border {
47 48 background-color: #fff;
48 49 border: 1px solid grey;
49 50 width: 100%;
50 51 }
51 52
52 53 div.progressBar div.background {
53 54 background-color: #333;
54 55 height: 18px;
55 56 width: 0%;
56 57 }
@@ -1,26 +1,41
1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 ecookbook:
3 id: 1
4 name: eCookbook
5 descr: Recipes management application
6 homepage: http://ecookbook.somenet.foo/
7 projects_count: 1
8 created_on: 2005-01-01 01:00:00
9 updated_on: 2005-01-01 01:00:00
10 onlinestore:
11 id: 2
12 name: OnlineStore
13 descr: E-commerce web site
14 is_public: false
15 projects_count: 0
16 created_on: 2005-01-01 01:00:00
17 updated_on: 2005-01-01 01:00:00
18 tracker:
19 id: 3
20 name: tracker
21 descr: bug tracker
22 is_public: true
23 projects_count: 0
24 parent_id: 1
25 created_on: 2005-01-01 01:00:00
26 updated_on: 2005-01-01 01:00:00 No newline at end of file
1 ---
2 projects_001:
3 created_on: 2006-07-19 19:13:59 +02:00
4 name: eCookbook
5 updated_on: 2006-07-19 22:53:01 +02:00
6 projects_count: 2
7 id: 1
8 description: Recipes management application
9 homepage: http://ecookbook.somenet.foo/
10 is_public: true
11 parent_id:
12 projects_002:
13 created_on: 2006-07-19 19:14:19 +02:00
14 name: OnlineStore
15 updated_on: 2006-07-19 19:14:19 +02:00
16 projects_count: 0
17 id: 2
18 description: E-commerce web site
19 homepage: ""
20 is_public: false
21 parent_id:
22 projects_003:
23 created_on: 2006-07-19 19:15:21 +02:00
24 name: eCookbook Subproject 1
25 updated_on: 2006-07-19 19:18:12 +02:00
26 projects_count: 0
27 id: 3
28 description: eCookBook Subproject 1
29 homepage: ""
30 is_public: true
31 parent_id: 1
32 projects_004:
33 created_on: 2006-07-19 19:15:51 +02:00
34 name: eCookbook Subproject 2
35 updated_on: 2006-07-19 19:17:07 +02:00
36 projects_count: 0
37 id: 4
38 description: eCookbook Subproject 2
39 homepage: ""
40 is_public: true
41 parent_id: 1
@@ -1,10 +1,10
1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 manager:
3 id: 1
4 name: manager
5 developer:
6 id: 2
7 name: developer
8 reporter:
9 id: 3
10 name: reporter
1 ---
2 roles_001:
3 name: Manager
4 id: 1
5 roles_002:
6 name: Developer
7 id: 2
8 roles_003:
9 name: Reporter
10 id: 3
@@ -1,19 +1,61
1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 admin:
3 id: 1
4 login: admin
5 firstname: admin
6 lastname: admin
7 mail: admin@somenet.foo
8 hashed_password: d033e22ae348aeb5660fc2140aec35850c4da997
9 admin: true
10 language: en
11 paulochon:
12 id: 2
13 login: plochon
14 firstname: Paul
15 lastname: Ochon
16 mail: plochon@somenet.foo
17 hashed_password: d033e22ae348aeb5660fc2140aec35850c4da997
18 admin: false
19 language: en No newline at end of file
1 ---
2 users_004:
3 created_on: 2006-07-19 19:34:07 +02:00
4 status: 1
5 last_login_on:
6 language: en
7 hashed_password: 4e4aeb7baaf0706bd670263fef42dad15763b608
8 updated_on: 2006-07-19 19:34:07 +02:00
9 admin: false
10 mail: rhill@somenet.foo
11 lastname: Hill
12 firstname: Robert
13 id: 4
14 auth_source_id:
15 mail_notification: true
16 login: rhill
17 users_001:
18 created_on: 2006-07-19 19:12:21 +02:00
19 status: 1
20 last_login_on: 2006-07-19 22:57:52 +02:00
21 language: en
22 hashed_password: d033e22ae348aeb5660fc2140aec35850c4da997
23 updated_on: 2006-07-19 22:57:52 +02:00
24 admin: true
25 mail: admin@somenet.foo
26 lastname: Admin
27 firstname: redMine
28 id: 1
29 auth_source_id:
30 mail_notification: true
31 login: admin
32 users_002:
33 created_on: 2006-07-19 19:32:09 +02:00
34 status: 1
35 last_login_on: 2006-07-19 22:42:15 +02:00
36 language: en
37 hashed_password: a9a653d4151fa2c081ba1ffc2c2726f3b80b7d7d
38 updated_on: 2006-07-19 22:42:15 +02:00
39 admin: false
40 mail: jsmith@somenet.foo
41 lastname: Smith
42 firstname: John
43 id: 2
44 auth_source_id:
45 mail_notification: true
46 login: jsmith
47 users_003:
48 created_on: 2006-07-19 19:33:19 +02:00
49 status: 1
50 last_login_on:
51 language: en
52 hashed_password: 7feb7657aa7a7bf5aef3414a5084875f27192415
53 updated_on: 2006-07-19 19:33:19 +02:00
54 admin: false
55 mail: dlopper@somenet.foo
56 lastname: Lopper
57 firstname: Dave
58 id: 3
59 auth_source_id:
60 mail_notification: true
61 login: dlopper
@@ -1,47 +1,114
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.dirname(__FILE__) + '/../test_helper'
19 19 require 'projects_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class ProjectsController; def rescue_action(e) raise e end; end
23 23
24 24 class ProjectsControllerTest < Test::Unit::TestCase
25 fixtures :projects
25 fixtures :projects, :permissions
26 26
27 27 def setup
28 28 @controller = ProjectsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 end
32 32
33 33 def test_index
34 34 get :index
35 35 assert_response :success
36 36 assert_template 'list'
37 37 end
38 38
39 39 def test_list
40 40 get :list
41
42 41 assert_response :success
43 42 assert_template 'list'
44
45 43 assert_not_nil assigns(:projects)
44 end
45
46 def test_show
47 get :show, :id => 1
48 assert_response :success
49 assert_template 'show'
50 assert_not_nil assigns(:project)
51 end
52
53 def test_list_members
54 get :list_members, :id => 1
55 assert_response :success
56 assert_template 'list_members'
57 assert_not_nil assigns(:members)
58 end
59
60 def test_list_documents
61 get :list_documents, :id => 1
62 assert_response :success
63 assert_template 'list_documents'
64 assert_not_nil assigns(:documents)
65 end
66
67 def test_list_issues
68 get :list_issues, :id => 1
69 assert_response :success
70 assert_template 'list_issues'
71 assert_not_nil assigns(:issues)
72 end
73
74 def test_list_issues_with_filter
75 get :list_issues, :id => 1, :set_filter => 1
76 assert_response :success
77 assert_template 'list_issues'
78 assert_not_nil assigns(:issues)
79 end
80
81 def test_list_issues_reset_filter
82 post :list_issues, :id => 1
83 assert_response :success
84 assert_template 'list_issues'
85 assert_not_nil assigns(:issues)
86 end
87
88 def test_export_issues_csv
89 get :export_issues_csv, :id => 1
90 assert_response :success
91 assert_not_nil assigns(:issues)
92 end
93
94 def test_list_news
95 get :list_news, :id => 1
96 assert_response :success
97 assert_template 'list_news'
98 assert_not_nil assigns(:news)
99 end
100
101 def test_list_files
102 get :list_files, :id => 1
103 assert_response :success
104 assert_template 'list_files'
105 assert_not_nil assigns(:versions)
106 end
107
108 def test_changelog
109 get :changelog, :id => 1
110 assert_response :success
111 assert_template 'changelog'
112 assert_not_nil assigns(:fixed_issues)
46 113 end
47 114 end
@@ -1,76 +1,99
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require "#{File.dirname(__FILE__)}/../test_helper"
19 19
20 20 class AccountTest < ActionController::IntegrationTest
21 21 fixtures :users
22 22
23 23 # Replace this with your real tests.
24 24 def test_login
25 25 get "account/my_page"
26 26 assert_redirected_to "account/login"
27 log_user('plochon', 'admin')
27 log_user('jsmith', 'jsmith')
28 28
29 29 get "account/my_account"
30 30 assert_response :success
31 31 assert_template "account/my_account"
32 32 end
33 33
34 34 def test_change_password
35 log_user('plochon', 'admin')
35 log_user('jsmith', 'jsmith')
36 36 get "account/my_account"
37 37 assert_response :success
38 38 assert_template "account/my_account"
39 39
40 post "account/change_password", :password => 'admin', :new_password => "hello", :new_password_confirmation => "hello2"
40 post "account/change_password", :password => 'jsmith', :new_password => "hello", :new_password_confirmation => "hello2"
41 41 assert_response :success
42 42 assert_tag :tag => "div", :attributes => { :class => "errorExplanation" }
43 43
44 44 post "account/change_password", :password => 'admiN', :new_password => "hello", :new_password_confirmation => "hello"
45 45 assert_response :success
46 46 assert_equal 'Wrong password', flash[:notice]
47 47
48 post "account/change_password", :password => 'admin', :new_password => "hello", :new_password_confirmation => "hello"
48 post "account/change_password", :password => 'jsmith', :new_password => "hello", :new_password_confirmation => "hello"
49 49 assert_response :success
50 log_user('plochon', 'hello')
50 log_user('jsmith', 'hello')
51 51 end
52 52
53 53 def test_my_account
54 log_user('plochon', 'admin')
54 log_user('jsmith', 'jsmith')
55 55 get "account/my_account"
56 56 assert_response :success
57 57 assert_template "account/my_account"
58 58
59 59 post "account/my_account", :user => {:firstname => "Joe", :login => "root", :admin => 1}
60 60 assert_response :success
61 61 assert_template "account/my_account"
62 62 user = User.find(2)
63 63 assert_equal "Joe", user.firstname
64 assert_equal "plochon", user.login
65 assert_equal false, user.admin?
66
67 log_user('plochon', 'admin')
64 assert_equal "jsmith", user.login
65 assert_equal false, user.admin?
68 66 end
69 67
70 68 def test_my_page
71 log_user('plochon', 'admin')
69 log_user('jsmith', 'jsmith')
72 70 get "account/my_page"
73 71 assert_response :success
74 72 assert_template "account/my_page"
75 73 end
74
75 def test_lost_password
76 get "account/lost_password"
77 assert_response :success
78 assert_template "account/lost_password"
79
80 post "account/lost_password", :mail => 'jsmith@somenet.foo'
81 assert_redirected_to "account/login"
82
83 token = Token.find(:first)
84 assert_equal 'recovery', token.action
85 assert_equal 'jsmith@somenet.foo', token.user.mail
86 assert !token.expired?
87
88 get "account/lost_password", :token => token.value
89 assert_response :success
90 assert_template "account/password_recovery"
91
92 post "account/lost_password", :token => token.value, :new_password => 'newpass', :new_password_confirmation => 'newpass'
93 assert_redirected_to "account/login"
94 assert_equal 'Password was successfully updated.', flash[:notice]
95
96 log_user('jsmith', 'newpass')
97 assert_equal 0, Token.count
98 end
76 99 end
@@ -1,61 +1,61
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require "#{File.dirname(__FILE__)}/../test_helper"
19 19
20 20 class AdminTest < ActionController::IntegrationTest
21 21 fixtures :users
22 22
23 23 def test_add_user
24 24 log_user("admin", "admin")
25 25 get "/users/add"
26 26 assert_response :success
27 27 assert_template "users/add"
28 post "/users/add", :user => { :login => "jsmith", :firstname => "John", :lastname => "Smith", :mail => "jsmith@somenet.foo", :language => "en" }, :password => "jsmith09", :password_confirmation => "jsmith09"
28 post "/users/add", :user => { :login => "psmith", :firstname => "Paul", :lastname => "Smith", :mail => "psmith@somenet.foo", :language => "en" }, :password => "psmith09", :password_confirmation => "psmith09"
29 29 assert_redirected_to "users/list"
30 30
31 user = User.find_by_login("jsmith")
31 user = User.find_by_login("psmith")
32 32 assert_kind_of User, user
33 logged_user = User.try_to_login("jsmith", "jsmith09")
33 logged_user = User.try_to_login("psmith", "psmith09")
34 34 assert_kind_of User, logged_user
35 assert_equal "John", logged_user.firstname
35 assert_equal "Paul", logged_user.firstname
36 36
37 post "users/edit", :id => user.id, :user => { :locked => 1 }
37 post "users/edit", :id => user.id, :user => { :status => User::STATUS_LOCKED }
38 38 assert_redirected_to "users/list"
39 locked_user = User.try_to_login("jsmith", "jsmith09")
39 locked_user = User.try_to_login("psmith", "psmith09")
40 40 assert_equal nil, locked_user
41 41 end
42 42
43 43 def test_add_project
44 44 log_user("admin", "admin")
45 45 get "projects/add"
46 46 assert_response :success
47 47 assert_template "projects/add"
48 post "projects/add", :project => { :name => "blog", :descr => "weblog", :is_public => 1}
48 post "projects/add", :project => { :name => "blog", :description => "weblog", :is_public => 1}
49 49 assert_redirected_to "admin/projects"
50 50 assert_equal 'Project was successfully created.', flash[:notice]
51 51
52 52 project = Project.find_by_name("blog")
53 53 assert_kind_of Project, project
54 assert_equal "weblog", project.descr
54 assert_equal "weblog", project.description
55 55 assert_equal true, project.is_public?
56 56
57 57 get "admin/projects"
58 58 assert_response :success
59 59 assert_template "admin/projects"
60 60 end
61 61 end
@@ -1,55 +1,55
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 ENV["RAILS_ENV"] ||= "test"
19 19 require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
20 20 require 'test_help'
21 21
22 22 class Test::Unit::TestCase
23 23 # Transactional fixtures accelerate your tests by wrapping each test method
24 24 # in a transaction that's rolled back on completion. This ensures that the
25 25 # test database remains unchanged so your fixtures don't have to be reloaded
26 26 # between every test method. Fewer database queries means faster tests.
27 27 #
28 28 # Read Mike Clark's excellent walkthrough at
29 29 # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
30 30 #
31 31 # Every Active Record database supports transactions except MyISAM tables
32 32 # in MySQL. Turn off transactional fixtures in this case; however, if you
33 33 # don't care one way or the other, switching from MyISAM to InnoDB tables
34 34 # is recommended.
35 35 self.use_transactional_fixtures = true
36 36
37 37 # Instantiated fixtures are slow, but give you @david where otherwise you
38 38 # would need people(:david). If you don't want to migrate your existing
39 39 # test cases which use the @david style and don't mind the speed hit (each
40 40 # instantiated fixtures translates to a database query per test method),
41 41 # then set this back to true.
42 42 self.use_instantiated_fixtures = false
43 43
44 44 # Add more helper methods to be used by all tests here...
45 45
46 46 def log_user(login, password)
47 47 get "/account/login"
48 assert_equal nil, session[:user]
48 assert_equal nil, session[:user_id]
49 49 assert_response :success
50 50 assert_template "account/login"
51 51 post "/account/login", :login => login, :password => password
52 52 assert_redirected_to "account/my_page"
53 assert_equal login, session[:user].login
53 assert_equal login, User.find(session[:user_id]).login
54 54 end
55 55 end
@@ -1,77 +1,79
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.dirname(__FILE__) + '/../test_helper'
19 19
20 20 class ProjectTest < Test::Unit::TestCase
21 21 fixtures :projects
22 22
23 23 def setup
24 @project = projects(:ecookbook)
24 @ecookbook = Project.find(1)
25 @ecookbook_sub1 = Project.find(3)
25 26 end
26 27
27 28 def test_truth
28 assert_kind_of Project, @project
29 assert_equal "eCookbook", @project.name
29 assert_kind_of Project, @ecookbook
30 assert_equal "eCookbook", @ecookbook.name
30 31 end
31 32
32 33 def test_update
33 assert_equal "eCookbook", @project.name
34 @project.name = "eCook"
35 assert @project.save, @project.errors.full_messages.join("; ")
36 @project.reload
37 assert_equal "eCook", @project.name
34 assert_equal "eCookbook", @ecookbook.name
35 @ecookbook.name = "eCook"
36 assert @ecookbook.save, @ecookbook.errors.full_messages.join("; ")
37 @ecookbook.reload
38 assert_equal "eCook", @ecookbook.name
38 39 end
39 40
40 41 def test_validate
41 @project.name = ""
42 assert !@project.save
43 assert_equal 1, @project.errors.count
44 assert_equal "can't be blank", @project.errors.on(:name)
42 @ecookbook.name = ""
43 assert !@ecookbook.save
44 assert_equal 1, @ecookbook.errors.count
45 assert_equal l(:activerecord_error_blank), @ecookbook.errors.on(:name)
45 46 end
46 47
47 48 def test_public_projects
48 49 public_projects = Project.find(:all, :conditions => ["is_public=?", true])
49 assert_equal 2, public_projects.length
50 assert_equal 3, public_projects.length
50 51 assert_equal true, public_projects[0].is_public?
51 52 end
52 53
53 54 def test_destroy
54 @project.destroy
55 assert_raise(ActiveRecord::RecordNotFound) { Project.find(@project.id) }
55 @ecookbook.destroy
56 assert_raise(ActiveRecord::RecordNotFound) { Project.find(@ecookbook.id) }
56 57 end
57 58
58 59 def test_subproject_ok
59 60 sub = Project.find(2)
60 sub.parent = Project.find(1)
61 sub.parent = @ecookbook
61 62 assert sub.save
62 assert_equal 1, sub.parent.id
63 assert_equal 2, Project.find(1).projects_count
63 assert_equal @ecookbook.id, sub.parent.id
64 @ecookbook.reload
65 assert_equal 3, @ecookbook.projects_count
64 66 end
65 67
66 68 def test_subproject_invalid
67 69 sub = Project.find(2)
68 sub.parent = projects(:tracker)
70 sub.parent = @ecookbook_sub1
69 71 assert !sub.save
70 72 end
71 73
72 74 def test_subproject_invalid_2
73 sub = Project.find(1)
74 sub.parent = projects(:onlinestore)
75 sub = @ecookbook
76 sub.parent = Project.find(2)
75 77 assert !sub.save
76 78 end
77 79 end
@@ -1,64 +1,88
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.dirname(__FILE__) + '/../test_helper'
19 19
20 20 class UserTest < Test::Unit::TestCase
21 21 fixtures :users
22 22
23 def test_truth
24 assert_kind_of User, users(:paulochon)
23 def setup
24 @admin = User.find(1)
25 @jsmith = User.find(2)
25 26 end
26 27
28 def test_truth
29 assert_kind_of User, @jsmith
30 end
31
32 def test_create
33 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
34
35 user.login = "jsmith"
36 user.password, user.password_confirmation = "password", "password"
37 # login uniqueness
38 assert !user.save
39 assert_equal 1, user.errors.count
40
41 user.login = "newuser"
42 user.password, user.password_confirmation = "passwd", "password"
43 # password confirmation
44 assert !user.save
45 assert_equal 1, user.errors.count
46
47 user.password, user.password_confirmation = "password", "password"
48 assert user.save
49 end
50
27 51 def test_update
28 user = User.find(1)
29 assert_equal "admin", user.login
30 user.login = "john"
31 assert user.save, user.errors.full_messages.join("; ")
32 user.reload
33 assert_equal "john", user.login
52 assert_equal "admin", @admin.login
53 @admin.login = "john"
54 assert @admin.save, @admin.errors.full_messages.join("; ")
55 @admin.reload
56 assert_equal "john", @admin.login
34 57 end
35 58
36 59 def test_validate
37 user = User.find(1)
38 user.login = ""
39 assert !user.save
40 assert_equal 2, user.errors.count
60 @admin.login = ""
61 assert !@admin.save
62 assert_equal 2, @admin.errors.count
41 63 end
42 64
43 65 def test_password
44 66 user = User.try_to_login("admin", "admin")
45 67 assert_kind_of User, user
46 68 assert_equal "admin", user.login
47 69 user.password = "hello"
48 70 assert user.save
49 71
50 72 user = User.try_to_login("admin", "hello")
51 73 assert_kind_of User, user
52 74 assert_equal "admin", user.login
53 75 assert_equal User.hash_password("hello"), user.hashed_password
54 76 end
55 77
56 78 def test_lock
57 user = User.find(1)
58 user.locked = true
59 assert user.save
79 user = User.try_to_login("jsmith", "jsmith")
80 assert_equal @jsmith, user
60 81
61 user = User.try_to_login("admin", "admin")
82 @jsmith.status = User::STATUS_LOCKED
83 assert @jsmith.save
84
85 user = User.try_to_login("jsmith", "jsmith")
62 86 assert_equal nil, user
63 87 end
64 88 end
@@ -1,57 +1,57
1 1 # Original Localization plugin for Rails can be found at:
2 2 # http://mir.aculo.us/articles/2005/10/03/ruby-on-rails-i18n-revisited
3 3 #
4 4 # Slightly edited by Jean-Philippe Lang
5 5 # - added @@langs and modified self.define method to maintain an array of available
6 6 # langages with labels, eg. { 'en' => 'English, 'fr' => 'French }
7 7 # - modified self.generate_l10n_file method to retrieve already translated strings
8 8 #
9 9
10 10 module Localization
11 11 mattr_accessor :lang, :langs
12 12
13 13 @@l10s = { :default => {} }
14 14 @@lang = :default
15 @@langs = []
15 @@langs = {}
16 16
17 17 def self._(string_to_localize, *args)
18 18 translated = @@l10s[@@lang][string_to_localize] || string_to_localize
19 19 return translated.call(*args).to_s if translated.is_a? Proc
20 20 if translated.is_a? Array
21 21 translated = if translated.size == 3
22 22 translated[args[0]==0 ? 0 : (args[0]>1 ? 2 : 1)]
23 23 else
24 24 translated[args[0]>1 ? 1 : 0]
25 25 end
26 26 end
27 27 sprintf translated, *args
28 28 end
29 29
30 30 def self.define(lang = :default, name = :default)
31 31 @@l10s[lang] ||= {}
32 @@langs << [ name, lang ]
32 @@langs[lang] = [ name ]
33 33 yield @@l10s[lang]
34 end
34 end
35 35
36 36 def self.load
37 37 Dir.glob("#{RAILS_ROOT}/lang/*.rb"){ |t| require t }
38 38 Dir.glob("#{RAILS_ROOT}/lang/custom/*.rb"){ |t| require t }
39 39 end
40 40
41 41 # Generates a best-estimate l10n file from all views by
42 42 # collecting calls to _() -- note: use the generated file only
43 43 # as a start (this method is only guesstimating)
44 44 def self.generate_l10n_file(lang)
45 45 "Localization.define('en_US') do |l|\n" <<
46 46 Dir.glob("#{RAILS_ROOT}/app/views/**/*.rhtml").collect do |f|
47 47 ["# #{f}"] << File.read(f).scan(/<%.*[^\w]_\s*[\(]+[\"\'](.*?)[\"\'][\)]+/)
48 48 end.uniq.flatten.collect do |g|
49 49 g.starts_with?('#') ? "\n #{g}" : " l.store '#{g}', '#{@@l10s[lang][g]}'"
50 50 end.uniq.join("\n") << "\nend"
51 51 end
52 52
53 53 end
54 54
55 55 class Object
56 56 def _(*args); Localization._(*args); end
57 57 end No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now