active_component 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'activesupport'
4
+ gem 'haml'
5
+
6
+ group :development do
7
+ gem "rspec", "~> 2.3.0"
8
+ gem "bundler", "~> 1.0.0"
9
+ gem "jeweler", "~> 1.5.2"
10
+ end
@@ -0,0 +1,30 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.0.3)
5
+ diff-lcs (1.1.2)
6
+ git (1.2.5)
7
+ haml (3.0.25)
8
+ jeweler (1.5.2)
9
+ bundler (~> 1.0.0)
10
+ git (>= 1.2.5)
11
+ rake
12
+ rake (0.8.7)
13
+ rspec (2.3.0)
14
+ rspec-core (~> 2.3.0)
15
+ rspec-expectations (~> 2.3.0)
16
+ rspec-mocks (~> 2.3.0)
17
+ rspec-core (2.3.1)
18
+ rspec-expectations (2.3.0)
19
+ diff-lcs (~> 1.1.2)
20
+ rspec-mocks (2.3.0)
21
+
22
+ PLATFORMS
23
+ ruby
24
+
25
+ DEPENDENCIES
26
+ activesupport
27
+ bundler (~> 1.0.0)
28
+ haml
29
+ jeweler (~> 1.5.2)
30
+ rspec (~> 2.3.0)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Christian Peters
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.
@@ -0,0 +1,65 @@
1
+ Active Component
2
+ ================
3
+
4
+ Active Component introduces components into your Rails presentation layer.
5
+ The use of components improves consistency and development speed through reuse and a new way of view code organization.
6
+ Components are plain Ruby classes that are able to render themselves using a to_html method.
7
+ Active Component provides several means that make it easy to write and use components.
8
+
9
+
10
+ Example
11
+ =======
12
+
13
+ **Active Component Template:**
14
+
15
+ div 'kpi-report', :content => [
16
+
17
+ heading_with_label("in #{ Time.now.year }", "Group", 'group'),
18
+
19
+ report_table(@coreprocesses,
20
+ :headers => ["Core Processes"] + @companies.collect {|company| company.name},
21
+ :cols => [:name] + @companies.collect {|company|
22
+ proc {|cp| progress_chart(cp, :reporting_company_id => company.id, :chart_type => :boxes)}
23
+ }
24
+ )
25
+
26
+ ]
27
+
28
+ Each method represents a component.
29
+
30
+
31
+ **Comparision: Same Template in ERB:**
32
+
33
+ <div class="kpi_report">
34
+ <h1 class="content_header">
35
+ <span class="content_header_text">
36
+ <span class="label group_label">Group</span>
37
+ <%= title("Umsetzungsstand der Ziele") %>
38
+ in <%= Time.now.year %> <%= help_text %></span>
39
+ </h1>
40
+ <div class="content">
41
+ <div class="sub_content">
42
+ <table cellspacing="0">
43
+ <thead>
44
+ <tr>
45
+ <td width="80%">Core Processes</td>
46
+ <% @companies.each do |t| %>
47
+ <td><%= t.name %></td>
48
+ <% end %>
49
+ </tr>
50
+ </thead>
51
+ <% @coreprocesses.each do |cp| %>
52
+ <tr class="line">
53
+ <td class="small_name_column"><%= cp.name %></td>
54
+ <% @companies.each do |t| %>
55
+ <td class="small_indicator_column"><%= scale_helper(cp, true, t.id, Time.now.year, groupwide) %></td>
56
+ <% end %>
57
+ </tr>
58
+ <% end %>
59
+ </table>
60
+ </div>
61
+ </div>
62
+ </div>
63
+
64
+
65
+ Copyright (c) 2010 Christian Peters, released under the MIT license
@@ -0,0 +1,52 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "active_component"
16
+ gem.homepage = "http://github.com/ChristianPeters/activecomponent"
17
+ gem.license = "MIT"
18
+ gem.summary = "Build your views by assembling self-rendering components"
19
+ gem.description = %Q{Active Component introduces components into your Rails presentation layer.
20
+ The use of components improves consistency and development speed through reuse and a new way of view code organization.
21
+ Components are plain Ruby classes that are able to render themselves using a to_html method.
22
+ Active Component provides several means that make it easy to write and use components.}
23
+ gem.email = "christian.peters@zweitag.de"
24
+ gem.authors = ["Christian Peters"]
25
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
26
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
27
+ gem.add_dependency 'haml'
28
+ end
29
+ Jeweler::RubygemsDotOrgTasks.new
30
+
31
+ require 'rspec/core'
32
+ require 'rspec/core/rake_task'
33
+ RSpec::Core::RakeTask.new(:spec) do |spec|
34
+ spec.pattern = FileList['spec/**/*_spec.rb']
35
+ end
36
+
37
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
38
+ spec.pattern = 'spec/**/*_spec.rb'
39
+ spec.rcov = true
40
+ end
41
+
42
+ task :default => :spec
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "ac_tmp #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.2
@@ -0,0 +1,104 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{active_component}
8
+ s.version = "0.1.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Christian Peters"]
12
+ s.date = %q{2011-01-03}
13
+ s.description = %q{Active Component introduces components into your Rails presentation layer.
14
+ The use of components improves consistency and development speed through reuse and a new way of view code organization.
15
+ Components are plain Ruby classes that are able to render themselves using a to_html method.
16
+ Active Component provides several means that make it easy to write and use components.}
17
+ s.email = %q{christian.peters@zweitag.de}
18
+ s.extra_rdoc_files = [
19
+ "LICENSE.txt",
20
+ "README.rdoc"
21
+ ]
22
+ s.files = [
23
+ ".document",
24
+ ".rspec",
25
+ "Gemfile",
26
+ "Gemfile.lock",
27
+ "LICENSE.txt",
28
+ "README.rdoc",
29
+ "Rakefile",
30
+ "VERSION",
31
+ "active_component.gemspec",
32
+ "init.rb",
33
+ "lib/active_component.rb",
34
+ "lib/active_component/base.rb",
35
+ "lib/active_component/components/block.rb",
36
+ "lib/active_component/components/empty_tag.rb",
37
+ "lib/active_component/components/heading.rb",
38
+ "lib/active_component/components/inline_tag.rb",
39
+ "lib/active_component/components/section.rb",
40
+ "lib/active_component/components/table.rb",
41
+ "lib/active_component/config.rb",
42
+ "lib/active_component/core_extensions.rb",
43
+ "lib/active_component/template_handler.rb",
44
+ "pkg/active_component-0.1.2.gem",
45
+ "spec/active_component_spec.rb",
46
+ "spec/active_component_spec_helper.rb",
47
+ "spec/base_spec.rb",
48
+ "spec/components/block_spec.rb",
49
+ "spec/components/heading_spec.rb",
50
+ "spec/components/section_spec.rb",
51
+ "spec/components/table_spec.rb",
52
+ "spec/core_extensions_spec.rb",
53
+ "spec/factories.rb",
54
+ "spec/rcov.opts",
55
+ "spec/spec.opts",
56
+ "spec/spec_helper.rb"
57
+ ]
58
+ s.homepage = %q{http://github.com/ChristianPeters/activecomponent}
59
+ s.licenses = ["MIT"]
60
+ s.require_paths = ["lib"]
61
+ s.rubygems_version = %q{1.3.7}
62
+ s.summary = %q{Build your views by assembling self-rendering components}
63
+ s.test_files = [
64
+ "spec/active_component_spec.rb",
65
+ "spec/active_component_spec_helper.rb",
66
+ "spec/base_spec.rb",
67
+ "spec/components/block_spec.rb",
68
+ "spec/components/heading_spec.rb",
69
+ "spec/components/section_spec.rb",
70
+ "spec/components/table_spec.rb",
71
+ "spec/core_extensions_spec.rb",
72
+ "spec/factories.rb",
73
+ "spec/spec_helper.rb"
74
+ ]
75
+
76
+ if s.respond_to? :specification_version then
77
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
78
+ s.specification_version = 3
79
+
80
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
81
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
82
+ s.add_runtime_dependency(%q<haml>, [">= 0"])
83
+ s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
84
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
85
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
86
+ s.add_runtime_dependency(%q<haml>, [">= 0"])
87
+ else
88
+ s.add_dependency(%q<activesupport>, [">= 0"])
89
+ s.add_dependency(%q<haml>, [">= 0"])
90
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
91
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
92
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
93
+ s.add_dependency(%q<haml>, [">= 0"])
94
+ end
95
+ else
96
+ s.add_dependency(%q<activesupport>, [">= 0"])
97
+ s.add_dependency(%q<haml>, [">= 0"])
98
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
99
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
100
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
101
+ s.add_dependency(%q<haml>, [">= 0"])
102
+ end
103
+ end
104
+
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'lib', 'active_component')
@@ -0,0 +1,196 @@
1
+ # encoding: utf-8
2
+
3
+ require 'active_support'
4
+ require 'action_view'
5
+ require 'haml'
6
+ require 'haml/helpers/xss_mods'
7
+
8
+ module ActiveComponent
9
+
10
+ if defined? Rails::Railtie
11
+ class Railtie < Rails::Railtie
12
+ initializer "active_component.load_config" do
13
+ require 'active_component/config'
14
+ end
15
+ initializer "active_component.template_handler_registration" do
16
+ ActionView::Template.register_template_handler :act, TemplateHandler
17
+ end
18
+ end
19
+ else
20
+ require 'active_component/config'
21
+ end
22
+
23
+ HTML5_ELEMENTS = {
24
+ :meta => [:base, :command, :link, :meta, :noscript, :script, :style, :title],
25
+ :flow => [:a, :abbr, :address, :article, :aside, :audio, :b, :bdo, :blockquote, :br, :button, :canvas, :cite, :code, :command, :datalist, :del, :details, :dfn, :div, :dl, :em, :embed, :fieldset, :figure, :footer, :form, :h1, :h2, :h3, :h4, :h5, :h6, :header, :hgroup, :hr, :i, :iframe, :img, :input, :ins, :kbd, :keygen, :label, :map, :mark, :math, :menu, :meter, :nav, :noscript, :object, :ol, :output, :p, :pre, :progress, :q, :ruby, :samp, :script, :section, :select, :small, :span, :strong, :sub, :sup, :svg, :table, :textarea, :time, :ul, :var, :video, :wbr],
26
+ :sectioning => [:article, :aside, :nav, :section],
27
+ :heading => [:h1, :h2, :h3, :h4, :h5, :h6, :hgroup],
28
+ :phrasing => [:abbr, :audio, :b, :bdo, :br, :button, :canvas, :cite, :code, :command, :datalist, :dfn, :em, :embed, :i, :iframe, :img, :input, :kbd, :keygen, :label, :mark, :math, :meter, :noscript, :object, :output, :progress, :q, :ruby, :samp, :script, :select, :small, :span, :strong, :sub, :sup, :svg, :textarea, :time, :var, :video, :wbr],
29
+ :embedded => [:audio, :canvas, :embed, :iframe, :img, :math, :object, :svg, :video],
30
+ :interactive => [:a, :button, :details, :embed, :iframe, :keygen, :label, :select, :textarea],
31
+ :sectioning_roots => [:blockquote, :body, :details, :fieldset, :figure, :td],
32
+ :form_associated => [:button, :fieldset, :input, :keygen, :label, :meter, :object, :output, :progress, :select, :textarea],
33
+ :block_candidates => [:section, :nav, :article, :aside, :h1, :h2, :h3, :h4, :h5, :h6, :hgroup, :header, :footer, :address, :p, :pre, :blockquote, :div],
34
+ :uncategorized => [:col, :colgroup, :dd, :dt, :figcaption, :head, :html, :legend, :li, :optgroup, :option, :param, :rp, :rt, :source, :summary, :tbody, :tfoot, :th, :thead, :tr]
35
+ }
36
+
37
+ EMPTY_ELEMENTS = [:area, :base, :br, :col, :command, :embed, :hr, :img, :input, :keygen, :link, :meta, :param, :source, :wbr]
38
+ PHRASING_ELEMENTS = HTML5_ELEMENTS[:phrasing] - HTML5_ELEMENTS[:interactive] - HTML5_ELEMENTS[:embedded] - EMPTY_ELEMENTS - [:noscript, :time] + [:ins, :del]
39
+ BLOCK_ELEMENTS = HTML5_ELEMENTS[:block_candidates] - HTML5_ELEMENTS[:sectioning] - HTML5_ELEMENTS[:sectioning_roots] - HTML5_ELEMENTS[:heading] - [:p, :pre] + [:head, :html, :hgroup]
40
+ SECTION_ELEMENTS = HTML5_ELEMENTS[:sectioning] + HTML5_ELEMENTS[:sectioning_roots] - HTML5_ELEMENTS[:form_associated]
41
+ HEADING_ELEMENTS = HTML5_ELEMENTS[:heading] - [:hgroup]
42
+
43
+ # Embed
44
+ # Table
45
+ # List
46
+ # p, pre
47
+ # figure
48
+ # title
49
+
50
+ class ActiveComponentError < StandardError; end
51
+ class InvalidHtmlError < ActiveComponentError; end
52
+
53
+ # Generates a collection of tags wrapping content that is optionally printed using method(s)
54
+ def print_contents(tag, content_or_contents, method_or_methods = nil, *flags_and_attributes)
55
+ flags = []
56
+ attributes = {}
57
+ # Collect all flags (non-Hash) and attributes (by merging all Hashs)
58
+ for arg in flags_and_attributes
59
+ arg.is_a?(Hash) ? attributes.merge!(arg) : flags << arg
60
+ end
61
+
62
+ # Create a callable printing procedure for the case
63
+ # that its whole output should be wrapped with a tag
64
+ printing_procedure = Proc.new do
65
+ unless method_or_methods.present?
66
+ # Print content(s) without using methods
67
+ content_or_contents.transmogrify do |content|
68
+ if flags.include? :wrap_whole_content
69
+ # Write printed object to buffer (without tag)
70
+ write_to_buffer print_object(content)
71
+ else
72
+ # Wrap printed object with a tag and write result to buffer
73
+ tag_to_buffer(tag, print_object(content), attributes)
74
+ end
75
+ end
76
+ else
77
+ unless flags.include? :couple_methods_with_contents
78
+ # Print content(s) using (fixed set of) method(s)
79
+ content_or_contents.transmogrify do |content|
80
+ method_or_methods.transmogrify do |method|
81
+ if flags.include? :wrap_whole_content
82
+ # Write printed object to buffer (without tag)
83
+ write_to_buffer print_object(content, method)
84
+ else
85
+ # Wrap printed object with a tag and write result to buffer
86
+ tag_to_buffer(tag, print_object(content, method), attributes)
87
+ end
88
+ end
89
+ end
90
+ else
91
+ # Print contents using individually paired methods
92
+ content_or_contents.transmogrify_with_index do |content, index|
93
+ method = method_or_methods[index]
94
+ if flags.include? :wrap_whole_content
95
+ # Write printed object to buffer (without tag)
96
+ write_to_buffer print_object(content, method)
97
+ else
98
+ # Wrap printed objects with a tag and write result to buffer
99
+ tag_to_buffer(tag, print_object(content, method), attributes)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ if flags.include? :wrap_whole_content
107
+ # Wrap output of printing procedure with tag and write result to buffer
108
+ tag_to_buffer(tag, attributes, &printing_procedure)
109
+ else
110
+ # Call printing procedure and write result to buffer
111
+ printing_procedure.call
112
+ end
113
+
114
+ # Return buffer content
115
+ buffer
116
+ end
117
+
118
+ # Wraps content(s) into a single tag, optionally using a method
119
+ def wrap_contents(tag, content_or_contents, method_or_methods = nil, *flags_and_attributes)
120
+ print_contents(tag, content_or_contents, method_or_methods, :wrap_whole_content, *flags_and_attributes)
121
+ end
122
+
123
+ # Wraps haml_tag and directly captures the output buffer product.
124
+ # This should only be used if a single +haml_tag+ should be captured.
125
+ # Note that capturing buffer content should be done as rare as possible for performance reasons.
126
+ # For non-trivial content you might want to use `print_buffer { tag_to_buffer(:ul) { tag_to_buffer(:li, content) } }` instead.
127
+ #
128
+ # @param name [#to_s] The name of the tag
129
+ # @param flags [Array<Symbol>] Haml end-of-tag flags
130
+ # @param attributes [Hash] Hash of Haml (HTML) attributes
131
+ #
132
+ # @overload print_tag(name, *flags, attributes = {})
133
+ # @overload print_tag(name, text, *flags, attributes = {})
134
+ # @param text [#to_s] The text within the tag
135
+ def print_tag(name, *rest)
136
+ puts "warning: print_tag does not except blocks. Use print_buffer { tag_to_buffer(:ul) { tag_to_buffer(:li, content) } } instead" if block_given?
137
+ print_buffer { tag(name, *rest) }
138
+ end
139
+
140
+ # Prints a single object, optionally using a method
141
+ def print_object(object, method = nil)
142
+ #logger = RAILS_DEFAULT_LOGGER
143
+ #logger.info "\"print_object speaking. I am about to print Object: " + object.inspect + " Method: " + method.inspect + ". Over.\""
144
+ unless method.present?
145
+ if object.respond_to? :call
146
+ begin
147
+ object.call.to_s
148
+ # Haml buffers may be provided in callable form, but have to be captured
149
+ rescue Haml::Error
150
+ # Rescue is only successful if buffer available in current scope
151
+ print_buffer { object.call }
152
+ end
153
+ else
154
+ object.to_s # Each object responds to :to_s
155
+ end
156
+ else
157
+ # If the given method can be invoked on the object, the result is returned
158
+ if method.respond_to?(:to_sym) && object.respond_to?(method)
159
+ object.send(method.to_sym).to_s
160
+ # If the given method can be alled with the object, the result is returned
161
+ elsif method.respond_to? :call
162
+ # Call method with object if it takes at most 1 required parameter
163
+ # Arity returns -n-1 if n > 0 optional parameters exist
164
+ if method.arity == 1 || method.arity == -1 || method.arity == -2
165
+ method.call(object).to_s
166
+ else
167
+ raise ArgumentError, "Content is not printable. Too many (or no) parameters expected in the following method: " + method.inspect
168
+ end
169
+ else
170
+ raise ArgumentError, "Content is not printable. Provide a Proc/Method that can be called with object or a method name that can be invoked on the object. Alternatively, do not provide a method argument so that the object's :to_html, :call, or :to_s method is called. Parameters given: Object: " + object.inspect + " Method: " + method.inspect
171
+ end
172
+ end
173
+ end
174
+
175
+ end
176
+
177
+ $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
178
+
179
+ require 'active_component/core_extensions'
180
+ require 'active_component/base'
181
+
182
+ # Load components
183
+ require 'active_component/components/block'
184
+ require 'active_component/components/empty_tag'
185
+ require 'active_component/components/heading'
186
+ require 'active_component/components/inline_tag'
187
+ require 'active_component/components/section'
188
+ require 'active_component/components/table'
189
+
190
+ # Register Active Component template handler in Rails 2 app
191
+ if defined? ActionView::TemplateHandlers
192
+ extend ActionView::TemplateHandlers
193
+
194
+ require 'active_component/template_handler'
195
+ register_template_handler :act, ActiveComponent::TemplateHandler
196
+ end