sexy_presenter 0.9

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c128e4d50989621c37805fbd4bc848e1a7c03767
4
+ data.tar.gz: 84c28d6c20beb43b55db6a8b74cb17fe6395c84b
5
+ SHA512:
6
+ metadata.gz: d14c810f81b28fe8e8123749b109445e39dae7b1529156d59ebd55f7e0c6d9db8e9dbab6ff016f52512f3b825333a51a70a08b37070925e93a0de8fd21789a25
7
+ data.tar.gz: a95270e2ac187a8a4ed133ac56eb0e3691c4015342f5bf5ffb45bd5f365508ec437fdef50cd73a002f56fe0e6dda2b065476ea7e7d63a791af6fb4630e611969
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 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/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'SexyPresenter'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,4 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'railtie'
3
+
4
+
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ SexyPresenter::Engine.routes.draw do
2
+ end
@@ -0,0 +1,40 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module ActionView
3
+ class PartialRenderer < AbstractRenderer
4
+
5
+ def render(context, options, block)
6
+ setup(context, options, block)
7
+ identifier = (@template = find_partial) ? @template.identifier : @path
8
+
9
+ @lookup_context.rendered_format ||= begin
10
+ if @template && @template.formats.present?
11
+ @template.formats.first
12
+ else
13
+ formats.first
14
+ end
15
+ end
16
+
17
+ # Process before_render hook
18
+ if @template.class.instance_variable_get(:@presenters)
19
+ @template.class.instance_variable_get(:@presenters).each {|presenter|
20
+ if presenter.instance_variable_get(:@__before_render)
21
+ @view.send('instance_eval', &presenter.instance_variable_get(:@__before_render))
22
+ end
23
+ }
24
+ end
25
+
26
+ if @collection
27
+ instrument(:collection, :identifier => identifier || "collection", :count => @collection.size) do
28
+ render_collection
29
+ end
30
+ else
31
+ instrument(:partial, :identifier => identifier) do
32
+ render_partial
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+
40
+
@@ -0,0 +1,101 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module ActionView
3
+ # = Action View Resolver
4
+ class PathResolver < Resolver #:nodoc:
5
+ def query(path, details, formats)
6
+ query = build_query(path, details)
7
+
8
+ # deals with case-insensitive file systems.
9
+ sanitizer = Hash.new { |h,dir| h[dir] = Dir["#{dir}/*"] }
10
+
11
+ template_paths = Dir[query].reject { |filename|
12
+ File.directory?(filename) ||
13
+ !sanitizer[File.dirname(filename)].include?(filename)
14
+ }
15
+
16
+ template_paths.map { |template|
17
+ handler, format = extract_handler_and_format(template, formats)
18
+ contents = File.binread template
19
+
20
+ contents, template_class = detect_template_class_in_contents(template, contents)
21
+
22
+ template_class.new(contents, File.expand_path(template), handler,
23
+ :virtual_path => path.virtual,
24
+ :format => format,
25
+ :updated_at => mtime(template))
26
+ }
27
+ end
28
+
29
+ # This method create custom template class for using presenter module.
30
+ def detect_template_class_in_contents(template_full_path, org_contents)
31
+ frontmatter, contents = separate_frontmatter(org_contents)
32
+ if frontmatter
33
+ yaml = YAML.load(frontmatter)
34
+ if yaml.kind_of?(Hash) && (presenter_module_name = yaml['presenter']).present?
35
+ presenter_modules = Array(presenter_module_name).map(&:constantize)
36
+ template_class_name = make_template_class_name(template_full_path, presenter_modules)
37
+ unless Object.const_defined?(template_class_name)
38
+
39
+ # Create custom template class
40
+ #
41
+ # This defines custom template class by eval, in top level, because use using method.
42
+ # (Hack:
43
+ # using method could be used in eval. And in template that was module_evaled,
44
+ # refine in presenter_modules is effective.)
45
+ eval("
46
+ #{presenter_modules.map {|mod| "using #{mod.name}"}.join(';')}
47
+
48
+ class #{template_class_name} < ActionView::Template
49
+ @presenters = [#{presenter_modules.map {|mod| mod.name}.join(', ')}]
50
+ def eval_template_contents(mod, source)
51
+ mod.module_eval(source, identifier, #{frontmatter.each_line.to_a.size + 2})
52
+ end
53
+ end
54
+ ", TOPLEVEL_BINDING)
55
+ end
56
+
57
+ # return custom template class
58
+ return [contents, template_class_name.constantize]
59
+ end
60
+ end
61
+
62
+ # default behavior
63
+ [contents, Template]
64
+ end
65
+
66
+ def make_template_class_name(template_full_path, presenter_modules)
67
+ 'SexyPresenter_' +
68
+ template_full_path.sub(Rails.root.to_s, '').gsub(/[\/\\\-\.]/, '_') +
69
+ '_using_' +
70
+ presenter_modules.map(&:name).join('_').gsub(/:/, '') +
71
+ '_Template'
72
+ end
73
+
74
+ # separate view contents text in frontmatter and contents.
75
+ #
76
+ # example.html.slim
77
+ # =======================================
78
+ # ---
79
+ # presenter: PostShowTemplate
80
+ # ---
81
+ #
82
+ # h1 Example Page
83
+ #
84
+ # =======================================
85
+ #
86
+ # retval: [fronamatter, contents]
87
+ def separate_frontmatter(contents)
88
+ lines = contents.lines
89
+ frontmatter_break_rows = lines.map.with_index {|line, i| (line.chomp == '---') ? i : nil}.compact
90
+ frontmatter_start = frontmatter_break_rows[0]
91
+ frontmatter_end = frontmatter_break_rows[1]
92
+ if frontmatter_start && frontmatter_start == 0 && frontmatter_end
93
+ [lines[frontmatter_start+1...frontmatter_end].join,
94
+ lines[frontmatter_end+1..-1].join]
95
+ else
96
+ [nil, contents]
97
+ end
98
+ end
99
+ end
100
+ end
101
+
@@ -0,0 +1,73 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module ActionView
3
+ # = Action View Template
4
+ class Template
5
+
6
+ protected
7
+ # Among other things, this method is responsible for properly setting
8
+ # the encoding of the compiled template.
9
+ #
10
+ # If the template engine handles encodings, we send the encoded
11
+ # String to the engine without further processing. This allows
12
+ # the template engine to support additional mechanisms for
13
+ # specifying the encoding. For instance, ERB supports <%# encoding: %>
14
+ #
15
+ # Otherwise, after we figure out the correct encoding, we then
16
+ # encode the source into <tt>Encoding.default_internal</tt>.
17
+ # In general, this means that templates will be UTF-8 inside of Rails,
18
+ # regardless of the original source encoding.
19
+ def compile(view, mod) #:nodoc:
20
+ encode!
21
+ method_name = self.method_name
22
+ code = @handler.call(self)
23
+
24
+ # Make sure that the resulting String to be evalled is in the
25
+ # encoding of the code
26
+ source = <<-end_src
27
+ def #{method_name}(local_assigns, output_buffer)
28
+ _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code}
29
+ ensure
30
+ @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer
31
+ end
32
+ end_src
33
+
34
+ # Make sure the source is in the encoding of the returned code
35
+ source.force_encoding(code.encoding)
36
+
37
+ # In case we get back a String from a handler that is not in
38
+ # BINARY or the default_internal, encode it to the default_internal
39
+ source.encode!
40
+
41
+ # Now, validate that the source we got back from the template
42
+ # handler is valid in the default_internal. This is for handlers
43
+ # that handle encoding but screw up
44
+ unless source.valid_encoding?
45
+ raise WrongEncodingError.new(@source, Encoding.default_internal)
46
+ end
47
+
48
+ begin
49
+ # Replace eval to template_method
50
+ #mod.module_eval(source, identifier, 0)
51
+ eval_template_contents(mod, source)
52
+ ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])
53
+ rescue Exception => e # errors from template code
54
+ if logger = (view && view.logger)
55
+ logger.debug "ERROR: compiling #{method_name} RAISED #{e}"
56
+ logger.debug "Function body: #{source}"
57
+ logger.debug "Backtrace: #{e.backtrace.join("\n")}"
58
+ end
59
+
60
+ raise ActionView::Template::Error.new(self, e)
61
+ end
62
+ end
63
+
64
+ def eval_template_contents(mod, source)
65
+ mod.module_eval(source, identifier, 0)
66
+ end
67
+
68
+ end
69
+ end
70
+
71
+
72
+
73
+
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module ActionView
3
+ class TemplateRenderer < AbstractRenderer #:nodoc:
4
+ def render(context, options)
5
+ @view = context
6
+ @details = extract_details(options)
7
+ template = determine_template(options)
8
+ context = @lookup_context
9
+
10
+ prepend_formats(template.formats)
11
+
12
+ unless context.rendered_format
13
+ context.rendered_format = template.formats.first || formats.first
14
+ end
15
+
16
+ # Process before_render hook
17
+ if template.class.instance_variable_get(:@presenters)
18
+ template.class.instance_variable_get(:@presenters).each {|presenter|
19
+ if presenter.instance_variable_get(:@__before_render)
20
+ @view.send('instance_eval', &presenter.instance_variable_get(:@__before_render))
21
+ end
22
+ }
23
+ end
24
+ render_template(template, options[:layout], options[:locals])
25
+ end
26
+
27
+ end
28
+ end
29
+
30
+
data/lib/railtie.rb ADDED
@@ -0,0 +1,7 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'monkey/action_view/template'
3
+ require 'monkey/action_view/path_resolver'
4
+ require 'monkey/action_view/template_renderer'
5
+ require 'monkey/action_view/partial_renderer'
6
+
7
+
@@ -0,0 +1,5 @@
1
+ module SexyPresenter
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace SexyPresenter
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module SexyPresenter
3
+ module Hooks
4
+ def before_render(&block)
5
+ @__before_render = block
6
+ end
7
+ end
8
+ end
9
+
10
+
11
+
@@ -0,0 +1,3 @@
1
+ module SexyPresenter
2
+ VERSION = "0.9"
3
+ end
@@ -0,0 +1,5 @@
1
+ require "sexy_presenter/engine"
2
+ require "sexy_presenter/hooks"
3
+
4
+ module SexyPresenter
5
+ end
@@ -0,0 +1,10 @@
1
+ require 'test_helper'
2
+
3
+ class NavigationTest < ActionDispatch::IntegrationTest
4
+ fixtures :all
5
+
6
+ # test "the truth" do
7
+ # assert true
8
+ # end
9
+ end
10
+
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class SexyPresenterTest < ActiveSupport::TestCase
4
+ test "truth" do
5
+ assert_kind_of Module, SexyPresenter
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ # Configure Rails Environment
2
+ ENV["RAILS_ENV"] = "test"
3
+
4
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
+ require "rails/test_help"
6
+
7
+ Rails.backtrace_cleaner.remove_silencers!
8
+
9
+ # Load support files
10
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
11
+
12
+ # Load fixtures from the engine
13
+ if ActiveSupport::TestCase.method_defined?(:fixture_path=)
14
+ ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
15
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sexy_presenter
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.9'
5
+ platform: ruby
6
+ authors:
7
+ - Yoshihiro Kameda
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 4.0.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 4.0.2
27
+ description: A Rails presentation layer library powered by Refinements.
28
+ email:
29
+ - kameda.sbng@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - MIT-LICENSE
35
+ - Rakefile
36
+ - config/initializers/load_monkey_patch.rb
37
+ - config/routes.rb
38
+ - lib/monkey/action_view/partial_renderer.rb
39
+ - lib/monkey/action_view/path_resolver.rb
40
+ - lib/monkey/action_view/template.rb
41
+ - lib/monkey/action_view/template_renderer.rb
42
+ - lib/railtie.rb
43
+ - lib/sexy_presenter.rb
44
+ - lib/sexy_presenter/engine.rb
45
+ - lib/sexy_presenter/hooks.rb
46
+ - lib/sexy_presenter/version.rb
47
+ - test/integration/navigation_test.rb
48
+ - test/sexy_presenter_test.rb
49
+ - test/test_helper.rb
50
+ homepage: ''
51
+ licenses: []
52
+ metadata: {}
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 2.2.2
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: A Rails presentation layer library powered by Refinements.
73
+ test_files:
74
+ - test/integration/navigation_test.rb
75
+ - test/sexy_presenter_test.rb
76
+ - test/test_helper.rb