manage_meta 0.0.4

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 2011 YOURNAME
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.markdown ADDED
@@ -0,0 +1,132 @@
1
+ ManageMeta
2
+ ============
3
+
4
+ ManageMeta is yet another meta tag manager for Rails 3.x. Its features are: recognizes tags
5
+ should render as HTTP-EQUIV; supports the Google 'canonical' link; is extensible; is non-intrusive
6
+
7
+ How it works
8
+ -----------
9
+
10
+ Include the gem by adding this to your Gemfile file
11
+
12
+ `gem "manage_meta", :git => "git://github.com/mikehoward/manage_meta.git"`
13
+
14
+ Then, in your controller actions, call _add_meta_ for each meta tag you want
15
+ to define.
16
+
17
+ `add_meta :author, 'Fred Fink'`
18
+
19
+ If there are meta tags you don't want to define, you can use _del_meta_ to remove them.
20
+ At present there are only two automatically defined: 'robots' and 'generator'. You may
21
+ also redefine them by using _add_meta_ to give them new values.
22
+
23
+ If there is a meta tag which requires a currently unsupported format, you may add it
24
+ using _add_meta_format_.
25
+
26
+ Finally, edit app/views/layouts/application.html.erb - or equivalent - to insert
27
+
28
+ `<%= render_meta %>`
29
+
30
+ into the _head_ section of your HTML output. This will render and return all of the
31
+ defined meta tags.
32
+
33
+ What it Adds
34
+ ------------
35
+
36
+ ManageMeta defines four (4) methods and three (3) instance variables into all classes
37
+ derived from ApplicationController
38
+
39
+ The methods are:
40
+
41
+ * add_meta - adds a meta tag
42
+ * del_meta - which deletes a meta tag
43
+ * add_meta_format - which adds a meta tag format
44
+ * render_meta - which returns a string rendering all currently defined meta tags.
45
+
46
+ The instance variables are:
47
+
48
+ * @manage_meta_meta_hash - a Hash containing mapping defined meta tag names to content values
49
+ * @manage_meta_format_hash - a Hash mapping known meta tag format strings to actual format strings
50
+ * @manage_meta_name_to_format - a Hash mapping meta tag name strings to known formats
51
+
52
+ The Details
53
+ --------------
54
+
55
+ Here are the ugly details
56
+
57
+ ### Methods in Detail ###
58
+
59
+ #### add_meta ####
60
+
61
+ _add_meta_ accepts values in any of three formats:
62
+
63
+ `add_meta(name, value[, :format => :format_name])`
64
+ `add_meta(name, value[, :format => :format_name]) do ... end`
65
+ `add_meta(name[, :format => :format_name]) do ... end`
66
+
67
+ * name must be something which responds to 'to_s'. It will be used for the _name_ (or _http-equiv_)
68
+ attribute of the meta tag.
69
+ * value must be something which responds to 'to_s' and is not a Hash. Normally it will simply
70
+ be a string. If given, it supplies the leading part of the _content_ attribute of the meta tag
71
+ * The single option :format must supply an existing key in @manage_meta_format_hash. It is
72
+ used to associate a meta tag format with _name_. If not given and not currently defined in
73
+ @manage_meta_format_hash, it will be set to _:named_. (see below for details)
74
+ * The optional block is evaluated and the return value is used as the second [or only] part
75
+ of the _content_ attribute of the meta tag.
76
+
77
+ Three meta tag formats are defined automatically:
78
+
79
+ * `:named => '<meta name="#{name}" content="#{content}" char-encoding="utf-8" />'`
80
+ * `:http_equiv => '<meta http-equiv="#{name}" content="#{content}" char-encoding="utf-8" />'`
81
+ * `:canonical => '<link rel="canonical" href="#{content}" />'`
82
+
83
+ The _@manage_meta_name_to_format_ is populated with entries mapping known HTTP-EQUIV tags
84
+ and the CANONICAL Google link tag to the correct format.
85
+
86
+ #### del_meta ####
87
+
88
+ _del_meta_ is almost useless. It's there in case you want to get ride of a default tag.
89
+
90
+ `del_meta(name)`
91
+
92
+ where _name_ is something which responds to 'to_s' [or is a string]. If the meta tag is
93
+ defined in @manage_meta_meta_hash, then it will be deleted. Nothing bad happens if it isn't.
94
+
95
+ #### add_meta_format_ ####
96
+
97
+ `add_meta_format(format_name, format_string)`
98
+
99
+ _format_name__ will be converted to a symbol.
100
+
101
+ _format_string_ will be the value of @manage_meta_format_hash[_format_name.to_sym_].
102
+
103
+ It's your responsibility to format the string properly.
104
+
105
+ _render_meta_ will replace _name_ and _content_ with the string values given for the meta
106
+ tag - if present. It is not an error to omit either or both _name_ and/or _content_
107
+
108
+ #### render_meta ####
109
+
110
+ `render_meta`
111
+
112
+ simply goes through all the defined key, value pairs in @manage_meta_meta_hash and
113
+ returns their associated format strings after replacing the _#{name}_ and _#{content}_
114
+ symbols with their values.
115
+
116
+ ### Instance Variables in Detail ###
117
+
118
+ #### manage_meta_format_hash ####
119
+
120
+ keys are symbols,
121
+
122
+ values are strings which are used to render meta tags
123
+
124
+ #### manage_meta_meta_hash ####
125
+
126
+ keys are strings which are used for the names of meta tags
127
+
128
+ values are symbols which are keys in @manage_meta_format_hash
129
+
130
+ #### manage_meta_name_to_format ####
131
+
132
+ keys are strings which map meta tag names to keys in @manage_meta_format_hash
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require 'rake'
2
+
3
+ task :default => :test
4
+
5
+ desc "Run ManageMeta unit tests"
6
+ task :test do
7
+ require './test/manage_meta_test'
8
+ end
9
+
10
+ desc "run rdoc to create doc"
11
+ task :doc do
12
+ system 'rdoc'
13
+ end
14
+
15
+ desc "build gem"
16
+ task :gem do
17
+ system 'gem build manage_meta.gemspec'
18
+ end
@@ -0,0 +1,7 @@
1
+ require 'manage_meta/manage_meta'
2
+
3
+ if defined? Rails
4
+ class ApplicationController < ActionController::Base
5
+ include ManageMeta
6
+ end
7
+ end
@@ -0,0 +1,131 @@
1
+ module ManageMeta
2
+ def self.included(mod)
3
+ # OK this is a hack based on section 25.4 of Programming Ruby 1.9 by Dave Thomas
4
+ # we are using the _included_ hook from Ruby's Module module to run some code
5
+ # which replaces the 'initialize' routine with one which creates our required instance
6
+ # data.
7
+ # 1. We are saving the original 'initialize' as old_initialize.
8
+ # 2. we execute the private method 'define_method' via mod.send which has the side effect
9
+ # of carrying the definition of 'old_initialize' into the closure.
10
+ # 3. we have to bind 'old_initialize' to the run-time value of 'self' because it is an unbound
11
+ # method and 'self' will have the right value when it is run in the context of 'mod' creating
12
+ # an instance
13
+ # 4. we then define our instance variables so that everything will work properly
14
+
15
+ mod.helper_method :render_meta if mod.respond_to? :helper_method
16
+
17
+ old_initialize = mod.instance_method :initialize
18
+ mod.send(:define_method, :initialize) do |*args, &block|
19
+ result = old_initialize.bind(self).call(*args, &block)
20
+ @manage_meta_meta_hash = {}
21
+
22
+ @manage_meta_format_hash = {
23
+ :named => '<meta name="#{name}" content="#{content}" char-encoding="utf-8" />',
24
+ :http_equiv => '<meta http-equiv="#{name}" content="#{content}" char-encoding="utf-8" />',
25
+ :canonical => '<link rel="canonical" href="#{content}" />',
26
+ }
27
+
28
+ @manage_meta_name_to_format = {}
29
+ #-- set up http-equiv meta tags
30
+ ['accept', 'accept-charset', 'accept-encoding', 'accept-language', 'accept-ranges',
31
+ 'age', 'allow', 'authorization', 'cache-control', 'connecting', 'content-encoding',
32
+ 'content-language', 'content-length', 'content-location', 'content-md5', 'content-range',
33
+ 'content-type', 'date', 'etag', 'expect', 'expires', 'from', 'host', 'if-match', 'if-modified-since',
34
+ 'if-none-match', 'if-range', 'if-unmodified-since', 'last-modified', 'location',
35
+ 'max-forwards', 'pragma', 'proxy-authenticate', 'proxy-authorization', 'range', 'referer',
36
+ 'retry-after', 'server', 'te', 'trailer', 'transfer-encoding', 'upgrade', 'user-agent',
37
+ 'vary', 'via', 'warning', 'www-authenticate', ].each { |name| @manage_meta_name_to_format[name] = :http_equiv }
38
+ # set up Google's canonical link tag
39
+ ['canonical'].each { |name| @manage_meta_name_to_format[name] = :canonical }
40
+ # set up normal meta tags
41
+ ['description', 'keywords', 'language', 'robots'].each { |name| @manage_meta_name_to_format[name] = :named }
42
+
43
+ add_meta 'robots', 'index follow'
44
+ add_meta 'generator', "Rails #{Rails.version}" if defined?(Rails)
45
+ # add_meta 'canonical', request.fullpath
46
+ result
47
+ end
48
+ end
49
+
50
+ #--
51
+ protected
52
+
53
+ #++
54
+ # add_meta(name, value[, options]) - adds meta tag 'name' with value 'value' to meta tags to be displayed
55
+ # add_meta(name[, options] &block) - does same thing, except value is the return value of &block
56
+ # Note: if no both 'value' and 'block' are given, then the content of the meta tag is the concatenation
57
+ # of both values.
58
+ # options:
59
+ # :format => symbol - where 'symbol' is one of :named, :http_equiv, :canonical, or a format
60
+ # added with 'add_meta_format'
61
+ # all other options keys are ignored
62
+ #--
63
+ def add_meta(name, opt_value = nil, options = {}, &block)
64
+ # make sure name is a string
65
+ name = name.to_s
66
+
67
+ # handle optional nonsense
68
+ case
69
+ when opt_value.is_a?(String)
70
+ value = opt_value
71
+ value += yield.to_s if block_given?
72
+ when opt_value.is_a?(Hash)
73
+ raise ArgumentError, "Value for meta tag #{name} missing" if !block_given?
74
+ value = yield.to_s
75
+ options = opt_value
76
+ when opt_value.nil?
77
+ raise ArgumentError, "Value for meta tag #{name} missing" if !block_given?
78
+ value = yield.to_s
79
+ when opt_value.respond_to?(:to_s)
80
+ value = opt_value.to_s
81
+ value += yield.to_s if block_given?
82
+ else
83
+ raise ArgumentError, "add_meta(name, value[, options hash]) or add_meta(name[, option hash] do ... end)"
84
+ end
85
+ @manage_meta_meta_hash[name] = value
86
+
87
+ if (options.keys - [:format]).size > 0
88
+ raise RuntimeError, "add_meta(#{name}, ...): illegal option key(s): #{options.keys - [:format]}"
89
+ end
90
+
91
+ # if format is explicitly called out or if name is not yet known
92
+ if options.has_key?(:format)
93
+ raise RuntimeError, "Unsuported Format: #{options[:format]}: formats are #{@manage_meta_format_hash.keys.join(',')}" if !@manage_meta_format_hash.has_key?(options[:format].to_sym)
94
+ @manage_meta_name_to_format[name] = options[:format].to_sym
95
+ elsif !@manage_meta_name_to_format.has_key?(name)
96
+ @manage_meta_name_to_format[name] = :named
97
+ end
98
+ end
99
+
100
+ #++
101
+ # del_meta(name) - where _name_ is a string or a symbol.
102
+ #
103
+ # if _name_ is in @manage_meta_meta_hash, then it will be deleted
104
+ #--
105
+ def del_meta(name)
106
+ name = name.to_s
107
+ @manage_meta_meta_hash.delete name if @manage_meta_meta_hash.has_key? name
108
+ end
109
+
110
+ #++
111
+ # add_meta_format(key, format)
112
+ #
113
+ # adds the format _format_ to @manage_meta_format_hash using the key _key_
114
+ #--
115
+ def add_meta_format(key, format)
116
+ key = key.to_sym
117
+ @manage_meta_format_hash[key] = format
118
+ end
119
+
120
+ #++
121
+ # render_meta
122
+ #
123
+ # returns a string consisting of all defined meta names in @manage_meta_meta_hash, formatted
124
+ # using their name-specific formats and indented two spaces.
125
+ #--
126
+ def render_meta
127
+ ' ' + @manage_meta_meta_hash.map do |name, content|
128
+ @manage_meta_format_hash[@manage_meta_name_to_format[name]].sub('#{name}', name).sub('#{content}', content)
129
+ end.join("\n ") + " \n"
130
+ end
131
+ end
@@ -0,0 +1,116 @@
1
+ $LOAD_PATH << File.expand_path("../../lib", __FILE__)
2
+ require 'test/unit'
3
+ require 'manage_meta'
4
+
5
+ class ManageMetaTest < Test::Unit::TestCase
6
+ include ManageMeta
7
+
8
+ class NoToS ; end
9
+ NoToS.send :undef_method, :to_s
10
+
11
+ # add refute methods for ruby 1.8.7
12
+ if !self.instance_methods.include? :refute_respond_to
13
+ def refute_respond_to(obj, func, msg = nil)
14
+ assert ! obj.respond_to?( func, msg )
15
+ end
16
+
17
+ def refute(expr, msg = nil)
18
+ assert ! expr, msg
19
+ end
20
+ end
21
+
22
+ # test 'existence of add_meta method' do
23
+ def test_methods_exist
24
+ assert_respond_to self, :add_meta, "responds to add_meta()"
25
+ assert_respond_to self, :del_meta, "responds to del_meta()"
26
+ assert_respond_to self, :add_meta_format, "responds to add_meta_format()"
27
+ assert_respond_to self, :render_meta, "responds to render_meta()"
28
+ end
29
+
30
+ # add_meta tests
31
+ # test "add_meta argument edge cases" do
32
+ def test_add_meta_edge_cases
33
+
34
+ assert_raise(ArgumentError, "name of meta must be present") { add_meta }
35
+ assert_raise(ArgumentError, "value must be present") { add_meta :foo }
36
+ assert_raise(ArgumentError, "value must not be nil") { add_meta :foo, nil }
37
+ assert_raise(ArgumentError, "value must not be a hash") { add_meta :foo, :hash => true }
38
+
39
+ # make sure fails if value does not respond to :to_s
40
+ no_to_s = NoToS.new
41
+ refute_respond_to no_to_s, :to_s, "no_to_s must not respond to 'to_s'"
42
+ assert_raise(ArgumentError, "value must respond to to_s") { add_meta :no_to_s, no_to_s }
43
+
44
+ assert_raise(RuntimeError, "illegal option must raise an error") { add_meta :foo, 'value', :bad_opt => 'stuff'}
45
+ end
46
+
47
+ # test "add_meta adds methods to meta_hash" do
48
+ def test_add_meta_adds_meta
49
+ assert_nothing_raised(Exception, "add_meta foo, bar is ok") { add_meta :foo, "bar" }
50
+ assert self.instance_variable_get("@manage_meta_meta_hash").key?('foo'),
51
+ "meta variable 'foo' not defined #{self.instance_variable_get('@manage_meta_meta_hash')}"
52
+ assert self.instance_variable_get("@manage_meta_meta_hash")['foo'] == 'bar',
53
+ "meta variable 'foo' not defined #{self.instance_variable_get('@manage_meta_meta_hash')}"
54
+ assert_nothing_raised(Exception, "add_meta(bar) {'value'}") { add_meta( :bar ) { 'value' }}
55
+ assert self.instance_variable_get("@manage_meta_meta_hash").key?('bar'),
56
+ "meta variable 'bar' not defined #{self.instance_variable_get('@manage_meta_meta_hash')}"
57
+ assert self.instance_variable_get("@manage_meta_meta_hash")['bar'] == 'value',
58
+ "meta variable 'bar' not defined #{self.instance_variable_get('@manage_meta_meta_hash')}"
59
+ end
60
+
61
+ # test "add_meta concatenates value and output of block" do
62
+ def test_add_meta_concats_value_and_block
63
+ add_meta(:foo, 'arg value') { ' block value' }
64
+ assert_equal self.instance_variable_get("@manage_meta_meta_hash")['foo'], 'arg value block value',
65
+ "add meta must concatenate value of both arg value and output of block"
66
+ add_meta(:foo, 'arg value', :format => :canonical) { ' block value' }
67
+ assert_equal self.instance_variable_get("@manage_meta_meta_hash")['foo'], 'arg value block value',
68
+ "add meta must concatenate value of both arg value and output of block with option present"
69
+ end
70
+
71
+ # test "add_meta with :format argument" do
72
+ def test_add_meta_format_works
73
+ # bad format option
74
+ assert_raise(RuntimeError, "Must not accept undefined format") { add_meta :foo, 'value', :format => :bad_key }
75
+ # good format options
76
+ assert_nothing_raised("Must accept format arg as string") { add_meta :foo, 'value', :format => 'named' }
77
+ end
78
+
79
+ # test ' del_meta' do
80
+ def test_del_meta_deletes_meta_tag
81
+ assert_nothing_raised(Exception, "add_meta foo, bar is ok") { add_meta :foo, "bar" }
82
+ assert self.instance_variable_get("@manage_meta_meta_hash").key?('foo'),
83
+ "meta variable 'foo' not defined #{self.instance_variable_get('@manage_meta_meta_hash')}"
84
+ assert self.instance_variable_get("@manage_meta_meta_hash")['foo'] == 'bar',
85
+ "meta variable 'foo' not defined #{self.instance_variable_get('@manage_meta_meta_hash')}"
86
+ del_meta(:foo)
87
+ refute self.instance_variable_get("@manage_meta_meta_hash").key?('foo'),
88
+ "meta variable 'foo' should not be defined #{self.instance_variable_get('@manage_meta_meta_hash')}"
89
+ end
90
+
91
+ # test 'add_meta_format' do
92
+ def test_add_meta_format_adds_a_format
93
+ format = '<meta foo-type="#{name}" content="#{content}"'
94
+ add_meta_format(:foo, format)
95
+ assert self.instance_variable_get("@manage_meta_format_hash").key?(:foo),
96
+ "add_meta_format adds key to format_hash using symbol"
97
+ assert self.instance_variable_get("@manage_meta_format_hash")[:foo] == format,
98
+ "add_meta_format adds format properly"
99
+ add_meta_format('bar', format)
100
+ assert self.instance_variable_get("@manage_meta_format_hash").key?(:bar),
101
+ "add_meta_format adds key to format_hash using string"
102
+ assert self.instance_variable_get("@manage_meta_format_hash")[:bar] == format,
103
+ "add_meta_format adds format properly"
104
+ end
105
+
106
+ # test 'render_meta' do
107
+ def test_render_meta_renders_meta
108
+ assert_match /name="robots"/, render_meta, "render_meta contains robots meta tag"
109
+ assert_match /name="generator"/, render_meta, "render_meta contains generator meta tag" \
110
+ if defined? Rails
111
+ add_meta :foo, 'a value'
112
+ assert_match /name="foo"/, render_meta, "render_meta contains 'foo' meta tag"
113
+ assert_match /content="a value"/, render_meta, "render_meta tag for foo has content 'a value'"
114
+ end
115
+
116
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: manage_meta
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.4
6
+ platform: ruby
7
+ authors:
8
+ - Mike Howard
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-13 00:00:00 -06:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: Provides (semi-)intellegent management of meta tags for Rails 3
18
+ email: mike@clove.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - lib/manage_meta/manage_meta.rb
27
+ - lib/manage_meta.rb
28
+ - test/manage_meta_test.rb
29
+ - MIT-LICENSE
30
+ - Rakefile
31
+ - README.markdown
32
+ has_rdoc: true
33
+ homepage: http://github.com/mikehoward/manage_meta
34
+ licenses: []
35
+
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ requirements: []
54
+
55
+ rubyforge_project:
56
+ rubygems_version: 1.6.2
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: ManageMeta - Yet Another Meta Tag manager for Rails 3
60
+ test_files: []
61
+