postwave 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c9ded40bea3eeb7f6f76e5de2f3df929f4ced4d3e8045af330747b5390b06e70
4
- data.tar.gz: cc9f0bbe6554d86b510972d59eb979dd41911ad9b081a0a44c04ef974005ee38
3
+ metadata.gz: 3659ecd8d7d5b7d1fdfaddb0b8538b86414e34687febec04f29c3352dff8d6c2
4
+ data.tar.gz: f877ba937e8361518ca4a0c16f5d3ae77dfb101ac94becd0e2f2c3ae5f01abf4
5
5
  SHA512:
6
- metadata.gz: 1550146a4c3967f077312340d58e3b61691a0022e38c5bc225bae21da657be95b3340ac3a5ef04866f8d5a6861b996ec8161f0ecb57c6309a13d97c3e445d435
7
- data.tar.gz: aaec0f9aa5ad0ae598e204e777cfb80eb0087ca59717d6a60a40d7e615407545a4a4d1d1d5190706889ecedfa34c427c00367801c1996a89e5a400330991330e
6
+ metadata.gz: a866429e4ad00e427b8302527e4eafcd488d16b938b51d12f370104d9a8dc0abdec1f5b868f62c0afb7b10ac162a120bbe2494d6b4347f521c9c6f35cf9c00cd
7
+ data.tar.gz: 89575f81e742ca2bcd40d14c6e54ed3618daf4ad8434720ed65b6cdd4350e2189ba0721265351d62d565c49c9ac8c9a4686e96e93eabc358e29984a66999f3c1
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in trackstar.gemspec
3
+ # Specify your gem's dependencies in postwave.gemspec
4
4
  gemspec
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
+ [![Gem Version](https://badge.fury.io/rb/postwave.svg)](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 a client library.
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
- ### Installation
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. 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:
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 `index.csv` file
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 `summary.yaml`
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
- ## Available Client Libraries
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
- - [Ruby](https://github.com/dorkrawk/postwave-ruby-client)
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
 
@@ -8,41 +8,41 @@ module Postwave
8
8
  META_DIR = "meta"
9
9
  TAGS_DIR = "tags"
10
10
 
11
- def is_set_up?
12
- missing_paths = find_missing_paths
11
+ def is_set_up?(blog_root = Dir.pwd)
12
+ missing_paths = find_missing_paths(blog_root)
13
13
  missing_paths.empty?
14
14
  end
15
15
 
16
- def file_paths
16
+ def file_paths(blog_root = Dir.pwd)
17
17
  [
18
- File.join(Dir.pwd, CONFIG_FILE_NAME),
19
- File.join(Dir.pwd, POSTS_DIR, META_DIR, INDEX_FILE_NAME),
20
- File.join(Dir.pwd, POSTS_DIR, META_DIR, SUMMARY_FILE_NAME),
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),
21
21
  ]
22
22
  end
23
23
 
24
- def directory_paths
24
+ def directory_paths(blog_root = Dir.pwd)
25
25
  [
26
- File.join(Dir.pwd, POSTS_DIR),
27
- File.join(Dir.pwd, POSTS_DIR, META_DIR),
28
- File.join(Dir.pwd, POSTS_DIR, META_DIR, TAGS_DIR),
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),
29
29
  ]
30
30
  end
31
31
 
32
- def find_missing_paths
33
- 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)
34
34
  missing_paths = []
35
35
  paths_to_check.each do |path|
36
- missing_paths << path if !FileTest.exists?(path)
36
+ missing_paths << path if !FileTest.exist?(path)
37
37
  end
38
38
  missing_paths
39
39
  end
40
40
 
41
41
  def config_values
42
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
- {}
43
+ yaml_load.transform_keys(&:to_sym)
44
+ else
45
+ {}
46
46
  end
47
47
  end
48
48
  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
@@ -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
- class Post
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
@@ -59,8 +62,8 @@ module Postwave
59
62
  @file_name = file_name
60
63
 
61
64
  field_content.each do |field, value|
62
- instance_variable_set("@#{field}", value)
63
- self.class.send(:attr_accessor, field)
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)
64
67
  end
65
68
  end
66
69
 
@@ -76,6 +79,10 @@ module Postwave
76
79
  @slug = new_slug
77
80
  end
78
81
 
82
+ def body_html
83
+ @@markdown.render(@body)
84
+ end
85
+
79
86
  def generated_file_name
80
87
  # YYYY-MM-DD-slug-from-title.md
81
88
  "#{@date.to_s[..9]}-#{slug}.md"
@@ -1,35 +1,36 @@
1
1
  require_relative "blog_utilities"
2
- require "rss"
2
+ require "erb"
3
+ require 'redcarpet'
3
4
 
4
5
  module Postwave
5
6
  module RssHelper
6
7
  include BlogUtilities
7
8
 
9
+ FeedPost = Struct.new(:title, :link, :body, :date, :tags)
10
+
8
11
  def build_rss(posts)
