postwave 0.1.3 → 0.1.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 +23 -5
- data/lib/postwave/blog_builder.rb +9 -6
- data/lib/postwave/blog_creator.rb +6 -0
- data/lib/postwave/blog_utilities.rb +2 -0
- data/lib/postwave/client.rb +5 -1
- data/lib/postwave/errors.rb +3 -0
- data/lib/postwave/post.rb +15 -1
- data/lib/postwave/rss_helper.rb +4 -3
- data/lib/postwave/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 72de9f3a0519b58b611d16948184ca006efe255192165adb12daa63acc2f4a5b
|
|
4
|
+
data.tar.gz: 7cda4aa860cd5e1fddd8b627f404c690d8517d0d11b81c1531f145a3e6cf1fac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e78c9dbe00a6e5f69d7a40e45e5aac96c2d9cf86debace476e7b6f89a5060dfb089eaa789def679a660108d62bcf813f33cb7bcaae2b84b761548175042914a0
|
|
7
|
+
data.tar.gz: 0da1d0e033986bd2c3654a94c5dac1e9bf590bca2105489d1982282289658cbca62424267468ed6345c9925325ef2d743cad841cddb204a9daaf90f2c1b4f640
|
data/README.md
CHANGED
|
@@ -4,12 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
Write your posts statically. Interact with them dynamically.
|
|
6
6
|
|
|
7
|
+
[postwave.blog](https://postwave.blog/)
|
|
8
|
+
|
|
7
9
|
## What is Postwave?
|
|
8
10
|
|
|
9
11
|
Postwave is an opinionated flat-file based based blog engine.
|
|
10
12
|
|
|
11
13
|
It lets you write posts in Markdown and then display them on a dynamic site using the client functionality.
|
|
12
14
|
|
|
15
|
+
Read more about the philosophy behind [what Postwave is for](https://postwave.blog/posts/what-is-postwave-for).
|
|
16
|
+
|
|
13
17
|
## Installation
|
|
14
18
|
|
|
15
19
|
```
|
|
@@ -32,6 +36,7 @@ Here is what will be created:
|
|
|
32
36
|
|- _posts/
|
|
33
37
|
| |- meta/
|
|
34
38
|
| |- tags/
|
|
39
|
+
| |- .tags
|
|
35
40
|
| |- index.csv
|
|
36
41
|
| |- summary.yaml
|
|
37
42
|
postwave.yaml
|
|
@@ -39,7 +44,7 @@ postwave.yaml
|
|
|
39
44
|
|
|
40
45
|
`_posts/`: This is where you write all your posts in Markdown
|
|
41
46
|
|
|
42
|
-
`_posts/meta/tags/`: This will contain files for every tag your define in your posts
|
|
47
|
+
`_posts/meta/tags/`: This will contain files for every tag your define in your posts. It contains a `.tags` file to make sure the directory gets picked up by git even if you have no tags.
|
|
43
48
|
|
|
44
49
|
`_posts/meta/index.csv`: This will contain an ordered list of all the posts
|
|
45
50
|
|
|
@@ -77,6 +82,15 @@ draft: true
|
|
|
77
82
|
---
|
|
78
83
|
```
|
|
79
84
|
|
|
85
|
+
You can freeze the slug of a post by adding `frozen_slug: post-slug` to the top section of the post.
|
|
86
|
+
```
|
|
87
|
+
title: A New Title!
|
|
88
|
+
date: 2022-01-01
|
|
89
|
+
tags:
|
|
90
|
+
frozen_slug: keep-this-slug
|
|
91
|
+
```
|
|
92
|
+
The filename will remain `2022-01-01-keep-this-slug.md` after running `postwave build` (rather than updating to `2022-01-01-a-new-title.md`). Note that the date part of the filename still comes from the `date` field.
|
|
93
|
+
|
|
80
94
|
### Build the Blog
|
|
81
95
|
|
|
82
96
|
```
|
|
@@ -86,14 +100,14 @@ draft: true
|
|
|
86
100
|
This will "build" the blog. This involves:
|
|
87
101
|
- regenerating the `/meta/index.csv` file
|
|
88
102
|
- generating slugs for each posts based on the post title and ensuring that there are no duplicate slugs
|
|
89
|
-
- changing the post file names to match `yyyy-dd-
|
|
103
|
+
- changing the post file names to match `yyyy-mm-dd-slug.md`
|
|
90
104
|
- updating the `/meta/summary.yaml`
|
|
91
105
|
- creating and updating tag files (which will be `/tags/[tag-name].yaml` files for each tag)
|
|
92
106
|
- updating the `/meta/rss` file to create a feed for your posts
|
|
93
107
|
|
|
94
108
|
## Displaying Posts
|
|
95
109
|
|
|
96
|
-
You can
|
|
110
|
+
You can use Postwave's built in Ruby client to display these posts in your project.
|
|
97
111
|
|
|
98
112
|
### Include the Client In Your Project
|
|
99
113
|
|
|
@@ -131,7 +145,7 @@ puts post.body_preview(8) # an HTML free preview of the post with optional `limi
|
|
|
131
145
|
|
|
132
146
|
### Get a Collection of Posts
|
|
133
147
|
|
|
134
|
-
This will give you a list of posts
|
|
148
|
+
This will give you a list of posts.
|
|
135
149
|
|
|
136
150
|
You can also filter by tags and specify offsets and limits (useful for pagination).
|
|
137
151
|
|
|
@@ -148,7 +162,7 @@ Posts will be in reverse chronological order.
|
|
|
148
162
|
|
|
149
163
|
### Get an Index of Posts
|
|
150
164
|
|
|
151
|
-
This will give you a quick list of post summaries containing the title, date, and stub, useful for building
|
|
165
|
+
This will give you a quick list of post summaries containing the title, date, and stub, useful for building a summary page or quick index of posts.
|
|
152
166
|
|
|
153
167
|
You can also specify offsets and limits (useful for pagination).
|
|
154
168
|
```ruby
|
|
@@ -229,6 +243,10 @@ archive = postwave_client.archive(by: "month")
|
|
|
229
243
|
# }
|
|
230
244
|
```
|
|
231
245
|
|
|
246
|
+
## Example Site
|
|
247
|
+
|
|
248
|
+
The code for [postwave.blog](https://postwave.blog/) is available at [github.com/dorkrawk/postwave-site](https://github.com/dorkrawk/postwave-site) and serves as a good example of how to use Postwave in a real world project.
|
|
249
|
+
|
|
232
250
|
## Run Tests
|
|
233
251
|
|
|
234
252
|
```
|
|
@@ -7,6 +7,7 @@ require_relative "blog_utilities"
|
|
|
7
7
|
require_relative "display_helper"
|
|
8
8
|
require_relative "rss_helper"
|
|
9
9
|
require_relative "post"
|
|
10
|
+
require_relative "errors"
|
|
10
11
|
|
|
11
12
|
module Postwave
|
|
12
13
|
class BlogBuilder
|
|
@@ -30,12 +31,13 @@ module Postwave
|
|
|
30
31
|
# load, rename, and sort post file names
|
|
31
32
|
posts = load_posts
|
|
32
33
|
posts = ensure_unique_slugs(posts).sort_by { |p| p.date }.reverse
|
|
33
|
-
draft_posts, published_posts = posts.partition { |p| p.
|
|
34
|
+
draft_posts, published_posts = posts.partition { |p| p.draft? }
|
|
34
35
|
tags = {}
|
|
35
36
|
|
|
36
37
|
CSV.open(File.join(Dir.pwd, POSTS_DIR, META_DIR, INDEX_FILE_NAME), "w") do |csv|
|
|
37
38
|
csv << INDEX_HEADERS
|
|
38
39
|
published_posts.each do |post|
|
|
40
|
+
raise BlogBuilderError, "Post slug cannot be blank." if post.slug.empty?
|
|
39
41
|
post.update_file_name!
|
|
40
42
|
|
|
41
43
|
csv << [post.slug, post.date, post.title]
|
|
@@ -73,12 +75,13 @@ module Postwave
|
|
|
73
75
|
slug_count = {}
|
|
74
76
|
|
|
75
77
|
posts.sort_by { |p| p.date }.each do |post|
|
|
76
|
-
|
|
77
|
-
if slug_count.key?(
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
post_slug = post.frozen_slug? ? post.frozen_slug : post.title_slug
|
|
79
|
+
if slug_count.key?(post_slug)
|
|
80
|
+
raise BlogBuilderError, "Duplicate frozen slug: #{post_slug}" if post.frozen_slug?
|
|
81
|
+
slug_count[post_slug] += 1
|
|
82
|
+
post.slug = "#{post_slug}-#{slug_count[post_slug]}"
|
|
80
83
|
else
|
|
81
|
-
slug_count[
|
|
84
|
+
slug_count[post_slug] = 0
|
|
82
85
|
end
|
|
83
86
|
end
|
|
84
87
|
|
|
@@ -21,6 +21,7 @@ module Postwave
|
|
|
21
21
|
build_directories
|
|
22
22
|
build_files
|
|
23
23
|
write_initial_summary_contents
|
|
24
|
+
write_tag_file_contents
|
|
24
25
|
|
|
25
26
|
configure_blog
|
|
26
27
|
|
|
@@ -48,6 +49,11 @@ module Postwave
|
|
|
48
49
|
File.write(File.join(Dir.pwd, POSTS_DIR, META_DIR, SUMMARY_FILE_NAME), summary.transform_keys(&:to_s).to_yaml)
|
|
49
50
|
end
|
|
50
51
|
|
|
52
|
+
def write_tag_file_contents
|
|
53
|
+
# just put something in the file
|
|
54
|
+
File.write(File.join(Dir.pwd, POSTS_DIR, META_DIR, TAGS_DIR, TAG_FILE_NAME), "[]")
|
|
55
|
+
end
|
|
56
|
+
|
|
51
57
|
def configure_blog
|
|
52
58
|
config = {}
|
|
53
59
|
|
|
@@ -3,6 +3,7 @@ module Postwave
|
|
|
3
3
|
CONFIG_FILE_NAME = "postwave.yaml"
|
|
4
4
|
INDEX_FILE_NAME = "index.csv"
|
|
5
5
|
SUMMARY_FILE_NAME = "summary.yaml"
|
|
6
|
+
TAG_FILE_NAME = ".tags"
|
|
6
7
|
RSS_FILE_NAME = "rss"
|
|
7
8
|
POSTS_DIR = "_posts"
|
|
8
9
|
META_DIR = "meta"
|
|
@@ -18,6 +19,7 @@ module Postwave
|
|
|
18
19
|
File.join(blog_root, CONFIG_FILE_NAME),
|
|
19
20
|
File.join(blog_root, POSTS_DIR, META_DIR, INDEX_FILE_NAME),
|
|
20
21
|
File.join(blog_root, POSTS_DIR, META_DIR, SUMMARY_FILE_NAME),
|
|
22
|
+
File.join(blog_root, POSTS_DIR, META_DIR, TAGS_DIR, TAG_FILE_NAME),
|
|
21
23
|
]
|
|
22
24
|
end
|
|
23
25
|
|
data/lib/postwave/client.rb
CHANGED
|
@@ -18,7 +18,11 @@ module Postwave
|
|
|
18
18
|
raise MissingConfigError unless is_valid_config?(config_path)
|
|
19
19
|
|
|
20
20
|
@blog_root = File.dirname(config_path)
|
|
21
|
-
|
|
21
|
+
missing_paths = find_missing_paths(@blog_root)
|
|
22
|
+
unless missing_paths.empty?
|
|
23
|
+
missing_paths_message = "Your blog is missing the following files/directories: #{missing_paths.join(',')}"
|
|
24
|
+
raise InvalidBlogError, missing_paths_message
|
|
25
|
+
end
|
|
22
26
|
|
|
23
27
|
@all_posts = get_all_posts if preload
|
|
24
28
|
end
|
data/lib/postwave/errors.rb
CHANGED
data/lib/postwave/post.rb
CHANGED
|
@@ -68,7 +68,21 @@ module Postwave
|
|
|
68
68
|
self.class.send(:attr_reader, field) unless self.public_methods.include?(field.to_sym)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
@slug =
|
|
71
|
+
@slug = if frozen_slug?
|
|
72
|
+
frozen_slug
|
|
73
|
+
elsif file_name_slug&.empty?
|
|
74
|
+
title_slug
|
|
75
|
+
else
|
|
76
|
+
file_name_slug
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def draft?
|
|
81
|
+
respond_to?(:draft) && draft
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def frozen_slug?
|
|
85
|
+
respond_to?(:frozen_slug) && !!frozen_slug
|
|
72
86
|
end
|
|
73
87
|
|
|
74
88
|
def title_slug
|
data/lib/postwave/rss_helper.rb
CHANGED
|
@@ -15,16 +15,17 @@ module Postwave
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def feed_content(posts)
|
|
18
|
-
link = config_values[:url]
|
|
18
|
+
link = config_values[:url].chomp("/")
|
|
19
19
|
updated = Time.now.iso8601.to_s
|
|
20
20
|
title = config_values[:name]
|
|
21
21
|
description = config_values[:description]
|
|
22
22
|
|
|
23
23
|
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, fenced_code_blocks: true)
|
|
24
24
|
feed_posts = posts.map do |post|
|
|
25
|
-
post_link = "#{
|
|
25
|
+
post_link = "#{link}/#{config_values[:posts_path]}/#{post.slug}"
|
|
26
26
|
html_body = CGI.unescapeHTML(markdown.render(post.body))
|
|
27
|
-
|
|
27
|
+
post_title = CGI.escapeHTML(post.title)
|
|
28
|
+
FeedPost.new(post_title, post_link, html_body, post.date.iso8601, post.tags)
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
path = File.join(__dir__, "templates/feed.erb")
|
data/lib/postwave/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: postwave
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dave Schwantes
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-01-21 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: redcarpet
|
|
@@ -138,6 +139,7 @@ homepage: https://github.com/dorkrawk/postwave
|
|
|
138
139
|
licenses:
|
|
139
140
|
- MIT
|
|
140
141
|
metadata: {}
|
|
142
|
+
post_install_message:
|
|
141
143
|
rdoc_options: []
|
|
142
144
|
require_paths:
|
|
143
145
|
- lib
|
|
@@ -152,7 +154,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
152
154
|
- !ruby/object:Gem::Version
|
|
153
155
|
version: '0'
|
|
154
156
|
requirements: []
|
|
155
|
-
rubygems_version: 3.
|
|
157
|
+
rubygems_version: 3.4.10
|
|
158
|
+
signing_key:
|
|
156
159
|
specification_version: 4
|
|
157
160
|
summary: An opinionated flatfile based blog engine.
|
|
158
161
|
test_files: []
|