josevalim-localized_templates 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 Thomas Preston-Werner
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,76 @@
1
+ Copyright (c) 2008 José Valim (jose.valim@gmail.com)
2
+ http://www.pagestacker.com/
3
+ http://josevalim.blogspot.com/
4
+ License: MIT
5
+ Version: 0.2
6
+
7
+ LocalizedTemplates
8
+ ==================
9
+
10
+ This plugin uses Rails I18n (http://rails-i18n.org/) to allow templates localization.
11
+ You can localize your views using the following naming convention:
12
+
13
+ <tt>pt-BR/projects/index.html.erb</tt>
14
+ <tt>en-US/projects/edit.rss.builder</tt>
15
+
16
+ OR:
17
+
18
+ <tt>projects/pt-BR/index.html.erb</tt>
19
+ <tt>projects/en-US/index.html.erb</tt>
20
+
21
+ And you can also localize rescue files:
22
+
23
+ <tt>public/pt-BR/404.html</tt>
24
+ <tt>public/en-US/404.html</tt>
25
+
26
+ If you don't want to localize a file (like a xml file), simply don't change it and it will be
27
+ rendered as default to all languages.
28
+
29
+ Installation
30
+ =================
31
+
32
+ Install LocalizedTemplates is very easy. It is stored in GitHub, so if you have
33
+ never installed a gem via GitHub run the following:
34
+
35
+ gem sources -a http://gems.github.com
36
+
37
+ Then install the gem:
38
+
39
+ sudo gem install josevalim-localized_templates
40
+
41
+ In RAILS_ROOT/config/environment.rb:
42
+
43
+ config.gem "josevalim-localized_templates", :lib => "localized_templates", :source => "http://gems.github.com"
44
+
45
+ If you want it as plugin, just do:
46
+
47
+ cd myapp
48
+ git clone git://github.com/josevalim/localized_templates.git
49
+ rm -rf vendor/plugins/localized_templates/.git
50
+
51
+ Adding a new locale
52
+ =================
53
+
54
+ To add a new locale, simply create a new file in config/locales. You can make your life easier by copying an existing
55
+ locale and basing your new locale on it.
56
+
57
+ Check installed locales
58
+ =================
59
+
60
+ To display a list of all locales installed in config/locales, you can use the following rake command:
61
+
62
+ rake locales
63
+
64
+ Changing the default locale
65
+ =================
66
+
67
+ If you want to use a default locale other than en-US, you have to tell the i18n plugin the locale you want to use by
68
+ default. Simply put the following line in an initializer in config/initializers or include it in your environment.rb:
69
+
70
+ I18n.default_locale = 'de-AT'
71
+
72
+ Bugs and Feedback
73
+ =================
74
+
75
+ If you discover any bugs, please send me an e-mail to jose.valim@gmail.com
76
+ If you have positive feedback, that's fine too! =)
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Run tests.'
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.pattern = 'test/**/*_test.rb'
8
+ t.verbose = true
9
+ end
10
+
11
+ desc 'Generate documentation.'
12
+ Rake::RDocTask.new(:rdoc) do |rdoc|
13
+ rdoc.rdoc_dir = 'rdoc'
14
+ rdoc.title = 'SimpleLocalization'
15
+ rdoc.options << '--line-numbers' << '--inline-source'
16
+ rdoc.rdoc_files.include('README')
17
+ rdoc.rdoc_files.include('lib/**/*.rb')
18
+ end
data/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ # Load all source files in the lib directory.
2
+ require 'localized_templates'
3
+ require 'localized_rescue'
@@ -0,0 +1,11 @@
1
+ # = Localized rescue
2
+ #
3
+ # This feature extends Rails rescue handling and allows the use of localized
4
+ # rescues like <code>en-US/404.html</code> on the public dir. The plugin will
5
+ # then pick the rescue page matching the currently used locale
6
+ # (<code>I18n#locale</code>).
7
+ #
8
+ # If the localized rescue page isn't found, the plugin will render the
9
+ # <code>404.html</code> file if it exists.
10
+ #
11
+ require 'localized_rescue/actioncontroller/rescue'
@@ -0,0 +1,27 @@
1
+ module ActionController
2
+ class Base
3
+
4
+ protected
5
+ # Attempts to render a static error page based on the <tt>status_code</tt> thrown,
6
+ # or just return headers if no such file exists. For example, if a 500 error is
7
+ # being handled Rails will first attempt to render the file at the current locale
8
+ # such as <tt>public/en-US/500.html</tt>. Then the file with no locale
9
+ # <tt>public/500.html</tt>. If the files doesn't exist, the body of the response
10
+ # will be left empty.
11
+ #
12
+ def render_optional_error_file(status_code)
13
+ status = interpret_status(status_code)
14
+ locale_path = "#{Rails.public_path}/#{I18n.locale}/#{status[0,3]}.html" if I18n.locale
15
+ path = "#{Rails.public_path}/#{status[0,3]}.html"
16
+
17
+ if locale_path && File.exist?(locale_path)
18
+ render :file => locale_path, :status => status
19
+ elsif File.exist?(path)
20
+ render :file => path, :status => status
21
+ else
22
+ head status
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,28 @@
1
+ # = Localized templates
2
+ #
3
+ # This feature extends Rails template handling and allows the use of localized
4
+ # templates like <code>projects/pt-BR/index.html.erb</code> or
5
+ # <code>pt-BR/projects/index.html.erb</code>. The plugin will pick the
6
+ # template matching the currently used locale (<code>I18n#locale</code>).
7
+ #
8
+ # If the localized template isn't found, the plugin will try to render
9
+ # <code>prjects/index.html.erb</code>. If <code>index.html.erb</code> doesn't
10
+ # exist, a 404 will be raised.
11
+ #
12
+ # If you have a template that is the same for all languages (like a xml file)
13
+ # just keep it without localization: <code>index.xml.builder</code>.
14
+
15
+ # Theoretically, we just need to overwrite _pick_template and _pick_partial_template
16
+ # methods in order to have LocalizedTemplates, but memoize doesn't help
17
+ # since it doesn't see locale changes and would memoize values for only one locale.
18
+ #
19
+ # We can fix this by passing the locale to _pick_template as argument or creating a
20
+ # localized memoize, that would memoize different values based on the locale.
21
+ #
22
+ # For now, we will use the first solution: pass the locale to _pick_template. As
23
+ # consequence, we need to overwrite all methods that call _pick_template.
24
+ #
25
+ require 'localized_templates/actioncontroller/base'
26
+ require 'localized_templates/actioncontroller/layout'
27
+ require 'localized_templates/actionview/base'
28
+ require 'localized_templates/actionview/partials'
@@ -0,0 +1,12 @@
1
+ module ActionController
2
+ class Base
3
+
4
+ private
5
+ def template_exists?(template_name = default_template_name)
6
+ @template.send(:_pick_template, template_name, I18n.locale) ? true : false
7
+ rescue ActionView::MissingTemplate
8
+ false
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module ActionController
2
+ class Base
3
+
4
+ private
5
+ def layout_directory?(layout_name)
6
+ @template.__send__(:_pick_template, "#{File.join('layouts', layout_name)}.#{@template.template_format}", I18n.locale) ? true : false
7
+ rescue ActionView::MissingTemplate
8
+ false
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,96 @@
1
+ module ActionView
2
+ class Base
3
+ @@exempt_from_layout = Set.new([/\.rjs$/])
4
+
5
+ # Renders the template present at <tt>template_path</tt> (relative to the view_paths array).
6
+ # The hash in <tt>local_assigns</tt> is made available as local variables.
7
+ def render(options = {}, local_assigns = {}, &block) #:nodoc:
8
+ local_assigns ||= {}
9
+
10
+ if options.is_a?(String)
11
+ ActiveSupport::Deprecation.warn(
12
+ "Calling render with a string will render a partial from Rails 2.3. " +
13
+ "Change this call to render(:file => '#{options}', :locals => locals_hash)."
14
+ )
15
+
16
+ render(:file => options, :locals => local_assigns)
17
+ elsif options == :update
18
+ update_page(&block)
19
+ elsif options.is_a?(Hash)
20
+ options = options.reverse_merge(:locals => {})
21
+ if options[:layout]
22
+ _render_with_layout(options, local_assigns, &block)
23
+ elsif options[:file]
24
+ _pick_template(options[:file], I18n.locale).render_template(self, options[:locals])
25
+ elsif options[:partial]
26
+ render_partial(options)
27
+ elsif options[:inline]
28
+ InlineTemplate.new(options[:inline], options[:type]).render(self, options[:locals])
29
+ elsif options[:text]
30
+ options[:text]
31
+ end
32
+ end
33
+ end
34
+
35
+ private
36
+ def _pick_template(template_path, locale = nil)
37
+ return template_path if template_path.respond_to?(:render)
38
+
39
+ path = template_path.sub(/^\//, '')
40
+ if m = path.match(/(.*)\.(\w+)$/)
41
+ template_file_name, template_file_extension = m[1], m[2]
42
+ else
43
+ template_file_name = path
44
+ end
45
+
46
+ # Try to render locale/controller/action
47
+ if locale && template = _template_view_path_check("#{locale}/#{template_file_name}")
48
+ template
49
+ # Try to render controller/locale/action
50
+ elsif locale && template = _template_view_path_check(template_file_name.gsub(/\//, "/#{locale}/"))
51
+ template
52
+ # Try to render controller/action
53
+ elsif template = _template_view_path_check(template_file_name)
54
+ template
55
+ else
56
+ template = Template.new(template_path, view_paths)
57
+
58
+ if self.class.warn_cache_misses && logger
59
+ logger.debug "[PERFORMANCE] Rendering a template that was " +
60
+ "not found in view path. Templates outside the view path are " +
61
+ "not cached and result in expensive disk operations. Move this " +
62
+ "file into #{view_paths.join(':')} or add the folder to your " +
63
+ "view path list"
64
+ end
65
+
66
+ template
67
+ end
68
+ end
69
+ memoize :_pick_template
70
+
71
+ def _template_view_path_check(template_file_name)
72
+ # OPTIMIZE: Checks to lookup template in view path
73
+ if template = self.view_paths["#{template_file_name}.#{template_format}"]
74
+ template
75
+ elsif template = self.view_paths[template_file_name]
76
+ template
77
+ elsif (first_render = @_render_stack.first) && first_render.respond_to?(:format_and_extension) &&
78
+ (template = self.view_paths["#{template_file_name}.#{first_render.format_and_extension}"])
79
+ template
80
+ elsif template_format == :js && template = self.view_paths["#{template_file_name}.html"]
81
+ @template_format = :html
82
+ template
83
+ else
84
+ nil
85
+ end
86
+ end
87
+
88
+ def _exempt_from_layout?(template_path) #:nodoc:
89
+ template = _pick_template(template_path, I18n.locale).to_s
90
+ @@exempt_from_layout.any? { |ext| template =~ ext }
91
+ rescue ActionView::MissingTemplate
92
+ return false
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,65 @@
1
+ module ActionView
2
+ class Base
3
+
4
+ private
5
+ def render_partial(options = {}) #:nodoc:
6
+ local_assigns = options[:locals] || {}
7
+
8
+ case partial_path = options[:partial]
9
+ when String, Symbol, NilClass
10
+ if options.has_key?(:collection)
11
+ render_partial_collection(options)
12
+ else
13
+ _pick_partial_template(partial_path).render_partial(self, options[:object], local_assigns)
14
+ end
15
+ when ActionView::Helpers::FormBuilder
16
+ builder_partial_path = partial_path.class.to_s.demodulize.underscore.sub(/_builder$/, '')
17
+ local_assigns.merge!(builder_partial_path.to_sym => partial_path)
18
+ render_partial(:partial => builder_partial_path, :object => options[:object], :locals => local_assigns)
19
+ when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope
20
+ render_partial_collection(options.except(:partial).merge(:collection => partial_path))
21
+ else
22
+ object = partial_path
23
+ render_partial(
24
+ :partial => ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path),
25
+ :object => object,
26
+ :locals => local_assigns
27
+ )
28
+ end
29
+ end
30
+
31
+ def render_partial_collection(options = {}) #:nodoc:
32
+ return nil if options[:collection].blank?
33
+
34
+ partial = options[:partial]
35
+ spacer = options[:spacer_template] ? render(:partial => options[:spacer_template]) : ''
36
+ local_assigns = options[:locals] ? options[:locals].clone : {}
37
+ as = options[:as]
38
+
39
+ index = 0
40
+ options[:collection].map do |object|
41
+ _partial_path ||= partial ||
42
+ ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path)
43
+ template = _pick_partial_template(_partial_path, I18n.locale)
44
+ local_assigns[template.counter_name] = index
45
+ result = template.render_partial(self, object, local_assigns.dup, as)
46
+ index += 1
47
+ result
48
+ end.join(spacer)
49
+ end
50
+
51
+ def _pick_partial_template(partial_path, locale = nil) #:nodoc:
52
+ if partial_path.include?('/')
53
+ path = File.join(File.dirname(partial_path), "_#{File.basename(partial_path)}")
54
+ elsif controller
55
+ path = "#{controller.class.controller_path}/_#{partial_path}"
56
+ else
57
+ path = "_#{partial_path}"
58
+ end
59
+
60
+ _pick_template(path, locale)
61
+ end
62
+ memoize :_pick_partial_template
63
+
64
+ end
65
+ end
@@ -0,0 +1,2 @@
1
+ "en-US":
2
+ about: "language fixture"
@@ -0,0 +1,3 @@
1
+ <none>
2
+ <%= yield %>
3
+ </none>
@@ -0,0 +1 @@
1
+ xml.en_US "text"
@@ -0,0 +1 @@
1
+ none index view
@@ -0,0 +1 @@
1
+ xml.none "text"
@@ -0,0 +1 @@
1
+ pt-BR index view
@@ -0,0 +1,2 @@
1
+ "pt-BR":
2
+ about: "language fixture"
@@ -0,0 +1,3 @@
1
+ <pt-BR>
2
+ <%= yield %>
3
+ </pt-BR>
@@ -0,0 +1 @@
1
+ 500 error fixture
@@ -0,0 +1 @@
1
+ 404 en-US error fixture
@@ -0,0 +1 @@
1
+ 404 pt-BR error fixture
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + '/setup'
2
+ require File.dirname(__FILE__) + '/../lib/localized_rescue.rb'
3
+
4
+ class LocalizedRescueController < ActionController::Base
5
+ def index
6
+ render_optional_error_file params[:id]
7
+ end
8
+ end
9
+
10
+ class LocalizedRescueTest < Test::Unit::TestCase
11
+
12
+ def setup
13
+ @controller = LocalizedRescueController.new
14
+ @request = ActionController::TestRequest.new
15
+ @response = ActionController::TestResponse.new
16
+ end
17
+
18
+ def test_render_optional_error_file_without_localization
19
+ I18n.locale = 'en-US'
20
+ get :index, :id => 500
21
+
22
+ assert_response 500
23
+ body = File.read("#{FIXTURES_PATH}/public/500.html")
24
+ assert_equal body, @response.body
25
+ end
26
+
27
+ def test_render_optional_error_file_with_localization
28
+ I18n.locale = 'en-US'
29
+ get :index, :id => 404
30
+
31
+ assert_response 404
32
+ body = File.read("#{FIXTURES_PATH}/public/en-US/404.html")
33
+ assert_equal body, @response.body
34
+
35
+ I18n.locale = 'pt-BR'
36
+ get :index, :id => 404
37
+
38
+ assert_response 404
39
+ body = File.read("#{FIXTURES_PATH}/public/pt-BR/404.html")
40
+ assert_equal body, @response.body
41
+ end
42
+
43
+ end
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + '/setup'
2
+ require File.dirname(__FILE__) + '/../lib/localized_templates.rb'
3
+
4
+ class ProjectsController < ActionController::Base
5
+ layout 'default'
6
+
7
+ def index
8
+ respond_to do |format|
9
+ format.html {
10
+ #
11
+ }
12
+ format.rss{
13
+ render :layout => false
14
+ }
15
+ end
16
+ end
17
+ end
18
+
19
+ class LocalizedTemplatesTest < Test::Unit::TestCase
20
+
21
+ def setup
22
+ @controller = ProjectsController.new
23
+ @request = ActionController::TestRequest.new
24
+ @response = ActionController::TestResponse.new
25
+ end
26
+
27
+ def test_render_without_localization
28
+ I18n.locale = 'en-US'
29
+ get :index
30
+
31
+ assert_response 200
32
+ assert_equal "<none>\n none index view\n</none>", @response.body
33
+ end
34
+
35
+ def test_render_rss_without_localization
36
+ I18n.locale = 'pt-BR'
37
+ @request.env['CONTENT_TYPE'] = Mime::EXTENSION_LOOKUP['rss'].to_s
38
+ get :index
39
+
40
+ assert_response 200
41
+ assert_equal "<none>text</none>\n", @response.body
42
+ end
43
+
44
+ def test_render_with_localization
45
+ I18n.locale = 'pt-BR'
46
+ get :index
47
+
48
+ assert_response 200
49
+ assert_equal "<pt-BR>\n pt-BR index view\n</pt-BR>", @response.body
50
+ end
51
+
52
+ def test_render_rss_with_localization
53
+ I18n.locale = 'en-US'
54
+ @request.env['CONTENT_TYPE'] = Mime::EXTENSION_LOOKUP['rss'].to_s
55
+ get :index
56
+
57
+ assert_response 200
58
+ assert_equal "<en_US>text</en_US>\n", @response.body
59
+ end
60
+
61
+ end
data/test/setup.rb ADDED
@@ -0,0 +1,15 @@
1
+ # Those lines are plugin test settings
2
+ ENV['RAILS_ENV'] = 'test'
3
+
4
+ require File.dirname(__FILE__) + '/../../../../config/environment'
5
+ require 'test_help'
6
+
7
+ FIXTURES_PATH = File.join(File.dirname(__FILE__), 'fixtures')
8
+ ActionController::Base.view_paths = FIXTURES_PATH
9
+ Rails.public_path = "#{FIXTURES_PATH}/public"
10
+
11
+ ActionController::Routing::Routes.draw do |map|
12
+ map.connect ':controller/:action/:id'
13
+ end
14
+
15
+ I18n.locale = 'en-US'
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: josevalim-localized_templates
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.2"
5
+ platform: ruby
6
+ authors:
7
+ - "Jos\xC3\xA9 Valim"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-11-29 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Templates localization for Rails 2.2
17
+ email: jose.valim@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - MIT-LICENSE
26
+ - README
27
+ - Rakefile
28
+ - init.rb
29
+ - lib/localized_rescue.rb
30
+ - lib/localized_templates.rb
31
+ - lib/localized_rescue/actioncontroller/rescue.rb
32
+ - lib/localized_templates/actioncontroller/base.rb
33
+ - lib/localized_templates/actioncontroller/layout.rb
34
+ - lib/localized_templates/actionview/base.rb
35
+ - lib/localized_templates/actionview/partials.rb
36
+ has_rdoc: true
37
+ homepage: http://github.com/josevalim/localized_templates
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --main
41
+ - README
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.2.0
60
+ signing_key:
61
+ specification_version: 2
62
+ summary: Templates localization for Rails 2.2
63
+ test_files:
64
+ - test/localized_rescue_test.rb
65
+ - test/localized_templates_test.rb
66
+ - test/setup.rb
67
+ - test/fixtures/en-US.yml
68
+ - test/fixtures/pt-BR.yml
69
+ - test/fixtures/layouts/default.html.erb
70
+ - test/fixtures/projects/index.html.erb
71
+ - test/fixtures/projects/index.rss.builder
72
+ - test/fixtures/projects/en-US/index.rss.builder
73
+ - test/fixtures/projects/pt-BR/index.html.erb
74
+ - test/fixtures/pt-BR/layouts/default.html.erb
75
+ - test/fixtures/public/500.html
76
+ - test/fixtures/public/en-US/404.html
77
+ - test/fixtures/public/pt-BR/404.html