docyard 0.7.0 → 0.8.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/.rubocop.yml +5 -1
- data/CHANGELOG.md +20 -1
- data/lib/docyard/build/asset_bundler.rb +22 -7
- data/lib/docyard/build/file_copier.rb +49 -27
- data/lib/docyard/build/sitemap_generator.rb +6 -6
- data/lib/docyard/build/static_generator.rb +85 -12
- data/lib/docyard/builder.rb +6 -6
- data/lib/docyard/config/branding_resolver.rb +126 -17
- data/lib/docyard/config/constants.rb +6 -4
- data/lib/docyard/config/validator.rb +122 -99
- data/lib/docyard/config.rb +36 -43
- data/lib/docyard/initializer.rb +15 -76
- data/lib/docyard/navigation/breadcrumb_builder.rb +133 -0
- data/lib/docyard/navigation/prev_next_builder.rb +4 -1
- data/lib/docyard/navigation/sidebar/children_discoverer.rb +51 -0
- data/lib/docyard/navigation/sidebar/config_parser.rb +136 -108
- data/lib/docyard/navigation/sidebar/file_resolver.rb +78 -0
- data/lib/docyard/navigation/sidebar/file_system_scanner.rb +2 -1
- data/lib/docyard/navigation/sidebar/item.rb +45 -7
- data/lib/docyard/navigation/sidebar/local_config_loader.rb +51 -0
- data/lib/docyard/navigation/sidebar/metadata_extractor.rb +69 -0
- data/lib/docyard/navigation/sidebar/metadata_reader.rb +47 -0
- data/lib/docyard/navigation/sidebar/path_prefixer.rb +34 -0
- data/lib/docyard/navigation/sidebar/renderer.rb +55 -37
- data/lib/docyard/navigation/sidebar/sorter.rb +21 -0
- data/lib/docyard/navigation/sidebar/tree_builder.rb +99 -26
- data/lib/docyard/navigation/sidebar/tree_filter.rb +55 -0
- data/lib/docyard/navigation/sidebar_builder.rb +105 -36
- data/lib/docyard/rendering/icon_helpers.rb +13 -0
- data/lib/docyard/rendering/icons/phosphor.rb +23 -1
- data/lib/docyard/rendering/markdown.rb +5 -0
- data/lib/docyard/rendering/renderer.rb +74 -34
- data/lib/docyard/rendering/template_resolver.rb +172 -0
- data/lib/docyard/routing/fallback_resolver.rb +92 -0
- data/lib/docyard/search/build_indexer.rb +1 -1
- data/lib/docyard/search/dev_indexer.rb +51 -6
- data/lib/docyard/search/pagefind_support.rb +2 -0
- data/lib/docyard/server/asset_handler.rb +24 -19
- data/lib/docyard/server/pagefind_handler.rb +63 -0
- data/lib/docyard/server/preview_server.rb +1 -1
- data/lib/docyard/server/rack_application.rb +81 -64
- data/lib/docyard/templates/assets/css/code.css +18 -51
- data/lib/docyard/templates/assets/css/components/breadcrumbs.css +143 -0
- data/lib/docyard/templates/assets/css/components/callout.css +67 -67
- data/lib/docyard/templates/assets/css/components/code-block.css +180 -282
- data/lib/docyard/templates/assets/css/components/heading-anchor.css +28 -15
- data/lib/docyard/templates/assets/css/components/icon.css +0 -1
- data/lib/docyard/templates/assets/css/components/logo.css +0 -2
- data/lib/docyard/templates/assets/css/components/nav-menu.css +237 -0
- data/lib/docyard/templates/assets/css/components/navigation.css +186 -167
- data/lib/docyard/templates/assets/css/components/prev-next.css +76 -47
- data/lib/docyard/templates/assets/css/components/search.css +186 -174
- data/lib/docyard/templates/assets/css/components/tab-bar.css +163 -0
- data/lib/docyard/templates/assets/css/components/table-of-contents.css +127 -114
- data/lib/docyard/templates/assets/css/components/tabs.css +119 -160
- data/lib/docyard/templates/assets/css/components/theme-toggle.css +48 -44
- data/lib/docyard/templates/assets/css/landing.css +815 -0
- data/lib/docyard/templates/assets/css/layout.css +489 -87
- data/lib/docyard/templates/assets/css/main.css +1 -3
- data/lib/docyard/templates/assets/css/markdown.css +111 -93
- data/lib/docyard/templates/assets/css/reset.css +0 -3
- data/lib/docyard/templates/assets/css/typography.css +43 -41
- data/lib/docyard/templates/assets/css/variables.css +268 -208
- data/lib/docyard/templates/assets/favicon.svg +7 -8
- data/lib/docyard/templates/assets/fonts/Inter-Variable.ttf +0 -0
- data/lib/docyard/templates/assets/js/components/code-block.js +24 -42
- data/lib/docyard/templates/assets/js/components/heading-anchor.js +26 -24
- data/lib/docyard/templates/assets/js/components/navigation.js +181 -70
- data/lib/docyard/templates/assets/js/components/search.js +0 -75
- data/lib/docyard/templates/assets/js/components/sidebar-toggle.js +29 -0
- data/lib/docyard/templates/assets/js/components/tab-navigation.js +145 -0
- data/lib/docyard/templates/assets/js/components/table-of-contents.js +153 -66
- data/lib/docyard/templates/assets/js/components/tabs.js +31 -69
- data/lib/docyard/templates/assets/js/theme.js +0 -3
- data/lib/docyard/templates/assets/logo-dark.svg +8 -2
- data/lib/docyard/templates/assets/logo.svg +7 -4
- data/lib/docyard/templates/config/docyard.yml.erb +37 -34
- data/lib/docyard/templates/errors/404.html.erb +1 -1
- data/lib/docyard/templates/errors/500.html.erb +1 -1
- data/lib/docyard/templates/layouts/default.html.erb +18 -67
- data/lib/docyard/templates/layouts/splash.html.erb +176 -0
- data/lib/docyard/templates/partials/_breadcrumbs.html.erb +24 -0
- data/lib/docyard/templates/partials/_code_block.html.erb +5 -3
- data/lib/docyard/templates/partials/_doc_footer.html.erb +25 -0
- data/lib/docyard/templates/partials/_features.html.erb +15 -0
- data/lib/docyard/templates/partials/_footer.html.erb +42 -0
- data/lib/docyard/templates/partials/_head.html.erb +22 -0
- data/lib/docyard/templates/partials/_header.html.erb +49 -0
- data/lib/docyard/templates/partials/_heading_anchor.html.erb +3 -1
- data/lib/docyard/templates/partials/_hero.html.erb +27 -0
- data/lib/docyard/templates/partials/_nav_group.html.erb +25 -11
- data/lib/docyard/templates/partials/_nav_leaf.html.erb +1 -1
- data/lib/docyard/templates/partials/_nav_menu.html.erb +42 -0
- data/lib/docyard/templates/partials/_nav_nested_section.html.erb +11 -0
- data/lib/docyard/templates/partials/_nav_section.html.erb +1 -1
- data/lib/docyard/templates/partials/_prev_next.html.erb +8 -2
- data/lib/docyard/templates/partials/_scripts.html.erb +7 -0
- data/lib/docyard/templates/partials/_search_modal.html.erb +2 -6
- data/lib/docyard/templates/partials/_search_trigger.html.erb +2 -6
- data/lib/docyard/templates/partials/_sidebar.html.erb +21 -4
- data/lib/docyard/templates/partials/_tab_bar.html.erb +25 -0
- data/lib/docyard/templates/partials/_table_of_contents.html.erb +12 -12
- data/lib/docyard/templates/partials/_table_of_contents_toggle.html.erb +1 -3
- data/lib/docyard/templates/partials/_tabs.html.erb +2 -2
- data/lib/docyard/templates/partials/_theme_toggle.html.erb +2 -11
- data/lib/docyard/version.rb +1 -1
- metadata +33 -5
- data/lib/docyard/templates/markdown/getting-started/installation.md.erb +0 -77
- data/lib/docyard/templates/markdown/guides/configuration.md.erb +0 -202
- data/lib/docyard/templates/markdown/guides/markdown-features.md.erb +0 -247
- data/lib/docyard/templates/markdown/index.md.erb +0 -82
|
@@ -1,42 +1,45 @@
|
|
|
1
1
|
# Docyard Configuration
|
|
2
2
|
# Documentation: https://github.com/yourusername/docyard
|
|
3
3
|
|
|
4
|
-
# Site
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
description: "Documentation for my project"
|
|
4
|
+
# Site Identity
|
|
5
|
+
title: "My Documentation"
|
|
6
|
+
description: "Documentation for my project"
|
|
8
7
|
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
# Branding (Optional)
|
|
9
|
+
# Docyard auto-detects these files from docs/public/:
|
|
10
|
+
# - logo.svg or logo.png (and logo-dark.svg for dark mode)
|
|
11
|
+
# - favicon.ico, favicon.svg, or favicon.png
|
|
12
|
+
# Only configure if you need custom paths or filenames.
|
|
13
|
+
# branding:
|
|
14
|
+
# logo: "custom-logo.svg" # Override auto-detected logo
|
|
15
|
+
# favicon: "custom.ico" # Override auto-detected favicon
|
|
16
|
+
# credits: true # Show "Built with Docyard" link
|
|
18
17
|
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
|
|
36
|
-
#
|
|
18
|
+
# Social Links (Optional)
|
|
19
|
+
# These appear in the footer
|
|
20
|
+
# socials:
|
|
21
|
+
# github: https://github.com/user/repo
|
|
22
|
+
# twitter: https://twitter.com/handle
|
|
23
|
+
|
|
24
|
+
# Tab Navigation (Optional)
|
|
25
|
+
# Use tabs to organize large documentation into sections
|
|
26
|
+
# tabs:
|
|
27
|
+
# - text: Guide
|
|
28
|
+
# href: /guide
|
|
29
|
+
# - text: API Reference
|
|
30
|
+
# href: /api
|
|
31
|
+
# - text: Blog
|
|
32
|
+
# href: https://blog.example.com
|
|
33
|
+
# external: true
|
|
34
|
+
|
|
35
|
+
# Search Configuration
|
|
36
|
+
# search:
|
|
37
|
+
# enabled: true
|
|
38
|
+
# placeholder: "Search documentation..."
|
|
39
|
+
# exclude:
|
|
40
|
+
# - /drafts/*
|
|
37
41
|
|
|
38
42
|
# Build Configuration
|
|
39
43
|
build:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
clean: true # Clean output directory before building
|
|
44
|
+
output: "dist" # Output directory for static files
|
|
45
|
+
base: "/" # Base URL for deployment (e.g., "/docs/" for subdirectory)
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>404 - Page Not Found</title>
|
|
7
|
-
<link rel="stylesheet" href="/
|
|
7
|
+
<link rel="stylesheet" href="/_docyard/css/main.css">
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
<main>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>500 - Server Error</title>
|
|
7
|
-
<link rel="stylesheet" href="/
|
|
7
|
+
<link rel="stylesheet" href="/_docyard/css/main.css">
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
<main>
|
|
@@ -1,99 +1,50 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
|
-
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<meta name="description" content="<%= @site_description %>">
|
|
7
|
-
<title><%= @page_title %> | <%= @site_title %></title>
|
|
8
|
-
<link rel="icon" href="<%= asset_path(@favicon) %>" type="image/svg+xml">
|
|
9
|
-
|
|
10
|
-
<!-- Prevent flash of wrong theme -->
|
|
11
|
-
<script>
|
|
12
|
-
(function() {
|
|
13
|
-
const theme = localStorage.getItem('theme') ||
|
|
14
|
-
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
|
15
|
-
document.documentElement.classList.toggle('dark', theme === 'dark');
|
|
16
|
-
})();
|
|
17
|
-
</script>
|
|
18
|
-
|
|
19
|
-
<link rel="stylesheet" href="/assets/css/main.css">
|
|
4
|
+
<%= render_partial('_head') %>
|
|
20
5
|
</head>
|
|
21
|
-
<body
|
|
22
|
-
<!-- Skip to main content for accessibility -->
|
|
6
|
+
<body<%= ' class="has-tabs"' if @has_tabs %>>
|
|
23
7
|
<a href="#main-content" class="skip-link">Skip to main content</a>
|
|
24
8
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
<a href="<%= link_path('/') %>" class="header-logo">
|
|
29
|
-
<% if @display_logo %>
|
|
30
|
-
<div class="site-logo-container">
|
|
31
|
-
<% if @logo %>
|
|
32
|
-
<img src="<%= asset_path(@logo) %>" alt="<%= @site_title %>" class="site-logo site-logo-light">
|
|
33
|
-
<% end %>
|
|
34
|
-
<% if @logo_dark %>
|
|
35
|
-
<img src="<%= asset_path(@logo_dark) %>" alt="<%= @site_title %>" class="site-logo site-logo-dark">
|
|
36
|
-
<% else %>
|
|
37
|
-
<img src="<%= asset_path(@logo) %>" alt="<%= @site_title %>" class="site-logo site-logo-dark">
|
|
38
|
-
<% end %>
|
|
39
|
-
</div>
|
|
40
|
-
<% end %>
|
|
41
|
-
<% if @display_title %>
|
|
42
|
-
<span class="header-title"><%= @site_title %></span>
|
|
43
|
-
<% end %>
|
|
44
|
-
</a>
|
|
45
|
-
|
|
46
|
-
<% if @search_enabled %>
|
|
47
|
-
<div class="header-center">
|
|
48
|
-
<%= render_partial('_search_trigger') %>
|
|
49
|
-
</div>
|
|
50
|
-
<% end %>
|
|
51
|
-
|
|
52
|
-
<div class="header-actions">
|
|
53
|
-
<%= render_partial('_theme_toggle') %>
|
|
54
|
-
</div>
|
|
55
|
-
</div>
|
|
56
|
-
</header>
|
|
9
|
+
<%= render_partial('_header') %>
|
|
10
|
+
<%= render_partial('_tab_bar') %>
|
|
11
|
+
<%= render_partial('_nav_menu') %>
|
|
57
12
|
|
|
58
|
-
<!-- Secondary Header (Mobile Navigation) -->
|
|
59
13
|
<div class="secondary-header">
|
|
60
14
|
<button class="secondary-header-menu" aria-label="Toggle navigation menu" aria-expanded="false">
|
|
61
|
-
|
|
62
|
-
<path d="M224,128a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,128ZM40,72H216a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16ZM216,184H40a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16Z"></path>
|
|
63
|
-
</svg>
|
|
15
|
+
<%= icon(:sidebar) %>
|
|
64
16
|
<span>Menu</span>
|
|
65
17
|
</button>
|
|
66
18
|
|
|
67
19
|
<%= render_partial('_table_of_contents_toggle') %>
|
|
68
20
|
</div>
|
|
69
21
|
|
|
70
|
-
<!-- Mobile overlay -->
|
|
71
22
|
<div class="mobile-overlay" aria-hidden="true"></div>
|
|
72
23
|
|
|
73
24
|
<div class="layout">
|
|
74
|
-
<!-- Sidebar navigation -->
|
|
75
25
|
<%= @sidebar_html %>
|
|
76
26
|
|
|
77
|
-
<!-- Main content area -->
|
|
78
27
|
<div class="layout-main">
|
|
79
28
|
<main id="main-content" class="content" data-pagefind-body>
|
|
29
|
+
<%= render_partial('_breadcrumbs') %>
|
|
80
30
|
<%= @content %>
|
|
81
31
|
|
|
82
|
-
<!-- Previous/Next Navigation -->
|
|
83
32
|
<%= @prev_next_html %>
|
|
33
|
+
|
|
34
|
+
<div class="doc-footer-mobile">
|
|
35
|
+
<%= render_partial('_doc_footer') %>
|
|
36
|
+
</div>
|
|
84
37
|
</main>
|
|
85
38
|
</div>
|
|
86
39
|
|
|
87
|
-
|
|
88
|
-
|
|
40
|
+
<aside class="doc-aside">
|
|
41
|
+
<%= render_partial('_table_of_contents') %>
|
|
42
|
+
<div class="doc-footer-desktop">
|
|
43
|
+
<%= render_partial('_doc_footer') %>
|
|
44
|
+
</div>
|
|
45
|
+
</aside>
|
|
89
46
|
</div>
|
|
90
47
|
|
|
91
|
-
|
|
92
|
-
<%= render_partial('_search_modal') %>
|
|
93
|
-
<% end %>
|
|
94
|
-
|
|
95
|
-
<script src="/assets/js/theme.js"></script>
|
|
96
|
-
<script src="/assets/js/components.js"></script>
|
|
97
|
-
<script src="/assets/js/reload.js"></script>
|
|
48
|
+
<%= render_partial('_scripts') %>
|
|
98
49
|
</body>
|
|
99
50
|
</html>
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<%= render_partial('_head') %>
|
|
5
|
+
</head>
|
|
6
|
+
<body class="splash-page<%= ' has-sidebar' if @show_sidebar %><%= ' has-tabs' if @has_tabs %>">
|
|
7
|
+
<a href="#main-content" class="skip-link">Skip to main content</a>
|
|
8
|
+
|
|
9
|
+
<%= render_partial('_header') %>
|
|
10
|
+
<%= render_partial('_tab_bar') %>
|
|
11
|
+
<%= render_partial('_nav_menu') %>
|
|
12
|
+
|
|
13
|
+
<% if @show_sidebar %>
|
|
14
|
+
<div class="secondary-header">
|
|
15
|
+
<button class="secondary-header-menu" aria-label="Toggle navigation menu" aria-expanded="false">
|
|
16
|
+
<%= icon(:sidebar) %>
|
|
17
|
+
<span>Menu</span>
|
|
18
|
+
</button>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<div class="mobile-overlay" aria-hidden="true"></div>
|
|
22
|
+
|
|
23
|
+
<div class="layout">
|
|
24
|
+
<%= @sidebar_html %>
|
|
25
|
+
|
|
26
|
+
<div class="layout-main">
|
|
27
|
+
<% end %>
|
|
28
|
+
|
|
29
|
+
<main id="main-content" class="splash-content">
|
|
30
|
+
<% if @hero %>
|
|
31
|
+
<%
|
|
32
|
+
hero_class = @hero[:image] ? 'hero hero--with-image' : 'hero hero--centered'
|
|
33
|
+
bg_style = @hero[:background] || 'grid'
|
|
34
|
+
%>
|
|
35
|
+
<section class="<%= hero_class %>">
|
|
36
|
+
<% if bg_style != 'none' %>
|
|
37
|
+
<div class="hero-bg hero-bg--<%= bg_style %>" aria-hidden="true">
|
|
38
|
+
<% if bg_style == 'glow' %>
|
|
39
|
+
<div class="hero-bg-orb hero-bg-orb--1"></div>
|
|
40
|
+
<div class="hero-bg-orb hero-bg-orb--2"></div>
|
|
41
|
+
<div class="hero-bg-orb hero-bg-orb--3"></div>
|
|
42
|
+
<% elsif bg_style == 'mesh' %>
|
|
43
|
+
<div class="hero-bg-mesh"></div>
|
|
44
|
+
<% end %>
|
|
45
|
+
</div>
|
|
46
|
+
<% end %>
|
|
47
|
+
|
|
48
|
+
<div class="hero-content">
|
|
49
|
+
<% if @hero[:badge] %>
|
|
50
|
+
<div class="hero-badge">
|
|
51
|
+
<span class="hero-badge-dot"></span>
|
|
52
|
+
<span class="hero-badge-text"><%= @hero[:badge] %></span>
|
|
53
|
+
</div>
|
|
54
|
+
<% end %>
|
|
55
|
+
<% if @hero[:title] %>
|
|
56
|
+
<%
|
|
57
|
+
title_class = @hero[:gradient] ? 'hero-title hero-title--gradient' : 'hero-title'
|
|
58
|
+
%>
|
|
59
|
+
<h1 class="<%= title_class %>"><%= @hero[:title] %></h1>
|
|
60
|
+
<% end %>
|
|
61
|
+
<% if @hero[:tagline] %>
|
|
62
|
+
<p class="hero-tagline"><%= @hero[:tagline] %></p>
|
|
63
|
+
<% end %>
|
|
64
|
+
<% if @hero[:actions]&.any? %>
|
|
65
|
+
<div class="hero-actions">
|
|
66
|
+
<% @hero[:actions].each do |action| %>
|
|
67
|
+
<%
|
|
68
|
+
is_external = action[:link]&.start_with?('http')
|
|
69
|
+
target_attr = action[:target] || (is_external ? '_blank' : nil)
|
|
70
|
+
rel_attr = action[:rel] || (is_external ? 'noopener noreferrer' : nil)
|
|
71
|
+
link_attrs = []
|
|
72
|
+
link_attrs << "target=\"#{target_attr}\"" if target_attr
|
|
73
|
+
link_attrs << "rel=\"#{rel_attr}\"" if rel_attr
|
|
74
|
+
%>
|
|
75
|
+
<a href="<%= link_path(action[:link]) %>" class="hero-action hero-action--<%= action[:variant] || 'primary' %>"<%= link_attrs.any? ? ' ' + link_attrs.join(' ') : '' %>>
|
|
76
|
+
<% if action[:icon] %>
|
|
77
|
+
<span class="hero-action-icon"><%= icon(action[:icon]) %></span>
|
|
78
|
+
<% end %>
|
|
79
|
+
<span><%= action[:text] %></span>
|
|
80
|
+
<% if action[:variant] != "secondary" %>
|
|
81
|
+
<svg class="hero-action-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
|
|
82
|
+
<% end %>
|
|
83
|
+
</a>
|
|
84
|
+
<% end %>
|
|
85
|
+
</div>
|
|
86
|
+
<% end %>
|
|
87
|
+
</div>
|
|
88
|
+
<% if @hero[:image] %>
|
|
89
|
+
<div class="hero-image">
|
|
90
|
+
<% if @hero[:image][:light] || @hero[:image][:dark] %>
|
|
91
|
+
<% if @hero[:image][:light] %>
|
|
92
|
+
<img src="<%= asset_path(@hero[:image][:light]) %>" alt="<%= @hero[:image][:alt] || '' %>" loading="eager" class="hero-image-light">
|
|
93
|
+
<% end %>
|
|
94
|
+
<% if @hero[:image][:dark] %>
|
|
95
|
+
<img src="<%= asset_path(@hero[:image][:dark]) %>" alt="<%= @hero[:image][:alt] || '' %>" loading="eager" class="hero-image-dark">
|
|
96
|
+
<% end %>
|
|
97
|
+
<% else %>
|
|
98
|
+
<img src="<%= asset_path(@hero[:image][:src]) %>" alt="<%= @hero[:image][:alt] || '' %>" loading="eager">
|
|
99
|
+
<% end %>
|
|
100
|
+
</div>
|
|
101
|
+
<% end %>
|
|
102
|
+
|
|
103
|
+
</section>
|
|
104
|
+
<% end %>
|
|
105
|
+
|
|
106
|
+
<% if @features&.any? %>
|
|
107
|
+
<section class="features-section">
|
|
108
|
+
<% if @features_header %>
|
|
109
|
+
<div class="features-header">
|
|
110
|
+
<% if @features_header[:label] %>
|
|
111
|
+
<p class="features-label"><%= @features_header[:label] %></p>
|
|
112
|
+
<% end %>
|
|
113
|
+
<% if @features_header[:title] %>
|
|
114
|
+
<h2 class="features-title"><%= @features_header[:title] %></h2>
|
|
115
|
+
<% end %>
|
|
116
|
+
<% if @features_header[:description] %>
|
|
117
|
+
<p class="features-description"><%= @features_header[:description] %></p>
|
|
118
|
+
<% end %>
|
|
119
|
+
</div>
|
|
120
|
+
<% end %>
|
|
121
|
+
|
|
122
|
+
<div class="features-magazine">
|
|
123
|
+
<% @features.each_with_index do |feature, index| %>
|
|
124
|
+
<%
|
|
125
|
+
icon_color = feature[:color] || 'primary'
|
|
126
|
+
size_class = feature[:size] ? "feature-card--#{feature[:size]}" : ''
|
|
127
|
+
has_link = feature[:link] && !feature[:link].to_s.strip.empty?
|
|
128
|
+
tag = has_link ? 'a' : 'div'
|
|
129
|
+
|
|
130
|
+
feature_link_attrs = []
|
|
131
|
+
if has_link
|
|
132
|
+
feature_link_attrs << "href=\"#{link_path(feature[:link])}\""
|
|
133
|
+
is_external = feature[:link]&.start_with?('http')
|
|
134
|
+
target_attr = feature[:target] || (is_external ? '_blank' : nil)
|
|
135
|
+
rel_attr = feature[:rel] || (is_external ? 'noopener noreferrer' : nil)
|
|
136
|
+
feature_link_attrs << "target=\"#{target_attr}\"" if target_attr
|
|
137
|
+
feature_link_attrs << "rel=\"#{rel_attr}\"" if rel_attr
|
|
138
|
+
end
|
|
139
|
+
%>
|
|
140
|
+
<<%= tag %> <%= feature_link_attrs.join(' ') %> class="feature-card <%= size_class %>" style="--card-color: var(--feature-<%= icon_color %>)">
|
|
141
|
+
<% if feature[:icon] %>
|
|
142
|
+
<span class="feature-icon feature-icon--<%= icon_color %>"><%= icon(feature[:icon]) %></span>
|
|
143
|
+
<% end %>
|
|
144
|
+
<h3 class="feature-title"><%= feature[:title] %></h3>
|
|
145
|
+
<% if feature[:description] %>
|
|
146
|
+
<p class="feature-description"><%= feature[:description] %></p>
|
|
147
|
+
<% end %>
|
|
148
|
+
<% if has_link %>
|
|
149
|
+
<div class="feature-arrow">
|
|
150
|
+
<span><%= feature[:link_text] || 'Learn more' %></span>
|
|
151
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
|
|
152
|
+
</div>
|
|
153
|
+
<% end %>
|
|
154
|
+
</<%= tag %>>
|
|
155
|
+
<% end %>
|
|
156
|
+
</div>
|
|
157
|
+
</section>
|
|
158
|
+
<% end %>
|
|
159
|
+
|
|
160
|
+
<% if @content && !@content.strip.empty? %>
|
|
161
|
+
<section class="splash-markdown">
|
|
162
|
+
<%= @content %>
|
|
163
|
+
</section>
|
|
164
|
+
<% end %>
|
|
165
|
+
</main>
|
|
166
|
+
|
|
167
|
+
<% if @show_sidebar %>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
<% end %>
|
|
171
|
+
|
|
172
|
+
<%= render_partial('_footer') %>
|
|
173
|
+
|
|
174
|
+
<%= render_partial('_scripts') %>
|
|
175
|
+
</body>
|
|
176
|
+
</html>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<% if @breadcrumbs&.should_show? %>
|
|
2
|
+
<nav class="breadcrumbs<%= ' breadcrumbs--single' if @breadcrumbs.items.length == 1 %>" aria-label="Breadcrumb">
|
|
3
|
+
<button class="breadcrumb-toggle" aria-label="Toggle sidebar" aria-expanded="true" type="button">
|
|
4
|
+
<%= icon(:sidebar) %>
|
|
5
|
+
</button>
|
|
6
|
+
|
|
7
|
+
<ol class="breadcrumb-list">
|
|
8
|
+
<% @breadcrumbs.items.each_with_index do |item, index| %>
|
|
9
|
+
<li class="breadcrumb-item<%= ' breadcrumb-item--current' if item.current %><%= ' breadcrumb-item--ellipsis' if item.title == '...' %>">
|
|
10
|
+
<% if item.title == '...' %>
|
|
11
|
+
<span class="breadcrumb-ellipsis" aria-hidden="true">...</span>
|
|
12
|
+
<% elsif item.current %>
|
|
13
|
+
<span class="breadcrumb-text" aria-current="page"><%= item.title %></span>
|
|
14
|
+
<% else %>
|
|
15
|
+
<a href="<%= link_path(item.href) %>" class="breadcrumb-link"><%= item.title %></a>
|
|
16
|
+
<% end %>
|
|
17
|
+
</li>
|
|
18
|
+
<% unless index == @breadcrumbs.items.length - 1 %>
|
|
19
|
+
<li class="breadcrumb-separator" aria-hidden="true">/</li>
|
|
20
|
+
<% end %>
|
|
21
|
+
<% end %>
|
|
22
|
+
</ol>
|
|
23
|
+
</nav>
|
|
24
|
+
<% end %>
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
<% if has_title %>
|
|
3
3
|
<div class="docyard-code-block__header">
|
|
4
4
|
<% if @icon %>
|
|
5
|
-
<span class="docyard-code-block__icon"><% if @icon_source == "file-extension" %><%=
|
|
5
|
+
<span class="docyard-code-block__icon"><% if @icon_source == "file-extension" %><%= icon_file_extension(@icon) %><% elsif @icon_source == "phosphor" %><%= icon(@icon) %><% end %></span>
|
|
6
6
|
<% end %>
|
|
7
7
|
<span class="docyard-code-block__title" title="<%= @title %>"><%= @title %></span>
|
|
8
8
|
<button class="docyard-code-block__copy" aria-label="Copy code to clipboard" data-code="<%= @code_text %>">
|
|
9
|
-
|
|
9
|
+
<span class="docyard-code-block__copy-icon"><%= @copy_icon %></span>
|
|
10
|
+
<span class="docyard-code-block__copy-text">Copy</span>
|
|
10
11
|
</button>
|
|
11
12
|
</div>
|
|
12
13
|
<% end %>
|
|
@@ -47,7 +48,8 @@
|
|
|
47
48
|
</div>
|
|
48
49
|
<% unless has_title %>
|
|
49
50
|
<button class="docyard-code-block__copy" aria-label="Copy code to clipboard" data-code="<%= @code_text %>">
|
|
50
|
-
|
|
51
|
+
<span class="docyard-code-block__copy-icon"><%= @copy_icon %></span>
|
|
52
|
+
<span class="docyard-code-block__copy-text">Copy</span>
|
|
51
53
|
</button>
|
|
52
54
|
<% end %>
|
|
53
55
|
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<% has_social = @social&.any? %>
|
|
2
|
+
<% show_footer = has_social || @credits || @copyright %>
|
|
3
|
+
|
|
4
|
+
<% if show_footer %>
|
|
5
|
+
<div class="site-footer">
|
|
6
|
+
<% if has_social %>
|
|
7
|
+
<div class="site-footer__socials">
|
|
8
|
+
<% @social.each do |social| %>
|
|
9
|
+
<a href="<%= social[:url] %>" class="site-footer__link" target="_blank" rel="noopener noreferrer" aria-label="<%= social[:platform].capitalize %>">
|
|
10
|
+
<%= icon(social[:icon]) %>
|
|
11
|
+
</a>
|
|
12
|
+
<% end %>
|
|
13
|
+
</div>
|
|
14
|
+
<% end %>
|
|
15
|
+
|
|
16
|
+
<div class="site-footer__credits">
|
|
17
|
+
<% if @credits %>
|
|
18
|
+
<a href="https://docyard.dev" target="_blank" rel="noopener noreferrer" class="site-footer__attribution">Built with Docyard</a>
|
|
19
|
+
<% end %>
|
|
20
|
+
<% if @copyright %>
|
|
21
|
+
<span class="site-footer__copyright"><%= icon(:copyright) %> <%= @copyright %></span>
|
|
22
|
+
<% end %>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
<% end %>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<section class="features">
|
|
2
|
+
<div class="features-grid">
|
|
3
|
+
<% @features.each do |feature| %>
|
|
4
|
+
<div class="feature-card">
|
|
5
|
+
<% if feature[:icon] %>
|
|
6
|
+
<span class="feature-icon"><%= icon(feature[:icon]) %></span>
|
|
7
|
+
<% end %>
|
|
8
|
+
<h3 class="feature-title"><%= feature[:title] %></h3>
|
|
9
|
+
<% if feature[:description] %>
|
|
10
|
+
<p class="feature-description"><%= feature[:description] %></p>
|
|
11
|
+
<% end %>
|
|
12
|
+
</div>
|
|
13
|
+
<% end %>
|
|
14
|
+
</div>
|
|
15
|
+
</section>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<% has_footer_links = @footer_links&.any? %>
|
|
2
|
+
<% has_social = @social&.any? %>
|
|
3
|
+
<% show_footer = has_footer_links || has_social || @credits %>
|
|
4
|
+
|
|
5
|
+
<% if show_footer %>
|
|
6
|
+
<footer class="footer">
|
|
7
|
+
<%
|
|
8
|
+
# Determine layout class
|
|
9
|
+
footer_class = "footer-content"
|
|
10
|
+
if !@credits && !has_social && has_footer_links
|
|
11
|
+
footer_class += " footer-content--no-attribution"
|
|
12
|
+
elsif !has_footer_links && !has_social && @credits
|
|
13
|
+
footer_class += " footer-content--centered"
|
|
14
|
+
elsif !has_footer_links && has_social && !@credits
|
|
15
|
+
footer_class += " footer-content--centered"
|
|
16
|
+
end
|
|
17
|
+
%>
|
|
18
|
+
<div class="<%= footer_class %>">
|
|
19
|
+
<% if @credits %>
|
|
20
|
+
<a href="https://docyard.org" target="_blank" rel="noopener noreferrer" class="footer-attribution">Built with Docyard</a>
|
|
21
|
+
<% end %>
|
|
22
|
+
|
|
23
|
+
<% if has_footer_links %>
|
|
24
|
+
<nav class="footer-links">
|
|
25
|
+
<% @footer_links.each do |link| %>
|
|
26
|
+
<a href="<%= link[:link]&.start_with?('http') ? link[:link] : link_path(link[:link]) %>"<%= link[:link]&.start_with?('http') ? ' target="_blank" rel="noopener noreferrer"' : '' %>><%= link[:text] %></a>
|
|
27
|
+
<% end %>
|
|
28
|
+
</nav>
|
|
29
|
+
<% end %>
|
|
30
|
+
|
|
31
|
+
<% if has_social %>
|
|
32
|
+
<div class="footer-socials">
|
|
33
|
+
<% @social.each do |social| %>
|
|
34
|
+
<a href="<%= social[:url] %>" target="_blank" rel="noopener noreferrer" aria-label="<%= social[:platform].capitalize %>">
|
|
35
|
+
<%= icon(social[:icon]) %>
|
|
36
|
+
</a>
|
|
37
|
+
<% end %>
|
|
38
|
+
</div>
|
|
39
|
+
<% end %>
|
|
40
|
+
</div>
|
|
41
|
+
</footer>
|
|
42
|
+
<% end %>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<meta charset="UTF-8">
|
|
2
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3
|
+
<meta name="description" content="<%= @site_description %>">
|
|
4
|
+
<meta name="view-transition" content="same-origin">
|
|
5
|
+
<title><%= @page_title %> | <%= @site_title %></title>
|
|
6
|
+
<link rel="icon" href="<%= asset_path(@favicon) %>" type="image/svg+xml">
|
|
7
|
+
|
|
8
|
+
<link rel="preload" href="/_docyard/fonts/Inter-Variable.ttf" as="font" type="font/ttf" crossorigin>
|
|
9
|
+
|
|
10
|
+
<script>
|
|
11
|
+
(function() {
|
|
12
|
+
const theme = localStorage.getItem('theme') ||
|
|
13
|
+
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
|
14
|
+
document.documentElement.classList.toggle('dark', theme === 'dark');
|
|
15
|
+
|
|
16
|
+
if (localStorage.getItem('docyard_sidebar_collapsed') === 'true') {
|
|
17
|
+
document.documentElement.classList.add('sidebar-collapsed');
|
|
18
|
+
}
|
|
19
|
+
})();
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<link rel="stylesheet" href="/_docyard/css/main.css">
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<header class="header">
|
|
2
|
+
<div class="header-content">
|
|
3
|
+
<a href="<%= link_path('/') %>" class="header-logo">
|
|
4
|
+
<% if @has_custom_logo %>
|
|
5
|
+
<div class="site-logo-container">
|
|
6
|
+
<img src="<%= asset_path(@logo) %>" alt="<%= @site_title %>" class="site-logo site-logo-light">
|
|
7
|
+
<% if @logo_dark %>
|
|
8
|
+
<img src="<%= asset_path(@logo_dark) %>" alt="<%= @site_title %>" class="site-logo site-logo-dark">
|
|
9
|
+
<% else %>
|
|
10
|
+
<img src="<%= asset_path(@logo) %>" alt="<%= @site_title %>" class="site-logo site-logo-dark">
|
|
11
|
+
<% end %>
|
|
12
|
+
</div>
|
|
13
|
+
<% else %>
|
|
14
|
+
<span class="header-title"><%= @site_title %></span>
|
|
15
|
+
<% end %>
|
|
16
|
+
</a>
|
|
17
|
+
|
|
18
|
+
<% if @search_enabled %>
|
|
19
|
+
<div class="header-center">
|
|
20
|
+
<%= render_partial('_search_trigger') %>
|
|
21
|
+
</div>
|
|
22
|
+
<% end %>
|
|
23
|
+
|
|
24
|
+
<div class="header-actions">
|
|
25
|
+
<% if @header_ctas&.any? %>
|
|
26
|
+
<div class="header-ctas">
|
|
27
|
+
<% @header_ctas.sort_by { |cta| cta[:variant] == 'secondary' ? 0 : 1 }.each do |cta| %>
|
|
28
|
+
<a href="<%= cta[:external] ? cta[:href] : link_path(cta[:href]) %>"
|
|
29
|
+
class="header-cta header-cta--<%= cta[:variant] || 'primary' %>"
|
|
30
|
+
<%= 'target="_blank" rel="noopener noreferrer"' if cta[:external] %>>
|
|
31
|
+
<%= cta[:text] %>
|
|
32
|
+
<% if cta[:variant] != 'secondary' %>
|
|
33
|
+
<svg class="header-cta-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
34
|
+
<path d="M9 5l7 7-7 7"/>
|
|
35
|
+
</svg>
|
|
36
|
+
<% end %>
|
|
37
|
+
</a>
|
|
38
|
+
<% end %>
|
|
39
|
+
</div>
|
|
40
|
+
<% end %>
|
|
41
|
+
<%= render_partial('_theme_toggle') %>
|
|
42
|
+
<% if @has_tabs %>
|
|
43
|
+
<button class="nav-menu-btn" id="navMenuBtn" aria-label="Toggle navigation menu" aria-expanded="false">
|
|
44
|
+
<%= icon(:equals) %>
|
|
45
|
+
</button>
|
|
46
|
+
<% end %>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</header>
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
<a href="#<%= @id %>" class="heading-anchor" aria-label="Link to this section" data-heading-id="<%= @id %>" data-pagefind-ignore
|
|
1
|
+
<a href="#<%= @id %>" class="heading-anchor" aria-label="Link to this section" data-heading-id="<%= @id %>" data-pagefind-ignore>
|
|
2
|
+
<%= icon(:link_simple) %>
|
|
3
|
+
</a>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<section class="hero">
|
|
2
|
+
<div class="hero-content">
|
|
3
|
+
<% if @title %>
|
|
4
|
+
<h1 class="hero-title"><%= @title %></h1>
|
|
5
|
+
<% end %>
|
|
6
|
+
<% if @tagline %>
|
|
7
|
+
<p class="hero-tagline"><%= @tagline %></p>
|
|
8
|
+
<% end %>
|
|
9
|
+
<% if @actions&.any? %>
|
|
10
|
+
<div class="hero-actions">
|
|
11
|
+
<% @actions.each do |action| %>
|
|
12
|
+
<a href="<%= link_path(action[:link]) %>" class="hero-action hero-action--<%= action[:variant] || 'primary' %>">
|
|
13
|
+
<%= action[:text] %>
|
|
14
|
+
<% if action[:variant] == "primary" || action[:variant].nil? %>
|
|
15
|
+
<%= icon(:arrow_right) %>
|
|
16
|
+
<% end %>
|
|
17
|
+
</a>
|
|
18
|
+
<% end %>
|
|
19
|
+
</div>
|
|
20
|
+
<% end %>
|
|
21
|
+
</div>
|
|
22
|
+
<% if @image %>
|
|
23
|
+
<div class="hero-image">
|
|
24
|
+
<img src="<%= link_path(@image[:src]) %>" alt="<%= @image[:alt] || '' %>">
|
|
25
|
+
</div>
|
|
26
|
+
<% end %>
|
|
27
|
+
</section>
|