impression 0.4 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f310190c6415f14cdc24e4ab871dee51122a148292b778d6fc4679dafa03b10c
4
- data.tar.gz: 302dd60dea184497508d7200354bf230835e0e84768ef6f5e5f5ee1e8ee27416
3
+ metadata.gz: 8db17f3627f0b8de2ed13a81effd9689f8a292b0861104c276d343bf5ec23e8f
4
+ data.tar.gz: 79cc272aed0503e1514723815f7019002c780a890995ef7c6f2d4718d9704000
5
5
  SHA512:
6
- metadata.gz: dc1469936dd52810143d48ce608335a96b2fcfac8187d481c6df031bc4b3bc9d22ef41a3532660fb0826973dd356ef7ba7f181fdd1ac8ea8be31bc080b99013c
7
- data.tar.gz: 89294842887b2da78309bb2c5cb3472123f363a315e2b22d9dcac67753e6008926374222895a40f373738c6dbdb964752873d459fac942cd99a68eafb4e1fd11
6
+ metadata.gz: 46112700200e6018c10b9a84b3a90184ce590e0da7369096a787467af4c84aba6578c043c1c9ad520cfa6da83638492def2c53b8cc9d51407d74695e3c12af4f
7
+ data.tar.gz: 94b1e171d6161bdd452ce27a6ee5effde4c9a1fdb2fd0247b72449fcb7048a8c1800dc616c6e291d56ea639dcec8a4d2d2dad5e9aa6865ccc0cb96cac4525688
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ # 0.5 2022-01-20
2
+
3
+ - Pass resource and request to rendered templates (#8)
4
+ - Implement Jamstack#page_list method (#7)
5
+
1
6
  # 0.4 2022-01-19
2
7
 
3
8
  - Remove deprecated Pages code (#6)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- impression (0.4)
4
+ impression (0.5)
5
5
  modulation (~> 1.1)
6
6
  papercraft (~> 0.14)
7
7
  polyphony (~> 0.73.1)
@@ -50,7 +50,7 @@ GEM
50
50
  localhost (1.1.9)
51
51
  minitest (5.11.3)
52
52
  modulation (1.1)
53
- msgpack (1.4.2)
53
+ msgpack (1.4.3)
54
54
  multipart-post (2.1.1)
55
55
  papercraft (0.14)
56
56
  escape_utils (= 1.2.1)
@@ -85,7 +85,7 @@ GEM
85
85
  websocket (1.2.9)
86
86
 
87
87
  PLATFORMS
88
- ruby
88
+ x86_64-linux
89
89
 
90
90
  DEPENDENCIES
91
91
  impression!
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'fileutils'
4
4
  require 'yaml'
5
+ require 'date'
5
6
  require 'modulation'
6
7
  require 'papercraft'
7
8
 
@@ -17,8 +18,68 @@ module Impression
17
18
  @layouts = {}
18
19
  end
19
20
 
21
+ # Returns a list of pages found in the given directory (relative to the base
22
+ # directory). Each entry containins the absolute file path, the pretty URL,
23
+ # the possible date parsed from the file name, and any other front matter
24
+ # attributes (for .md files). This method will detect only pages with the
25
+ # extensions .html, .md, .rb. The returned entries are sorted by file path.
26
+ #
27
+ # @param dir [String] relative directory
28
+ # @return [Array<Hash>] array of page entries
29
+ def page_list(dir)
30
+ base = File.join(@directory, dir)
31
+ Dir.glob('*.{html,md}', base: base)
32
+ .map { |fn| page_entry(fn, dir) }
33
+ .sort_by { |i| i[:path] }
34
+ end
35
+
20
36
  private
21
37
 
38
+ DATE_REGEXP = /^(\d{4}\-\d{2}\-\d{2})/.freeze
39
+ MARKDOWN_PAGE_REGEXP = /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m.freeze
40
+ MD_EXT_REGEXP = /\.md$/.freeze
41
+ PAGE_EXT_REGEXP = /^(.+)\.(md|html|rb)$/.freeze
42
+ INDEX_PAGE_REGEXP = /^(.+)\/index$/.freeze
43
+
44
+ # Returns a page entry for the given file.
45
+ #
46
+ # @param fn [String] file name
47
+ # @param dir [String] relative directory
48
+ # @return [Hash] page entry
49
+ def page_entry(fn, dir)
50
+ relative_path = File.join(dir, fn)
51
+ absolute_path = File.join(@directory, relative_path)
52
+ info = {
53
+ path: absolute_path,
54
+ url: pretty_url(relative_path)
55
+ }
56
+ if fn =~ MD_EXT_REGEXP
57
+ atts, _ = parse_markdown_file(absolute_path)
58
+ info.merge!(atts)
59
+ end
60
+
61
+ if (m = fn.match(DATE_REGEXP))
62
+ info[:date] ||= Date.parse(m[1])
63
+ end
64
+
65
+ info
66
+ end
67
+
68
+ # Returns the pretty URL for the given relative path. For pages, the
69
+ # extension is removed. For index pages, the index suffix is removed.
70
+ #
71
+ # @param relative_path [String] relative path
72
+ # @return [String] pretty URL
73
+ def pretty_url(relative_path)
74
+ if (m = relative_path.match(PAGE_EXT_REGEXP))
75
+ relative_path = m[1]
76
+ end
77
+ if (m = relative_path.match(INDEX_PAGE_REGEXP))
78
+ relative_path = m[1]
79
+ end
80
+ File.join(absolute_path, relative_path)
81
+ end
82
+
22
83
  # Renders a file response for the given request and the given path info.
23
84
  #
24
85
  # @param req [Qeweney::Request] request
@@ -43,7 +104,7 @@ module Impression
43
104
  def render_papercraft_module(req, path)
44
105
  mod = import path
45
106
 
46
- html = H(mod).render
107
+ html = H(mod).render(request: req, resource: self)
47
108
  req.respond(html, 'Content-Type' => Qeweney::MimeTypes[:html])
48
109
  end
49
110
 
@@ -57,7 +118,7 @@ module Impression
57
118
 
58
119
  layout = get_layout(attributes[:layout])
59
120
 
60
- html = layout.render(**attributes) { emit_markdown markdown }
121
+ html = layout.render(request: req, resource: self, **attributes) { emit_markdown markdown }
61
122
  req.respond(html, 'Content-Type' => Qeweney::MimeTypes[:html])
62
123
  end
63
124
 
@@ -73,8 +134,6 @@ module Impression
73
134
 
74
135
  import path
75
136
  end
76
-
77
- MARKDOWN_PAGE_REGEXP = /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m.freeze
78
137
 
79
138
  # Parses the markdown file at the given path.
80
139
  #
@@ -82,13 +141,23 @@ module Impression
82
141
  # @return [Array] an tuple containing properties<Hash>, contents<String>
83
142
  def parse_markdown_file(path)
84
143
  data = IO.read(path) || ''
144
+ atts = {}
145
+
146
+ # Parse date from file name
147
+ if (m = path.match(DATE_REGEXP))
148
+ atts[:date] ||= Date.parse(m[1])
149
+ end
150
+
85
151
  if (m = data.match(MARKDOWN_PAGE_REGEXP))
86
152
  front_matter = m[1]
87
-
88
- [symbolize_keys(YAML.load(front_matter)), m.post_match]
89
- else
90
- [{}, data]
153
+ data = m.post_match
154
+
155
+ YAML.load(front_matter).each_with_object(atts) do |(k, v), h|
156
+ h[k.to_sym] = v
157
+ end
91
158
  end
159
+
160
+ [atts, data]
92
161
  end
93
162
 
94
163
  # Converts a hash with string keys to one with symbol keys.
@@ -96,7 +165,7 @@ module Impression
96
165
  # @param hash [Hash] input hash
97
166
  # @return [Hash] output hash
98
167
  def symbolize_keys(hash)
99
- hash.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
168
+
100
169
  end
101
170
 
102
171
  # Returns the supported path extensions used for searching for files based
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Impression
4
- VERSION = '0.4'
4
+ VERSION = '0.5'
5
5
  end
@@ -0,0 +1,6 @@
1
+ ---
2
+ title: MMM
3
+ layout: article
4
+ ---
5
+
6
+ ## BBB
@@ -0,0 +1,6 @@
1
+ ---
2
+ title: NNN
3
+ layout: article
4
+ ---
5
+
6
+ ## BBB
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ layout = import('./_layouts/default')
4
+
5
+ export_default layout.apply(title: 'Foobar') { |resource:, request:, **props|
6
+ h1 request.query[:q]
7
+ resource.page_list('/articles').each do |i|
8
+ a i[:title], href: i[:url]
9
+ end
10
+ }
@@ -116,7 +116,7 @@ class JamstackTest < MiniTest::Test
116
116
  assert_response a.render, :html, req
117
117
  end
118
118
 
119
- def test_non_root_file_tree_response
119
+ def test_non_root_jamstack_response
120
120
  @jamstack = Impression::Jamstack.new(path: '/app', directory: JAMSTACK_PATH)
121
121
 
122
122
  req = mock_req(':method' => 'GET', ':path' => '/app/roo')
@@ -205,4 +205,59 @@ class JamstackTest < MiniTest::Test
205
205
  }
206
206
  assert_response a.render, :html, req
207
207
  end
208
+
209
+ def test_page_list
210
+ @jamstack = Impression::Jamstack.new(path: '/app', directory: JAMSTACK_PATH)
211
+
212
+ list = @jamstack.page_list('/')
213
+ assert_equal [
214
+ { path: File.join(JAMSTACK_PATH, 'bar.html'), url: '/app/bar' },
215
+ { path: File.join(JAMSTACK_PATH, 'index.md'), title: 'Hello', url: '/app/index' },
216
+ ], list
217
+
218
+
219
+ list = @jamstack.page_list('/articles')
220
+ assert_equal [
221
+ {
222
+ path: File.join(JAMSTACK_PATH, 'articles/2008-06-14-manu.md'),
223
+ url: '/app/articles/2008-06-14-manu',
224
+ title: 'MMM',
225
+ layout: 'article',
226
+ date: Date.new(2008, 06, 14)
227
+ },
228
+ {
229
+ path: File.join(JAMSTACK_PATH, 'articles/2009-06-12-noatche.md'),
230
+ url: '/app/articles/2009-06-12-noatche',
231
+ title: 'NNN',
232
+ layout: 'article',
233
+ date: Date.new(2009, 06, 12)
234
+ },
235
+ {
236
+ path: File.join(JAMSTACK_PATH, 'articles/a.md'),
237
+ url: '/app/articles/a',
238
+ title: 'AAA',
239
+ layout: 'article'
240
+ },
241
+ ], list
242
+ end
243
+
244
+ def test_template_resource_and_request
245
+ req = mock_req(':method' => 'GET', ':path' => '/foobar?q=42')
246
+ @jamstack.route_and_call(req)
247
+
248
+ foo = H {
249
+ html5 {
250
+ head {
251
+ title 'Foobar'
252
+ }
253
+ body {
254
+ h1 '42'
255
+ a 'MMM', href: '/articles/2008-06-14-manu'
256
+ a 'NNN', href: '/articles/2009-06-12-noatche'
257
+ a 'AAA', href: '/articles/a'
258
+ }
259
+ }
260
+ }
261
+ assert_response foo.render, :html, req
262
+ end
208
263
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: impression
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.4'
4
+ version: '0.5'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-19 00:00:00.000000000 Z
11
+ date: 2022-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: polyphony
@@ -158,11 +158,14 @@ files:
158
158
  - test/helper.rb
159
159
  - test/jamstack/_layouts/article.rb
160
160
  - test/jamstack/_layouts/default.rb
161
+ - test/jamstack/articles/2008-06-14-manu.md
162
+ - test/jamstack/articles/2009-06-12-noatche.md
161
163
  - test/jamstack/articles/a.md
162
164
  - test/jamstack/assets/js/a.js
163
165
  - test/jamstack/bar.html
164
166
  - test/jamstack/baz/index.md
165
167
  - test/jamstack/foo.rb
168
+ - test/jamstack/foobar.rb
166
169
  - test/jamstack/index.md
167
170
  - test/run.rb
168
171
  - test/static/bar/index.html