context_help 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in context_help.gemspec
4
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = ContextHelp
2
+
3
+ ContexHelp is a ruby gem for discovering documentable elements in rails applications
4
+ and showing help for them. Currently ContextHelp detects form_tag elements, models and
5
+ attributes in forms rendered by form_for or formtastic, and other html elements rendered
6
+ by *_tag helpers.
7
+
8
+ == Features
9
+
10
+ * Autodetection of model and attributes present on a view from formtastic y form_for helpers.
11
+ * Autodetection of html tags rendered by *_tag helpers
12
+ * Custom documentation for custom elements through I18n like routes. Ej: 'en.context_help.custom.tree_view'
13
+ * Basic inline and contextual help HTML renderer
14
+ * Customizable renderers
15
+ * Internationalized text. ContextHelp gets help texts from I18n files.
16
+
17
+ ==
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "context_help/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "context_help"
7
+ s.version = ContextHelp::VERSION
8
+ s.authors = ["Juan Pablo Marzetti"]
9
+ s.email = ["jmarzetti@sequre.com.ar"]
10
+ s.homepage = "http://sequre.com.ar"
11
+ s.summary = %q{A Rails context help facility to offer help about yor models and attributes}
12
+ s.description = %q{ContextHelp is a gem that allows you to show inline or aside help about every input item found in a form tag, a model, its attributes and even custom help about other HTML tags}
13
+
14
+ s.rubyforge_project = "context_help"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
@@ -0,0 +1,181 @@
1
+ module ContextHelp
2
+ module Base
3
+ @help_items = []
4
+ @config = {
5
+ :show_inline => false,
6
+ :title_tag => 'h1',
7
+ :title_class => 'help_title',
8
+ :text_tag => 'span',
9
+ :text_class => 'help_text',
10
+ :level_classes => {
11
+ :model => 'help_level_1',
12
+ :model_attribute => 'help_level_2',
13
+ :html => {
14
+ :default => 'help_level_2',
15
+
16
+ :form => 'help_level_1',
17
+ :fieldset => 'help_level_2',
18
+ },
19
+ :custom => 'help_level_3'
20
+ },
21
+ :exclude_tags => [:script, :link, :li],
22
+ :exclude_models => [],
23
+ :show_missing => false,
24
+ :link_to_object => false,
25
+ :link_to_help => false
26
+ }
27
+
28
+ def self.help_for(options)
29
+ help_options = options[:context_help]
30
+ self.help_path_for(help_options)
31
+ self.inline_help(help_options)
32
+ end
33
+ def self.context_help(&block)
34
+ help = ''
35
+ @help_items.each do |item|
36
+ item[:calculated_path] = self.help_path_for(item, false) if !item[:calculated_path]
37
+ if block_given?
38
+ help += yield(item)
39
+ elsif !item[:skip] and item[:calculated_path]
40
+ help += self.html_help(item)
41
+ end
42
+ end
43
+ help.strip
44
+ end
45
+ def self.help_items
46
+ @help_items
47
+ end
48
+ def self.config
49
+ @config
50
+ end
51
+ def self.flush_items
52
+ @help_items = []
53
+ end
54
+ def self.inline_help(options)
55
+ return '' if options[:skip] or !options[:calculated_path]
56
+ if options[:inline_help_builder].is_a?(Proc)
57
+ options[:inline_help_builder].call(options)
58
+ elsif options[:show_inline]
59
+ self.html_help(options)
60
+ else
61
+ ''
62
+ end
63
+ end
64
+ def self.help_path_for(options,register=true)
65
+ path = options[:path]
66
+ return path if path.is_a?(String)
67
+
68
+ ruta = nil
69
+ if !options[:skip]
70
+ if path[:model] and @config[:exclude_models].index(path[:model].to_sym).nil?
71
+ ruta = 'context_help.models.'+model_name(path[:model])
72
+ options[:pre_level_class] = @config[:level_classes][:model]
73
+
74
+ if (path[:attribute])
75
+ ruta = ruta + '.attributes.'+ path[:attribute].to_s.underscore
76
+ options[:pre_level_class] = @config[:level_classes][:model_attribute]
77
+ end
78
+ elsif path[:tag] and @config[:exclude_tags].index(path[:tag].to_sym).nil?
79
+ ruta = 'context_help.html.'+path[:tag].to_s.downcase
80
+ ruta = ruta + '.' + path[:tag_options][:id].to_s if path[:tag_options][:id]
81
+
82
+ if @config[:level_classes][:html].include?(path[:tag])
83
+ options[:pre_level_class] = @config[:level_classes][:html][path[:tag]]
84
+ else
85
+ options[:pre_level_class] = @config[:level_classes][:html][:default]
86
+ end
87
+ elsif path[:custom]
88
+ ruta = 'context_help.custom.'+path[:custom]
89
+ options[:pre_level_class] = @config[:level_classes][:custom]
90
+ end
91
+ end
92
+ if ruta
93
+ options[:calculated_path] = ruta if (I18n.t(ruta+'.title', :default => '') != '') or (Rails.env.development? and @config[:show_missing])
94
+ self.register_item(options) if register
95
+ return options[:calculated_path]
96
+ end
97
+ nil
98
+ end
99
+ def self.html_help(options)
100
+ if options[:help_builder].is_a?(Proc)
101
+ options[:help_builder].call(options)
102
+ elsif options[:calculated_path]
103
+ title = options[:title] || I18n.t(options[:calculated_path]+'.title')
104
+ text = options[:text] || I18n.t(options[:calculated_path]+'.text')
105
+ html = "<#{options[:title_tag]} id=\"#{options[:item_id]}\" class=\"#{options[:title_class]} #{options[:level_class]}\">#{title}</#{options[:title_tag]}>
106
+ <#{options[:text_tag]} class=\"#{options[:text_class]} #{options[:level_class]}\">#{text}</#{options[:text_tag]}>"
107
+ html += self.link_to_object(options)
108
+ html
109
+ end
110
+ end
111
+ def self.link_to_help(options)
112
+ if options[:link_to_help_builder].is_a?(Proc)
113
+ options[:link_to_help_builder].call(options)
114
+ elsif options[:link_to_help] and !I18n.t(options[:calculated_path]+'.title', :default => {}).is_a?(Hash)
115
+ "<a href=\"##{options[:item_id]}\" id=\"#{options[:item_id]}_object\" class=\"context_help_link_to_help\">help</a>"
116
+ else
117
+ ''
118
+ end
119
+ end
120
+ def self.link_to_object(options)
121
+ if options[:link_to_object_builder].is_a?(Proc)
122
+ options[:link_to_object_builder].call(options)
123
+ elsif options[:link_to_object]
124
+ "<a href=\"#link_to_help_#{options[:item_id]}\">help</a>"
125
+ else
126
+ ''
127
+ end
128
+ end
129
+ def self.register_item(options)
130
+ def self.get_option(name, options)
131
+ return @config[name] if options[:calculated_path].nil?
132
+ value = I18n.t(options[:calculated_path]+'.'+name.to_s, :default => {})
133
+ if value.is_a?(Hash)
134
+ @config[name]
135
+ else
136
+ value
137
+ end
138
+ end
139
+ found = false
140
+ @help_items.each do |item|
141
+ found = (item[:calculated_path] == options[:calculated_path])
142
+ break if found
143
+ end
144
+ if not found
145
+ options[:show_inline] ||= get_option(:show_inline, options)
146
+ options[:title_tag] ||= get_option(:title_tag, options)
147
+ options[:title_class] ||= get_option(:title_class, options)
148
+ options[:text_tag] ||= get_option(:text_tag, options)
149
+ options[:text_class] ||= get_option(:text_class, options)
150
+ options[:link_to_object] ||= get_option(:link_to_object, options)
151
+ options[:link_to_help] ||= get_option(:link_to_help, options)
152
+ options[:level_class] ||= I18n.t(options[:calculated_path]+'.level_class', :default => (options[:pre_level_class] || 'help_level_1'))
153
+ options[:link_to_help_builder] ||= @config[:link_to_help_builder]
154
+ options[:link_to_object_builder] ||= @config[:link_to_object_builder]
155
+ options[:inline_help_builder] ||= @config[:inline_help_builder]
156
+ options[:help_builder] ||= @config[:help_builder]
157
+
158
+ options[:item_id] = "context_help_item_#{(@help_items.length+1).to_s}"
159
+ @help_items << options
160
+ end
161
+ end
162
+ def self.model_name(model)
163
+ model = model.to_s.underscore
164
+ if model =~ /^[a-z][a-z0-9_]*\[[a-z][a-z0-9_]*_attributes\]/
165
+ model.match(/^[a-z][a-z0-9_]*\[([a-z][a-z0-9_]*)_attributes\]/)[1].singularize
166
+ else
167
+ model
168
+ end
169
+ end
170
+ def self.merge_options(base, added)
171
+ if base.is_a?(Hash) and added.is_a?(Hash)
172
+ added.each do |key,value|
173
+ base[key] = self.merge_options(base[key], value)
174
+ end
175
+ return base
176
+ else
177
+ return base || added
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,69 @@
1
+ module ActionView
2
+ module Helpers
3
+ module FormHelper
4
+ def fields_for_with_context_help_fields_for(record_or_name_or_array, *args, &block)
5
+ case record_or_name_or_array
6
+ when String, Symbol
7
+ object_name = record_or_name_or_array
8
+ else
9
+ object_name = ActionController::RecordIdentifier.singular_class_name(record_or_name_or_array)
10
+ end
11
+
12
+ options = ContextHelp::Base.merge_options({:context_help => {:path => {:model => object_name.to_sym} } }, args.last.is_a?(::Hash)? args.last : {})
13
+ help = ContextHelp::Base.help_for(options)
14
+ help + fields_for_without_context_help_fields_for(record_or_name_or_array, *args, &block)
15
+ end
16
+ def label_with_context_help_label(object_name, method, text = nil, options = {})
17
+ help_options = ContextHelp::Base.merge_options({:context_help => {:path => {:model => object_name.to_sym, :attribute=> method.to_sym}}}, options)
18
+ ContextHelp::Base.help_for(help_options)
19
+ link_to_help = ContextHelp::Base.link_to_help(help_options[:context_help])
20
+ label_without_context_help_label(object_name, method, text.to_s + link_to_help, options)
21
+ end
22
+ def text_field_with_context_help_text_field(object_name, method, options = {})
23
+ help_options = ContextHelp::Base.merge_options({:context_help => {:path => {:model => object_name.to_sym, :attribute=> method.to_sym}}}, options)
24
+ help = ContextHelp::Base.help_for(help_options)
25
+ text_field_without_context_help_text_field(object_name, method, options) + help
26
+ end
27
+ def password_field_with_context_help_password_field(object_name, method, options = {})
28
+ help_options = ContextHelp::Base.merge_options({:context_help => {:path => {:model => object_name.to_sym, :attribute=> method.to_sym}}}, options)
29
+ help = ContextHelp::Base.help_for(help_options)
30
+ password_field_without_context_help_password_field(object_name, method, options) + help
31
+ end
32
+ def hidden_field_with_context_help_hidden_field(object_name, method, options = {})
33
+ help_options = ContextHelp::Base.merge_options({:context_help => {:path => {:model => object_name.to_sym, :attribute=> method.to_sym}}}, options)
34
+ help = ContextHelp::Base.help_for(help_options)
35
+ hidden_field_without_context_help_hidden_field(object_name, method, options) + help
36
+ end
37
+ def file_field_with_context_help_file_field(object_name, method, options = {})
38
+ help_options = ContextHelp::Base.merge_options({:context_help => {:path => {:model => object_name.to_sym, :attribute=> method.to_sym}}}, options)
39
+ help = ContextHelp::Base.help_for(help_options)
40
+ file_field_without_context_help_file_field(object_name, method, options) + help
41
+ end
42
+ def text_area_with_context_help_text_area(object_name, method, options = {})
43
+ help_options = ContextHelp::Base.merge_options({:context_help => {:path => {:model => object_name.to_sym, :attribute=> method.to_sym}}}, options)
44
+ help = ContextHelp::Base.help_for(help_options)
45
+ text_area_without_context_help_text_area(object_name, method, options) + help
46
+ end
47
+ def check_box_with_context_help_check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
48
+ help_options = ContextHelp::Base.merge_options({:context_help => {:path => {:model => object_name.to_sym, :attribute=> method.to_sym}}}, options)
49
+ help = ContextHelp::Base.help_for(help_options)
50
+ check_box_without_context_help_check_box(object_name, method, options, checked_value, unchecked_value) + help
51
+ end
52
+ def radio_button_with_context_help_radio_button(object_name, method, tag_value, options = {})
53
+ help_options = ContextHelp::Base.merge_options({:context_help => {:path => {:model => object_name.to_sym, :attribute=> method.to_sym}}}, options)
54
+ help = ContextHelp::Base.help_for(help_options)
55
+ radio_button_without_context_help_radio_button(object_name, method, tag_value, options) +help
56
+ end
57
+
58
+ alias_method_chain :fields_for, :context_help_fields_for
59
+ alias_method_chain :label, :context_help_label
60
+ alias_method_chain :text_field, :context_help_text_field
61
+ alias_method_chain :password_field, :context_help_password_field
62
+ alias_method_chain :hidden_field, :context_help_hidden_field
63
+ alias_method_chain :file_field, :context_help_file_field
64
+ alias_method_chain :text_area, :context_help_text_area
65
+ alias_method_chain :check_box, :context_help_check_box
66
+ alias_method_chain :radio_button, :context_help_radio_button
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,27 @@
1
+ module ContextHelp
2
+ class SemanticFormBuilder < Formtastic::SemanticFormBuilder
3
+ def inputs(*args, &block)
4
+ title = field_set_title_from_args(*args)
5
+ html_options = args.extract_options!
6
+ help_options = ContextHelp::Base.merge_options({:context_help => {:path => {:tag => 'fieldset', :tag_options => html_options}}}, html_options)
7
+ help_options[:context_help][:title] = title if help_options[:context_help][:path][:tag]
8
+ help = ContextHelp::Base.help_for(help_options)
9
+ super *(args<<help_options), &block
10
+ end
11
+ def input(method, options = {})
12
+ options = ContextHelp::Base.merge_options({:context_help => {:path => {:model => model_name.to_sym, :attribute=> method.to_sym}}}, options || {})
13
+ html = super
14
+ end
15
+ def legend_tag(method, options = {})
16
+ if options[:label] == false
17
+ Formtastic::Util.html_safe("")
18
+ else
19
+ text = localized_string(method, options[:label], :label) || humanized_attribute_name(method)
20
+ text += required_or_optional_string(options.delete(:required))
21
+ text = Formtastic::Util.html_safe(text)
22
+ text += ContextHelp::Base.link_to_help(options[:context_help])
23
+ template.content_tag :legend, template.label_tag(nil, text, :for => nil), :class => :label
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ module ActionView
2
+ module Helpers
3
+ module TagHelper
4
+ def tag_with_context_help_tag(name, options = {}, open = false, escape = true)
5
+ help_options = ContextHelp::Base.merge_options({:context_help => {:path => {:tag => name.to_sym, :tag_options => options}}}, options)
6
+ help = ContextHelp::Base.help_for(help_options)
7
+ tag_without_context_help_tag(name, options, open, escape) + help
8
+ end
9
+ def content_tag_with_context_help_content_tag(name, content_or_options_with_block = nil, options = {}, escape = true, &block)
10
+ help_options = ContextHelp::Base.merge_options({:context_help => {:path => {:tag => name.to_sym, :tag_options => options}}}, options)
11
+ help = ContextHelp::Base.help_for(help_options)
12
+ html = content_tag_without_context_help_content_tag(name, content_or_options_with_block, options, escape, &block) + help
13
+ end
14
+
15
+ alias_method_chain :tag, :context_help_tag
16
+ alias_method_chain :content_tag, :context_help_content_tag
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module ContextHelp
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'context_help/patches/tag_helper_patch'
2
+ require 'context_help/patches/form_helper_patch'
3
+ require 'context_help/patches/formtastic_patch'
4
+ require "context_help/version"
5
+ require 'context_help/base'
6
+
7
+ Formtastic::SemanticFormHelper.builder = ContextHelp::SemanticFormBuilder if defined?(Formtastic)
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: context_help
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Juan Pablo Marzetti
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-10 00:00:00.000000000 -03:00
13
+ default_executable:
14
+ dependencies: []
15
+ description: ContextHelp is a gem that allows you to show inline or aside help about
16
+ every input item found in a form tag, a model, its attributes and even custom help
17
+ about other HTML tags
18
+ email:
19
+ - jmarzetti@sequre.com.ar
20
+ executables: []
21
+ extensions: []
22
+ extra_rdoc_files: []
23
+ files:
24
+ - .gitignore
25
+ - Gemfile
26
+ - README.rdoc
27
+ - Rakefile
28
+ - context_help.gemspec
29
+ - lib/context_help.rb
30
+ - lib/context_help/base.rb
31
+ - lib/context_help/patches/form_helper_patch.rb
32
+ - lib/context_help/patches/formtastic_patch.rb
33
+ - lib/context_help/patches/tag_helper_patch.rb
34
+ - lib/context_help/version.rb
35
+ has_rdoc: true
36
+ homepage: http://sequre.com.ar
37
+ licenses: []
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project: context_help
56
+ rubygems_version: 1.6.2
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: A Rails context help facility to offer help about yor models and attributes
60
+ test_files: []