jenner 0.0.3 → 0.2.6
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.
- data/README.md +158 -11
- data/bin/jenner +9 -0
- data/jenner.gemspec +1 -0
- data/lib/jenner.rb +35 -0
- data/lib/jenner/asset.rb +52 -0
- data/lib/jenner/item.rb +87 -20
- data/lib/jenner/liquid_filters.rb +56 -0
- data/lib/jenner/site.rb +52 -21
- data/lib/jenner/tag.rb +24 -0
- data/lib/jenner/template.rb +22 -5
- data/lib/jenner/template_file_system.rb +9 -4
- data/lib/jenner/version.rb +1 -1
- data/test/fixtures/source/_site/_hidden.html +8 -0
- data/test/fixtures/source/_site/blog/20140128_test_post.markdown +8 -0
- data/test/fixtures/source/_site/embed_test.html +7 -0
- data/test/fixtures/source/_site/foo.txt +0 -0
- data/test/fixtures/source/_site/haml_test.haml +9 -0
- data/test/fixtures/source/_site/markdown_test.markdown +3 -1
- data/test/fixtures/source/_site/subdirectory/subfile.html +1 -2
- data/test/fixtures/source/_site/test.html +1 -1
- data/test/fixtures/source/_templates/haml_template.haml +1 -0
- data/test/fixtures/source/_templates/post.html +1 -0
- data/test/fixtures/source/_templates/simple.html +1 -1
- data/test/fixtures/source/_templates/wrapper.html +1 -1
- data/test/jenner/test_asset.rb +50 -0
- data/test/jenner/test_item.rb +63 -8
- data/test/jenner/test_liquid_filters.rb +76 -0
- data/test/jenner/test_site.rb +12 -0
- data/test/jenner/test_tag.rb +22 -0
- data/test/jenner/test_template.rb +38 -1
- metadata +39 -2
data/README.md
CHANGED
|
@@ -34,30 +34,58 @@ Your generated site will be in `./public`.
|
|
|
34
34
|
|
|
35
35
|
### Items
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Items can be created as HTML or [Haml](http://haml.info/) files.
|
|
38
|
+
|
|
39
|
+
Here's an example HTML item:
|
|
38
40
|
|
|
39
41
|
---
|
|
40
42
|
title: 'Example Page'
|
|
41
43
|
date: 2014-01-23 17:02:00 -6
|
|
42
|
-
template: 'page'
|
|
44
|
+
template: 'page.html'
|
|
43
45
|
---
|
|
44
46
|
|
|
47
|
+
<h1>{{self.title}}</h1>
|
|
45
48
|
<p>This is an example page.</p>
|
|
46
49
|
|
|
50
|
+
Here's the same example using Haml + Liquid:
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
title: 'Example Page'
|
|
54
|
+
date: 2014-01-23 17:02:00 -6
|
|
55
|
+
template: 'page.html'
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
%h1 {{self.title}}
|
|
59
|
+
%p This is an example page.
|
|
60
|
+
|
|
61
|
+
Here's the same example using Haml directly, not Liquid:
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
title: 'Example Page'
|
|
65
|
+
date: 2014-01-23 17:02:00 -6
|
|
66
|
+
template: 'page.html'
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
%h1= self.title
|
|
70
|
+
%p This is an example page.
|
|
71
|
+
|
|
72
|
+
It's your choice: HTML, HTML + Liquid, Haml, Haml+ Liquid.
|
|
73
|
+
|
|
47
74
|
This item will be rendered using the `page` template. The `page`
|
|
48
75
|
template can use the following data:
|
|
49
76
|
|
|
50
77
|
{{item.title}} => "Example Page"
|
|
51
78
|
{{item.data}} => 2014-01-23 17:02:00 -6
|
|
52
|
-
{{item.
|
|
79
|
+
{{item.template_path}} => "page.html"
|
|
53
80
|
{{item.body}} => "<p>This is an example page.</p>
|
|
81
|
+
{{item.url}} => "/example.html"
|
|
54
82
|
|
|
55
83
|
You can define additional pieces of data in the item header like this:
|
|
56
84
|
|
|
57
85
|
---
|
|
58
86
|
title: 'Example Page'
|
|
59
87
|
date: 2014-01-23 17:02:00 -6
|
|
60
|
-
template: 'page'
|
|
88
|
+
template: 'page.html'
|
|
61
89
|
foo: 'bar'
|
|
62
90
|
answer: 42
|
|
63
91
|
---
|
|
@@ -74,31 +102,150 @@ they will be processed as Markdown.
|
|
|
74
102
|
---
|
|
75
103
|
title: 'Example Markdown Page'
|
|
76
104
|
date: 2014-01-23 17:02:00 -6
|
|
77
|
-
template: 'page'
|
|
105
|
+
template: 'page.html'
|
|
78
106
|
---
|
|
79
107
|
|
|
80
108
|
# This is an example page
|
|
81
109
|
|
|
82
|
-
|
|
83
110
|
### Templates
|
|
84
111
|
|
|
85
|
-
Templates are just HTML files that use
|
|
86
|
-
create is rendered with a template that
|
|
87
|
-
header.
|
|
112
|
+
Templates are just HTML or [Haml](http://haml.info/) files that use
|
|
113
|
+
Liquid markup. Every item you create is rendered with a template that
|
|
114
|
+
you specify in the item's header via the `template` attribute.
|
|
115
|
+
|
|
116
|
+
Haml templates can use Liquid, but they don't have to. You could simply
|
|
117
|
+
use the template's context in Haml:
|
|
118
|
+
|
|
119
|
+
%h1= item.title
|
|
120
|
+
= item.body
|
|
121
|
+
|
|
122
|
+
instead of:
|
|
123
|
+
|
|
124
|
+
%h1 {{item.title}}
|
|
125
|
+
{{item.body}}
|
|
88
126
|
|
|
89
127
|
Every item provides the following data at minimum:
|
|
90
128
|
|
|
91
129
|
{{item.title}}
|
|
92
130
|
{{item.date}}
|
|
93
|
-
{{item.
|
|
131
|
+
{{item.template_path}}
|
|
94
132
|
{{item.body}}
|
|
133
|
+
{{item.url}}
|
|
134
|
+
{{site}}
|
|
95
135
|
|
|
96
136
|
Additional pieces of data are available within `{{item.data}}` if they
|
|
97
137
|
are defined in the item's YAML header.
|
|
98
138
|
|
|
99
139
|
You can include other templates with the `{% include %}` tag.
|
|
100
140
|
|
|
101
|
-
{% include '
|
|
141
|
+
{% include 'header.html' %}
|
|
142
|
+
{{item.body}}
|
|
143
|
+
{% include 'footer.html' %}
|
|
144
|
+
|
|
145
|
+
### Assets
|
|
146
|
+
|
|
147
|
+
All your other files/subdirectories will be copied over as-is with two
|
|
148
|
+
exceptions:
|
|
149
|
+
|
|
150
|
+
1. [Sass](http://sass-lang.com/) `.scss` files will be processed and copied over as `.css`
|
|
151
|
+
2. Filenames starting with _ will be ignored (e.g. _hidden.html)
|
|
152
|
+
|
|
153
|
+
### Tags
|
|
154
|
+
|
|
155
|
+
Tags are a special addition to the YAML header. You can specify them as
|
|
156
|
+
a YAML string array e.g.:
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
title: 'Example Page'
|
|
160
|
+
date: 2014-01-23 17:02:00 -6
|
|
161
|
+
template: 'page.html'
|
|
162
|
+
tags: [one, two, three]
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
You will have access to the tag names in {{item.tags}}. You can also get
|
|
166
|
+
a tag by name with a Liquid filter.
|
|
167
|
+
|
|
168
|
+
{{ 'one' | tag | assign_to: my_tag }}
|
|
169
|
+
|
|
170
|
+
{% for item in my_tag.items %}
|
|
171
|
+
{{item.body}}
|
|
172
|
+
{% endfor %}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
### Other Liquid Filters
|
|
176
|
+
|
|
177
|
+
I personally dislike having to write specialized plugins or generators
|
|
178
|
+
to generate my site. By simply adding a couple of filters to Liquid, we
|
|
179
|
+
can easily do just about anything on the item/page level without having
|
|
180
|
+
to write anymore outside Ruby.
|
|
181
|
+
|
|
182
|
+
<h1>Page rendering two items</h1>
|
|
183
|
+
{{ 'item_one.html' | item_from_path | assign_to: item_one }}
|
|
184
|
+
{{ 'item_two.html' | item_from_path | assign_to: item_two }}
|
|
185
|
+
|
|
186
|
+
<table>
|
|
187
|
+
<tr>
|
|
188
|
+
<th>{{item_one.title}}</th>
|
|
189
|
+
<th>{{item_two.title}}</th>
|
|
190
|
+
</tr>
|
|
191
|
+
<tr>
|
|
192
|
+
<td>{{item_one.body}}</td>
|
|
193
|
+
<td>{{item_two.body}}</td>
|
|
194
|
+
</tr>
|
|
195
|
+
<table>
|
|
196
|
+
|
|
197
|
+
<h1>Bunch of items</h1>
|
|
198
|
+
{{ 'blog\/' | items_from_path | assign_to: blog_posts }}
|
|
199
|
+
{% for blog_post in blog_posts %}
|
|
200
|
+
do something with {{blog_post}} here
|
|
201
|
+
{% endfor %}
|
|
202
|
+
|
|
203
|
+
Some other useful helpers:
|
|
204
|
+
|
|
205
|
+
{{ 'test.css' | stylesheet_tag }}
|
|
206
|
+
{{ 'test.js' | javascript_tag }}
|
|
207
|
+
{{ 'page_one.html' | item_from_path | link_to }}
|
|
208
|
+
{{ 'test.gif' | asset_from_path | assign_to: my_image }}
|
|
209
|
+
<img src="{{my_image.url}}" />
|
|
210
|
+
|
|
211
|
+
You can also use a couple of filters to grab items by custom data or
|
|
212
|
+
custom data and value combination. For example, say you have a few items
|
|
213
|
+
with an author attribute.
|
|
214
|
+
|
|
215
|
+
{{'author' | items_with_data | assign_to: items_with_author_defined}}
|
|
216
|
+
|
|
217
|
+
Or maybe you just want a certain author:
|
|
218
|
+
|
|
219
|
+
{{'author' | items_with_data: 'Mark Twain' | assign_to: items_twain_wrote }}
|
|
220
|
+
|
|
221
|
+
If the custom data you created can be an array, it works on that too:
|
|
222
|
+
|
|
223
|
+
{{'favorite_colors' | items_with_data: 'blue' | assign_to: items_who_like_blue_and_possibly_other_colors }}
|
|
224
|
+
|
|
225
|
+
### Custom URL Formatting
|
|
226
|
+
|
|
227
|
+
By default, all items will be copied over as-is e.g. if your item
|
|
228
|
+
resides in /blog/2014/0128_test_post.html it will end up in
|
|
229
|
+
/public/blog/2014/0128_test_post.html.
|
|
230
|
+
|
|
231
|
+
You can specify a custom url_format parameter in your YAML item header.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
title: 'test post'
|
|
235
|
+
date: 2014-01-28 15:23:00 -6
|
|
236
|
+
template: 'post.html'
|
|
237
|
+
url_format: '%Y/%m/%d/:title'
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
The formatting will be relative to whatever directory the file resides
|
|
241
|
+
in, and will be processed by using [Ruby's Time#strftime](http://www.ruby-doc.org/core-1.9.3/Time.html#method-i-strftime)
|
|
242
|
+
method on the item's date, and `:title` will be replaced with an
|
|
243
|
+
underscored version of your site's title.
|
|
244
|
+
|
|
245
|
+
If the above example post resides in /blog, the output file will go to:
|
|
246
|
+
/public/blog/2014/01/28/test-post/index.html. The `{{item.url}}`
|
|
247
|
+
parameter will not include the index.html to keep things pretty. It will
|
|
248
|
+
be: `/blog/2014/01/28/test-post`.
|
|
102
249
|
|
|
103
250
|
|
|
104
251
|
## Contributing
|
data/bin/jenner
CHANGED
|
@@ -17,4 +17,13 @@ Mercenary.program(:jenner) do |p|
|
|
|
17
17
|
Jenner.build(args, options)
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
|
+
|
|
21
|
+
p.command(:serve) do |c|
|
|
22
|
+
c.syntax "jenner serve"
|
|
23
|
+
c.description "Serve your Jenner site"
|
|
24
|
+
|
|
25
|
+
c.action do |args, options|
|
|
26
|
+
Jenner.serve(args, options)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
20
29
|
end
|
data/jenner.gemspec
CHANGED
|
@@ -17,6 +17,7 @@ Gem::Specification.new do |gem|
|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
18
18
|
gem.require_paths = ["lib"]
|
|
19
19
|
|
|
20
|
+
gem.add_dependency "haml", "~> 4.0.5"
|
|
20
21
|
gem.add_dependency "liquid", "~> 2.6.1"
|
|
21
22
|
gem.add_dependency "maruku", "~> 0.7.1"
|
|
22
23
|
gem.add_dependency "mercenary", "~> 0.2.1"
|
data/lib/jenner.rb
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
require "bundler/setup"
|
|
2
|
+
require "haml"
|
|
2
3
|
require "liquid"
|
|
3
4
|
require "maruku"
|
|
5
|
+
require "ostruct"
|
|
4
6
|
require "sass"
|
|
7
|
+
require "webrick"
|
|
5
8
|
|
|
9
|
+
require "jenner/asset"
|
|
6
10
|
require "jenner/item"
|
|
11
|
+
require "jenner/liquid_filters"
|
|
7
12
|
require "jenner/site"
|
|
13
|
+
require "jenner/tag"
|
|
8
14
|
require "jenner/template"
|
|
9
15
|
require "jenner/template_file_system"
|
|
10
16
|
require "jenner/version"
|
|
@@ -15,4 +21,33 @@ module Jenner
|
|
|
15
21
|
puts "Building a site at #{@site.root}"
|
|
16
22
|
@site.generate!
|
|
17
23
|
end
|
|
24
|
+
|
|
25
|
+
def self.serve(args, options={})
|
|
26
|
+
root = File.expand_path("./public")
|
|
27
|
+
if Dir.exists?(root)
|
|
28
|
+
puts "Starting server on port 9191"
|
|
29
|
+
server = WEBrick::HTTPServer.new :Port => 9191, :DocumentRoot => root
|
|
30
|
+
trap 'INT' do server.shutdown end
|
|
31
|
+
|
|
32
|
+
server.start
|
|
33
|
+
else
|
|
34
|
+
puts "Site does not appear to be built. Run 'jenner build' first"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.deep_struct(obj)
|
|
39
|
+
case obj
|
|
40
|
+
when Hash
|
|
41
|
+
obj = obj.clone
|
|
42
|
+
obj.each do |key,value|
|
|
43
|
+
obj[key] = Jenner.deep_struct(value)
|
|
44
|
+
end
|
|
45
|
+
OpenStruct.new(obj)
|
|
46
|
+
when Array
|
|
47
|
+
obj = obj.clone
|
|
48
|
+
obj.map! {|i| Jenner.deep_struct(i) }
|
|
49
|
+
else
|
|
50
|
+
obj
|
|
51
|
+
end
|
|
52
|
+
end
|
|
18
53
|
end
|
data/lib/jenner/asset.rb
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Jenner
|
|
2
|
+
class Asset
|
|
3
|
+
attr_reader :path
|
|
4
|
+
def initialize(path, site)
|
|
5
|
+
@path = path
|
|
6
|
+
@site = site
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def filename
|
|
10
|
+
File.basename(@path)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def sass?
|
|
14
|
+
File.extname(filename) == ".scss"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def output_filename
|
|
18
|
+
sass? ? filename.sub(".scss",".css") : filename
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def source_path
|
|
22
|
+
File.join(@site.root,"_site",@path)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def output_path
|
|
26
|
+
@path.sub(filename, output_filename)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def url
|
|
30
|
+
"/#{output_path}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def public_path
|
|
34
|
+
File.join(@site.root,"public", output_path)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def to_liquid
|
|
38
|
+
{
|
|
39
|
+
'url' => url
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def generate!
|
|
44
|
+
if sass?
|
|
45
|
+
engine = Sass::Engine.new(File.read(source_path), syntax: :scss)
|
|
46
|
+
File.write(public_path, engine.render)
|
|
47
|
+
else
|
|
48
|
+
FileUtils.cp source_path, public_path
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
data/lib/jenner/item.rb
CHANGED
|
@@ -1,64 +1,131 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
1
2
|
module Jenner
|
|
2
3
|
class Item
|
|
3
|
-
attr_reader :
|
|
4
|
-
def initialize(
|
|
5
|
-
@
|
|
4
|
+
attr_reader :title, :date, :template_path, :data, :tags
|
|
5
|
+
def initialize(path, site)
|
|
6
|
+
@path = path
|
|
6
7
|
@site = site
|
|
7
8
|
|
|
8
|
-
@body = File.read(File.join(@site.root,'_site',@
|
|
9
|
+
@body = File.read(File.join(@site.root,'_site',@path))
|
|
9
10
|
|
|
10
11
|
if @body =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
|
11
12
|
@body = $'
|
|
12
13
|
@header = YAML.load($1)
|
|
13
14
|
end
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
begin
|
|
17
|
+
@title = @header.delete("title")
|
|
18
|
+
@date = @header.delete("date")
|
|
19
|
+
@template_path = @header.delete("template")
|
|
20
|
+
@tags = @header.delete("tags") || []
|
|
21
|
+
@url_format = @header.delete("url_format")
|
|
22
|
+
@data = @header
|
|
23
|
+
rescue Exception => e
|
|
24
|
+
raise "Invalid header data on item at path: #{@path}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def relative_path
|
|
29
|
+
path = File.dirname(@path)
|
|
30
|
+
return "" if path == "."
|
|
31
|
+
|
|
32
|
+
"#{path}/"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def local_path
|
|
36
|
+
@path
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def path
|
|
40
|
+
return @path if @url_format.nil?
|
|
41
|
+
|
|
42
|
+
if File.extname(url) == ""
|
|
43
|
+
"#{url}/index.html"
|
|
44
|
+
else
|
|
45
|
+
url
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def output_filename
|
|
50
|
+
return "index.html" if File.extname(url) == ""
|
|
51
|
+
|
|
52
|
+
File.basename(@path).sub(".markdown",".html")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def input_filename
|
|
56
|
+
File.extname(@path)
|
|
20
57
|
end
|
|
21
58
|
|
|
22
59
|
def url
|
|
23
|
-
"/#{@
|
|
60
|
+
@url_format.nil? ? "/#{@path.sub(".markdown",".html")}" : formatted_url
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def underscored_title
|
|
64
|
+
@title.gsub(/[^\w]+/,"-").downcase
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def formatted_url
|
|
68
|
+
"/#{relative_path}#{@date.strftime(@url_format).gsub(":title", underscored_title)}"
|
|
24
69
|
end
|
|
25
70
|
|
|
26
71
|
def template
|
|
27
|
-
Jenner::Template.from_file(File.join(@site.root,'_templates',"#{@
|
|
72
|
+
Jenner::Template.from_file(File.join(@site.root,'_templates',"#{@template_path}"), @site)
|
|
28
73
|
end
|
|
29
74
|
|
|
30
|
-
def
|
|
75
|
+
def to_liquid_without_body
|
|
31
76
|
{
|
|
32
77
|
'title' => @title,
|
|
33
78
|
'date' => @date,
|
|
34
|
-
'
|
|
79
|
+
'template_path' => @template_path,
|
|
35
80
|
'tags' => @tags,
|
|
36
81
|
'data' => @data,
|
|
37
|
-
'url' => url
|
|
82
|
+
'url' => url,
|
|
83
|
+
'site' => @site
|
|
38
84
|
}
|
|
39
85
|
end
|
|
40
86
|
|
|
41
|
-
def
|
|
42
|
-
|
|
87
|
+
def to_liquid
|
|
88
|
+
to_liquid_without_body.merge(
|
|
89
|
+
'body' => body
|
|
90
|
+
)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def markdown?
|
|
94
|
+
File.extname(@path) == ".markdown"
|
|
95
|
+
end
|
|
43
96
|
|
|
44
|
-
|
|
97
|
+
def haml?
|
|
98
|
+
File.extname(@path) == ".haml"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def liquid_body
|
|
102
|
+
Liquid::Template.parse(@body).render({'self' => self.to_liquid_without_body}, registers: { site: @site })
|
|
45
103
|
end
|
|
46
104
|
|
|
47
105
|
def body
|
|
48
|
-
|
|
106
|
+
if haml?
|
|
107
|
+
Haml::Engine.new(liquid_body).render(Jenner.deep_struct(self.to_liquid_without_body), :site => Jenner.deep_struct(@site.to_liquid))
|
|
108
|
+
elsif markdown?
|
|
109
|
+
Maruku.new(liquid_body).to_html
|
|
110
|
+
else
|
|
111
|
+
liquid_body
|
|
112
|
+
end
|
|
49
113
|
end
|
|
50
114
|
|
|
51
115
|
def render
|
|
52
116
|
template.render(
|
|
53
|
-
'item' => self.to_liquid
|
|
117
|
+
'item' => self.to_liquid
|
|
54
118
|
)
|
|
55
119
|
end
|
|
56
120
|
|
|
57
121
|
def public_path
|
|
58
|
-
File.join(@site.root,'public'
|
|
122
|
+
File.join(@site.root,'public',path.sub('.markdown','.html').sub(".haml",".html"))
|
|
59
123
|
end
|
|
60
124
|
|
|
61
125
|
def generate!
|
|
126
|
+
return if File.basename(public_path)[0] == "_"
|
|
127
|
+
|
|
128
|
+
FileUtils.mkdir_p(File.dirname(public_path))
|
|
62
129
|
File.write(public_path,render)
|
|
63
130
|
end
|
|
64
131
|
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Jenner
|
|
2
|
+
module LiquidFilters
|
|
3
|
+
|
|
4
|
+
def asset_from_path(path)
|
|
5
|
+
@context.registers[:site].assets.find { |asset| asset.path == path } || "Asset with path '#{path}' not found"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def item_from_path(path)
|
|
9
|
+
@context.registers[:site].items.find { |item| item.local_path == path } || "Item with path '#{path}' not found"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def items_from_path(path)
|
|
13
|
+
@context.registers[:site].items.select {|item| item.local_path =~ /^#{path}/ } || []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def tag(name)
|
|
17
|
+
@context.registers[:site].tags.find { |tag| tag.name == name } || "Tag with name '#{name}' not found"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def items_with_data(key, value=nil)
|
|
21
|
+
key_matches = @context.registers[:site].items.select { |item|
|
|
22
|
+
item.data.keys.include?(key)
|
|
23
|
+
}
|
|
24
|
+
return key_matches if value.nil?
|
|
25
|
+
|
|
26
|
+
# value was provided
|
|
27
|
+
key_matches.select do |item|
|
|
28
|
+
if item.data[key].is_a?(Array)
|
|
29
|
+
item.data[key].include?(value)
|
|
30
|
+
else
|
|
31
|
+
item.data[key] == value
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def assign_to(value, name)
|
|
37
|
+
@context[name] = value
|
|
38
|
+
nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def stylesheet_tag(path)
|
|
42
|
+
%(<link href="#{path}" media="all" rel="stylesheet" type="text/css" />)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def javascript_tag(path)
|
|
46
|
+
%(<script type="text/javascript" src="#{path}"></script>)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def link_to(item)
|
|
50
|
+
%(<a href="#{item.url}">#{item.title}</a>)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
Liquid::Template.register_filter(Jenner::LiquidFilters)
|
data/lib/jenner/site.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
1
2
|
module Jenner
|
|
2
3
|
class Site
|
|
3
4
|
attr_reader :root
|
|
@@ -7,22 +8,45 @@ module Jenner
|
|
|
7
8
|
Liquid::Template.file_system = Jenner::TemplateFileSystem.new(File.join(@root,'_templates'))
|
|
8
9
|
end
|
|
9
10
|
|
|
11
|
+
def to_liquid
|
|
12
|
+
{
|
|
13
|
+
'root' => @root,
|
|
14
|
+
'assets' => assets,
|
|
15
|
+
'items' => items,
|
|
16
|
+
'tag_names' => tag_names,
|
|
17
|
+
'tags' => tags
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
|
|
10
21
|
def site_path
|
|
11
22
|
File.join(@root,"_site")
|
|
12
23
|
end
|
|
13
24
|
|
|
14
|
-
def
|
|
15
|
-
Dir.glob(File.join(site_path,"
|
|
16
|
-
|
|
25
|
+
def all_files
|
|
26
|
+
@all_files ||= Dir.glob(File.join(site_path,"**","*.*"))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def item_files
|
|
30
|
+
@item_files ||= all_files.select {|f| ['.html','.markdown'].include? File.extname(f) }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def asset_files
|
|
34
|
+
@asset_files ||= all_files - item_files
|
|
17
35
|
end
|
|
18
36
|
|
|
19
37
|
def relative_path(item)
|
|
20
38
|
(item.split("/") - site_path.split("/")).join("/")
|
|
21
39
|
end
|
|
22
40
|
|
|
41
|
+
def assets
|
|
42
|
+
@assets ||= asset_files.inject([]) { |a,asset|
|
|
43
|
+
a << Jenner::Asset.new(relative_path(asset), self)
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
|
|
23
47
|
def items
|
|
24
|
-
|
|
25
|
-
a << Jenner::Item.new(relative_path(
|
|
48
|
+
@items ||= item_files.inject([]) { |a, item|
|
|
49
|
+
a << Jenner::Item.new(relative_path(item), self)
|
|
26
50
|
}
|
|
27
51
|
end
|
|
28
52
|
|
|
@@ -38,30 +62,37 @@ module Jenner
|
|
|
38
62
|
site_dir.split("/")
|
|
39
63
|
end
|
|
40
64
|
|
|
65
|
+
def tag_names
|
|
66
|
+
@tag_names ||= items.inject([]) {|a,i|
|
|
67
|
+
a << i.tags
|
|
68
|
+
}.flatten.uniq
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def tags
|
|
72
|
+
@tags ||= tag_names.inject([]) { |a,tag|
|
|
73
|
+
a << Jenner::Tag.new(tag, self)
|
|
74
|
+
}
|
|
75
|
+
end
|
|
76
|
+
|
|
41
77
|
def relative_path_to_public(item)
|
|
42
78
|
(item.split("/") - site_dirs).join("/")
|
|
43
79
|
end
|
|
44
80
|
|
|
81
|
+
def create_directories!
|
|
82
|
+
Dir.glob(File.join(@root,"_site","**")).each do |dir|
|
|
83
|
+
next unless File.directory?(dir)
|
|
84
|
+
|
|
85
|
+
FileUtils.mkdir_p(File.join(public_dir,relative_path_to_public(dir)))
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
45
89
|
def generate!
|
|
46
90
|
FileUtils.rm_rf(public_dir)
|
|
47
91
|
FileUtils.mkdir(public_dir)
|
|
48
92
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
FileUtils.mkdir_p(File.join(public_dir,relative_path_to_public(item)))
|
|
53
|
-
else
|
|
54
|
-
next if [".html",".markdown"].include? File.extname(item)
|
|
55
|
-
if File.extname(item) == ".scss"
|
|
56
|
-
engine = Sass::Engine.new(File.read(item), :syntax => :scss)
|
|
57
|
-
item = item.sub(".scss",".css")
|
|
58
|
-
File.write(File.join(public_dir,relative_path_to_public(item)),engine.render)
|
|
59
|
-
else
|
|
60
|
-
destination = File.join(public_dir,relative_path_to_public(item))
|
|
61
|
-
FileUtils.cp item, destination
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
93
|
+
create_directories!
|
|
94
|
+
|
|
95
|
+
assets.map(&:generate!)
|
|
65
96
|
items.map(&:generate!)
|
|
66
97
|
end
|
|
67
98
|
end
|
data/lib/jenner/tag.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Jenner
|
|
2
|
+
class Tag
|
|
3
|
+
attr_reader :name
|
|
4
|
+
def initialize(name, site)
|
|
5
|
+
@name = name
|
|
6
|
+
@site = site
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def items
|
|
10
|
+
@items ||= @site.items.select { |item|
|
|
11
|
+
item.tags.include?(@name)
|
|
12
|
+
}.inject([]) {|a, item|
|
|
13
|
+
a << item
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_liquid
|
|
18
|
+
{
|
|
19
|
+
"name" => @name,
|
|
20
|
+
"items" => items
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/jenner/template.rb
CHANGED
|
@@ -1,17 +1,34 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
1
2
|
module Jenner
|
|
2
3
|
class Template
|
|
3
|
-
|
|
4
|
-
def initialize(body, site)
|
|
4
|
+
def initialize(body, site, options={})
|
|
5
5
|
@body = body
|
|
6
6
|
@site = site
|
|
7
|
+
@haml = options[:haml]
|
|
7
8
|
end
|
|
8
9
|
|
|
9
|
-
def
|
|
10
|
-
|
|
10
|
+
def haml?
|
|
11
|
+
@haml
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def body(context={})
|
|
15
|
+
haml? ? Haml::Engine.new(@body).render(Jenner.deep_struct(context)) : @body
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def render(context={})
|
|
19
|
+
Liquid::Template.parse(body(context.merge('site' => @site))).render(context.merge('site' => @site), registers: { site: @site }).to_s.encode("utf-8")
|
|
11
20
|
end
|
|
12
21
|
|
|
13
22
|
def self.from_file(file_path, site)
|
|
14
|
-
|
|
23
|
+
if File.extname(file_path) != ".haml"
|
|
24
|
+
new(File.read(file_path), site)
|
|
25
|
+
else
|
|
26
|
+
from_haml(File.read(file_path), site)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.from_haml(haml_body, site)
|
|
31
|
+
new(haml_body, site, haml: true)
|
|
15
32
|
end
|
|
16
33
|
end
|
|
17
34
|
end
|
|
@@ -1,20 +1,25 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
1
2
|
module Jenner
|
|
2
3
|
class TemplateFileSystem
|
|
3
4
|
attr_reader :root
|
|
4
5
|
def initialize(root)
|
|
5
6
|
@root = root
|
|
6
|
-
@pattern = "%s
|
|
7
|
+
@pattern = "%s"
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def read_template_file(template_path, context)
|
|
10
11
|
full_path = full_path(template_path)
|
|
11
12
|
raise FileSystemError, "No such template '#{template_path}'" unless File.exists?(full_path)
|
|
12
13
|
|
|
13
|
-
File.
|
|
14
|
+
if File.extname(template_path) == ".haml"
|
|
15
|
+
Haml::Engine.new(File.read(full_path)).render(Jenner.deep_struct(context.environments.first))
|
|
16
|
+
else
|
|
17
|
+
File.read(full_path)
|
|
18
|
+
end
|
|
14
19
|
end
|
|
15
20
|
|
|
16
21
|
def full_path(template_path)
|
|
17
|
-
raise FileSystemError, "Illegal template name '#{template_path}'" unless template_path =~ /^[^.\/][a-zA-Z0-9_\/]+$/
|
|
22
|
+
#raise Liquid::FileSystemError, "Illegal template name '#{template_path}'" unless template_path =~ /^[^.\/][a-zA-Z0-9_\/]+$/
|
|
18
23
|
|
|
19
24
|
full_path = if template_path.include?('/')
|
|
20
25
|
File.join(root, File.dirname(template_path), @pattern % File.basename(template_path))
|
|
@@ -22,7 +27,7 @@ module Jenner
|
|
|
22
27
|
File.join(root, @pattern % template_path)
|
|
23
28
|
end
|
|
24
29
|
|
|
25
|
-
raise FileSystemError, "Illegal template path '#{File.expand_path(full_path)}'" unless File.expand_path(full_path) =~ /^#{File.expand_path(root)}/
|
|
30
|
+
raise Liquid::FileSystemError, "Illegal template path '#{File.expand_path(full_path)}'" unless File.expand_path(full_path) =~ /^#{File.expand_path(root)}/
|
|
26
31
|
|
|
27
32
|
full_path
|
|
28
33
|
end
|
data/lib/jenner/version.rb
CHANGED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
%p #{item.body}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{item.body}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
item: {{item.
|
|
1
|
+
item: {{item.body}}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
|
|
3
|
+
class TestAsset < Test::Unit::TestCase
|
|
4
|
+
def setup
|
|
5
|
+
super
|
|
6
|
+
@asset = Jenner::Asset.new('test.scss', @site)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def test_filename
|
|
10
|
+
assert_equal "test.scss", @asset.filename
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_sass
|
|
14
|
+
assert @asset.sass?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_sass_on_an_image
|
|
18
|
+
@asset = Jenner::Asset.new("subdirectory/test.png", @site)
|
|
19
|
+
assert !@asset.sass?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_output_filename
|
|
23
|
+
assert_equal "test.css", @asset.output_filename
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_url
|
|
27
|
+
assert_equal "/test.css", @asset.url
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_public_path
|
|
31
|
+
assert_equal site_file("public/test.css"), @asset.public_path
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_generate
|
|
35
|
+
FileUtils.mkdir(File.join(@site.root,"public"))
|
|
36
|
+
@asset.generate!
|
|
37
|
+
assert File.exists?(File.join(@site.root,"public","test.css"))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_generate_on_non_sass
|
|
41
|
+
FileUtils.mkdir(File.join(@site.root,"public"))
|
|
42
|
+
@asset = Jenner::Asset.new("foo.txt", @site)
|
|
43
|
+
@asset.generate!
|
|
44
|
+
assert File.exists?(File.join(@site.root,"public","foo.txt"))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_to_liquid
|
|
48
|
+
assert_equal({'url' => @asset.url}, @asset.to_liquid)
|
|
49
|
+
end
|
|
50
|
+
end
|
data/test/jenner/test_item.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
1
2
|
require 'helper'
|
|
2
3
|
|
|
3
4
|
class TestItem < Test::Unit::TestCase
|
|
@@ -5,7 +6,7 @@ class TestItem < Test::Unit::TestCase
|
|
|
5
6
|
item = Jenner::Item.new('test.html',@site)
|
|
6
7
|
assert_equal "test", item.title
|
|
7
8
|
assert_equal Time.new(2014,1,23,17,2,0,"-06:00"), item.date
|
|
8
|
-
assert_equal "wrapper", item.
|
|
9
|
+
assert_equal "wrapper.html", item.template_path
|
|
9
10
|
assert_equal({ "foo" => "bar" }, item.data)
|
|
10
11
|
end
|
|
11
12
|
|
|
@@ -16,7 +17,7 @@ class TestItem < Test::Unit::TestCase
|
|
|
16
17
|
|
|
17
18
|
def test_render
|
|
18
19
|
item = Jenner::Item.new('test.html',@site)
|
|
19
|
-
assert_equal "top\ntest\n2014-01-23 17:02:00 -0600\nwrapper\ntest\nbar\nitem content\n\nbottom\n", item.render
|
|
20
|
+
assert_equal "top\ntest\n2014-01-23 17:02:00 -0600\nwrapper.html\ntest\nbar\nitem content\n\nbottom\n", item.render
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
def test_public_path
|
|
@@ -26,16 +27,19 @@ class TestItem < Test::Unit::TestCase
|
|
|
26
27
|
|
|
27
28
|
def test_generate!
|
|
28
29
|
item = Jenner::Item.new('test.html',@site)
|
|
29
|
-
# make the public dir for the item, since @site normally does it
|
|
30
|
-
FileUtils.mkdir(File.join(@site.root,'public'))
|
|
31
30
|
item.generate!
|
|
32
31
|
assert File.exists?(File.join(@site.root,'public','test.html'))
|
|
33
|
-
assert_equal item.render, File.read(File.join(@site.root,'public','test.html')
|
|
32
|
+
assert_equal item.render, File.read(File.join(@site.root,'public','test.html'))
|
|
34
33
|
end
|
|
35
34
|
|
|
36
35
|
def test_markdown_template
|
|
37
36
|
item = Jenner::Item.new('markdown_test.markdown', @site)
|
|
38
|
-
assert_equal "top\nmarkdown test\n2014-01-23 17:02:00 -0600\nwrapper\n\n<h1 id=\"markdown_test\">markdown test</h1>\n\n<p>item content</p>\n\nbottom\n", item.render
|
|
37
|
+
assert_equal "top\nmarkdown test\n2014-01-23 17:02:00 -0600\nwrapper.html\n\n<h1 id=\"markdown_test\">markdown test</h1>\n\n<p>item content</p>\n\nbottom\n", item.render
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_markdown_template_public_path
|
|
41
|
+
item = Jenner::Item.new('markdown_test.markdown', @site)
|
|
42
|
+
assert_equal site_file('public/markdown_test.html'), item.public_path
|
|
39
43
|
end
|
|
40
44
|
|
|
41
45
|
def test_public_path_on_subdir_item
|
|
@@ -45,10 +49,9 @@ class TestItem < Test::Unit::TestCase
|
|
|
45
49
|
|
|
46
50
|
def test_generate_on_subdir_item
|
|
47
51
|
item = Jenner::Item.new("subdirectory/subfile.html",@site)
|
|
48
|
-
FileUtils.mkdir_p(File.join(@site.root,'public','subdirectory'))
|
|
49
52
|
item.generate!
|
|
50
53
|
assert File.exists?(File.join(@site.root,'public','subdirectory','subfile.html'))
|
|
51
|
-
assert_equal "item: subfile\n", File.read(File.join(@site.root,'public','subdirectory','subfile.html'))
|
|
54
|
+
assert_equal "item: subfile\n\n", File.read(File.join(@site.root,'public','subdirectory','subfile.html'))
|
|
52
55
|
end
|
|
53
56
|
|
|
54
57
|
def test_url
|
|
@@ -60,4 +63,56 @@ class TestItem < Test::Unit::TestCase
|
|
|
60
63
|
item = Jenner::Item.new('subdirectory/subfile.html',@site)
|
|
61
64
|
assert_equal "/subdirectory/subfile.html", item.url
|
|
62
65
|
end
|
|
66
|
+
|
|
67
|
+
def test_underscored_title
|
|
68
|
+
item = Jenner::Item.new('blog/20140128_TEST_post.markdown', @site)
|
|
69
|
+
assert_equal "test-post", item.underscored_title
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_relative_path
|
|
73
|
+
item = Jenner::Item.new('blog/20140128_TEST_post.markdown', @site)
|
|
74
|
+
assert_equal "blog/", item.relative_path
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_output_filename_on_custom_url
|
|
78
|
+
item = Jenner::Item.new('blog/20140128_TEST_post.markdown', @site)
|
|
79
|
+
assert_equal "index.html", item.output_filename
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test_output_filename_on_regular_markdown_file
|
|
83
|
+
item = Jenner::Item.new('markdown_test.markdown', @site)
|
|
84
|
+
assert_equal "markdown_test.html", item.output_filename
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_custom_url
|
|
88
|
+
item = Jenner::Item.new('blog/20140128_TEST_post.markdown', @site)
|
|
89
|
+
assert_equal "/blog/2014/01/28/test-post", item.url
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def test_public_path_on_custom_url
|
|
93
|
+
item = Jenner::Item.new('blog/20140128_TEST_post.markdown', @site)
|
|
94
|
+
assert_equal site_file("public/blog/2014/01/28/test-post/index.html"), item.public_path
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def test_generate_on_custom_url
|
|
98
|
+
item = Jenner::Item.new('blog/20140128_TEST_post.markdown', @site)
|
|
99
|
+
item.generate!
|
|
100
|
+
assert File.exists?(site_file("public/blog/2014/01/28/test-post/index.html"))
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_item_from_path
|
|
104
|
+
item = Jenner::Item.new('embed_test.html', @site)
|
|
105
|
+
assert_equal "item: \nsecret: 42\n\n\n", item.render
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_haml_item
|
|
109
|
+
item = Jenner::Item.new("haml_test.haml", @site)
|
|
110
|
+
assert_equal "<p>liquid: haml test bar</p>\n<p>haml: haml test bar</p>\n\n", item.render
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def test_haml_generation
|
|
114
|
+
item = Jenner::Item.new("haml_test.haml", @site)
|
|
115
|
+
item.generate!
|
|
116
|
+
assert File.exists?(site_file("public/haml_test.html"))
|
|
117
|
+
end
|
|
63
118
|
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
|
|
3
|
+
class TestLiquidFilters < Test::Unit::TestCase
|
|
4
|
+
include Liquid
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
super
|
|
8
|
+
|
|
9
|
+
@context = Liquid::Context.new({},{},site: @site)
|
|
10
|
+
@context.add_filters(Jenner::LiquidFilters)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_item_from_path
|
|
14
|
+
assert Variable.new("'test.html' | item_from_path").render(@context).is_a?(Jenner::Item)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_items_from_path
|
|
18
|
+
a = Variable.new("'[^\/]+\.html' | items_from_path").render(@context)
|
|
19
|
+
assert a.is_a?(Array)
|
|
20
|
+
assert_equal 3, a.length
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_asset_from_path
|
|
24
|
+
assert Variable.new("'foo.txt' | asset_from_path").render(@context).is_a?(Jenner::Asset)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_assign_to(value, name)
|
|
28
|
+
assert_nil Variable.new("'bar' | assign_to: 'foo'").render(@context)
|
|
29
|
+
assert_equal "bar", @context['foo']
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_stylesheet_tag
|
|
33
|
+
assert_equal %(<link href="test.css" media="all" rel="stylesheet" type="text/css" />),
|
|
34
|
+
Variable.new("'test.css' | stylesheet_tag").render(@context)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_javascript_tag
|
|
38
|
+
assert_equal %(<script type="text/javascript" src="test.js"></script>),
|
|
39
|
+
Variable.new("'test.js' | javascript_tag").render(@context)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_link_to
|
|
43
|
+
assert_equal %(<a href="/test.html">test</a>),
|
|
44
|
+
Variable.new("'test.html' | item_from_path | link_to").render(@context)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_tag
|
|
48
|
+
assert Variable.new("'one' | tag").render(@context).is_a?(Jenner::Tag)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def test_items_with_data
|
|
52
|
+
items = Variable.new("'foo' | items_with_data").render(@context)
|
|
53
|
+
paths = items.map(&:path)
|
|
54
|
+
assert paths.include?("test.html")
|
|
55
|
+
assert paths.include?("_hidden.html")
|
|
56
|
+
assert paths.include?("markdown_test.markdown")
|
|
57
|
+
assert !paths.include?("foo.txt")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_items_with_data_and_value
|
|
61
|
+
items = Variable.new(%('foo' | items_with_data: "bar")).render(@context)
|
|
62
|
+
paths = items.map(&:path)
|
|
63
|
+
assert paths.include?("test.html")
|
|
64
|
+
assert paths.include?("_hidden.html")
|
|
65
|
+
assert !paths.include?("markdown_test.markdown")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def test_items_with_data_and_value_on_array
|
|
69
|
+
items = Variable.new(%('bar' | items_with_data: 2)).render(@context)
|
|
70
|
+
paths = items.map(&:path)
|
|
71
|
+
assert !paths.include?("test.html")
|
|
72
|
+
assert paths.include?("_hidden.html")
|
|
73
|
+
assert paths.include?("markdown_test.markdown")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
data/test/jenner/test_site.rb
CHANGED
|
@@ -36,4 +36,16 @@ class TestSite < Test::Unit::TestCase
|
|
|
36
36
|
assert File.exists?(site_file("public/test.css"))
|
|
37
37
|
assert_equal "body {\n background-color: blue; }\n", File.read(site_file("public/test.css"), encoding: "US-ASCII")
|
|
38
38
|
end
|
|
39
|
+
|
|
40
|
+
def test_asset_files
|
|
41
|
+
assert @site.asset_files.include? site_file('_site/test.scss')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_tag_names
|
|
45
|
+
assert_equal ['one',"three","two"], @site.tag_names.sort
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_tags
|
|
49
|
+
assert @site.tags.first.is_a? Jenner::Tag
|
|
50
|
+
end
|
|
39
51
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'helper'
|
|
2
|
+
|
|
3
|
+
class TestTag < Test::Unit::TestCase
|
|
4
|
+
def setup
|
|
5
|
+
super
|
|
6
|
+
|
|
7
|
+
@tag = Jenner::Tag.new('one', @site)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_name
|
|
11
|
+
assert_equal "one", @tag.name
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_items
|
|
15
|
+
assert_equal "/test.html", @tag.items.first.url
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_to_liquid
|
|
19
|
+
assert_equal "one", @tag.to_liquid["name"]
|
|
20
|
+
assert_equal "/test.html", @tag.to_liquid["items"].first.url
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
1
2
|
require 'helper'
|
|
2
3
|
|
|
3
4
|
class TestTemplate < Test::Unit::TestCase
|
|
@@ -16,8 +17,44 @@ class TestTemplate < Test::Unit::TestCase
|
|
|
16
17
|
assert_equal "hi, {{name}}\n", template.body
|
|
17
18
|
end
|
|
18
19
|
|
|
20
|
+
def test_has_access_to_site_as_liquid
|
|
21
|
+
template = Jenner::Template.new("{{site.root}}", @site)
|
|
22
|
+
assert_equal @site.root, template.render
|
|
23
|
+
end
|
|
24
|
+
|
|
19
25
|
def test_include
|
|
20
|
-
template = Jenner::Template.new("{% include 'test' %}", @site)
|
|
26
|
+
template = Jenner::Template.new("{% include 'test.html' %}", @site)
|
|
21
27
|
assert_equal "hi, jay\n", template.render('name' => 'jay')
|
|
22
28
|
end
|
|
29
|
+
|
|
30
|
+
def test_include_haml
|
|
31
|
+
template = Jenner::Template.new("{% include 'haml_template.haml' with item %}", @site)
|
|
32
|
+
assert_equal "<p>foo</p>\n", template.render('item' => {'body' => 'foo'})
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_support_for_haml
|
|
36
|
+
template = Jenner::Template.from_haml("!!! 5", @site)
|
|
37
|
+
assert_equal "<!DOCTYPE html>\n", template.render
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_haml_from_file
|
|
41
|
+
template = Jenner::Template.from_file(template_file('haml_template.haml'), @site)
|
|
42
|
+
assert_equal "<p>foo</p>\n", template.render('item' => { 'body' => 'foo' })
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_haml_can_use_liquid
|
|
46
|
+
template = Jenner::Template.new("%p hi, {{name}}", @site, haml: true)
|
|
47
|
+
assert_equal "<p>hi, jay</p>\n", template.render('name' => 'jay')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_haml_has_access_to_liquid_context_in_body
|
|
51
|
+
template = Jenner::Template.new(%(%p hi, \#{name}), @site, haml: true)
|
|
52
|
+
assert_equal "<p>hi, jay</p>\n", template.body('name' => 'jay')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def test_haml_body_gets_passed_through_with_render
|
|
56
|
+
template = Jenner::Template.new(%(%p hi, \#{name}), @site, haml: true)
|
|
57
|
+
assert_equal "<p>hi, jay</p>\n", template.render('name' => 'jay')
|
|
58
|
+
end
|
|
59
|
+
|
|
23
60
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jenner
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.6
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,8 +9,24 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2014-01-
|
|
12
|
+
date: 2014-01-30 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: haml
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ~>
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: 4.0.5
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ~>
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: 4.0.5
|
|
14
30
|
- !ruby/object:Gem::Dependency
|
|
15
31
|
name: liquid
|
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -107,23 +123,35 @@ files:
|
|
|
107
123
|
- bin/jenner
|
|
108
124
|
- jenner.gemspec
|
|
109
125
|
- lib/jenner.rb
|
|
126
|
+
- lib/jenner/asset.rb
|
|
110
127
|
- lib/jenner/item.rb
|
|
128
|
+
- lib/jenner/liquid_filters.rb
|
|
111
129
|
- lib/jenner/site.rb
|
|
130
|
+
- lib/jenner/tag.rb
|
|
112
131
|
- lib/jenner/template.rb
|
|
113
132
|
- lib/jenner/template_file_system.rb
|
|
114
133
|
- lib/jenner/version.rb
|
|
115
134
|
- test/fixtures/source/_site/_hidden.html
|
|
135
|
+
- test/fixtures/source/_site/blog/20140128_test_post.markdown
|
|
136
|
+
- test/fixtures/source/_site/embed_test.html
|
|
137
|
+
- test/fixtures/source/_site/foo.txt
|
|
138
|
+
- test/fixtures/source/_site/haml_test.haml
|
|
116
139
|
- test/fixtures/source/_site/markdown_test.markdown
|
|
117
140
|
- test/fixtures/source/_site/subdirectory/subfile.html
|
|
118
141
|
- test/fixtures/source/_site/subdirectory/test.png
|
|
119
142
|
- test/fixtures/source/_site/test.html
|
|
120
143
|
- test/fixtures/source/_site/test.scss
|
|
144
|
+
- test/fixtures/source/_templates/haml_template.haml
|
|
145
|
+
- test/fixtures/source/_templates/post.html
|
|
121
146
|
- test/fixtures/source/_templates/simple.html
|
|
122
147
|
- test/fixtures/source/_templates/test.html
|
|
123
148
|
- test/fixtures/source/_templates/wrapper.html
|
|
124
149
|
- test/helper.rb
|
|
150
|
+
- test/jenner/test_asset.rb
|
|
125
151
|
- test/jenner/test_item.rb
|
|
152
|
+
- test/jenner/test_liquid_filters.rb
|
|
126
153
|
- test/jenner/test_site.rb
|
|
154
|
+
- test/jenner/test_tag.rb
|
|
127
155
|
- test/jenner/test_template.rb
|
|
128
156
|
homepage: http://github.com/unreal/jenner
|
|
129
157
|
licenses: []
|
|
@@ -151,16 +179,25 @@ specification_version: 3
|
|
|
151
179
|
summary: Jenner is an opinionated static site generator
|
|
152
180
|
test_files:
|
|
153
181
|
- test/fixtures/source/_site/_hidden.html
|
|
182
|
+
- test/fixtures/source/_site/blog/20140128_test_post.markdown
|
|
183
|
+
- test/fixtures/source/_site/embed_test.html
|
|
184
|
+
- test/fixtures/source/_site/foo.txt
|
|
185
|
+
- test/fixtures/source/_site/haml_test.haml
|
|
154
186
|
- test/fixtures/source/_site/markdown_test.markdown
|
|
155
187
|
- test/fixtures/source/_site/subdirectory/subfile.html
|
|
156
188
|
- test/fixtures/source/_site/subdirectory/test.png
|
|
157
189
|
- test/fixtures/source/_site/test.html
|
|
158
190
|
- test/fixtures/source/_site/test.scss
|
|
191
|
+
- test/fixtures/source/_templates/haml_template.haml
|
|
192
|
+
- test/fixtures/source/_templates/post.html
|
|
159
193
|
- test/fixtures/source/_templates/simple.html
|
|
160
194
|
- test/fixtures/source/_templates/test.html
|
|
161
195
|
- test/fixtures/source/_templates/wrapper.html
|
|
162
196
|
- test/helper.rb
|
|
197
|
+
- test/jenner/test_asset.rb
|
|
163
198
|
- test/jenner/test_item.rb
|
|
199
|
+
- test/jenner/test_liquid_filters.rb
|
|
164
200
|
- test/jenner/test_site.rb
|
|
201
|
+
- test/jenner/test_tag.rb
|
|
165
202
|
- test/jenner/test_template.rb
|
|
166
203
|
has_rdoc:
|