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 +4 -4
- data/.copier-answers.ci.yml +2 -3
- data/.vscode/tasks.json +2 -2
- data/README.md +32 -1
- data/Rakefile +24 -0
- data/lib/jekyll/awesome_nav/config.rb +18 -1
- data/lib/jekyll/awesome_nav/generator.rb +3 -1
- data/lib/jekyll/awesome_nav/navigation_result.rb +14 -3
- data/lib/jekyll/awesome_nav/page_set.rb +23 -2
- data/lib/jekyll/awesome_nav/tree_builder.rb +11 -3
- data/lib/jekyll/awesome_nav/utils.rb +5 -1
- data/lib/jekyll/awesome_nav/version.rb +1 -1
- data/site/_config.yml +6 -2
- data/site/_layouts/awesome_nav_demo.html +352 -75
- data/site/docs/getting-started.md +2 -2
- data/site/docs/guides/config.md +10 -0
- data/site/docs/guides/data.md +4 -0
- data/site/docs/guides/install.md +1 -1
- data/site/docs/guides/layouts.md +2 -2
- metadata +2 -3
- data/site/_includes/awesome-nav-demo-tree.html +0 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 01fa08c8a44630c6314fb330db8db6de0977bc66adb8e2c48dd5f127ede6ff8d
|
|
4
|
+
data.tar.gz: 29964bc8684fc64593bb76b9385ec19706b578aef5ee780155be2f518c50873b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d191dc308b3c7b7b2431417f12c4cdfe59b7acb4c2461364beec68a481909b81dad07724405ee2a2a1644203b6bf13705e86f60af8e98b0895363b3a202a5cb1
|
|
7
|
+
data.tar.gz: ef4ed52b48b7595d0994ff1f19ba64d70d4e81998ea1ded6b14b395f165a11a0ea5efe43bff3de73ebd8c7e35a48a5e06e7ec1054ff2407becfc838e7ceae6ae
|
data/.copier-answers.ci.yml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
|
|
2
|
-
_commit:
|
|
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
|
|
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
|
|
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/
|
|
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
|
|
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" =>
|
|
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" =>
|
|
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 ==
|
|
20
|
+
root_dir.empty? || dir == root_dir || dir.start_with?("#{root_dir}/")
|
|
14
21
|
end
|
|
15
|
-
@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(
|
|
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
|
|
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
|
|
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)
|
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:
|
|
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
|
-
|
|
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(
|
|
9
|
-
max-width: 72rem;
|
|
39
|
+
grid-template-columns: minmax(15rem, 18rem) minmax(0, 1fr) minmax(13rem, 15rem);
|
|
10
40
|
margin: 0 auto;
|
|
11
|
-
|
|
41
|
+
max-width: 82rem;
|
|
42
|
+
padding: 2rem 1rem 4rem;
|
|
43
|
+
position: relative;
|
|
44
|
+
z-index: 1;
|
|
12
45
|
}
|
|
13
46
|
|
|
14
|
-
.awesome-nav-
|
|
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-
|
|
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
|
|
107
|
+
padding: 0;
|
|
24
108
|
}
|
|
25
109
|
|
|
26
|
-
.awesome-nav-
|
|
27
|
-
margin
|
|
28
|
-
padding-left:
|
|
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-
|
|
32
|
-
|
|
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-
|
|
36
|
-
.awesome-nav-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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
|
|
172
|
+
margin: 0;
|
|
51
173
|
padding: 0;
|
|
52
174
|
}
|
|
53
175
|
|
|
54
|
-
.awesome-nav-
|
|
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-
|
|
64
|
-
|
|
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
|
-
|
|
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
|
-
|
|
69
|
-
|
|
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-
|
|
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-
|
|
78
|
-
|
|
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-
|
|
84
|
-
<
|
|
85
|
-
<
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
{
|
|
90
|
-
</
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
</
|
|
126
|
-
|
|
127
|
-
|
|
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">☰</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
|
|
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:
|
|
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.
|
data/site/docs/guides/config.md
CHANGED
|
@@ -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
|
|
data/site/docs/guides/data.md
CHANGED
|
@@ -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.
|
data/site/docs/guides/install.md
CHANGED
data/site/docs/guides/layouts.md
CHANGED
|
@@ -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/
|
|
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:
|
|
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
|
|
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-
|
|
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 %}
|