jekyll-awesome-nav 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d260f9f2584da9eadd23954eeaea7886a7b4aa76a9ff7ea5e51b96f0968a35c
4
- data.tar.gz: fc44438a6db69080c36db2b6d01613438f4d8561d7d7f4b10720ed29f0c15e1a
3
+ metadata.gz: 01fa08c8a44630c6314fb330db8db6de0977bc66adb8e2c48dd5f127ede6ff8d
4
+ data.tar.gz: 29964bc8684fc64593bb76b9385ec19706b578aef5ee780155be2f518c50873b
5
5
  SHA512:
6
- metadata.gz: a2a84a0bbddfb75659facdd03ab3d0561ad4be3cd5e762fe2742501f6bcec9149d521c32b897c05a258c8a719975507e553cbefc73c115801d8f48ea795d7e24
7
- data.tar.gz: e141a89da191d1444cdbbf6d23906b4bf7361fb9f782255c4793143a010387c18d98ce90ab62bba19f37444d0c10646885d0de8abe5800ea2f67095abbb4cd6e
6
+ metadata.gz: d191dc308b3c7b7b2431417f12c4cdfe59b7acb4c2461364beec68a481909b81dad07724405ee2a2a1644203b6bf13705e86f60af8e98b0895363b3a202a5cb1
7
+ data.tar.gz: ef4ed52b48b7595d0994ff1f19ba64d70d4e81998ea1ded6b14b395f165a11a0ea5efe43bff3de73ebd8c7e35a48a5e06e7ec1054ff2407becfc838e7ceae6ae
@@ -1,5 +1,5 @@
1
1
  # Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
2
- _commit: 7ca8425
2
+ _commit: aac269f
3
3
  _src_path: gh:athackst/ci
4
4
  automerge_mode: poll
5
5
  bump_script_path: ''
@@ -7,6 +7,5 @@ do_releases: true
7
7
  release_template: '## What''s changed
8
8
 
9
9
 
10
- $CHANGES
11
- '
10
+ $CHANGES '
12
11
  site_generator: none