9
12
  File.open(File.join(Dir.pwd, POSTS_DIR, META_DIR, RSS_FILE_NAME), "w") do |rss|
10
- rss << rss_content(posts)
13
+ rss << feed_content(posts)
11
14
  end
12
15
  end
13
16
 
14
- def rss_content(posts)
15
- RSS::Maker.make("2.0") do |maker|
16
- maker.channel.title = config_values[:name]
17
- maker.channel.description = config_values[:description]
18
- maker.channel.link = config_values[:url]
19
- maker.channel.generator = "Postwave"
20
- maker.channel.updated = Time.now.to_s
21
-
22
- posts.each do |post|
23
- link = "#{config_values[:url]}/#{config_values[:posts_path]}/#{post.slug}"
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]
24
22
 
25
- maker.items.new_item do |item|
26
- item.title = post.title
27
- item.link = link
28
- item.description = post.body
29
- item.pubDate = post.date
30
- end
31
- end
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)
32
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)
33
34
  end
34
35
  end
35
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>
@@ -1,3 +1,3 @@
1
1
  module Postwave
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
data/lib/postwave.rb CHANGED
@@ -14,7 +14,7 @@ module Postwave
14
14
  Postwave::BlogBuilder.instance.build
15
15
  else
16
16
  if options[:version]
17
- puts "postwave #{VERSION} [ruby]"
17
+ puts "postwave #{VERSION}"
18
18
  end
19
19
  end
20
20
  end
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
- # spec.add_dependency ""
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.2
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: 2024-01-17 00:00:00.000000000 Z
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,19 +62,21 @@ 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
54
- - crystal/src/postwave.cr
55
- - crystal/src/postwave/post.cr
56
69
  - lib/postwave.rb
57
70
  - lib/postwave/blog_builder.rb
58
71
  - lib/postwave/blog_creator.rb
59
72
  - lib/postwave/blog_utilities.rb
73
+ - lib/postwave/client.rb
60
74
  - lib/postwave/display_helper.rb
75
+ - lib/postwave/errors.rb
61
76
  - lib/postwave/post.rb
62
77
  - lib/postwave/post_creator.rb
63
78
  - lib/postwave/rss_helper.rb
79
+ - lib/postwave/templates/feed.erb
64
80
  - lib/postwave/version.rb
65
81
  - postwave.gemspec
66
82
  homepage: https://github.com/dorkrawk/postwave
@@ -1,77 +0,0 @@
1
- class Postwave::Post
2
- KNOWN_FIELDS = %w(title date tags title_slug body draft)
3
- REQUIRED_FIELDS = %w(title date)
4
- MEATADATA_DELIMTER = "---"
5
-
6
- def self.new_from_file_path(path : String)
7
- metadata_delimter_count = 0
8
- body_buffer_count = 0
9
- field_content = { "body" => "" }
10
-
11
- File.readlines(path).each do |line|
12
- clean_line = line.strip
13
-
14
- if clean_line == MEATADATA_DELIMTER
15
- metadata_delimter_count += 1
16
- next
17
- end
18
-
19
- if metadata_delimter_count == 0
20
- next
21
- elsif metadata_delimter_count == 1
22
- field, value = clean_line.split(":", 2).map(&:strip)
23
- field_content[field] = value
24
- else
25
- if body_buffer_count == 0
26
- body_buffer_count += 1
27
- next if clean_line.empty?
28
- end
29
-
30
- field_content["body"] += "#{line}"
31
- end
32
- end
33
-
34
- # turn "date" into a Time object
35
- field_content["date"] = Time.parse(field_content["date"])
36
-
37
- # turn "tags" into an array
38
- if field_content["tags"]
39
- field_content["tags"] = field_content["tags"].split(",").map do |tag|
40
- tag.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, "")
41
- end
42
- end
43
-
44
- # turn "draft" into boolean
45
- if field_content["draft"]
46
- field_content["draft"] = field_content["draft"].downcase == "true"
47
- end
48
-
49
- self.new(path, field_content)
50
- end
51
-
52
- def initialize(@file_name : String, field_content : Hash)
53
-
54
- field_content.each do |field, value|
55
- # instance_variable_set("@#{field}", value)
56
- self.send("@#{field}".to_sym, value)
57
- self.class.send(:attr_accessor, field)
58
- end
59
- end
60
-
61
- def title_slug : String
62
- @title_slug ||= @title.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, "")
63
- end
64
-
65
- def slug : String
66
- @slug ||= @title_slug
67
- end
68
-
69
- def slug=(new_slug)
70
- @slug = new_slug
71
- end
72
-
73
- def generated_file_name
74
- # YYYY-MM-DD-slug-from-title.md
75
- "#{@date.to_s[..9]}-#{slug}.md"
76
- end
77
- end
@@ -1,4 +0,0 @@
1
- require "./postwave/*"
2
-
3
- module Postwave
4
- end