client_pages 0.0.3.beta → 0.0.5
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 +4 -4
- data/README.md +3 -2
- data/client_pages.gemspec +2 -2
- data/lib/client_pages/configuration.rb +4 -9
- data/lib/client_pages/markdown_content/content_builder.rb +1 -1
- data/lib/client_pages/markdown_content/renderer.rb +5 -5
- data/lib/client_pages/template.rb +16 -2
- data/lib/client_pages/version.rb +1 -1
- data/lib/client_pages.rb +6 -7
- data/spec/integration/client_pages_spec.rb +44 -44
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/template_spec.rb +20 -7
- metadata +6 -7
- data/.gitignore +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d193fa65ba3d80471b486aff88d4ab9392ef39e2
|
4
|
+
data.tar.gz: 9ca9c1d6e184188d711b08f04e32f6788b01b264
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 782054588bfe71e9483a492e95e1ace9b51fd37839f507796fb5a560136cfd123f14274fd68780bcae2edb9aed7289b9cc07f0bf853b6fc693e7e3b20835eaee
|
7
|
+
data.tar.gz: fa2bb9d7498d84aa797089b1cbb6faae58d89da9061cc3094b4470e46730e41ac35a642a64203a8b9740605946f7ac6fab82414b3428e290fe659b2faf980a80
|
data/README.md
CHANGED
@@ -72,7 +72,7 @@ no framework? pure rack?
|
|
72
72
|
for convenience you can add ``` include ClientPages::MarkdownContent ``` to your application controller/view_helper/presenter/... or something which is responsible for building html
|
73
73
|
so that you can call ```render_content``` there.
|
74
74
|
|
75
|
-
or if you're riding the real blank slate, just call ```ClientPages
|
75
|
+
or if you're riding the real blank slate, just call ```ClientPages.render_content``` directly.
|
76
76
|
|
77
77
|
sinatra?
|
78
78
|
|
@@ -106,9 +106,10 @@ sinatra?
|
|
106
106
|
- by default...
|
107
107
|
- content_path
|
108
108
|
- if you go the full remote path without fallback, you might consider to turn on caching.
|
109
|
+
- s3 ?
|
109
110
|
|
110
111
|
```
|
111
|
-
ClientPages.
|
112
|
+
ClientPages.configure do |c|
|
112
113
|
c.remote = true
|
113
114
|
c.remote_content_path = 'https://dl.dropboxusercontent.com/u/363312/rackedy_rack'
|
114
115
|
c.content_path = 'content'
|
data/client_pages.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.homepage = ''
|
18
18
|
s.license = 'MIT'
|
19
19
|
|
20
|
-
s.files = `git ls-files`.split($/)
|
20
|
+
s.files = `git ls-files`.split($/) - Dir['examples/**/*'] - %w(.gitignore)
|
21
21
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
22
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
23
23
|
s.require_paths = ['lib']
|
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.add_development_dependency 'bundler', '~> 1.5.3'
|
28
28
|
s.add_development_dependency 'rake', '~> 10.1.1'
|
29
29
|
s.add_development_dependency 'rspec', '~> 2.14.1'
|
30
|
-
s.add_development_dependency 'webmock', '~> 1.17.
|
30
|
+
s.add_development_dependency 'webmock', '~> 1.17.4'
|
31
31
|
s.add_development_dependency 'pry-plus', '~> 1.0.0'
|
32
32
|
s.add_development_dependency 'rubocop', '~> 0.18.1'
|
33
33
|
s.add_development_dependency 'flog', '~> 4.2.0'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ClientPages
|
2
2
|
class Configuration
|
3
|
-
attr_accessor :content_path, :remote, :remote_content_path, :caching, :
|
3
|
+
attr_accessor :content_path, :remote, :remote_content_path, :caching, :raw_markdown
|
4
4
|
attr_reader :render_options, :markdown_extensions
|
5
5
|
|
6
6
|
def initialize
|
@@ -10,20 +10,15 @@ module ClientPages
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def render_options=(options)
|
13
|
-
|
13
|
+
render_options.merge!(options)
|
14
14
|
end
|
15
15
|
|
16
16
|
def markdown_extensions=(options)
|
17
|
-
|
17
|
+
markdown_extensions.merge!(options)
|
18
18
|
end
|
19
19
|
|
20
20
|
def to_hash
|
21
|
-
|
22
|
-
{
|
23
|
-
content_path: content_path,
|
24
|
-
render_options: render_options,
|
25
|
-
markdown_extensions: markdown_extensions
|
26
|
-
}
|
21
|
+
Hash[instance_variables.map { |name| [name[1..-1].to_sym, instance_variable_get(name)] }]
|
27
22
|
end
|
28
23
|
end
|
29
24
|
end
|
@@ -41,7 +41,7 @@ module ClientPages
|
|
41
41
|
|
42
42
|
def conditions(tag, line, condition)
|
43
43
|
return yield if condition.nil?
|
44
|
-
if condition.respond_to?(:call) &&
|
44
|
+
if condition.respond_to?(:call) && Matcher.new(tag, line).instance_exec(&condition)
|
45
45
|
yield
|
46
46
|
elsif condition.is_a?(Hash) && Matcher.new(tag, line).match_all?(condition)
|
47
47
|
yield
|
@@ -2,9 +2,9 @@ module ClientPages
|
|
2
2
|
module MarkdownContent
|
3
3
|
class Renderer
|
4
4
|
class << self
|
5
|
-
def render_content(file, options = {})
|
5
|
+
def render_content(file, options = {}, &block)
|
6
6
|
html = new(file, options).html
|
7
|
-
block_given? ?
|
7
|
+
block_given? ? ContentBuilder.new(html).instance_eval(&block) : html.strip
|
8
8
|
rescue OpenURI::HTTPError
|
9
9
|
"404: could not find '#{file}'"
|
10
10
|
rescue Errno::ENOENT
|
@@ -22,7 +22,7 @@ module ClientPages
|
|
22
22
|
|
23
23
|
def html
|
24
24
|
html = html_from_markdown
|
25
|
-
html = template
|
25
|
+
html = template(html) if options.key?(:template)
|
26
26
|
html
|
27
27
|
end
|
28
28
|
|
@@ -40,8 +40,8 @@ module ClientPages
|
|
40
40
|
Redcarpet::Markdown.new(html_renderer, extensions).render(markdown)
|
41
41
|
end
|
42
42
|
|
43
|
-
def template
|
44
|
-
|
43
|
+
def template(html)
|
44
|
+
ContentBuilder.new(html).instance_eval(&Template[options[:template]])
|
45
45
|
end
|
46
46
|
|
47
47
|
def markdown
|
@@ -1,7 +1,21 @@
|
|
1
1
|
module ClientPages
|
2
2
|
class Template
|
3
|
-
|
4
|
-
|
3
|
+
class << self
|
4
|
+
def templates
|
5
|
+
@templates ||= {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def template(name, &settings)
|
9
|
+
templates[name] = Proc.new(&settings)
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](template)
|
13
|
+
templates[template]
|
14
|
+
end
|
15
|
+
|
16
|
+
def templating(&block)
|
17
|
+
instance_eval(&block)
|
18
|
+
end
|
5
19
|
end
|
6
20
|
end
|
7
21
|
end
|
data/lib/client_pages/version.rb
CHANGED
data/lib/client_pages.rb
CHANGED
@@ -14,19 +14,18 @@ module ClientPages
|
|
14
14
|
end
|
15
15
|
|
16
16
|
class << self
|
17
|
+
extend Forwardable
|
17
18
|
attr_accessor :configuration
|
18
19
|
|
20
|
+
def_delegator MarkdownContent::Renderer, :render_content
|
21
|
+
def_delegator Template, :templating
|
22
|
+
|
19
23
|
def config
|
20
24
|
self.configuration ||= Configuration.new
|
21
|
-
block_given? ? yield(configuration) : configuration
|
22
|
-
end
|
23
|
-
|
24
|
-
def template
|
25
|
-
@template ||= {}
|
26
25
|
end
|
27
26
|
|
28
|
-
def
|
29
|
-
yield
|
27
|
+
def configure
|
28
|
+
yield(config)
|
30
29
|
end
|
31
30
|
|
32
31
|
def cache
|
@@ -2,25 +2,25 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module ClientPages
|
4
4
|
describe 'MarkdownContent' do
|
5
|
-
subject { ClientPages
|
5
|
+
subject { ClientPages }
|
6
6
|
|
7
7
|
describe 'invalid path' do
|
8
|
-
before { ClientPages.
|
8
|
+
before { ClientPages.configure { |c| c.content_path = 'not_there' } }
|
9
9
|
it { expect(subject.render_content(:bar)).to eql('No such file or directory - bar') }
|
10
10
|
end
|
11
11
|
|
12
12
|
describe 'valid path' do
|
13
|
-
before { ClientPages.
|
13
|
+
before { ClientPages.configure { |c| c.content_path = 'spec/fixtures/foo' } }
|
14
14
|
it { expect(subject.render_content(:bar)).to eql("<h1>foo</h1>\n\n<p>bar</p>") }
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'blends' do
|
18
18
|
expect(
|
19
|
-
subject.render_content(:test_content) do
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
subject.render_content(:test_content) do
|
20
|
+
modify :h1, with: { class: 'mycss_class', 'data-foo' => 'bar' }, if: -> { includes?('Content') }
|
21
|
+
modify :a, with: { class: 'fancy', title: 'woah' }, if: { href: 'http://somewhere.com' }
|
22
|
+
wrap :h1, :div, with: { id: 'my-id', class: 'foo' }
|
23
|
+
replace :p, :span, with: { class: 'bar', 'data-p' => 'no-more' }
|
24
24
|
end
|
25
25
|
).to eql(
|
26
26
|
"<div id=\"my-id\" class=\"foo\"><h1 class=\"mycss_class\" data-foo=\"bar\">Content from "\
|
@@ -35,7 +35,7 @@ module ClientPages
|
|
35
35
|
let(:markdown) { fixture('test_content') }
|
36
36
|
|
37
37
|
before do
|
38
|
-
ClientPages.
|
38
|
+
ClientPages.configure do |c|
|
39
39
|
c.remote = true
|
40
40
|
c.caching = false
|
41
41
|
c.remote_content_path = 'http://somewhere.com'
|
@@ -53,7 +53,7 @@ module ClientPages
|
|
53
53
|
|
54
54
|
describe 'raw markdown' do
|
55
55
|
before do
|
56
|
-
ClientPages.
|
56
|
+
ClientPages.configure { |c| c.raw_markdown = true }
|
57
57
|
end
|
58
58
|
|
59
59
|
it 'renders HTML content for given markdown' do
|
@@ -78,9 +78,9 @@ module ClientPages
|
|
78
78
|
|
79
79
|
it 'modifies tags and html attributes' do
|
80
80
|
expect(
|
81
|
-
subject.render_content(:test_content) do
|
82
|
-
|
83
|
-
|
81
|
+
subject.render_content(:test_content) do
|
82
|
+
modify :h1, with: { class: 'mycss_class', 'data-foo' => 'bar' }
|
83
|
+
modify :a, with: { class: 'fancy', title: 'woah' }
|
84
84
|
end
|
85
85
|
).to include(
|
86
86
|
'<h1 class="mycss_class" data-foo="bar">'\
|
@@ -91,9 +91,9 @@ module ClientPages
|
|
91
91
|
|
92
92
|
it 'adds attributes conditionally' do
|
93
93
|
expect(
|
94
|
-
subject.render_content(:test_content) do
|
95
|
-
|
96
|
-
|
94
|
+
subject.render_content(:test_content) do
|
95
|
+
modify :h1, with: { class: 'add_me cool' }, if: true
|
96
|
+
modify :a, with: { class: 'add_me_not' }, if: false
|
97
97
|
end
|
98
98
|
).to include(
|
99
99
|
'<h1 class="add_me cool">Content from <a href="http://somewhere.com">somewhere</a></h1>'
|
@@ -102,10 +102,10 @@ module ClientPages
|
|
102
102
|
|
103
103
|
it 'adds any attribute conditionally and selective' do
|
104
104
|
expect(
|
105
|
-
subject.render_content(:link_list) do
|
106
|
-
|
107
|
-
|
108
|
-
|
105
|
+
subject.render_content(:link_list) do
|
106
|
+
modify :li, with: { class: 'yay' }, if: -> { match_any?(:href, '/link1') }
|
107
|
+
modify :a, with: { class: 'active' }, if: { href: '/link2' }
|
108
|
+
modify :a, with: { class: 'important', 'data-foo' => 'bar' }, if: { title: 'i haz title' }
|
109
109
|
end
|
110
110
|
).to include(
|
111
111
|
"<li class=\"yay\"><a href=\"/link1\">link1</a></li>\n"\
|
@@ -116,9 +116,9 @@ module ClientPages
|
|
116
116
|
|
117
117
|
it 'wraps multiple tags with container' do
|
118
118
|
expect(
|
119
|
-
subject.render_content(:text_list) do
|
120
|
-
|
121
|
-
|
119
|
+
subject.render_content(:text_list) do
|
120
|
+
wrap :ul, :div, with: { class: 'wrapper foo' }
|
121
|
+
wrap :em, :span, with: { class: 'special' }, if: -> { includes?('Bar') }
|
122
122
|
end
|
123
123
|
).to eql(
|
124
124
|
"<div class=\"wrapper foo\"><ul>\n"\
|
@@ -130,9 +130,9 @@ module ClientPages
|
|
130
130
|
|
131
131
|
it 'wraps and modifies tags' do
|
132
132
|
expect(
|
133
|
-
subject.render_content(:text_list) do
|
134
|
-
|
135
|
-
|
133
|
+
subject.render_content(:text_list) do
|
134
|
+
wrap :ul, :div, with: { class: 'container' }
|
135
|
+
modify :em, with: { style: 'color: #c0ffee' }
|
136
136
|
end
|
137
137
|
).to eql(
|
138
138
|
"<div class=\"container\"><ul>\n"\
|
@@ -144,9 +144,9 @@ module ClientPages
|
|
144
144
|
|
145
145
|
it 'replaces tags and adds class' do
|
146
146
|
expect(
|
147
|
-
subject.render_content(:test_content) do
|
148
|
-
|
149
|
-
|
147
|
+
subject.render_content(:test_content) do
|
148
|
+
replace :p, :div, with: { class: 'byebye' }
|
149
|
+
replace :em, :span, with: { id: 'i-am', class: 'cool', 'data-u' => 'r-not' }
|
150
150
|
end
|
151
151
|
).to eql(
|
152
152
|
"<h1>Content from <a href=\"http://somewhere.com\">somewhere</a></h1>\n\n"\
|
@@ -159,10 +159,10 @@ module ClientPages
|
|
159
159
|
|
160
160
|
it 'wraps and replaces conditionally' do
|
161
161
|
expect(
|
162
|
-
subject.render_content(:test_content) do
|
163
|
-
|
164
|
-
|
165
|
-
|
162
|
+
subject.render_content(:test_content) do
|
163
|
+
wrap :a, :span, with: { class: 'btn' }, if: { href: 'http://somewhere.com' }
|
164
|
+
replace :p, :div, if: -> { includes?('Lorem') }
|
165
|
+
replace :em, :span, with: { class: 'replaced' }, if: -> { includes?('incididunt') }
|
166
166
|
end
|
167
167
|
).to eql(
|
168
168
|
"<h1>Content from <span class=\"btn\"><a href=\"http://somewhere.com\">somewhere</a></span></h1>\n\n"\
|
@@ -174,11 +174,11 @@ module ClientPages
|
|
174
174
|
|
175
175
|
describe 'with caching' do
|
176
176
|
before(:each) { ClientPages.cache.clear }
|
177
|
-
after { ClientPages.
|
177
|
+
after { ClientPages.configure { |c| c.caching = false } }
|
178
178
|
|
179
179
|
context 'enabled' do
|
180
180
|
before do
|
181
|
-
ClientPages.
|
181
|
+
ClientPages.configure do |c|
|
182
182
|
c.caching = true
|
183
183
|
c.remote = true
|
184
184
|
c.remote_content_path = 'http://c.ly'
|
@@ -203,7 +203,7 @@ module ClientPages
|
|
203
203
|
|
204
204
|
context 'disabled' do
|
205
205
|
before do
|
206
|
-
ClientPages.
|
206
|
+
ClientPages.configure do |c|
|
207
207
|
c.caching = false
|
208
208
|
c.remote = true
|
209
209
|
c.remote_content_path = 'http://c.ly'
|
@@ -226,19 +226,19 @@ module ClientPages
|
|
226
226
|
|
227
227
|
describe 'default templates' do
|
228
228
|
before do
|
229
|
-
ClientPages.
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
229
|
+
ClientPages.templating do
|
230
|
+
template :basic do
|
231
|
+
modify :h1, with: { class: 'headers' }
|
232
|
+
wrap :a, :span, with: { class: 'links' }, if: -> { includes?('somewhere') }
|
233
|
+
replace :p, :div
|
234
234
|
end
|
235
235
|
end
|
236
236
|
end
|
237
237
|
|
238
238
|
it 'uses templates and accepts additional block' do
|
239
239
|
expect(
|
240
|
-
subject.render_content(:test_content, template: :basic) do
|
241
|
-
|
240
|
+
subject.render_content(:test_content, template: :basic) do
|
241
|
+
modify :h1, with: { 'data-foo' => 'bar' }
|
242
242
|
end
|
243
243
|
).to eql(
|
244
244
|
"<h1 class=\"headers\" data-foo=\"bar\">Content from <span class=\"links\">"\
|
@@ -256,7 +256,7 @@ module ClientPages
|
|
256
256
|
|
257
257
|
it 'is configurable with a block' do
|
258
258
|
expect {
|
259
|
-
subject.
|
259
|
+
subject.configure do |c|
|
260
260
|
c.content_path = 'somewhere'
|
261
261
|
c.render_options = { foo: 'bar' }
|
262
262
|
c.markdown_extensions = { bam: true }
|
data/spec/spec_helper.rb
CHANGED
data/spec/unit/template_spec.rb
CHANGED
@@ -1,16 +1,29 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
module ClientPages
|
4
|
-
describe
|
5
|
-
|
4
|
+
describe Template do
|
5
|
+
subject { described_class }
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
describe '#template' do
|
8
|
+
before do
|
9
|
+
subject.template(:foo) { |args| 'foobar' + args }
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'saves a referenceable block with arguments' do
|
13
|
+
expect(subject.templates[:foo].call('bam')).to eql('foobarbam')
|
14
|
+
end
|
10
15
|
end
|
11
16
|
|
12
|
-
|
13
|
-
|
17
|
+
context 'in a templating block' do
|
18
|
+
before do
|
19
|
+
subject.templating do
|
20
|
+
template(:bar) { '42' }
|
21
|
+
template(:baz) { 'yay' }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it { expect(subject[:bar].call).to eql('42') }
|
26
|
+
it { expect(subject[:baz].call).to eql('yay') }
|
14
27
|
end
|
15
28
|
end
|
16
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: client_pages
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marco Schaden
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redcarpet
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - ~>
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 1.17.
|
75
|
+
version: 1.17.4
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ~>
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 1.17.
|
82
|
+
version: 1.17.4
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: pry-plus
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,7 +146,6 @@ executables: []
|
|
146
146
|
extensions: []
|
147
147
|
extra_rdoc_files: []
|
148
148
|
files:
|
149
|
-
- .gitignore
|
150
149
|
- .rubocop.yml
|
151
150
|
- Gemfile
|
152
151
|
- LICENSE.txt
|
@@ -186,9 +185,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
186
185
|
version: '0'
|
187
186
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
187
|
requirements:
|
189
|
-
- - '
|
188
|
+
- - '>='
|
190
189
|
- !ruby/object:Gem::Version
|
191
|
-
version:
|
190
|
+
version: '0'
|
192
191
|
requirements: []
|
193
192
|
rubyforge_project:
|
194
193
|
rubygems_version: 2.1.11
|
data/.gitignore
DELETED