data/.vscode/tasks.json CHANGED
@@ -36,7 +36,7 @@
36
36
  {
37
37
  "label": "Build Docs Site",
38
38
  "type": "shell",
39
- "command": "bundle exec jekyll build --source site --destination /tmp/jekyll-awesome-nav-site",
39
+ "command": "bundle exec rake site",
40
40
  "options": {
41
41
  "cwd": "${workspaceFolder}"
42
42
  },
@@ -46,7 +46,7 @@
46
46
  {
47
47
  "label": "Serve Docs Site",
48
48
  "type": "shell",
49
- "command": "bundle exec jekyll serve --source site --destination /tmp/jekyll-awesome-nav-site --livereload",
49
+ "command": "bundle exec rake serve",
50
50
  "options": {
51
51
  "cwd": "${workspaceFolder}"
52
52
  },
data/README.md CHANGED
@@ -28,6 +28,37 @@ awesome_nav:
28
28
  enabled: true
29
29
  root: docs
30
30
  nav_filename: .nav.yml
31
+ include:
32
+ - "**/*.md"
33
+ - "**/*.html"
34
+ - "**/*.htm"
35
+ ignore:
36
+ - "assets/**"
37
+ ```
38
+
39
+ ## Configuration
40
+
41
+ `awesome_nav` options:
42
+
43
+ - `enabled` (default: `true`): enable or disable the plugin.
44
+ - `root` (default: `docs`): source directory root to build navigation from.
45
+ - `nav_filename` (default: `.nav.yml`): per-directory override filename.
46
+ - `include` (default: `["**/*.md", "**/*.html", "**/*.htm"]`): source path globs that are eligible for navigation.
47
+ - `ignore` (default: `["assets/**"]`): source path globs excluded from navigation.
48
+
49
+ `include`/`ignore` apply to source paths in `site.pages` before tree generation. If `include` is set, a page must match
50
+ at least one include pattern to be considered. Ignore patterns are then applied to remove matches.
51
+
52
+ Example custom filtering:
53
+
54
+ ```yaml
55
+ awesome_nav:
56
+ root: ""
57
+ include:
58
+ - "README.md"
59
+ - "docs/**/*.md"
60
+ ignore:
61
+ - "docs/drafts/**"
31
62
  ```
32
63
 
33
64
  ## Exposed Page Data
@@ -154,7 +185,7 @@ bundle exec jekyll serve --source site
154
185
  ```
155
186
 
156
187
  The docs site renders `page.awesome_nav`, `page.awesome_nav_local`, `page.breadcrumbs`, and previous/next links
157
- through a small layout in `site/_layouts/docs.html`.
188
+ through a small layout in `site/_layouts/awesome_nav_demo.html`.
158
189
 
159
190
  ## Development
160
191
 
data/Rakefile CHANGED
@@ -1,11 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler/gem_tasks"
4
+ require "fileutils"
4
5
  require "rake/testtask"
6
+ require "rubocop/rake_task"
5
7
 
6
8
  Rake::TestTask.new(:test) do |test|
7
9
  test.libs << "test"
8
10
  test.pattern = "test/**/*_test.rb"
9
11
  end
10
12
 
13
+ RuboCop::RakeTask.new(:lint)
14
+
15
+ desc "Build documentation site"
16
+ task :site do
17
+ sh "bundle exec jekyll build --source site --destination _site"
18
+ end
19
+
20
+ desc "Serve documentation site"
21
+ task :serve do
22
+ sh "bundle exec jekyll serve --source site --destination _site --livereload"
23
+ end
24
+
25
+ desc "Remove local build and cache artifacts"
26
+ task :clean do
27
+ artifacts = [
28
+ "_site",
29
+ ".jekyll-cache",
30
+ ".sass-cache"
31
+ ]
32
+ artifacts.each { |path| FileUtils.rm_rf(path) }
33
+ end
34
+
11
35
  task default: :test
@@ -6,7 +6,9 @@ module Jekyll
6
6
  DEFAULTS = {
7
7
  "enabled" => true,
8
8
  "root" => "docs",
9
- "nav_filename" => ".nav.yml"
9
+ "nav_filename" => ".nav.yml",
10
+ "ignore" => ["assets/**"],
11
+ "include" => ["**/*.md", "**/*.html", "**/*.htm"]
10
12
  }.freeze
11
13
 
12
14
  def initialize(raw_config)
@@ -26,6 +28,21 @@ module Jekyll
26
28
  def nav_filename
27
29
  @data["nav_filename"].to_s
28
30
  end
31
+
32
+ def ignore_patterns
33
+ value = @data["ignore"]
34
+ return [] if value.nil?
35
+
36
+ Array(value).map { |pattern| Utils.normalize_dir(pattern.to_s) }.reject(&:empty?)
37
+ end
38
+
39
+ def include_patterns
40
+ value = @data["include"]
41
+ return nil if value.nil?
42
+
43
+ patterns = Array(value).map { |pattern| Utils.normalize_dir(pattern.to_s) }.reject(&:empty?)
44
+ patterns.empty? ? nil : patterns
45
+ end
29
46
  end
30
47
  end
31
48
  end
@@ -4,7 +4,9 @@ module Jekyll
4
4
  module AwesomeNav
5
5
  class Generator < Jekyll::Generator
6
6
  safe true
7
- priority :low
7
+ # Run after low-priority generators (for example jekyll-readme-index),
8
+ # so synthetic pages are present before nav data assignment.
9
+ priority :lowest
8
10
 
9
11
  def generate(site)
10
12
  config = Config.new(site.config["awesome_nav"])
@@ -85,13 +85,13 @@ module Jekyll
85
85
 
86
86
  def root_breadcrumb(page)
87
87
  title = page.data["nav_title"] || page.data["title"] || Utils.titleize(Utils.last_segment(@root_dir))
88
+ title = resolved_root_title if title.to_s.empty?
88
89
  [{ "title" => title, "url" => Utils.normalize_url(page.url) }]
89
90
  end
90
91
 
91
92
  def prepend_root_breadcrumb(breadcrumbs)
92
93
  root_crumb = {
93
- "title" => @root_page&.data&.fetch("nav_title",
94
- nil) || @root_page&.data&.fetch("title", nil) || Utils.titleize(Utils.last_segment(@root_dir)),
94
+ "title" => resolved_root_title,
95
95
  "url" => Utils.normalize_url(@root_page&.url || "/#{@root_dir}/")
96
96
  }
97
97
 
@@ -105,7 +105,7 @@ module Jekyll
105
105
  items = []
106
106
  if @root_page
107
107
  items << {
108
- "title" => @root_page.data["nav_title"] || @root_page.data["title"] || Utils.titleize(Utils.last_segment(@root_dir)),
108
+ "title" => resolved_root_title,
109
109
  "url" => Utils.normalize_url(@root_page.url)
110
110
  }
111
111
  end
@@ -145,6 +145,17 @@ module Jekyll
145
145
  def deep_copy(value)
146
146
  Marshal.load(Marshal.dump(value))
147
147
  end
148
+
149
+ def resolved_root_title
150
+ title = @root_page&.data&.fetch("nav_title", nil) ||
151
+ @root_page&.data&.fetch("title", nil) ||
152
+ Utils.titleize(Utils.last_segment(@root_dir))
153
+ if title.to_s.empty? && @root_page
154
+ basename = File.basename(@root_page.path.to_s, File.extname(@root_page.path.to_s))
155
+ title = Utils.page_title(@root_page, basename)
156
+ end
157
+ title.to_s.empty? ? "Home" : title
158
+ end
148
159
  end
149
160
  end
150
161
  end
@@ -6,13 +6,20 @@ module Jekyll
6
6
  include Enumerable
7
7
 
8
8
  def initialize(site, config)
9
+ root_dir = config.root_dir
10
+ include_patterns = config.include_patterns
11
+ ignore_patterns = config.ignore_patterns
9
12
  @pages = site.pages.select do |page|
13
+ source_path = Utils.source_path_for(page)
14
+
10
15
  next false if File.basename(page.path) == config.nav_filename
16
+ next false unless included?(source_path, include_patterns)
17
+ next false if ignored?(source_path, ignore_patterns)
11
18
 
12
19
  dir = Utils.source_dir_for(page)
13
- dir == config.root_dir || dir.start_with?("#{config.root_dir}/")
20
+ root_dir.empty? || dir == root_dir || dir.start_with?("#{root_dir}/")
14
21
  end
15
- @root_dir = config.root_dir
22
+ @root_dir = root_dir
16
23
  end
17
24
 
18
25
  def each(&block)
@@ -26,6 +33,20 @@ module Jekyll
26
33
  def root_page
27
34
  @pages.find { |page| Utils.source_dir_for(page) == @root_dir && Utils.index_page?(page) }
28
35
  end
36
+
37
+ def ignored?(source_path, patterns)
38
+ patterns.any? do |pattern|
39
+ File.fnmatch?(pattern, source_path, File::FNM_PATHNAME | File::FNM_DOTMATCH)
40
+ end
41
+ end
42
+
43
+ def included?(source_path, patterns)
44
+ return true if patterns.nil?
45
+
46
+ patterns.any? do |pattern|
47
+ File.fnmatch?(pattern, source_path, File::FNM_PATHNAME | File::FNM_DOTMATCH)
48
+ end
49
+ end
29
50
  end
30
51
  end
31
52
  end
@@ -34,12 +34,12 @@ module Jekyll
34
34
  current = child
35
35
  end
36
36
 
37
- basename = File.basename(page.path, File.extname(page.path))
37
+ basename = File.basename(page_path, File.extname(page_path))
38
38
  title = Utils.page_title(page, basename)
39
39
  url = Utils.normalize_url(page.url)
40
40
 
41
- if basename == "index"
42
- current.title = title
41
+ if Utils.index_page?(page)
42
+ current.title = section_title_for_index(page, basename, current, title)
43
43
  current.url = url
44
44
  current.path = page_path
45
45
  current.filename = File.basename(page_path)
@@ -63,6 +63,14 @@ module Jekyll
63
63
  end
64
64
  end
65
65
 
66
+ def section_title_for_index(page, basename, current, resolved_title)
67
+ return resolved_title unless basename.downcase == "readme"
68
+ return resolved_title if page.data["nav_title"] || page.data["title"]
69
+ return current.title unless current.title.to_s.empty?
70
+
71
+ resolved_title
72
+ end
73
+
66
74
  def sort_key(child)
67
75
  [
68
76
  child.section? ? 0 : 1,
@@ -63,7 +63,11 @@ module Jekyll
63
63
  end
64
64
 
65
65
  def index_page?(page)
66
- File.basename(page.path, File.extname(page.path)) == "index"
66
+ basename = File.basename(source_path_for(page), File.extname(source_path_for(page))).downcase
67
+ return true if basename == "index"
68
+
69
+ # jekyll-readme-index can map README.* to the directory index URL.
70
+ basename == "readme" && normalize_url(page.url) == normalize_url(source_dir_for(page))
67
71
  end
68
72
 
69
73
  def source_dir_for(page)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Jekyll
4
4
  module AwesomeNav
5
- VERSION = "0.0.1"
5
+ VERSION = "0.1.0"
6
6
 
7
7
  def self.warn_if_unstamped_version(output = $stderr)
8
8
  return unless VERSION == "0.0.0"
data/site/_config.yml CHANGED
@@ -15,12 +15,15 @@ nav:
15
15
  - name: Getting Started
16
16
  url: /docs/getting-started/
17
17
  plugins:
18
- - jekyll-seo-tag
19
18
  - jekyll-awesome-nav
19
+ - jekyll-seo-tag
20
+ - jekyll-toc
20
21
  awesome_nav:
21
22
  enabled: true
22
23
  root: docs
23
24
  nav_filename: .nav.yml
25
+ toc:
26
+ max_level: 2 # default: 6
24
27
  markdown: kramdown
25
28
  defaults:
26
29
  - scope:
@@ -30,4 +33,5 @@ defaults:
30
33
  - scope:
31
34
  path: "docs"
32
35
  values:
33
- layout: docs
36
+ layout: awesome_nav_demo
37
+ toc: true
@@ -1,128 +1,405 @@
1
1
  ---
2
2
  layout: default
3
3
  ---
4
+ {% assign nav_title = page.nav_title | default: page.title %}
5
+ {% assign docs_root = site.awesome_nav.root | default: "docs" %}
6
+ {% assign local_nav = page.awesome_nav_local %}
7
+ {% assign previous_item = page.awesome_nav_previous %}
8
+ {% assign next_item = page.awesome_nav_next %}
9
+
4
10
  <style>
5
- .awesome-nav-docs {
11
+
12
+ html {
13
+ scrollbar-gutter: stable;
14
+ }
15
+
16
+ body {
17
+ overflow-y: scroll;
18
+ }
19
+
20
+ .awesome-nav-demo {
21
+ min-height: calc(100vh - var(--topbar-height, 0rem));
22
+ position: relative;
23
+ }
24
+
25
+ .awesome-nav-demo::before {
26
+ content: "";
27
+ inset: 0;
28
+ pointer-events: none;
29
+ position: absolute;
30
+ }
31
+
32
+ .awesome-nav-demo a {
33
+ color: inherit;
34
+ }
35
+
36
+ .awesome-nav-demo__wrap {
6
37
  display: grid;
7
38
  gap: 2rem;
8
- grid-template-columns: minmax(14rem, 18rem) minmax(0, 1fr);
9
- max-width: 72rem;
39
+ grid-template-columns: minmax(15rem, 18rem) minmax(0, 1fr) minmax(13rem, 15rem);
10
40
  margin: 0 auto;
11
- padding: 2rem 1rem;
41
+ max-width: 82rem;
42
+ padding: 2rem 1rem 4rem;
43
+ position: relative;
44
+ z-index: 1;
12
45
  }
13
46
 
14
- .awesome-nav-docs__sidebar {
47
+ .awesome-nav-demo__sidebar,
48
+ .awesome-nav-demo__toc {
15
49
  align-self: start;
50
+ max-height: calc(100vh - var(--topbar-height, 4rem) - 2rem);
51
+ overflow: auto;
52
+ padding: 1rem;
16
53
  position: sticky;
17
- top: 1rem;
54
+ top: calc(var(--topbar-height, 4rem) + 1rem);
55
+ }
56
+
57
+ .awesome-nav-demo__brand {
58
+ align-items: center;
59
+ display: flex;
60
+ gap: 0.75rem;
61
+ margin-bottom: 1rem;
62
+ padding-bottom: 1rem;
63
+ }
64
+
65
+ .awesome-nav-demo__brand-mark {
66
+ align-items: end;
67
+ aspect-ratio: 1;
68
+ display: grid;
69
+ flex: 0 0 2.75rem;
70
+ gap: 0.2rem;
71
+ grid-template-columns: repeat(3, 1fr);
72
+ padding: 0.55rem;
73
+ }
74
+
75
+ .awesome-nav-demo__brand-mark span {
76
+ min-height: 0.55rem;
77
+ }
78
+
79
+ .awesome-nav-demo__brand-mark span:nth-child(2) {
80
+ min-height: 1.45rem;
81
+ }
82
+
83
+ .awesome-nav-demo__brand-mark span:nth-child(3) {
84
+ min-height: 1.05rem;
85
+ }
86
+
87
+ .awesome-nav-demo__brand strong,
88
+ .awesome-nav-demo__brand small {
89
+ display: block;
18
90
  }
19
91
 
20
- .awesome-nav-docs__sidebar ul {
92
+ .awesome-nav-demo__brand small,
93
+ .awesome-nav-demo__eyebrow,
94
+ .awesome-nav-demo__meta {
95
+ font-size: 0.72rem;
96
+ font-weight: 800;
97
+ letter-spacing: 0.12em;
98
+ text-transform: uppercase;
99
+ }
100
+
101
+ .awesome-nav-demo__tree,
102
+ .awesome-nav-demo__tree ul,
103
+ .awesome-nav-demo__local-list,
104
+ .awesome-nav-demo__local-list li {
21
105
  list-style: none;
22
106
  margin: 0;
23
- padding-left: 0;
107
+ padding: 0;
24
108
  }
25
109
 
26
- .awesome-nav-docs__sidebar ul ul {
27
- margin-top: 0.25rem;
28
- padding-left: 1rem;
110
+ .awesome-nav-demo__tree ul {
111
+ margin: 0.25rem 0 0.35rem 0.7rem;
112
+ padding-left: 0.7rem;
29
113
  }
30
114
 
31
- .awesome-nav-docs__sidebar li {
32
- margin: 0.25rem 0;
115
+ .awesome-nav-demo__tree li,
116
+ .awesome-nav-demo__local-list li {
117
+ margin: 0.12rem 0;
33
118
  }
34
119
 
35
- .awesome-nav-docs__sidebar a,
36
- .awesome-nav-docs__sidebar span {
120
+ .awesome-nav-demo__tree a,
121
+ .awesome-nav-demo__tree span,
122
+ .awesome-nav-demo__local-list a,
123
+ .awesome-nav-demo__local-list span {
37
124
  display: block;
38
- padding: 0.25rem 0;
125
+ line-height: 1.35;
126
+ overflow-wrap: anywhere;
127
+ padding: 0.42rem 0.55rem;
128
+ text-decoration: none;
39
129
  }
40
130
 
41
- .awesome-nav-docs__sidebar a[aria-current="page"] {
131
+ .awesome-nav-demo__tree span,
132
+ .awesome-nav-demo__local-list span {
42
133
  font-weight: 700;
43
134
  }
44
135
 
45
- .awesome-nav-docs__breadcrumbs ol {
136
+ .awesome-nav-demo__tree a[aria-current="page"],
137
+ .awesome-nav-demo__local-list a[aria-current="page"] {
138
+ font-weight: 800;
139
+ }
140
+
141
+ .awesome-nav-demo__main {
142
+ min-width: 0;
143
+ }
144
+
145
+ .awesome-nav-demo__hero {
146
+ margin: 0 0 1.25rem;
147
+ padding: 1.25rem 0.25rem 0;
148
+ }
149
+
150
+ .awesome-nav-demo__eyebrow {
151
+ margin: 0 0 0.75rem;
152
+ }
153
+
154
+ .awesome-nav-demo__title {
155
+ font-size: clamp(2.8rem, 7vw, 5.8rem);
156
+ letter-spacing: -0.07em;
157
+ line-height: 0.9;
158
+ margin: 0;
159
+ max-width: 12ch;
160
+ }
161
+
162
+ .awesome-nav-demo__breadcrumbs {
163
+ font-size: 0.9rem;
164
+ margin-top: 1rem;
165
+ }
166
+
167
+ .awesome-nav-demo__breadcrumbs ol {
46
168
  display: flex;
47
169
  flex-wrap: wrap;
48
170
  gap: 0.25rem;
49
171
  list-style: none;
50
- margin: 0 0 1rem;
172
+ margin: 0;
51
173
  padding: 0;
52
174
  }
53
175
 
54
- .awesome-nav-docs__breadcrumbs li {
55
- margin: 0.25rem;
56
- }
57
-
58
- .awesome-nav-docs__breadcrumbs li:not(:last-child)::after {
176
+ .awesome-nav-demo__breadcrumbs li:not(:last-child)::after {
59
177
  content: "/";
60
178
  margin-left: 0.25rem;
61
179
  }
62
180
 
63
- .awesome-nav-docs__pager {
64
- border-top: 1px solid var(--borderColor-default, #d0d7de);
181
+ .awesome-nav-demo__mobile-summary {
182
+ display: none;
183
+ margin-bottom: 1rem;
184
+ }
185
+
186
+ .awesome-nav-demo__mobile-summary summary {
187
+ cursor: pointer;
188
+ font-weight: 800;
189
+ list-style: none;
190
+ padding: 0.85rem 1rem;
191
+ }
192
+
193
+ .awesome-nav-demo__mobile-summary summary::-webkit-details-marker {
194
+ display: none;
195
+ }
196
+
197
+ .awesome-nav-demo__mobile-summary nav {
198
+ padding: 0.75rem;
199
+ }
200
+
201
+ .awesome-nav-demo__content {
202
+ padding: clamp(1.25rem, 4vw, 3rem);
203
+ }
204
+
205
+ .awesome-nav-demo__content > h1:first-child {
206
+ display: none;
207
+ }
208
+
209
+ .awesome-nav-demo__toc h2,
210
+ .awesome-nav-demo__sidebar h2 {
211
+ font-size: 0.95rem;
212
+ margin: 0 0 0.75rem;
213
+ }
214
+
215
+ .awesome-nav-demo__toc {
65
216
  display: flex;
66
- justify-content: space-between;
217
+ flex-direction: column;
218
+ gap: 1.25rem;
219
+ }
220
+
221
+ .awesome-nav-demo__toc-section {
222
+ padding-bottom: 1.25rem;
223
+ }
224
+
225
+ .awesome-nav-demo__toc-section:last-child {
226
+ border-bottom: 0;
227
+ padding-bottom: 0;
228
+ }
229
+
230
+ .awesome-nav-demo__meta {
231
+ margin: 0.35rem 0 0;
232
+ overflow-wrap: anywhere;
233
+ }
234
+
235
+ .awesome-nav-demo__pager {
236
+ display: grid;
67
237
  gap: 1rem;
68
- margin-top: 3rem;
69
- padding-top: 1rem;
238
+ grid-template-columns: repeat(2, minmax(0, 1fr));
239
+ margin-top: 1.25rem;
240
+ }
241
+
242
+ .awesome-nav-demo__pager a {
243
+ border-radius: 1.25rem;
244
+ display: flex;
245
+ flex-direction: column;
246
+ gap: 0.35rem;
247
+ min-height: 6rem;
248
+ padding: 1rem;
249
+ text-decoration: none;
250
+ }
251
+
252
+ .awesome-nav-demo__pager a:last-child {
253
+ text-align: right;
254
+ }
255
+
256
+ .awesome-nav-demo__pager span {
257
+ font-size: 0.78rem;
258
+ font-weight: 800;
259
+ letter-spacing: 0.08em;
260
+ text-transform: uppercase;
261
+ }
262
+
263
+ .awesome-nav-demo__pager strong {
264
+ font-size: 1.1rem;
265
+ }
266
+
267
+ .awesome-nav-demo__empty-state {
268
+ border-radius: 1.25rem;
269
+ padding: 1rem;
270
+ }
271
+
272
+ @media (max-width: 68rem) {
273
+ .awesome-nav-demo__wrap {
274
+ grid-template-columns: minmax(14rem, 17rem) minmax(0, 1fr);
275
+ }
276
+
277
+ .awesome-nav-demo__toc {
278
+ display: none;
279
+ }
70
280
  }
71
281
 
72
282
  @media (max-width: 48rem) {
73
- .awesome-nav-docs {
283
+ .awesome-nav-demo__wrap {
284
+ display: block;
285
+ padding-top: 1rem;
286
+ }
287
+
288
+ .awesome-nav-demo__sidebar {
289
+ display: none;
290
+ }
291
+
292
+ .awesome-nav-demo__mobile-summary {
293
+ display: block;
294
+ }
295
+
296
+ .awesome-nav-demo__hero {
297
+ padding-top: 0.5rem;
298
+ }
299
+
300
+ .awesome-nav-demo__title {
301
+ font-size: clamp(2.6rem, 15vw, 4.2rem);
302
+ }
303
+
304
+ .awesome-nav-demo__pager {
74
305
  grid-template-columns: 1fr;
75
306
  }
76
307
 
77
- .awesome-nav-docs__sidebar {
78
- position: static;
308
+ .awesome-nav-demo__pager a:last-child {
309
+ text-align: left;
79
310
  }
80
311
  }
81
312
  </style>
82
313
 
83
- <div class="awesome-nav-docs">
84
- <aside class="awesome-nav-docs__sidebar">
85
- <h2>Docs</h2>
86
- {% if page.awesome_nav %}
87
- <nav aria-label="Documentation">
88
- <ul>
89
- {% include awesome-nav-tree.html items=page.awesome_nav %}
90
- </ul>
91
- </nav>
92
- {% endif %}
93
- </aside>
94
-
95
- <main class="markdown-body">
96
- {% if page.breadcrumbs %}
97
- <nav class="awesome-nav-docs__breadcrumbs" aria-label="Breadcrumbs">
98
- <ol>
99
- {% for item in page.breadcrumbs %}
100
- <li>
101
- <a href="{{ item.url | relative_url }}">{{ item.title }}</a>
102
- </li>
103
- {% endfor %}
104
- </ol>
105
- </nav>
106
- {% endif %}
107
-
108
- <h1>{{ page.title }}</h1>
109
- {{ content }}
110
-
111
- <nav class="awesome-nav-docs__pager" aria-label="Pagination">
112
- <div>
113
- {% if page.awesome_nav_previous %}
114
- <a href="{{ page.awesome_nav_previous.url | relative_url }}">
115
- Previous: {{ page.awesome_nav_previous.title }}
116
- </a>
117
- {% endif %}
314
+ <div class="awesome-nav-demo">
315
+ <div class="awesome-nav-demo__wrap">
316
+ <aside class="awesome-nav-demo__sidebar" aria-label="Documentation navigation">
317
+ <div class="awesome-nav-demo__brand">
318
+ <span>
319
+ <strong>{{ site.title | default: "Awesome Nav" }}</strong>
320
+ <small>{{ docs_root }} navigation</small>
321
+ </span>
118
322
  </div>
119
- <div>
120
- {% if page.awesome_nav_next %}
121
- <a href="{{ page.awesome_nav_next.url | relative_url }}">
122
- Next: {{ page.awesome_nav_next.title }}
123
- </a>
323
+
324
+ {% if page.awesome_nav %}
325
+ <nav aria-label="Documentation">
326
+ <ul class="awesome-nav-demo__tree">
327
+ {% include awesome-nav-tree.html items=page.awesome_nav %}
328
+ </ul>
329
+ </nav>
330
+ {% else %}
331
+ <p class="awesome-nav-demo__empty-state">Navigation data is not available for this page.</p>
332
+ {% endif %}
333
+ </aside>
334
+
335
+ <main class="awesome-nav-demo__main">
336
+ <section class="awesome-nav-demo__hero">
337
+ <p class="awesome-nav-demo__eyebrow">Awesome nav demo</p>
338
+ <h1 class="awesome-nav-demo__title">{{ nav_title }}</h1>
339
+
340
+ {% if page.breadcrumbs %}
341
+ <nav class="awesome-nav-demo__breadcrumbs" aria-label="Breadcrumbs">
342
+ <ol>
343
+ {% for item in page.breadcrumbs %}
344
+ <li>
345
+ <a href="{{ item.url | relative_url }}">{{ item.title }}</a>
346
+ </li>
347
+ {% endfor %}
348
+ </ol>
349
+ </nav>
124
350
  {% endif %}
125
- </div>
126
- </nav>
127
- </main>
351
+ </section>
352
+
353
+ {% if page.awesome_nav %}
354
+ <details class="awesome-nav-demo__mobile-summary">
355
+ <summary aria-label="Browse documentation" title="Browse documentation">&#9776;</summary>
356
+ <nav aria-label="Documentation">
357
+ <ul class="awesome-nav-demo__tree">
358
+ {% include awesome-nav-tree.html items=page.awesome_nav %}
359
+ </ul>
360
+ </nav>
361
+ </details>
362
+ {% endif %}
363
+
364
+ <article class="awesome-nav-demo__content markdown-body">
365
+ {{ content | inject_anchors }}
366
+ </article>
367
+
368
+ {% if previous_item or next_item %}
369
+ <nav class="awesome-nav-demo__pager" aria-label="Pagination">
370
+ {% if previous_item %}
371
+ <a href="{{ previous_item.url | relative_url }}">
372
+ <span>Previous</span>
373
+ <strong>{{ previous_item.title }}</strong>
374
+ </a>
375
+ {% else %}
376
+ <span></span>
377
+ {% endif %}
378
+
379
+ {% if next_item %}
380
+ <a href="{{ next_item.url | relative_url }}">
381
+ <span>Next</span>
382
+ <strong>{{ next_item.title }}</strong>
383
+ </a>
384
+ {% else %}
385
+ <span></span>
386
+ {% endif %}
387
+ </nav>
388
+ {% endif %}
389
+ </main>
390
+
391
+ <aside class="awesome-nav-demo__toc" aria-label="Current navigation context">
392
+ <section class="awesome-nav-demo__toc-section">
393
+ <h2>In this article</h2>
394
+ {% if local_nav %}
395
+ <nav aria-label="This section">
396
+ <ul class="awesome-nav-demo__local-list">
397
+ {{ content | toc_only }}
398
+ </ul>
399
+ </nav>
400
+ {% else %}
401
+ {% endif %}
402
+ </section>
403
+ </aside>
404
+ </div>
128
405
  </div>
@@ -55,14 +55,14 @@ The plugin builds navigation from these pages during the normal Jekyll build. Yo
55
55
 
56
56
  ## Render it
57
57
 
58
- If your theme already supports `jekyll-awesome-nav`, choose that docs layout for pages under your docs root. This site uses its docs layout through defaults:
58
+ If your theme already supports `jekyll-awesome-nav`, choose that docs layout for pages under your docs root. This site uses a small demo layout through defaults:
59
59
 
60
60
  ```yaml
61
61
  defaults:
62
62
  - scope:
63
63
  path: "docs"
64
64
  values:
65
- layout: docs
65
+ layout: awesome_nav_demo
66
66
  ```
67
67
 
68
68
  If your theme does not support it yet, use the examples in [Layout Integration]({{ "/docs/guides/layouts/" | relative_url }}) to wire the data into your own layout.
@@ -9,6 +9,12 @@ awesome_nav:
9
9
  enabled: true
10
10
  root: docs
11
11
  nav_filename: .nav.yml
12
+ include:
13
+ - "**/*.md"
14
+ - "**/*.html"
15
+ - "**/*.htm"
16
+ ignore:
17
+ - "assets/**"
12
18
  ```
13
19
 
14
20
  ## Options
@@ -18,6 +24,10 @@ awesome_nav:
18
24
  | `enabled` | `true` | Turns generation on or off. |
19
25
  | `root` | `docs` | Folder that contains your documentation pages. |
20
26
  | `nav_filename` | `.nav.yml` | Filename used for local subtree overrides. |
27
+ | `include` | `["**/*.md", "**/*.html", "**/*.htm"]` | Source path globs eligible for nav generation. |
28
+ | `ignore` | `["assets/**"]` | Source path globs excluded from nav generation. |
29
+
30
+ `include` is evaluated first, then `ignore` removes matches.
21
31
 
22
32
  ## Page titles
23
33
 
@@ -15,6 +15,8 @@ The plugin writes navigation data onto each page under the configured docs root.
15
15
  | `page.awesome_nav_previous` | Previous page in the resolved navigation order. |
16
16
  | `page.awesome_nav_next` | Next page in the resolved navigation order. |
17
17
 
18
+ For README-indexed directories, these values are computed using the directory index URL (for example `/ros2/`) rather than a nested `README` leaf item.
19
+
18
20
  ## Tree item shape
19
21
 
20
22
  Navigation entries are hashes with a title, URL, and optional children:
@@ -37,4 +39,6 @@ The plugin also writes resolved data into `site.config` for advanced theme use:
37
39
  | `site.awesome_nav_local_map` | Local navigation lookup by directory. |
38
40
  | `site.awesome_nav_files` | Loaded `.nav.yml` data. |
39
41
 
42
+ When the site uses `jekyll-readme-index`, generated README index pages are included in these resolved structures because awesome-nav runs after low-priority generators.
43
+
40
44
  Most layouts should prefer the `page.*` variables because they are already scoped to the current page.
@@ -47,7 +47,7 @@ defaults:
47
47
  - scope:
48
48
  path: "docs"
49
49
  values:
50
- layout: docs
50
+ layout: awesome_nav_demo
51
51
  ```
52
52
 
53
53
  The plugin generates the data. The layout decides how that data looks.
@@ -4,7 +4,7 @@ title: Layout Integration
4
4
 
5
5
  `jekyll-awesome-nav` generates navigation data. Your layout renders it.
6
6
 
7
- This site uses its own small layout at `site/_layouts/docs.html`, with a recursive include at `site/_includes/awesome-nav-tree.html`.
7
+ This site uses its own small demo layout at `site/_layouts/awesome_nav_demo.html`, with a recursive include at `site/_includes/awesome-nav-tree.html`.
8
8
 
9
9
  You can use those files as a starting point when wiring the same data into another Jekyll theme.
10
10
 
@@ -17,7 +17,7 @@ defaults:
17
17
  - scope:
18
18
  path: "docs"
19
19
  values:
20
- layout: docs
20
+ layout: awesome_nav_demo
21
21
  ```
22
22
 
23
23
  Inside that layout, check for generated navigation before rendering plugin-specific UI:
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-awesome-nav
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Allison Thackston
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-06 00:00:00.000000000 Z
11
+ date: 2026-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -67,7 +67,6 @@ files:
67
67
  - lib/jekyll/awesome_nav/utils.rb
68
68
  - lib/jekyll/awesome_nav/version.rb
69
69
  - site/_config.yml
70
- - site/_includes/awesome-nav-demo-tree.html
71
70
  - site/_includes/awesome-nav-tree.html
72
71
  - site/_layouts/awesome_nav_demo.html
73
72
  - site/docs/getting-started.md
@@ -1,15 +0,0 @@
1
- {% for item in include.items %}
2
- <li>
3
- <a
4
- href="{{ item.url | relative_url }}"
5
- {% if item.url == page.url %}aria-current="page"{% endif %}
6
- >
7
- {{ item.title }}
8
- </a>
9
- {% if item.children %}
10
- <ul>
11
- {% include awesome-nav-demo-tree.html items=item.children %}
12
- </ul>
13
- {% endif %}
14
- </li>
15
- {% endfor %}