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 +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +34 -0
- data/config/initializers/load_monkey_patch.rb +4 -0
- data/config/routes.rb +2 -0
- data/lib/monkey/action_view/partial_renderer.rb +40 -0
- data/lib/monkey/action_view/path_resolver.rb +101 -0
- data/lib/monkey/action_view/template.rb +73 -0
- data/lib/monkey/action_view/template_renderer.rb +30 -0
- data/lib/railtie.rb +7 -0
- data/lib/sexy_presenter/engine.rb +5 -0
- data/lib/sexy_presenter/hooks.rb +11 -0
- data/lib/sexy_presenter/version.rb +3 -0
- data/lib/sexy_presenter.rb +5 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/sexy_presenter_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- metadata +76 -0
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
|
data/config/routes.rb
ADDED
|
@@ -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
data/test/test_helper.rb
ADDED
|
@@ -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
|