feat: add scheduled publishing with publish_at frontmatter field

Posts with a future publish_at date are hidden from the public API
and feeds, same as drafts. The admin form exposes a Publish at field.
This commit is contained in:
2026-06-25 22:06:49 +02:00
parent 52be2bb996
commit 73be893bf8
5 changed files with 56 additions and 1 deletions
+18
View File
@@ -56,6 +56,24 @@ module Volumen
metadata["cover"]
end
def publish_at
metadata["publish_at"]
end
def scheduled?
value = publish_at
return false if value.nil?
date = case value
when Date then value
when Time then value.to_date
else Date.iso8601(value.to_s)
end
date > Date.today
rescue ArgumentError
false
end
def reading_time
words = body.split(/\s+/).count { |word| !word.empty? }
[(words / 200.0).ceil, 1].max
+3 -1
View File
@@ -79,7 +79,8 @@ module Volumen
end
def published_posts
store.all.reject(&:draft?).sort_by { |post| post.date_string || "" }.reverse
store.all.reject { |post| post.draft? || post.scheduled? }
.sort_by { |post| post.date_string || "" }.reverse
end
def site_payload
@@ -369,6 +370,7 @@ module Volumen
"lang" => presence(http_params["lang"]),
"author" => presence(http_params["author"]),
"date" => parse_date(http_params["date"]),
"publish_at" => parse_date(http_params["publish_at"]),
"tags" => parse_tags(http_params["tags"]),
"excerpt" => presence(http_params["excerpt"]),
"cover" => presence(http_params["cover"]),
+5
View File
@@ -17,6 +17,11 @@
<label>Language <input type="text" name="lang" value="<%= h(@post.lang) %>"></label>
<label>Author <input type="text" name="author" value="<%= h(@post.author) %>"></label>
<label>Date <input type="date" name="date" value="<%= h(@post.date_string) %>"></label>
<label>Publish at
<input type="date" name="publish_at"
value="<%= @post.publish_at.is_a?(Date) ? @post.publish_at.strftime("%Y-%m-%d") : "" %>"
placeholder="leave empty for immediate">
</label>
<label>Tags
<input type="text" name="tags" value="<%= h(@post.tags.join(", ")) %>"
placeholder="comma, separated">