markdowndocs 0.5.0 → 0.6.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/CHANGELOG.md +35 -0
- data/README.md +21 -0
- data/app/controllers/markdowndocs/docs_controller.rb +10 -2
- data/app/models/markdowndocs/documentation.rb +41 -4
- data/lib/markdowndocs/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 57e0fd3a2811b71d43a7e32029abd3a252af462158017fe7dff81abe94b827eb
|
|
4
|
+
data.tar.gz: bc74b02043fb27fa165d89cbbad04f8c89209fd45ef584ac6e1d017ffd89548b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ce7f0b7b5ad9e21ff9b58d7bfe5a55319b127b68b9f614d33c69c2d825f3cb33bf8e58be7915ab619bcdb54b3830b7d699ed2ea1efa995204b7759f1967a45bc
|
|
7
|
+
data.tar.gz: 2fbb656ed33f668b517f2d8a105fd3c1be00a2b0a3f6d212f7fc80b603118121e5eea04e569ea7d75d0146a82537c299a65cebfc425e9b36dd49a5205aa1e60f
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,41 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.6.0] - 2026-05-13
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `audience:` frontmatter key on individual docs. Accepts a single string
|
|
13
|
+
or an array of mode names (e.g. `audience: technical`, or
|
|
14
|
+
`audience: [guide, technical]`). When the current mode does not appear
|
|
15
|
+
in a doc's audience, the doc is hidden from the index and unreachable
|
|
16
|
+
via slug (returns 404). Docs WITHOUT an `audience:` key remain visible
|
|
17
|
+
in every mode — fully backward compatible with pre-0.6 docs.
|
|
18
|
+
- `Documentation#audience` returns the resolved audience as `Array<String>`.
|
|
19
|
+
- `Documentation#visible_to?(mode)` predicate. `nil` mode means no filter.
|
|
20
|
+
- `Documentation.find_by_slug(slug, mode: nil)` and
|
|
21
|
+
`Documentation.grouped_by_category(mode: nil)` both accept an optional
|
|
22
|
+
`mode:` kwarg. Default behavior (no kwarg) is unchanged — backward
|
|
23
|
+
compatible signature.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- `Documentation.grouped_by_category` now drops empty categories when a
|
|
28
|
+
`mode:` filter is applied — categories whose docs are all hidden by the
|
|
29
|
+
current audience no longer render as empty headers.
|
|
30
|
+
- `Markdowndocs::DocsController#index` and `#show` pass the resolved
|
|
31
|
+
`@docs_mode` through to `Documentation` so the index reflects the
|
|
32
|
+
user's mode pick. URL guessing / shared links to wrong-audience docs
|
|
33
|
+
now return 404.
|
|
34
|
+
|
|
35
|
+
### Migration notes
|
|
36
|
+
|
|
37
|
+
- No action required if you don't use modes. Existing docs continue to
|
|
38
|
+
appear in both `guide` and `technical` modes.
|
|
39
|
+
- To restrict a doc to a specific audience, add `audience: technical`
|
|
40
|
+
(or `audience: guide`) to its frontmatter.
|
|
41
|
+
- To make a doc explicitly multi-audience, use `audience: [guide, technical]`.
|
|
42
|
+
|
|
8
43
|
## [0.5.0] - 2026-05-05
|
|
9
44
|
|
|
10
45
|
### Added
|
data/README.md
CHANGED
|
@@ -108,6 +108,9 @@ Add optional YAML front matter to set metadata:
|
|
|
108
108
|
---
|
|
109
109
|
title: "Quick Start Guide"
|
|
110
110
|
description: "Get up and running in five minutes"
|
|
111
|
+
audience:
|
|
112
|
+
- guide
|
|
113
|
+
- technical
|
|
111
114
|
modes:
|
|
112
115
|
- guide
|
|
113
116
|
- technical
|
|
@@ -121,6 +124,24 @@ Your content here...
|
|
|
121
124
|
|
|
122
125
|
If front matter is omitted, the title is extracted from the first H1 heading and the description from the first paragraph.
|
|
123
126
|
|
|
127
|
+
### Audience Filtering (whole-document)
|
|
128
|
+
|
|
129
|
+
For content that's split into separate files per audience (a user guide
|
|
130
|
+
and a deep-dive technical reference, for example), use the `audience:`
|
|
131
|
+
key in front matter to declare who a doc is for:
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
audience: technical # single-audience: shown only when mode=technical
|
|
135
|
+
audience: [guide, technical] # multi-audience: shown in either mode
|
|
136
|
+
# omit `audience:` # backward-compatible: shown in every mode
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
When the current mode does not appear in a doc's audience, the doc is
|
|
140
|
+
hidden from the index AND unreachable via slug (404). This complements
|
|
141
|
+
the in-page `<!-- mode: -->` blocks below: use mode blocks when one doc
|
|
142
|
+
mixes audience-specific snippets; use `audience:` when whole docs are
|
|
143
|
+
audience-specific.
|
|
144
|
+
|
|
124
145
|
### Mode Blocks
|
|
125
146
|
|
|
126
147
|
Use HTML comments to show content only in specific modes:
|
|
@@ -9,7 +9,10 @@ module Markdowndocs
|
|
|
9
9
|
SAFE_SLUG_PATTERN = /\A[a-zA-Z0-9_-]+\z/
|
|
10
10
|
|
|
11
11
|
def index
|
|
12
|
-
|
|
12
|
+
# Pass the resolved mode so docs whose `audience:` frontmatter
|
|
13
|
+
# excludes it are hidden from the index. Categories with no
|
|
14
|
+
# surviving docs are dropped (see Documentation.grouped_by_category).
|
|
15
|
+
@docs_by_category = Documentation.grouped_by_category(mode: @docs_mode)
|
|
13
16
|
@search_enabled = Markdowndocs.config.search_enabled
|
|
14
17
|
end
|
|
15
18
|
|
|
@@ -38,7 +41,12 @@ module Markdowndocs
|
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
def show
|
|
41
|
-
|
|
44
|
+
# Audience filter: a doc with `audience: technical` is unreachable
|
|
45
|
+
# via slug while the user is in guide mode — they get the 404 page,
|
|
46
|
+
# not the doc's content. This matters because the index already
|
|
47
|
+
# hides those docs; making the show route honor the same filter
|
|
48
|
+
# keeps URL guessing / shared-link scenarios consistent.
|
|
49
|
+
@doc = Documentation.find_by_slug(params[:slug], mode: @docs_mode)
|
|
42
50
|
|
|
43
51
|
if @doc.nil?
|
|
44
52
|
render_not_found
|
|
@@ -23,14 +23,21 @@ module Markdowndocs
|
|
|
23
23
|
end.sort_by(&:slug)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
# When `mode:` is given (e.g. "guide" / "technical"), returns nil if
|
|
27
|
+
# the resolved doc's `audience:` frontmatter excludes that mode. Docs
|
|
28
|
+
# without an explicit `audience:` key default to "visible in all modes"
|
|
29
|
+
# — backward compatible with pre-0.6 docs.
|
|
30
|
+
def self.find_by_slug(slug, mode: nil)
|
|
27
31
|
return nil if slug.blank?
|
|
28
32
|
return nil if slug.include?("..") || slug.include?("/")
|
|
29
33
|
|
|
30
34
|
file_path = Markdowndocs.config.resolved_docs_path.join("#{slug}.md")
|
|
31
35
|
return nil unless file_path.exist?
|
|
32
36
|
|
|
33
|
-
new(file_path)
|
|
37
|
+
doc = new(file_path)
|
|
38
|
+
return nil unless doc.visible_to?(mode)
|
|
39
|
+
|
|
40
|
+
doc
|
|
34
41
|
rescue => e
|
|
35
42
|
Rails.logger.error("Error finding documentation by slug '#{slug}': #{e.message}")
|
|
36
43
|
nil
|
|
@@ -40,9 +47,13 @@ module Markdowndocs
|
|
|
40
47
|
all.select { |doc| doc.category == category }
|
|
41
48
|
end
|
|
42
49
|
|
|
43
|
-
|
|
50
|
+
# When `mode:` is given, filters out docs whose `audience:` excludes
|
|
51
|
+
# that mode AND drops categories that end up empty (so the index
|
|
52
|
+
# sidebar doesn't render headers with no children).
|
|
53
|
+
def self.grouped_by_category(mode: nil)
|
|
44
54
|
Markdowndocs.config.categories.each_with_object({}) do |(category, slugs), hash|
|
|
45
|
-
|
|
55
|
+
docs = slugs.map { |slug| find_by_slug(slug, mode: mode) }.compact
|
|
56
|
+
hash[category] = docs unless docs.empty?
|
|
46
57
|
end
|
|
47
58
|
end
|
|
48
59
|
|
|
@@ -83,6 +94,32 @@ module Markdowndocs
|
|
|
83
94
|
available_modes.include?(mode.to_s)
|
|
84
95
|
end
|
|
85
96
|
|
|
97
|
+
# The audience(s) this doc is written for, declared via `audience:`
|
|
98
|
+
# frontmatter. Accepts a single string or an array; both are coerced
|
|
99
|
+
# to an Array<String>. When the frontmatter key is missing, defaults
|
|
100
|
+
# to all configured modes — a doc with no audience declaration is
|
|
101
|
+
# visible in every mode (backward compat with pre-0.6 docs).
|
|
102
|
+
def audience
|
|
103
|
+
@audience ||= begin
|
|
104
|
+
parsed = parse_frontmatter
|
|
105
|
+
raw = parsed[:frontmatter]["audience"]
|
|
106
|
+
case raw
|
|
107
|
+
when Array then raw.map(&:to_s)
|
|
108
|
+
when String then [ raw ]
|
|
109
|
+
when nil then Markdowndocs.config.modes.dup
|
|
110
|
+
else Markdowndocs.config.modes.dup
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Whether this doc should be surfaced to a viewer in the given mode.
|
|
116
|
+
# `nil` mode is treated as "no filter" — useful for callers that
|
|
117
|
+
# don't care about audience (search indexer, admin tools).
|
|
118
|
+
def visible_to?(mode)
|
|
119
|
+
return true if mode.nil?
|
|
120
|
+
audience.include?(mode.to_s)
|
|
121
|
+
end
|
|
122
|
+
|
|
86
123
|
# Returns content stripped of frontmatter, markdown syntax, and HTML tags
|
|
87
124
|
# for use in search indexing.
|
|
88
125
|
def plain_text_content
|
data/lib/markdowndocs/version.rb
CHANGED