lwe-page_title_helper 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ doc/
2
+ pkg/
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 by Lukas Westermann (Zurich, Switzerland)
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,92 @@
1
+ = Page title helper
2
+
3
+ Ever wondered if there was an easier and DRY-way to set your page titles (and/or headings). Backed
4
+ byRails (>= 2.3) new support for <i>I18n</i> the solution is a simple helper method.
5
+
6
+ In your layout add this to your <tt><head>-section</tt>:
7
+
8
+ ...
9
+ <title><%=h page_title %></title>
10
+ ...
11
+
12
+ That's it. Now just add your translations, to the locales, in e.g. <tt>config/locales/en.yml</tt>:
13
+
14
+ en:
15
+ contacts:
16
+ index:
17
+ title: "Contacts"
18
+
19
+ When <tt>contacs/index.html.erb</tt> is rendered, the key <tt>:en, :contacts, :index, :title</tt>
20
+ is looked up and printed, together with the applications basename, like: <tt>My cool app - Contacts</tt>.
21
+ The format etc. is of course configurable, just head down to the options.
22
+
23
+ == Customize titles
24
+
25
+ Need a custom title, or need to fill in some placeholders? Just provide a block, in e.g.
26
+ <tt>contacts/show.html.erb</tt> the requirement is to display the contacts name in the
27
+ <tt><title>-tag</tt> as well as in the heading?
28
+
29
+ <h1><%=h page_title { @contact.name } %></h1>
30
+
31
+ A call to <tt>page_title</tt> will now return the contacts name, neat :) if for example the
32
+ <tt>h1</tt> does not match the +title+, then
33
+ well, just do something like:
34
+
35
+ <% page_title { @contact.name + " (" + @contact.company.name + ")" } %>
36
+ <h1><%=h @contact.name %></h1>
37
+
38
+ Guess, that's it. Of course it's also possible to use +translate+ within the +page_title+ block, so
39
+ to translate customzied titles, like:
40
+
41
+ # in config/locales/en.yml:
42
+ en:
43
+ dashboard:
44
+ index:
45
+ title: "Welcome back, {{name}}"
46
+
47
+ # in app/views/dashboard/index.html.erb:
48
+ <h1><%=h page_title { t '.title', :name => @user.first_name } %></h1>
49
+
50
+ Btw - a helpful rule-of-thumb: if +page_title+ is used with a +block+ a title is <b>defined</b>,
51
+ if it's used without the current title is rendered.
52
+
53
+ == More fun with <tt>:format</tt>
54
+
55
+ The <tt>:format</tt> option is used to specify how a title is formatted, i.e. if the app name is
56
+ prependor appended, or if it contains the account name etc. It uses a similar approach as
57
+ <tt>paperclip</tt>s path interpolations:
58
+
59
+ page_title :format => ':title / :app' # => "Contacts / My cool app"
60
+
61
+ Adding custom interpolations is as easy as defining a block, for example to access the current
62
+ controller:
63
+
64
+ PageTitleHelper.interpolates :controller do |title,options|
65
+ controller.class.humanize
66
+ end
67
+
68
+ page_title :format => ':title / :controller / :app' # => "Welcome back / Dashboard / My cool app"
69
+
70
+ To access just the title, without any magic app stuff interpolated or appended, use:
71
+
72
+ page_title { "untitled" }
73
+ page_title :format => false # => "untitled"
74
+
75
+ == All options - explained
76
+
77
+ * <tt>page_title { ... }</tt> - not per se an option, but if a block is given the methods sets a
78
+ custom title and overwrites any DRY-I18n title.
79
+ * <tt>:app</tt> - specifiy the applications name, however it's recommended to define the
80
+ translation key <tt>:'app.name'</tt>. If set to <tt>true</tt>, just returns the app name,
81
+ as defined in the translations or based on the +RAILS_ROOT+ humanized basename.
82
+ * <tt>:default</tt> - string which is displayed when no translation exists and no custom title
83
+ has been specified. Can also be set to a symbol or array to take advantage of
84
+ <tt>I18n.translate</tt>s <tt>:default</tt> option. (Default is <tt>:'app.tagline'</tt>)
85
+ * <tt>:format</tt> - defines the output format, accepts a string containing multiple interpolations,
86
+ see <i>More fun with <tt>:format</tt></i>. If set to +false+, just the current title is returned.
87
+ (Default is <tt>":app - :title"</tt>)
88
+ * <tt>:suffix</tt> - not happy with the fact that the translations must be named like
89
+ <tt>en -> contacts -> index -> title</tt>, but prefer e.g. them to be suffixed with
90
+ <tt>page_title</tt>? Then just set <tt>:suffix => :page_title</tt>. (Default <tt>:title</tt>)
91
+
92
+ Copyright (c) 2009 Lukas Westermann (Zurich, Switzerland), released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,66 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ begin
9
+ require 'jeweler'
10
+ Jeweler::Tasks.new do |gemspec|
11
+ gemspec.name = "page_title_helper"
12
+ gemspec.summary = "Simple, internationalized and DRY page titles and headings for rails."
13
+ gemspec.email = "lukas.westermann@gmail.com"
14
+ gemspec.homepage = "http://github.com/lwe/page_title_helper"
15
+ gemspec.authors = ["Lukas Westermann"]
16
+ end
17
+ rescue LoadError
18
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
19
+ end
20
+
21
+ desc 'Test the page_title_helper plugin.'
22
+ Rake::TestTask.new(:test) do |t|
23
+ t.libs << 'test'
24
+ t.pattern = 'test/**/*_test.rb'
25
+ t.verbose = true
26
+ end
27
+
28
+ desc 'Generate documentation for the page_title_helper plugin.'
29
+ Rake::RDocTask.new(:rdoc) do |rdoc|
30
+ rdoc.rdoc_dir = 'doc'
31
+ rdoc.title = 'PageTitleHelper'
32
+ rdoc.options << '--line-numbers' << '--inline-source'
33
+ rdoc.rdoc_files.include('README.rdoc')
34
+ rdoc.rdoc_files.include('lib/**/*.rb')
35
+ end
36
+
37
+ namespace :metrics do
38
+ desc 'Report code statistics for library and tests to shell.'
39
+ task :stats do |t|
40
+ require 'code_statistics'
41
+ dirs = {
42
+ 'Libraries' => 'lib',
43
+ 'Unit tests' => 'test'
44
+ }.map { |name,dir| [name, File.join(File.dirname(__FILE__), dir)] }
45
+ CodeStatistics.new(*dirs).to_s
46
+ end
47
+
48
+ desc 'Report code coverage to HTML (doc/coverage) and shell (requires rcov).'
49
+ task :coverage do |t|
50
+ rm_f "doc/coverage"
51
+ mkdir_p "doc/coverage"
52
+ rcov = %(rcov -Ilib:test --exclude '\/gems\/' -o doc/coverage -T test/*_test.rb )
53
+ system rcov
54
+ end
55
+ end
56
+
57
+ desc 'Start IRB console with loaded test/test_helper.rb and sqlite db.'
58
+ task :console do |t|
59
+ chdir File.dirname(__FILE__)
60
+ exec 'irb -Ilib/ -r page_title_helper'
61
+ end
62
+
63
+ desc 'Clean up generated files.'
64
+ task :clean do |t|
65
+ FileUtils.rm_rf "doc"
66
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 4
4
+ :patch: 0
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'lib', 'page_title_helper')
@@ -0,0 +1,96 @@
1
+ # PageTitleHelper
2
+ module PageTitleHelper
3
+ module Interpolations
4
+ extend self
5
+
6
+ # Returns a sorted list of all interpolations.
7
+ def self.all
8
+ self.instance_methods(false).sort
9
+ end
10
+
11
+ def self.interpolate(pattern, *args)
12
+ all.reverse.inject(pattern.dup) do |result, tag|
13
+ result.gsub(/:#{tag}/) do |match|
14
+ send(tag, *args)
15
+ end
16
+ end
17
+ end
18
+
19
+ def app(title, options)
20
+ options[:app] || I18n.translate(:'app.name', :default => File.basename(RAILS_ROOT).humanize)
21
+ end
22
+
23
+ def title(title, options)
24
+ title
25
+ end
26
+ end
27
+
28
+ # Add new, custom, interpolation.
29
+ def self.interpolates(key, &block)
30
+ Interpolations.send(:define_method, key, &block)
31
+ end
32
+
33
+ # Default options, which are globally referenced and can
34
+ # be changed globally, which might be useful in some cases.
35
+ def self.options
36
+ @options ||= {
37
+ :format => ':app - :title',
38
+ :default => :'app.tagline',
39
+ :suffix => :title
40
+ }
41
+ end
42
+
43
+ def page_title(options = nil, &block)
44
+ if block_given?
45
+ content_for(:page_title) { yield }
46
+ return read_page_title_content_block
47
+ end
48
+
49
+ options = PageTitleHelper.options.merge(options || {})
50
+ options.assert_valid_keys(:app, :suffix, :default, :format)
51
+ # just return the applications name
52
+ return Interpolations.app('', {}) if options[:app] == true
53
+
54
+ # read page title
55
+ page_title = read_page_title_content_block
56
+ page_title = I18n.translate(i18n_template_key(options[:suffix]), :default => options[:default]) if page_title.blank?
57
+
58
+ # return page title if format is set explicitly to false
59
+ return page_title if options[:format] == false
60
+
61
+ # else -> interpolate
62
+ Interpolations.interpolate options[:format] || ':app - :title', page_title, options
63
+ end
64
+
65
+ protected
66
+
67
+ # Access <tt>@content_for_page_title</tt> variable, though this is a tad
68
+ # hacky, because... what if they (the rails guys) change the behaviour of
69
+ # <tt>content_for</tt>? Well, in Rails 2.3.x it works so far.
70
+ #
71
+ # But to simplify compatibility with later versions, this method kinda abstracts
72
+ # away access to the content within a <tt>content_for</tt> block.
73
+ def read_page_title_content_block
74
+ instance_variable_get(:'@content_for_page_title')
75
+ end
76
+
77
+ # Access +ActionView+s internal <tt>@_first_render</tt> variable, to access
78
+ # template first rendered, this is to help create the DRY-I18n-titles magic,
79
+ # and also kind of a hack, because this really seems to be some sort if
80
+ # internal variable, that's why it's "abstracted" away as well.
81
+ #
82
+ def read_first_render_path
83
+ @_first_render.template_path
84
+ end
85
+
86
+ def i18n_template_key(suffix = nil)
87
+ ikey = read_first_render_path.gsub(/\.html\.erb$/, '').tr('/', '.')
88
+ ikey = ikey + "." + suffix.to_s unless suffix.nil?
89
+ ikey
90
+ end
91
+ end
92
+
93
+ # tie stuff together
94
+ if Object.const_defined?('ActionView')
95
+ ActionView::Base.send(:include, PageTitleHelper)
96
+ end
@@ -0,0 +1,47 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{page_title_helper}
5
+ s.version = "0.4.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Lukas Westermann"]
9
+ s.date = %q{2009-07-07}
10
+ s.email = %q{lukas.westermann@gmail.com}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.rdoc"
14
+ ]
15
+ s.files = [
16
+ ".gitignore",
17
+ "LICENSE",
18
+ "README.rdoc",
19
+ "Rakefile",
20
+ "VERSION.yml",
21
+ "init.rb",
22
+ "lib/page_title_helper.rb",
23
+ "page_title_helper.gemspec",
24
+ "test/page_title_helper_test.rb",
25
+ "test/test_helper.rb"
26
+ ]
27
+ s.has_rdoc = true
28
+ s.homepage = %q{http://github.com/lwe/page_title_helper}
29
+ s.rdoc_options = ["--charset=UTF-8"]
30
+ s.require_paths = ["lib"]
31
+ s.rubygems_version = %q{1.3.2}
32
+ s.summary = %q{Simple, internationalized and DRY page titles and headings for rails.}
33
+ s.test_files = [
34
+ "test/page_title_helper_test.rb",
35
+ "test/test_helper.rb"
36
+ ]
37
+
38
+ if s.respond_to? :specification_version then
39
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
40
+ s.specification_version = 3
41
+
42
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
43
+ else
44
+ end
45
+ else
46
+ end
47
+ end
@@ -0,0 +1,87 @@
1
+ require 'test_helper'
2
+ require 'page_title_helper'
3
+
4
+ class MockRender
5
+ def initialize(template_path = 'contacts/index.html.erb')
6
+ @template_path = template_path
7
+ end
8
+ def template_path; @template_path; end
9
+ end
10
+
11
+ class MockView
12
+ include PageTitleHelper
13
+
14
+ def initialize(template_path = 'contacts/index.html.erb')
15
+ @_first_render = MockRender.new template_path
16
+ end
17
+
18
+ def content_for(sym, &block)
19
+ instance_variable_set('@content_for_' + sym.to_s, yield)
20
+ end
21
+ end
22
+
23
+ I18n.backend.store_translations :en, :contacts => { :list => { :title => 'contacts.list.title' }}
24
+ I18n.backend.store_translations :en, :placeholder => 'Displaying {{name}}'
25
+
26
+
27
+ class PageTitleHelperTest < ActiveSupport::TestCase
28
+ test "interpolations" do
29
+ assert_equal 'Page title helper', PageTitleHelper::Interpolations.app('untitled', {})
30
+ assert_equal 'Appname', PageTitleHelper::Interpolations.app('untitled', { :app => 'Appname' })
31
+ assert_equal 'untitled', PageTitleHelper::Interpolations.title('untitled', {})
32
+ end
33
+
34
+ test "adding custom interpolation" do
35
+ # extend Interpolations
36
+ PageTitleHelper.interpolates :app_reverse do |title, options|
37
+ app(title,options).reverse.downcase
38
+ end
39
+
40
+ assert_equal "anna", PageTitleHelper::Interpolations.app_reverse('untitled', { :app => 'Anna' })
41
+ assert_equal "ppa", PageTitleHelper::Interpolations.interpolate(':app_reverse', 'foo', { :app => 'app' })
42
+ end
43
+
44
+ test "setting title to 'foo' returns 'foo'" do
45
+ view = MockView.new
46
+ view.page_title { "foo" }
47
+ assert_equal 'Page title helper - foo', view.page_title
48
+ end
49
+
50
+ test "reading defaults from I18n" do
51
+ view = MockView.new 'contacts/list.html.erb'
52
+ assert_equal 'Page title helper - contacts.list.title', view.page_title
53
+ end
54
+
55
+ test "printing app name only if :app => true" do
56
+ view = MockView.new
57
+ assert_equal 'Page title helper', view.page_title(:app => true)
58
+ end
59
+
60
+ test "custom formatting options" do
61
+ view = MockView.new
62
+ view.page_title { "test" }
63
+
64
+ assert_equal "Some app :: test", view.page_title(:app => "Some app", :format => ':app :: :title')
65
+ assert_equal "Some app / test", view.page_title(:format => 'Some app / :title')
66
+ end
67
+
68
+ test "return value of block to be used as heading" do
69
+ view = MockView.new
70
+ assert_equal "untitled", view.page_title { "untitled" }
71
+ end
72
+
73
+ test "calling :format => false returns just current title, without any interpolations etc." do
74
+ view = MockView.new
75
+ view.page_title { "untitled" }
76
+ assert_equal "untitled", view.page_title(:format => false)
77
+
78
+ i18n_view = MockView.new 'contacts/list.html.erb'
79
+ assert_equal "contacts.list.title", i18n_view.page_title(:format => false)
80
+ end
81
+
82
+ test "custom title using a translation with a placeholder" do
83
+ view = MockView.new
84
+ view.page_title { I18n.t :placeholder, :name => 'Bella' }
85
+ assert_equal "Page title helper - Displaying Bella", view.page_title
86
+ end
87
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'active_support'
4
+ require 'active_support/test_case'
5
+
6
+ ROOT = File.expand_path File.dirname(File.dirname(__FILE__))
7
+ RAILS_ROOT = '/this/is/just/for/testing/page_title_helper'
8
+ RAILS_ENV = 'test'
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lwe-page_title_helper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Lukas Westermann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-07 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: lukas.westermann@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - .gitignore
27
+ - LICENSE
28
+ - README.rdoc
29
+ - Rakefile
30
+ - VERSION.yml
31
+ - init.rb
32
+ - lib/page_title_helper.rb
33
+ - page_title_helper.gemspec
34
+ - test/page_title_helper_test.rb
35
+ - test/test_helper.rb
36
+ has_rdoc: true
37
+ homepage: http://github.com/lwe/page_title_helper
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --charset=UTF-8
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 1.2.0
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: Simple, internationalized and DRY page titles and headings for rails.
62
+ test_files:
63
+ - test/page_title_helper_test.rb
64
+ - test/test_helper.rb