postwave 0.0.1 → 0.1.0
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/Gemfile +1 -1
- data/Gemfile.lock +22 -0
- data/README.md +105 -10
- data/lib/postwave/blog_builder.rb +6 -2
- data/lib/postwave/blog_creator.rb +19 -1
- data/lib/postwave/blog_utilities.rb +22 -13
- data/lib/postwave/client.rb +102 -0
- data/lib/postwave/display_helper.rb +20 -0
- data/lib/postwave/errors.rb +16 -0
- data/lib/postwave/post.rb +15 -5
- data/lib/postwave/rss_helper.rb +36 -0
- data/lib/postwave/templates/feed.erb +28 -0
- data/lib/postwave/version.rb +1 -1
- data/lib/postwave.rb +1 -1
- data/postwave.gemspec +1 -1
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3659ecd8d7d5b7d1fdfaddb0b8538b86414e34687febec04f29c3352dff8d6c2
|
4
|
+
data.tar.gz: f877ba937e8361518ca4a0c16f5d3ae77dfb101ac94becd0e2f2c3ae5f01abf4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a866429e4ad00e427b8302527e4eafcd488d16b938b51d12f370104d9a8dc0abdec1f5b868f62c0afb7b10ac162a120bbe2494d6b4347f521c9c6f35cf9c00cd
|
7
|
+
data.tar.gz: 89575f81e742ca2bcd40d14c6e54ed3618daf4ad8434720ed65b6cdd4350e2189ba0721265351d62d565c49c9ac8c9a4686e96e93eabc358e29984a66999f3c1
|
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
postwave (0.0.2)
|
5
|
+
redcarpet (~> 3.6)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
rake (12.3.3)
|
11
|
+
redcarpet (3.6.0)
|
12
|
+
|
13
|
+
PLATFORMS
|
14
|
+
arm64-darwin-21
|
15
|
+
|
16
|
+
DEPENDENCIES
|
17
|
+
bundler
|
18
|
+
postwave!
|
19
|
+
rake (~> 12.3)
|
20
|
+
|
21
|
+
BUNDLED WITH
|
22
|
+
2.2.31
|
data/README.md
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
# Postwave 🌊
|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/postwave)
|
4
|
+
|
3
5
|
Write your posts statically. Interact with them dynamically.
|
4
6
|
|
5
7
|
## What is Postwave?
|
6
8
|
|
7
9
|
Postwave is an opinionated flat-file based based blog engine.
|
8
10
|
|
9
|
-
It lets you write posts in Markdown and then display them on a dynamic site using
|
10
|
-
|
11
|
-
## Getting Started
|
11
|
+
It lets you write posts in Markdown and then display them on a dynamic site using the client functionality.
|
12
12
|
|
13
|
-
|
13
|
+
## Installation
|
14
14
|
|
15
15
|
```
|
16
16
|
gem install postwave
|
17
17
|
```
|
18
18
|
|
19
|
+
## Authoring Posts
|
20
|
+
|
19
21
|
### Setup
|
20
22
|
|
21
23
|
```
|
@@ -51,11 +53,11 @@ postwave.yaml
|
|
51
53
|
> postwave post
|
52
54
|
```
|
53
55
|
|
54
|
-
This will generate at new Markdown file in the `_posts/` directory. The filename will be the current timestamp.
|
56
|
+
This will generate at new Markdown file in the `_posts/` directory. The title is set to a random string of characters. The filename will be the current timestamp. This will eventually be overwritten by the `build` command, so don't worry too much about it. The file will have a general structure like this:
|
55
57
|
|
56
58
|
```
|
57
59
|
---
|
58
|
-
title:
|
60
|
+
title: FNJEXWZP
|
59
61
|
date: 2022-01-01
|
60
62
|
tags:
|
61
63
|
---
|
@@ -82,15 +84,108 @@ draft: true
|
|
82
84
|
```
|
83
85
|
|
84
86
|
This will "build" the blog. This involves:
|
85
|
-
- regenerating the
|
87
|
+
- regenerating the `/meta/index.csv` file
|
86
88
|
- generating slugs for each posts based on the post title and ensuring that there are no duplicate slugs
|
87
89
|
- changing the post file names to match `yyyy-dd-mm-slug.md`
|
88
|
-
- updating the
|
90
|
+
- updating the `/meta/summary.yaml`
|
89
91
|
- creating and updating tag files (which will be `/tags/[tag-name].yaml` files for each tag)
|
92
|
+
- updating the `/meta/rss` file to create a feed for your posts
|
93
|
+
|
94
|
+
## Displaying Posts
|
95
|
+
|
96
|
+
You can now use Postwave's build in client to display this posts in your project.
|
97
|
+
|
98
|
+
### Include the Client In Your Project
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
require 'postwave/client'
|
102
|
+
```
|
103
|
+
|
104
|
+
### Create a Postwave Client
|
105
|
+
```ruby
|
106
|
+
postwave_client = Postwave::Client.new("path/to/config/postwave.yaml")
|
107
|
+
```
|
108
|
+
|
109
|
+
If you'd like to preload all the posts:
|
110
|
+
```ruby
|
111
|
+
postwave_client = Postwave::Client.new("path/to/config/postwave.yaml", preload: true)
|
112
|
+
```
|
113
|
+
|
114
|
+
### Get a Single Post
|
115
|
+
|
116
|
+
Pass in the stub (the filename without '.md') for the post.
|
117
|
+
```ruby
|
118
|
+
post = postwave_client.post("my-great-post")
|
119
|
+
|
120
|
+
# <Postwave::Post title="My Great Post", date=<Time ...>, tags=["tag1"], body="bla bla bla..">
|
121
|
+
|
122
|
+
puts post.title
|
123
|
+
# "My Great Post"
|
124
|
+
```
|
125
|
+
|
126
|
+
### Get a Collection of Posts
|
127
|
+
|
128
|
+
This will give you a list of posts for displaying on a page.
|
129
|
+
|
130
|
+
You can also filter by tags and specify offsets and limits (useful for pagination).
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
posts = postwave_client.posts
|
134
|
+
|
135
|
+
# [<Postwave::Post ...>, <Postwave::Post ...>, ...]
|
136
|
+
|
137
|
+
tagged_posts = postwave_client.posts(tag: "lizards")
|
90
138
|
|
91
|
-
|
139
|
+
page2_posts = postwave_client.posts(offset: 10, limit: 10)
|
140
|
+
```
|
141
|
+
Posts will be in reverse chronological order.
|
142
|
+
|
143
|
+
### Get an Index of Posts
|
144
|
+
|
145
|
+
This will give you a quick list of post summaries containing the title, date, and stub, useful for building an archive page or quick index of posts.
|
146
|
+
|
147
|
+
You can also specify offsets and limits (useful for pagination).
|
148
|
+
```ruby
|
149
|
+
index = postwave_client(index)
|
150
|
+
|
151
|
+
# [<Postwave::PostStub title="My Great Post", date=<Time ...>, stub="my-great-post">, <Postwave::PostStub ...>, ...]
|
152
|
+
|
153
|
+
puts index.first.stub
|
154
|
+
# my-great-post
|
155
|
+
|
156
|
+
page2_index = postwave_client.index(offset: 10, limit: 10)
|
157
|
+
```
|
158
|
+
Index will be in reverse chronological order.
|
159
|
+
|
160
|
+
### Get Tags Used In the Blog
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
tags = postwave_client.tags
|
164
|
+
|
165
|
+
# ["tag1", "tag2", "another-tag"]
|
166
|
+
```
|
92
167
|
|
93
|
-
|
168
|
+
### Get Details For A Tag
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
tag = postwave_clinet.tag("tag1")
|
172
|
+
|
173
|
+
# <Postwave::Tag tile="tag1", count=1, post_slugs=["my-great-post"]>
|
174
|
+
```
|
175
|
+
|
176
|
+
### Get Text For An RSS Feed
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
rss = postwave_client.rss
|
180
|
+
|
181
|
+
# "<?xml version="1.0" encoding="utf-8"?>..."
|
182
|
+
```
|
183
|
+
|
184
|
+
## Run Tests
|
185
|
+
|
186
|
+
```
|
187
|
+
rake test
|
188
|
+
```
|
94
189
|
|
95
190
|
## What is Postwave Not?
|
96
191
|
|
@@ -5,6 +5,7 @@ require 'csv'
|
|
5
5
|
require 'time'
|
6
6
|
require_relative "blog_utilities"
|
7
7
|
require_relative "display_helper"
|
8
|
+
require_relative "rss_helper"
|
8
9
|
require_relative "post"
|
9
10
|
|
10
11
|
module Postwave
|
@@ -12,6 +13,7 @@ module Postwave
|
|
12
13
|
include Singleton
|
13
14
|
include BlogUtilities
|
14
15
|
include DisplayHelper
|
16
|
+
include RssHelper
|
15
17
|
|
16
18
|
INDEX_HEADERS = ["slug", "date", "title"]
|
17
19
|
|
@@ -53,6 +55,8 @@ module Postwave
|
|
53
55
|
build_tags_files(tags)
|
54
56
|
build_summary(published_posts, tags)
|
55
57
|
|
58
|
+
build_rss(published_posts)
|
59
|
+
|
56
60
|
build_time = Time.now - start
|
57
61
|
output_build_completed(build_time)
|
58
62
|
end
|
@@ -95,8 +99,8 @@ module Postwave
|
|
95
99
|
def build_summary(posts, tags)
|
96
100
|
summary = {
|
97
101
|
post_count: posts.count,
|
98
|
-
most_recent_file_name: posts.first
|
99
|
-
most_recent_date: posts.first
|
102
|
+
most_recent_file_name: posts.first&.file_name,
|
103
|
+
most_recent_date: posts.first&.date,
|
100
104
|
tags: tags.keys
|
101
105
|
}
|
102
106
|
File.write(File.join(Dir.pwd, POSTS_DIR, META_DIR, SUMMARY_FILE_NAME), summary.to_yaml)
|
@@ -22,6 +22,8 @@ module Postwave
|
|
22
22
|
build_files
|
23
23
|
write_initial_summary_contents
|
24
24
|
|
25
|
+
configure_blog
|
26
|
+
|
25
27
|
output_blog_created
|
26
28
|
end
|
27
29
|
|
@@ -43,7 +45,23 @@ module Postwave
|
|
43
45
|
tags: []
|
44
46
|
}
|
45
47
|
|
46
|
-
File.write(File.join(Dir.pwd, POSTS_DIR, META_DIR, SUMMARY_FILE_NAME), summary.to_yaml)
|
48
|
+
File.write(File.join(Dir.pwd, POSTS_DIR, META_DIR, SUMMARY_FILE_NAME), summary.transform_keys(&:to_s).to_yaml)
|
49
|
+
end
|
50
|
+
|
51
|
+
def configure_blog
|
52
|
+
config = {}
|
53
|
+
|
54
|
+
output_blog_name_prompt
|
55
|
+
config[:name] = gets.chomp
|
56
|
+
output_blog_url_prompt
|
57
|
+
config[:url] = gets.chomp
|
58
|
+
output_blog_posts_path_prompt
|
59
|
+
config[:posts_path] = gets.chomp
|
60
|
+
output_blog_description_prompt
|
61
|
+
config[:description] = gets.chomp
|
62
|
+
|
63
|
+
File.write(File.join(Dir.pwd, CONFIG_FILE_NAME), config.transform_keys(&:to_s).to_yaml)
|
64
|
+
output_config_message
|
47
65
|
end
|
48
66
|
end
|
49
67
|
end
|
@@ -3,38 +3,47 @@ module Postwave
|
|
3
3
|
CONFIG_FILE_NAME = "postwave.yaml"
|
4
4
|
INDEX_FILE_NAME = "index.csv"
|
5
5
|
SUMMARY_FILE_NAME = "summary.yaml"
|
6
|
+
RSS_FILE_NAME = "rss"
|
6
7
|
POSTS_DIR = "_posts"
|
7
8
|
META_DIR = "meta"
|
8
9
|
TAGS_DIR = "tags"
|
9
10
|
|
10
|
-
def is_set_up?
|
11
|
-
missing_paths = find_missing_paths
|
11
|
+
def is_set_up?(blog_root = Dir.pwd)
|
12
|
+
missing_paths = find_missing_paths(blog_root)
|
12
13
|
missing_paths.empty?
|
13
14
|
end
|
14
15
|
|
15
|
-
def file_paths
|
16
|
+
def file_paths(blog_root = Dir.pwd)
|
16
17
|
[
|
17
|
-
File.join(
|
18
|
-
File.join(
|
19
|
-
File.join(
|
18
|
+
File.join(blog_root, CONFIG_FILE_NAME),
|
19
|
+
File.join(blog_root, POSTS_DIR, META_DIR, INDEX_FILE_NAME),
|
20
|
+
File.join(blog_root, POSTS_DIR, META_DIR, SUMMARY_FILE_NAME),
|
20
21
|
]
|
21
22
|
end
|
22
23
|
|
23
|
-
def directory_paths
|
24
|
+
def directory_paths(blog_root = Dir.pwd)
|
24
25
|
[
|
25
|
-
File.join(
|
26
|
-
File.join(
|
27
|
-
File.join(
|
26
|
+
File.join(blog_root, POSTS_DIR),
|
27
|
+
File.join(blog_root, POSTS_DIR, META_DIR),
|
28
|
+
File.join(blog_root, POSTS_DIR, META_DIR, TAGS_DIR),
|
28
29
|
]
|
29
30
|
end
|
30
31
|
|
31
|
-
def find_missing_paths
|
32
|
-
paths_to_check = directory_paths + file_paths
|
32
|
+
def find_missing_paths(blog_root = Dir.pwd)
|
33
|
+
paths_to_check = directory_paths(blog_root) + file_paths(blog_root)
|
33
34
|
missing_paths = []
|
34
35
|
paths_to_check.each do |path|
|
35
|
-
missing_paths << path if !FileTest.
|
36
|
+
missing_paths << path if !FileTest.exist?(path)
|
36
37
|
end
|
37
38
|
missing_paths
|
38
39
|
end
|
40
|
+
|
41
|
+
def config_values
|
42
|
+
@config_values ||= if yaml_load = YAML.load_file(File.join(Dir.pwd, CONFIG_FILE_NAME))
|
43
|
+
yaml_load.transform_keys(&:to_sym)
|
44
|
+
else
|
45
|
+
{}
|
46
|
+
end
|
47
|
+
end
|
39
48
|
end
|
40
49
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require_relative "post"
|
2
|
+
require_relative "errors"
|
3
|
+
require_relative "blog_utilities"
|
4
|
+
|
5
|
+
require "csv"
|
6
|
+
require "time"
|
7
|
+
require "yaml"
|
8
|
+
|
9
|
+
Postwave::PostStub = Struct.new(:date, :title, :slug)
|
10
|
+
Postwave::Tag = Struct.new(:name, :count, :post_slugs)
|
11
|
+
|
12
|
+
module Postwave
|
13
|
+
class Client
|
14
|
+
include BlogUtilities
|
15
|
+
|
16
|
+
def initialize(config_path, preload: false)
|
17
|
+
raise MissingConfigError unless is_valid_config?(config_path)
|
18
|
+
|
19
|
+
@blog_root = File.dirname(config_path)
|
20
|
+
raise InvalidBlogError unless is_set_up?(@blog_root)
|
21
|
+
|
22
|
+
@all_posts = get_all_posts if preload
|
23
|
+
end
|
24
|
+
|
25
|
+
# returns: an array of PostStub Structs - [<struct PostStub date=Time, title="", stub="">]
|
26
|
+
def index(offset: 0, limit: nil)
|
27
|
+
working_index = @full_index || get_full_index
|
28
|
+
count = limit || working_index.size
|
29
|
+
working_index[offset, count]
|
30
|
+
end
|
31
|
+
|
32
|
+
# returns: a post - Postwave::Post
|
33
|
+
def post(slug)
|
34
|
+
post_file_path = Dir["#{File.join(@blog_root, POSTS_DIR)}/*#{slug}.md"].first
|
35
|
+
|
36
|
+
raise PostNotFoundError unless post_file_path && File.exist?(post_file_path)
|
37
|
+
|
38
|
+
Postwave::Post.new_from_file_path(post_file_path)
|
39
|
+
end
|
40
|
+
|
41
|
+
# returns: an array of posts - [Postwave::Post]
|
42
|
+
def posts(offset: 0, limit: nil, tag: nil)
|
43
|
+
posts = @all_posts || get_all_posts
|
44
|
+
posts = posts.select { |post| post.tags.include?(tag) } if tag
|
45
|
+
count = limit || posts.size
|
46
|
+
posts[offset, count]
|
47
|
+
end
|
48
|
+
|
49
|
+
# returns: an array of tags - [String]
|
50
|
+
def tags
|
51
|
+
summary = @blog_summary || get_summary
|
52
|
+
summary[:tags]
|
53
|
+
end
|
54
|
+
|
55
|
+
# returns: a Tag Struct - <Tag tag: "", count: Integer, post_slugs: ["post-slug",..]
|
56
|
+
def tag(tag)
|
57
|
+
tag_file_path = File.join(@blog_root, POSTS_DIR, META_DIR, TAGS_DIR, "#{tag}.yaml")
|
58
|
+
raise TagNotFoundError unless File.exist?(tag_file_path)
|
59
|
+
|
60
|
+
tag_info = YAML.load_file(tag_file_path)
|
61
|
+
|
62
|
+
Postwave::Tag.new(tag, tag_info[:count], tag_info[:post_slugs])
|
63
|
+
end
|
64
|
+
|
65
|
+
# returns: a string of the xml representing an RSS feed of posts - String
|
66
|
+
def rss
|
67
|
+
rss_file_path = File.join(@blog_root, POSTS_DIR, META_DIR, RSS_FILE_NAME)
|
68
|
+
rss = File.open(rss_file_path)
|
69
|
+
rss.read
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def is_valid_config?(config_path)
|
75
|
+
File.exist?(config_path)
|
76
|
+
end
|
77
|
+
|
78
|
+
def get_all_posts
|
79
|
+
posts = []
|
80
|
+
Dir.glob(File.join(@blog_root, POSTS_DIR, "*.md")) do |post_file_path|
|
81
|
+
posts << Postwave::Post.new_from_file_path(post_file_path)
|
82
|
+
end
|
83
|
+
posts.reject! { |p| p.draft if p.respond_to? :draft }
|
84
|
+
posts.sort_by { |p| p.date }.reverse
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_full_index
|
88
|
+
full_index = []
|
89
|
+
index_contents = CSV.read(File.join(@blog_root, POSTS_DIR, META_DIR, INDEX_FILE_NAME))
|
90
|
+
index_contents.shift # skip header
|
91
|
+
index_contents.each do |post|
|
92
|
+
full_index << Postwave::PostStub.new(Time.parse(post[1]), post[2], post[0])
|
93
|
+
end
|
94
|
+
full_index
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_summary
|
98
|
+
summary_file_path = File.join(@blog_root, POSTS_DIR, META_DIR, SUMMARY_FILE_NAME)
|
99
|
+
YAML.load_file(summary_file_path)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -7,6 +7,26 @@ module Postwave
|
|
7
7
|
puts "🌊 Creating new blog..."
|
8
8
|
end
|
9
9
|
|
10
|
+
def output_blog_name_prompt
|
11
|
+
puts "Enter the name of this blog (leave blank to skip): "
|
12
|
+
end
|
13
|
+
|
14
|
+
def output_blog_url_prompt
|
15
|
+
puts "Enter the url of this blog (leave blank to skip): "
|
16
|
+
end
|
17
|
+
|
18
|
+
def output_blog_posts_path_prompt
|
19
|
+
puts "Enter the directory for the blog posts (if a post will be at http://example.com/blog/posts/post-title put blog/posts):"
|
20
|
+
end
|
21
|
+
|
22
|
+
def output_blog_description_prompt
|
23
|
+
puts "Enter a short description of this blog (leave blank to skip): "
|
24
|
+
end
|
25
|
+
|
26
|
+
def output_config_message
|
27
|
+
puts "All configuration values can be changed at any time by editing the postwave.yaml file."
|
28
|
+
end
|
29
|
+
|
10
30
|
def output_blog_created
|
11
31
|
puts "New blog set up.".green
|
12
32
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Postwave
|
2
|
+
class PostwaveError < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
class MissingConfigError < PostwaveError
|
6
|
+
end
|
7
|
+
|
8
|
+
class InvalidBlogError < PostwaveError
|
9
|
+
end
|
10
|
+
|
11
|
+
class PostNotFoundError < PostwaveError
|
12
|
+
end
|
13
|
+
|
14
|
+
class TagNotFoundError < PostwaveError
|
15
|
+
end
|
16
|
+
end
|
data/lib/postwave/post.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require_relative "blog_utilities"
|
2
|
+
require "redcarpet"
|
2
3
|
|
3
4
|
module Postwave
|
4
|
-
|
5
|
+
class Post
|
5
6
|
include BlogUtilities
|
6
7
|
|
7
8
|
KNOWN_FIELDS = %w(title date tags title_slug body draft)
|
@@ -10,6 +11,8 @@ module Postwave
|
|
10
11
|
|
11
12
|
attr_accessor :file_name
|
12
13
|
|
14
|
+
@@markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, fenced_code_blocks: true)
|
15
|
+
|
13
16
|
def self.new_from_file_path(path)
|
14
17
|
metadata_delimter_count = 0
|
15
18
|
body_buffer_count = 0
|
@@ -33,10 +36,13 @@ module Postwave
|
|
33
36
|
next if clean_line.empty?
|
34
37
|
end
|
35
38
|
|
36
|
-
field_content["body"] += "#{line}
|
39
|
+
field_content["body"] += "#{line}"
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
43
|
+
# turn "date" into a Time object
|
44
|
+
field_content["date"] = Time.parse(field_content["date"])
|
45
|
+
|
40
46
|
# turn "tags" into an array
|
41
47
|
if field_content["tags"]
|
42
48
|
field_content["tags"] = field_content["tags"].split(",").map do |tag|
|
@@ -56,8 +62,8 @@ module Postwave
|
|
56
62
|
@file_name = file_name
|
57
63
|
|
58
64
|
field_content.each do |field, value|
|
59
|
-
instance_variable_set("@#{field}", value)
|
60
|
-
self.class.send(:
|
65
|
+
instance_variable_set("@#{field}", value) unless self.instance_variables.include?("@#{field}".to_sym)
|
66
|
+
self.class.send(:attr_reader, field) unless self.public_methods.include?(field.to_sym)
|
61
67
|
end
|
62
68
|
end
|
63
69
|
|
@@ -73,9 +79,13 @@ module Postwave
|
|
73
79
|
@slug = new_slug
|
74
80
|
end
|
75
81
|
|
82
|
+
def body_html
|
83
|
+
@@markdown.render(@body)
|
84
|
+
end
|
85
|
+
|
76
86
|
def generated_file_name
|
77
87
|
# YYYY-MM-DD-slug-from-title.md
|
78
|
-
"#{@date[..9]}-#{slug}.md"
|
88
|
+
"#{@date.to_s[..9]}-#{slug}.md"
|
79
89
|
end
|
80
90
|
|
81
91
|
def update_file_name!
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative "blog_utilities"
|
2
|
+
require "erb"
|
3
|
+
require 'redcarpet'
|
4
|
+
|
5
|
+
module Postwave
|
6
|
+
module RssHelper
|
7
|
+
include BlogUtilities
|
8
|
+
|
9
|
+
FeedPost = Struct.new(:title, :link, :body, :date, :tags)
|
10
|
+
|
11
|
+
def build_rss(posts)
|
12
|
+
File.open(File.join(Dir.pwd, POSTS_DIR, META_DIR, RSS_FILE_NAME), "w") do |rss|
|
13
|
+
rss << feed_content(posts)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def feed_content(posts)
|
18
|
+
link = config_values[:url]
|
19
|
+
updated = Time.now.iso8601.to_s
|
20
|
+
title = config_values[:name]
|
21
|
+
description = config_values[:description]
|
22
|
+
|
23
|
+
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, fenced_code_blocks: true)
|
24
|
+
feed_posts = posts.map do |post|
|
25
|
+
post_link = "#{config_values[:url]}/#{config_values[:posts_path]}/#{post.slug}"
|
26
|
+
html_body = CGI.unescapeHTML(markdown.render(post.body))
|
27
|
+
FeedPost.new(post.title, post_link, html_body, post.date.iso8601, post.tags)
|
28
|
+
end
|
29
|
+
|
30
|
+
path = File.join(__dir__, "templates/feed.erb")
|
31
|
+
template = File.read(path)
|
32
|
+
renderer = ERB.new(template)
|
33
|
+
renderer.result(binding)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<feed xmlns="http://www.w3.org/2005/Atom">
|
3
|
+
<generator uri="https://github.com/dorkrawk/postwave" version="<%= Postwave::VERSION %>">Postwave</generator>
|
4
|
+
<link href="<%= link %>" rel="self" type="application/atom+xml" />
|
5
|
+
<link href="<%= link %>" />
|
6
|
+
<updated><%= updated %></updated>
|
7
|
+
<id><%= link %></id>
|
8
|
+
<title type="html"><%= title %></title>
|
9
|
+
<subtitle><%= description %></subtitle>
|
10
|
+
<% feed_posts.each do |post| %>
|
11
|
+
<entry>
|
12
|
+
<title><%= post.title %></title>
|
13
|
+
<link href="<%= post.link %>" rel="alternate" type="text/html" title="<%= post.title %>" />
|
14
|
+
<id><%= post.link %></id>
|
15
|
+
<published><%= post.date %></published>
|
16
|
+
<updated><%= post.date %></updated>
|
17
|
+
<author>
|
18
|
+
<name><%= title %></name>
|
19
|
+
</author>
|
20
|
+
<content type="html">
|
21
|
+
<![CDATA[<%= post.body %>]]>
|
22
|
+
</content>
|
23
|
+
<% post.tags.each do |tag| %>
|
24
|
+
<category term="<%= tag %>" />
|
25
|
+
<% end %>
|
26
|
+
</entry>
|
27
|
+
<% end %>
|
28
|
+
</feed>
|
data/lib/postwave/version.rb
CHANGED
data/lib/postwave.rb
CHANGED
data/postwave.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = ['postwave']
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
|
21
|
+
spec.add_dependency "redcarpet", '~> 3.6'
|
22
22
|
|
23
23
|
spec.add_development_dependency "bundler"
|
24
24
|
spec.add_development_dependency "rake", "~> 12.3"
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postwave
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dave Schwantes
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: redcarpet
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.6'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -48,6 +62,7 @@ extra_rdoc_files: []
|
|
48
62
|
files:
|
49
63
|
- ".gitignore"
|
50
64
|
- Gemfile
|
65
|
+
- Gemfile.lock
|
51
66
|
- README.md
|
52
67
|
- Rakefile
|
53
68
|
- bin/postwave
|
@@ -55,9 +70,13 @@ files:
|
|
55
70
|
- lib/postwave/blog_builder.rb
|
56
71
|
- lib/postwave/blog_creator.rb
|
57
72
|
- lib/postwave/blog_utilities.rb
|
73
|
+
- lib/postwave/client.rb
|
58
74
|
- lib/postwave/display_helper.rb
|
75
|
+
- lib/postwave/errors.rb
|
59
76
|
- lib/postwave/post.rb
|
60
77
|
- lib/postwave/post_creator.rb
|
78
|
+
- lib/postwave/rss_helper.rb
|
79
|
+
- lib/postwave/templates/feed.erb
|
61
80
|
- lib/postwave/version.rb
|
62
81
|
- postwave.gemspec
|
63
82
|
homepage: https://github.com/dorkrawk/postwave
|