title_estuary 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 James Rosen
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.rdoc ADDED
@@ -0,0 +1,104 @@
1
+ Title Estuary is a gem/plugin that makes it easy to set page titles.
2
+ It it built with internationalization in mind. It requires
3
+ ActiveSupport's I18N, but should be usable with frameworks other
4
+ than Rails.
5
+
6
+ === How-To
7
+
8
+ ==== 1: tell Rails about the gem:
9
+
10
+ # in RAILS_ROOT/config/environment.rb:
11
+ config.gem 'title_estuary', :source => 'http://gemcutter.org'
12
+
13
+ ==== 2: have Rails install the gem:
14
+
15
+ [sudo] rake gems:install
16
+
17
+ ==== 3: set up your layout:
18
+
19
+ # in RAILS_ROOT/app/views/layouts/application.html.erb:
20
+ <html ...>
21
+ <head ...>
22
+ <title><%= page_title %></title>
23
+ ...
24
+ </head>
25
+ <body>
26
+ <h1><%= page_title %></h1>
27
+ ...
28
+ </body>
29
+ </html>
30
+
31
+ ==== 4. customize your titles:
32
+
33
+ Use the format "page.title.controller_name.action_name"
34
+
35
+ # in RAILS_ROOT/config/locales/en.yml:
36
+ en:
37
+ page:
38
+ title:
39
+ accounts:
40
+ new: "Sign Up"
41
+ sessions:
42
+ new: "Sign In"
43
+ projects:
44
+ index: "Your projects"
45
+ new: "Start a new project"
46
+
47
+ If you want to use any interpolated strings, make sure
48
+ you define an <tt>#interpolation_options</tt> method in
49
+ your controller:
50
+
51
+ # in RAILS_ROOT/config/locales/en.yml:
52
+ en:
53
+ page:
54
+ title:
55
+ projects:
56
+ index: "All {{number_of_projects}} of your projects"
57
+ show: "Project {{project_name}}"
58
+ edit: "Edit project {{project_name}}"
59
+
60
+ # An example controller (that would be defined
61
+ # in RAILS_ROOT/app/controllers/projects_controller.rb).
62
+ class ProjectsController < ActionController::Base
63
+ # An example definition of <tt>#interpolation_options</tt>
64
+ # that sets certain project-related values as applicable.
65
+ #
66
+ # @return [Hash] a hash of interpolation values
67
+ def interpolation_options
68
+ returning({}) do |result|
69
+ result[:number_of_projects] = @projects.size if @projects.present?
70
+ result[:project_name] = @project.name if @project.present?
71
+ result[:project_id] = params[:id]
72
+ end
73
+ end
74
+ hide_action :interpolation_options
75
+ end
76
+
77
+ If you need more dynamic titles than simple interpolation affords,
78
+ set the title manually in an action:
79
+
80
+ # in RAILS_ROOT/app/controllers/projects_controller.rb:
81
+ class ProjectsController < ActionController::Base
82
+ def show
83
+ @project = Project.find(params[:id])
84
+ self.page_title = "A title based on #{@project.some_complex_string}"
85
+ end
86
+ end
87
+
88
+ or in a filter:
89
+
90
+ # in RAILS_ROOT/app/controllers/projects_controller.rb:
91
+ class ProjectsController < ActionController::Base
92
+ before_filter :set_title
93
+ private
94
+ def set_title
95
+ self.page_title = "Some complex title"
96
+ end
97
+ end
98
+
99
+ or from a view:
100
+
101
+ # in RAILS_ROOT/app/view/projects/index.html.erb:
102
+ <% content_for :page_title do %>
103
+ Some complex page title
104
+ <% end %>
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ desc "Default: run all tests, including features"
2
+ task :default => [ 'test' ]
3
+
4
+ TITLE_ESTUARY_PROJECT_ROOT = File.expand_path(File.dirname(__FILE__))
5
+ LOAD_TITLE_ESTUARY_BUILD_TASKS = true
6
+
7
+ Dir.glob('tasks/*.task').each do |taskfile|
8
+ load File.expand_path("./#{taskfile}")
9
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,29 @@
1
+ module TitleEstuary
2
+
3
+ module InheritedResourcesSupport
4
+
5
+ private
6
+
7
+ # @return [#to_s] the requested_resource as loaded by
8
+ # InheritedResources.
9
+ def page_title_resource
10
+ # it should be loaded by now, but if not, don't
11
+ # make a special request on our behalf:
12
+ get_resource_ivar
13
+ end
14
+
15
+ # @return [String] an improved guess for the name of the requested resource.
16
+ def page_title_singular_resource_name
17
+ resource_name = if resource_class
18
+ if resource_class.respond_to?(:human_name)
19
+ resource_class.human_name
20
+ else
21
+ resource_class.name.humanize
22
+ end
23
+ else
24
+ params[:controller].to_s.singularize
25
+ end
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,114 @@
1
+ # @author James Rosen
2
+ module TitleEstuary
3
+
4
+ # When TitleEstuary is included by a controller,
5
+ # this hook prevents ActionPack from using
6
+ # <tt>#page_title</tt> as an action and makes that
7
+ # method available to helpers and views; it also
8
+ # auto-includes TitleEstuary::InheritedResourcesSupport
9
+ # if applicable.
10
+ def self.included(base)
11
+ base.send :include, TitleEstuary::InstanceMethods
12
+ base.hide_action(:page_title) if base.respond_to?(:hide_action)
13
+ base.helper_method(:page_title, :page_title=) if base.respond_to?(:helper_method)
14
+ if Object.const_defined?(:InheritedResources) && base < ::InheritedResources::Base
15
+ base.send :include, TitleEstuary::InheritedResourcesSupport
16
+ end
17
+ end
18
+
19
+ module InstanceMethods
20
+
21
+ # Get the page title. First checks for a dynamically-set
22
+ # title (set via <tt>#page_title=</tt> or via
23
+ # <tt>content_for :page_title</tt>); if none has been set,
24
+ # uses a version from I18n under the key
25
+ # 'page.title.<controller>.<action>'; if no such value exists,
26
+ # tries to generate a reasonable sane default.
27
+ #
28
+ # @return [String] the page title
29
+ def page_title
30
+ return @content_for_page_title if @content_for_page_title.present?
31
+ self.page_title = look_up_or_generate_page_title
32
+ end
33
+
34
+ protected
35
+
36
+ # Sets the page title.
37
+ #
38
+ # Available to views both as a helper method:
39
+ #
40
+ # <% self.page_title = '...' -%>
41
+ #
42
+ # and via <tt>:content_for :page_title</tt>:
43
+ #
44
+ # <% content_for :page_title do %>
45
+ # ...
46
+ # <% end %>
47
+ def page_title=(title)
48
+ @content_for_page_title = title
49
+ end
50
+
51
+ private
52
+
53
+ # @return [String] the I18n version of the page
54
+ # title, defaulting to the generated version.
55
+ #
56
+ # @see #page_title_i18n_key
57
+ # @see #default_page_title_from_controller_and_action
58
+ def look_up_or_generate_page_title
59
+ given_options = if self.respond_to?(:interpolation_options)
60
+ interpolation_options
61
+ else
62
+ {}
63
+ end
64
+ default = default_page_title_from_controller_and_action
65
+ options = given_options.merge(:default => default)
66
+ I18n.t page_title_i18n_key, options
67
+ end
68
+
69
+ # @return [Symbol] the I18n key for the page title for
70
+ # this controller/action pair.
71
+ def page_title_i18n_key
72
+ "page.title.#{params[:controller]}.#{params[:action]}".to_sym
73
+ end
74
+
75
+ # @return [String] a reasonably sane default title for
76
+ # this controller/action pair.
77
+ def default_page_title_from_controller_and_action
78
+ action = params[:action].to_s
79
+ resource_name = page_title_singular_resource_name
80
+ resource = page_title_resource
81
+ case action
82
+ when 'index'
83
+ "All #{resource_name.pluralize.titleize}"
84
+ when 'new', 'create'
85
+ "New #{resource_name.singularize.titleize}"
86
+ when 'show'
87
+ "#{resource_name.singularize.titleize} #{resource}"
88
+ when 'edit', 'update'
89
+ "Edit #{resource_name.singularize.titleize} #{resource}"
90
+ else
91
+ if resource.present?
92
+ "#{action.titleize} #{resource_name.singularize.titleize} #{resource}"
93
+ else
94
+ "#{action.titleize} #{resource_name.pluralize.titleize}"
95
+ end
96
+ end
97
+ end
98
+
99
+ # @return [#to_s] an instance variable representing the requested
100
+ # resource if it's in an obvious location.
101
+ def page_title_resource
102
+ if params[:id]
103
+ instance_variable_get(:"@#{page_title_singular_resource_name}") || params[:id]
104
+ end
105
+ end
106
+
107
+ # @return [String] a guess for the name of the requested resource.
108
+ def page_title_singular_resource_name
109
+ params[:controller].singularize
110
+ end
111
+
112
+ end
113
+
114
+ end
data/tasks/doc.task ADDED
@@ -0,0 +1,28 @@
1
+ # don't load these tasks if this project is used as a Rails plugin:
2
+ if Object.const_defined?(:LOAD_TITLE_ESTUARY_BUILD_TASKS) && LOAD_TITLE_ESTUARY_BUILD_TASKS
3
+ require 'yard'
4
+ require 'yard/rake/yardoc_task'
5
+
6
+ desc "Generate RDoc"
7
+ task :doc => ['doc:generate']
8
+
9
+ namespace :doc do
10
+
11
+ doc_dir = "#{TITLE_ESTUARY_PROJECT_ROOT}/doc/rdoc"
12
+ readme = "#{TITLE_ESTUARY_PROJECT_ROOT}/README.rdoc"
13
+
14
+ YARD::Rake::YardocTask.new(:generate) do |yt|
15
+ yt.files = FileList[
16
+ "#{TITLE_ESTUARY_PROJECT_ROOT}/lib/**/*.rb",
17
+ "#{TITLE_ESTUARY_PROJECT_ROOT}/README.rdoc"
18
+ ]
19
+ yt.options = ['--output-dir', doc_dir, '--readme', readme]
20
+ end
21
+
22
+ desc "Remove generated documenation"
23
+ task :clean do
24
+ rm_r doc_dir if File.exists?(doc_dir)
25
+ end
26
+
27
+ end
28
+ end
data/tasks/gem.task ADDED
@@ -0,0 +1,39 @@
1
+ # don't load these tasks if this project is used as a Rails plugin:
2
+ if Object.const_defined?(:LOAD_TITLE_ESTUARY_BUILD_TASKS) && LOAD_TITLE_ESTUARY_BUILD_TASKS
3
+
4
+ gem_files = FileList[
5
+ "[A-Z]*",
6
+ "{lib,tasks}/**/*"
7
+ ]
8
+
9
+ #raise gem_files.to_a.inspect
10
+
11
+ begin
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |s|
14
+ s.name = "title_estuary"
15
+ s.summary = 'Easy, internationalized page titles'
16
+ s.email = 'james.a.rosen@gmail.com'
17
+ s.homepage = "http://github.com/gcnovus/title_estuary"
18
+ s.description = 'Title Estuary speeds up development by giving you good default titles and simple customizability, including internationalization.'
19
+ s.authors = ['James Rosen']
20
+ s.files = gem_files
21
+ s.require_paths = ['lib']
22
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Title Estuary: RDoc", "--charset", "utf-8"]
23
+ end
24
+ rescue LoadError
25
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler -s http://gemcutter.org"
26
+ end
27
+
28
+ namespace :pkg do
29
+
30
+ pkg_dir = File.join(TITLE_ESTUARY_PROJECT_ROOT, 'pkg')
31
+
32
+ desc "Remove the pkg/ directory and all built gems"
33
+ task :clean do
34
+ rm_r pkg_dir if File.exists?(pkg_dir)
35
+ end
36
+
37
+ end
38
+
39
+ end
data/tasks/test.task ADDED
@@ -0,0 +1,23 @@
1
+ # don't load these tasks if this project is used as a Rails plugin:
2
+ if Object.const_defined?(:LOAD_TITLE_ESTUARY_BUILD_TASKS) && LOAD_TITLE_ESTUARY_BUILD_TASKS
3
+
4
+ require 'rake/testtask'
5
+
6
+ LIB_DIRECTORIES = FileList.new do |fl|
7
+ fl.include "#{TITLE_ESTUARY_PROJECT_ROOT}/lib"
8
+ fl.include "#{TITLE_ESTUARY_PROJECT_ROOT}/test/lib"
9
+ end
10
+
11
+ TEST_FILES = FileList.new do |fl|
12
+ fl.include "#{TITLE_ESTUARY_PROJECT_ROOT}/test/**/*_test.rb"
13
+ fl.exclude "#{TITLE_ESTUARY_PROJECT_ROOT}/test/test_helper.rb"
14
+ fl.exclude "#{TITLE_ESTUARY_PROJECT_ROOT}/test/lib/**/*.rb"
15
+ end
16
+
17
+ Rake::TestTask.new(:test) do |t|
18
+ t.libs = LIB_DIRECTORIES
19
+ t.test_files = TEST_FILES
20
+ t.verbose = true
21
+ end
22
+
23
+ end
@@ -0,0 +1,110 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require File.dirname(__FILE__) + '/village_model_and_controller'
3
+
4
+ class DefaultTitlesTest < ActionController::TestCase
5
+ include PageTitleMacros
6
+ tests VillagesController
7
+
8
+ context 'a RESTful, titleize controller' do
9
+
10
+ context 'with no custom page titles set up' do
11
+
12
+ setup { clear_translations! }
13
+
14
+ context 'on a GET to :index' do
15
+ setup { get :index }
16
+ should_set_the_page_title_to 'All Villages'
17
+ should 'not generate the title twice' do
18
+ @controller.page_title
19
+ @controller.stubs :look_up_or_generate_page_title
20
+ @controller.page_title
21
+ assert_received @controller, :look_up_or_generate_page_title do |expect|
22
+ expect.never
23
+ end
24
+ end
25
+ end
26
+
27
+ context 'on a GET to :new' do
28
+ setup { get :new }
29
+ should_set_the_page_title_to 'New Village'
30
+ end
31
+
32
+ context 'on a POST to :create that fails' do
33
+ setup { post :create }
34
+ should_set_the_page_title_to 'New Village'
35
+ end
36
+
37
+ context 'on a GET to :show for a resource that exists' do
38
+ setup do
39
+ Village.stubs(:find).returns(Village.new('Bostonburgh'))
40
+ get :show, :id => 'anything'
41
+ end
42
+ should_set_the_page_title_to "Village Bostonburgh"
43
+ end
44
+
45
+ context 'on a GET to :show for a resource that does not exist (or is not set to an obvious instance variable)' do
46
+ setup do
47
+ Village.stubs(:find).returns(nil)
48
+ get :show, :id => '2'
49
+ end
50
+ should_set_the_page_title_to "Village 2"
51
+ end
52
+
53
+ context 'on a GET to :edit for a resource that exists' do
54
+ setup do
55
+ Village.stubs(:find).returns(Village.new('Gloucestershire'))
56
+ get :edit, :id => 'something'
57
+ end
58
+ should_set_the_page_title_to "Edit Village Gloucestershire"
59
+ end
60
+
61
+ context 'on a GET to :edit for a resource that does not exist (or is not set to an obvious instance variable)' do
62
+ setup do
63
+ Village.stubs(:find).returns(nil)
64
+ get :edit, :id => '3'
65
+ end
66
+ should_set_the_page_title_to "Edit Village 3"
67
+ end
68
+
69
+ context 'on a PUT to :update for a resource that exists' do
70
+ setup do
71
+ Village.stubs(:find).returns(Village.new('East Umbridge'))
72
+ put :update, :id => 'seven'
73
+ end
74
+ should_set_the_page_title_to "Edit Village East Umbridge"
75
+ end
76
+
77
+ context 'on a PUT to :update for a resource that does not exist (or is not set to an obvious instance variable)' do
78
+ setup do
79
+ Village.stubs(:find).returns(nil)
80
+ put :update, :id => '100'
81
+ end
82
+ should_set_the_page_title_to "Edit Village 100"
83
+ end
84
+
85
+ context 'on a GET to a custom collection action' do
86
+ setup { get :burninated }
87
+ should_set_the_page_title_to "Burninated Villages"
88
+ end
89
+
90
+ context 'on a GET on a custom member action for a resource that exists' do
91
+ setup do
92
+ Village.stubs(:find).returns(Village.new('Parrotshire'))
93
+ get :burninate, :id => '14'
94
+ end
95
+ should_set_the_page_title_to "Burninate Village Parrotshire"
96
+ end
97
+
98
+ context 'on a GET to a custom member action for a resource that does not exist (or is not set to an obvious instance variable)' do
99
+ setup do
100
+ Village.stubs(:find).returns(nil)
101
+ get :burninate, :id => '9'
102
+ end
103
+ should_set_the_page_title_to "Burninate Village 9"
104
+ end
105
+
106
+ end
107
+
108
+ end
109
+
110
+ end
@@ -0,0 +1,48 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require File.dirname(__FILE__) + '/village_model_and_controller'
3
+
4
+ VillagesController.class_eval do
5
+ def index_with_dynamic_title
6
+ self.page_title = 'A Custom Title'
7
+ index_without_dynamic_title
8
+ end
9
+ alias_method :index_without_dynamic_title, :index
10
+ end
11
+
12
+ class DynamicPageTitle < ActionController::TestCase
13
+ include PageTitleMacros
14
+ tests VillagesController
15
+
16
+ context 'a RESTful, titleize controller' do
17
+
18
+ context 'that sets a page title dynamically' do
19
+
20
+ setup do
21
+ clear_translations!
22
+ VillagesController.class_eval do
23
+ alias_method :index, :index_with_dynamic_title
24
+ end
25
+ end
26
+
27
+ teardown do
28
+ VillagesController.class_eval do
29
+ alias_method :index, :index_without_dynamic_title
30
+ end
31
+ end
32
+
33
+ should 'use the dynamic title instead of the default' do
34
+ get :index
35
+ assert_page_title_is 'A Custom Title'
36
+ end
37
+
38
+ should 'use the dynamic title instead of a custom one from the I18n framework' do
39
+ define_translation 'page.title.villages.index', 'something else'
40
+ get :index
41
+ assert_page_title_is 'A Custom Title'
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,107 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require 'inherited_resources'
3
+ require 'inherited_resources/actions'
4
+ require 'inherited_resources/base_helpers'
5
+ require 'inherited_resources/class_methods'
6
+ require 'inherited_resources/url_helpers'
7
+ require 'inherited_resources/base'
8
+
9
+ class Pizza
10
+ def initialize(name); @name = name.to_s; end
11
+ def to_s; @name; end
12
+ def to_param; '1'; end
13
+ def method_missing(*args, &block); self; end
14
+ end
15
+
16
+ class DeliciousThingsController < InheritedResources::Base
17
+ self.resource_class = Pizza
18
+ include TitleEstuary
19
+ def cheesey; index; end
20
+ def add_topping; show; end
21
+ def pizza_url(*args); delicious_thing_url(*args); end
22
+ end
23
+
24
+ ActionController::Routing::Routes.draw do |map|
25
+ map.resources :delicious_things, :collection => { :cheesey => :get },
26
+ :member => { :add_topping => :get }
27
+ end
28
+
29
+ class InheritedResourcesIntegrationTest < ActionController::TestCase
30
+ include PageTitleMacros
31
+ tests DeliciousThingsController
32
+
33
+ context 'a RESTful controller using both Title Estuary and Inherited Resources' do
34
+
35
+ context 'with custom page titles that involve interpolation' do
36
+
37
+ setup do
38
+ clear_translations!
39
+ end
40
+
41
+ should 'have inherited-resources support installed' do
42
+ assert DeliciousThingsController < TitleEstuary::InheritedResourcesSupport
43
+ end
44
+
45
+ context 'on a GET to :index' do
46
+ setup do
47
+ Pizza.stubs(:find).returns([])
48
+ get :index
49
+ end
50
+ should_set_the_page_title_to 'All Pizzas'
51
+ end
52
+
53
+ context 'on a GET to :new' do
54
+ setup { get :new }
55
+ should_set_the_page_title_to 'New Pizza'
56
+ end
57
+
58
+ context 'on a POST to :create that fails' do
59
+ setup { post :create }
60
+ should_set_the_page_title_to 'New Pizza'
61
+ end
62
+
63
+ context 'on a GET to :show' do
64
+ setup do
65
+ Pizza.stubs(:find).returns(Pizza.new('Vegetarian Special'))
66
+ get :show, :id => 'anything'
67
+ end
68
+ should_set_the_page_title_to "Pizza Vegetarian Special"
69
+ end
70
+
71
+ context 'on a GET to :edit' do
72
+ setup do
73
+ Pizza.stubs(:find).returns(Pizza.new('NY Thin Crust'))
74
+ get :edit, :id => 'something'
75
+ end
76
+ should_set_the_page_title_to "Edit Pizza NY Thin Crust"
77
+ end
78
+
79
+ context 'on a PUT to :update' do
80
+ setup do
81
+ Pizza.stubs(:find).returns(Pizza.new('Neapolitan'))
82
+ put :update, :id => 'seven'
83
+ end
84
+ should_set_the_page_title_to "Edit Pizza Neapolitan"
85
+ end
86
+
87
+ context 'on a GET to a custom collection action' do
88
+ setup do
89
+ Pizza.stubs(:find).returns([])
90
+ get :cheesey
91
+ end
92
+ should_set_the_page_title_to "Cheesey Pizzas"
93
+ end
94
+
95
+ context 'on a GET on a custom member action for a resource that exists' do
96
+ setup do
97
+ Pizza.stubs(:find).returns(Pizza.new('Margherita'))
98
+ get :add_topping, :id => '14'
99
+ end
100
+ should_set_the_page_title_to "Add Topping Pizza Margherita"
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+
107
+ end
@@ -0,0 +1,58 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require File.dirname(__FILE__) + '/village_model_and_controller'
3
+
4
+ class InterpolatedPageTitlesTest < ActionController::TestCase
5
+ include PageTitleMacros
6
+ tests VillagesController
7
+
8
+ context 'a RESTful, titleize controller' do
9
+
10
+ context 'with custom page titles that involve interpolation' do
11
+
12
+ setup { clear_translations! }
13
+
14
+ setup do
15
+ self.class.controller_class.class_eval do
16
+ def interpolation_options
17
+ {
18
+ :villages_count => 12,
19
+ :village_name => 'Rhinoceros Town'
20
+ }
21
+ end
22
+ end
23
+ end
24
+
25
+ context 'on a GET to :index' do
26
+ setup do
27
+ define_translation 'page.title.villages.index', '{{villages_count}} Villages'
28
+ get :index
29
+ end
30
+ should_set_the_page_title_to '12 Villages'
31
+ end
32
+
33
+ context 'on a GET to :show' do
34
+ setup do
35
+ Village.stubs(:find).returns(Village.new('anything'))
36
+ define_translation 'page.title.villages.show', '{{village_name}}'
37
+ get :show, :id => 29291
38
+ end
39
+ should_set_the_page_title_to 'Rhinoceros Town'
40
+ end
41
+
42
+ context 'that fails to provide a necessary interpolation string' do
43
+ setup do
44
+ define_translation 'page.title.villages.new', '{{not_specified_by_the_controller}}'
45
+ get :new
46
+ end
47
+ should "raise a translation error" do
48
+ assert_raises I18n::MissingInterpolationArgument do
49
+ @controller.page_title
50
+ end
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require File.dirname(__FILE__) + '/village_model_and_controller'
3
+ require 'action_view/test_case'
4
+
5
+ class RailsIntegrationTest < ActionController::TestCase
6
+
7
+ include PageTitleMacros
8
+ tests VillagesController
9
+
10
+ def self.should_expose_as_helper(method)
11
+ should "expose :#{method} to views as a helper" do
12
+ helper = Object.new
13
+ helper.extend VillagesController.master_helper_module
14
+ assert helper.respond_to?(method)
15
+ end
16
+ end
17
+
18
+ context 'a RESTful, titleized controller' do
19
+
20
+ should "not have a :page_title action" do
21
+ assert !VillagesController.action_methods.map { |a| a.to_sym }.include?(:page_title)
22
+ end
23
+
24
+ should_expose_as_helper :page_title
25
+ should_expose_as_helper :page_title=
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,32 @@
1
+ module PageTitleMacros
2
+
3
+ def self.included(base)
4
+ base.extend PageTitleMacros::ControllerMacros
5
+ end
6
+
7
+ def clear_translations!
8
+ I18n.reload!
9
+ end
10
+
11
+ def define_translation(key, value)
12
+ hash = key.to_s.split('.').reverse.inject(value) do |value, key_part|
13
+ { key_part.to_sym => value }
14
+ end
15
+ I18n.backend.send :merge_translations, I18n.locale, hash
16
+ end
17
+
18
+ def assert_page_title_is(title)
19
+ assert_equal title, @controller.page_title
20
+ end
21
+
22
+ module ControllerMacros
23
+
24
+ def should_set_the_page_title_to(title)
25
+ should "set the page title to #{title}" do
26
+ assert_page_title_is title
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,34 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require File.dirname(__FILE__) + '/village_model_and_controller'
3
+
4
+ class SimpleCustomTitlesTest < ActionController::TestCase
5
+ include PageTitleMacros
6
+ tests VillagesController
7
+
8
+ context 'a RESTful, titleize controller' do
9
+
10
+ context 'with custom page titles set up' do
11
+
12
+ setup { clear_translations! }
13
+
14
+ context 'on a GET to :index' do
15
+ setup do
16
+ define_translation 'page.title.villages.index', 'Some Villages'
17
+ get :index
18
+ end
19
+ should_set_the_page_title_to 'Some Villages'
20
+ end
21
+
22
+ context 'on a GET to :new' do
23
+ setup do
24
+ define_translation 'page.title.villages.new', 'Add a Village'
25
+ get :new
26
+ end
27
+ should_set_the_page_title_to "Add a Village"
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,26 @@
1
+ test_dir = File.dirname(__FILE__)
2
+
3
+ # testing support:
4
+ require 'test/unit'
5
+ require 'test/unit/testcase'
6
+ require 'rubygems'
7
+ require 'shoulda'
8
+ gem 'jferris-mocha'
9
+ require 'mocha'
10
+ require 'redgreen'
11
+
12
+ # set up Rails:
13
+ ENV["RAILS_ENV"] ||= "test"
14
+ RAILS_ROOT = "anywhere"
15
+ require 'active_support'
16
+ require 'action_controller'
17
+ require 'action_controller/test_case'
18
+ require 'action_controller/test_process'
19
+ I18n.reload!
20
+ ActionController::Base.view_paths = File.join(File.dirname(__FILE__), 'views')
21
+ class ApplicationController < ActionController::Base; end
22
+
23
+ # load title_estuary:
24
+ ActiveSupport::Dependencies.load_paths << File.expand_path(File.join(test_dir, '..', 'lib'))
25
+ require_dependency 'title_estuary'
26
+ Shoulda.autoload_macros File.join(test_dir, '..')
@@ -0,0 +1,22 @@
1
+ class Village
2
+ def initialize(name); @name = name; end
3
+ def to_s; @name.to_s; end
4
+ end
5
+
6
+ class VillagesController < ActionController::Base
7
+ include TitleEstuary
8
+ def index; render :nothing => true; end
9
+ def burninated; index; end
10
+ def new; index; end
11
+ def create; index; end
12
+ def show; @village = Village.find; index; end
13
+ def burninate; show; end
14
+ def edit; show; end
15
+ def update; show; end
16
+ def destroy; show; end
17
+ end
18
+
19
+ ActionController::Routing::Routes.draw do |map|
20
+ map.resources :villages, :collection => { :burninated => :get },
21
+ :member => { :burninate => :get }
22
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: title_estuary
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - James Rosen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-02 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Title Estuary speeds up development by giving you good default titles and simple customizability, including internationalization.
17
+ email: james.a.rosen@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - MIT-LICENSE
26
+ - README.rdoc
27
+ - Rakefile
28
+ - VERSION
29
+ - lib/title_estuary.rb
30
+ - lib/title_estuary/inherited_resources_support.rb
31
+ - tasks/doc.task
32
+ - tasks/gem.task
33
+ - tasks/test.task
34
+ has_rdoc: true
35
+ homepage: http://github.com/gcnovus/title_estuary
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --line-numbers
41
+ - --inline-source
42
+ - --title
43
+ - "Title Estuary: RDoc"
44
+ - --charset
45
+ - utf-8
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ requirements: []
61
+
62
+ rubyforge_project:
63
+ rubygems_version: 1.3.3
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Easy, internationalized page titles
67
+ test_files:
68
+ - test/default_titles_test.rb
69
+ - test/dynamic_page_title_test.rb
70
+ - test/inherited_resources_integration_test.rb
71
+ - test/interpolated_page_titles_test.rb
72
+ - test/rails_integration_test.rb
73
+ - test/shoulda_macros/page_title_macros.rb
74
+ - test/simple_custom_titles_test.rb
75
+ - test/test_helper.rb
76
+ - test/village_model_and_controller.rb