Class: DocsKit::Configuration
- Inherits:
-
Object
- Object
- DocsKit::Configuration
- Defined in:
- lib/docs_kit/configuration.rb
Overview
Per-site configuration for the shared docs chrome. Everything that differs between two otherwise-identical docs sites lives here, so the Phlex shell (DocsUI::Shell, DocsUI::Sidebar, DocsUI::ThemeSwitcher) is byte-identical across sites and only the config changes.
DocsKit.configure do |c|
c.brand = "phlex-reactive"
c.title_suffix = "phlex-reactive"
c.themes = %w[dark light synthwave ...]
c.nav = -> { { "Demos" => Demo.grouped, "Docs" => Doc.grouped } }
end
Constant Summary collapse
- TOPBAR_BRAND_MODES =
The topbar-brand placements. At lg: the sidebar (with its own brand) is pinned open, so :mobile_only drops the duplicate; :always keeps it.
%i[always mobile_only].freeze
- DEFAULT_NAV =
The sentinel "no explicit nav" lambda. #nav_groups compares against this identity to decide whether to derive the sidebar from #nav_registries.
-> { {} }
- DEFAULT_SEARCH_SHORTCUTS =
The search-palette shortcuts before this was configurable — "/" and the platform command chord — so a site that never sets #search_shortcuts keeps exactly the previous behavior.
["/", "mod+k"].freeze
- DEFAULT_DARK_THEMES =
The built-in daisyUI theme names that are dark. #dark_themes defaults to this; #dark_themes_shipped intersects it with the site's #themes so only shipped themes ever generate dark code CSS. A site with custom dark themes overrides #dark_themes (docs-kit can't see the compiled daisyUI CSS to detect darkness at render time, so an honest static list + override wins).
%w[ dark synthwave halloween forest black luxury dracula business night coffee dim sunset abyss ].freeze
- DEFAULT_LEXER_ALIASES =
Built-in friendly aliases (kept small — Rouge resolves most names itself).
{ curl: "console", console: "console" }.freeze
- DEFAULT_LANGUAGE_LABELS =
Built-in tab labels for the common languages that don't just capitalize.
{ javascript: "JavaScript", typescript: "TypeScript", php: "PHP", curl: "cURL", json: "JSON", yaml: "YAML", html: "HTML", css: "CSS", erb: "ERB", jsx: "JSX", tsx: "TSX", sql: "SQL", graphql: "GraphQL" }.freeze
- ON_PAGE_MODES =
The auto-TOC placements, all driven by the same docs-nav Stimulus controller (it reads the page's headings from the DOM):
:panel — a sticky card in the top-right of the content column :toggle — a sticky floating button (top-right) opening a dropdown :sidebar — nested under the active nav item in the left sidebar %i[panel toggle sidebar].freeze
- DEFAULT_CODE_THEME =
The default Rouge theme both #code_theme_class and #code_theme_dark_class fall back to when a configured theme name can't be resolved — so a typo'd theme name degrades gracefully instead of raising on every code block.
"Rouge::Themes::Monokai"
Instance Attribute Summary collapse
-
#api_auth_header ⇒ Object
An example Authorization header line merged into every generated request snippet (e.g. "Authorization: Bearer sk_live_...").
-
#api_base_url ⇒ Object
The API base URL prefixed onto a DocsUI::RequestExample path so copy-pasted snippets point at a real host.
-
#api_clients ⇒ Object
The effective client map for DocsUI::RequestExample: the four shipped defaults with site overrides/extensions merged over them.
-
#app_link ⇒ Object
The normalized App Home link (a DocsKit::TopbarLink), or nil when unset — absent config, absent link, exactly like every other opt-in knob.
-
#brand ⇒ Object
The brand text shown in the topbar and sidebar header.
-
#brand_href ⇒ Object
The href the topbar brand link points at.
-
#code_language_labels ⇒ Object
Human labels for language tabs in DocsUI::Example, merged over the built-ins (e.g. { elixir: "Elixir", curl: "cURL" }).
-
#code_lexer_aliases ⇒ Object
Friendly-name → Rouge lexer aliases for code blocks, merged over the built-in defaults.
-
#code_lexer_fallback ⇒ Object
The lexer used when a requested language can't be resolved.
-
#code_theme ⇒ Object
The Rouge theme class used by DocsUI::Code for inline syntax-highlight CSS.
-
#code_theme_dark ⇒ Object
An optional second Rouge theme (String name or Class) used for the site's DARK daisyUI themes.
-
#dark_themes ⇒ Object
The theme names treated as DARK for #code_theme_dark scoping.
-
#default_group_icon ⇒ Object
The lucide icon name used for a nav group with no explicit icon.
- #default_theme ⇒ Object
-
#icon_library ⇒ Object
The RailsIcons library docs-kit renders its OWN chrome icons from (the sidebar carets, search glyph, theme toggle, etc.).
-
#mcp ⇒ Object
Whether the built-in read-only MCP endpoint (DocsKit::McpController, a POST /mcp JSON-RPC server exposing list_pages / get_page / search_docs over the same registry the docs render from) is active.
-
#nav ⇒ Object
A callable returning the sidebar nav as an ordered Hash of { "Heading" => { "Subgroup" => [items] } }.
-
#nav_registries ⇒ Object
An ordered { "Heading" => registry_class } map.
- #nav_storage_key ⇒ Object
-
#on_page_default ⇒ Object
The resolved default placement (a mode symbol or false).
-
#openapi ⇒ Object
The OpenAPI spec the
operationpage helper / DocsUI::OpenApiOperation read from: a String/Pathname path (.jsonparsed as JSON, else YAML) or an already-parsed Hash. -
#page_markdown_action ⇒ Object
Whether DocsUI::Page shows the "Markdown" masthead action — a link to the page's
.mdtwin that docs-nav enhances into copy-to-clipboard. -
#repo_url ⇒ Object
The site's source repository root (e.g. "https://github.com/me/repo"), used for the GitHub compare link between two versions' refs (#compare_url).
-
#search ⇒ Object
Whether the topbar renders the docs-search form (and the docs-nav palette markup).
-
#search_path ⇒ Object
The path the topbar search form submits to (GET ?q=), and the base the palette fetches
.jsonfrom. -
#search_shortcuts ⇒ Object
The parsed search-palette shortcuts (DocsKit::Shortcut list), with anything unparseable dropped.
-
#snapshots_path ⇒ Object
The resolved snapshots directory: the configured value verbatim, else Rails.root/"docs_snapshots" under Rails, else nil (no Rails, no default — the standalone suite passes explicit paths).
-
#stylesheets ⇒ Object
The stylesheet logical names linked in
, in order. -
#tagline ⇒ Object
A one-line site summary, rendered as the llms.txt blockquote (
> {tagline}) under the H1. -
#themes ⇒ Object
The themes offered by the ThemeSwitcher.
- #title_suffix ⇒ Object
-
#topbar_brand ⇒ Object
Where the topbar renders the brand: :always (the default — byte-compat), or :mobile_only, which hides it at the drawer-pinned breakpoint (lg:) where the sidebar brand is already visible, deduplicating the mark.
-
#topbar_links ⇒ Object
The normalized topbar links (DocsKit::TopbarLink list), in declaration order.
-
#version_badge ⇒ Object
Optional callable returning a short version-badge string for the sidebar header (e.g. -> { "v#DaisyUI::VERSION" }).
-
#versions ⇒ Object
The normalized version list (DocsKit::DocVersion list), in declaration order.
Instance Method Summary collapse
-
#brand_logo ⇒ Object
The normalized shell brand mark (a DocsKit::BrandLogo), or nil when unset.
-
#brand_logo=(value) ⇒ Object
The opt-in shell brand mark, rendered by BOTH the topbar and the sidebar header in place of the text #brand (which stays the accessible-name fallback).
-
#code_theme_class ⇒ Object
The Rouge theme class resolved from #code_theme (String or class).
-
#code_theme_dark_class ⇒ Object
The dark Rouge theme class resolved from #code_theme_dark (String or class), or nil when unset — mirrors #code_theme_class.
-
#compare_url(from, to) ⇒ Object
The GitHub compare URL between two versions' refs ("#repo_url/compare/fromfrom.ref...toto.ref"), or nil unless #repo_url and BOTH refs are present — absent value, absent link, never a broken one.
-
#current_version ⇒ Object
The version serving unprefixed at /docs: the entry marked current: true, else the first configured entry, else nil (an unversioned site).
-
#dark_themes_shipped ⇒ Object
The dark themes the site actually ships: #dark_themes intersected with #themes, in #themes declaration order.
-
#initialize ⇒ Configuration
constructor
A new instance of Configuration.
-
#landing ⇒ Object
The landing-page knobs (DocsKit::LandingConfig), read by DocsUI::Landing.
-
#language_labels ⇒ Object
The effective label map (built-ins + site overrides), symbol-keyed.
-
#lexer_aliases ⇒ Object
The effective alias map (built-ins + site overrides), symbol-keyed.
-
#mcp_enabled? ⇒ Boolean
Whether the built-in MCP endpoint is active: the #mcp toggle is on AND the optional
mcpgem is loadable — the same "toggle AND capability" shape as #search_enabled?. -
#nav_groups ⇒ Object
The resolved nav Hash for this request.
-
#normalize_on_page(value) ⇒ Object
Coerce a per-page on_page: value to a valid mode symbol or false.
-
#openapi_document ⇒ Object
The loaded DocsKit::OpenApi::Document for #openapi.
-
#resolve_version(id) ⇒ Object
The version a request's :version param resolves to: the strict #version lookup, falling back to #current_version for an unknown or missing id — one rule shared by DocsKit::Controller#render_page and the gem's own controllers (DocsKit::Scoping), so a bad param degrades to the current docs instead of 500ing.
-
#search_enabled? ⇒ Boolean
Whether the Shell renders the search affordance: search is on AND a path is set to submit to.
-
#seo ⇒ Object
The SEO / social-share knobs (DocsKit::SeoConfig), read by DocsUI::MetaTags.
-
#version(id) ⇒ Object
The configured version with this id, or nil when unknown (or nil id).
-
#version_badge_text ⇒ Object
The resolved version badge string, or nil.
-
#versioning_enabled? ⇒ Boolean
Whether the version chrome (switcher, llms.txt Versions block) renders.
Constructor Details
#initialize ⇒ Configuration
Returns a new instance of Configuration.
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'lib/docs_kit/configuration.rb', line 295 def initialize @brand = "Docs" @tagline = nil @brand_href = "/" @title_suffix = nil @themes = %w[dark light] @default_theme = nil # The default nav lambda. Until a site assigns #nav (which sets # @nav_explicit), #nav_groups treats nav as "unset" and derives the sidebar # from #nav_registries instead; an explicit c.nav (any lambda) then wins. @nav = DEFAULT_NAV @nav_explicit = false @nav_registries = {} @version_badge = nil @stylesheets = %w[application] @code_theme = "Rouge::Themes::Monokai" @code_theme_dark = nil @dark_themes = DEFAULT_DARK_THEMES @default_group_icon = "file-text" @icon_library = "lucide" @nav_storage_key = nil @on_page_default = :panel @code_lexer_aliases = {} @code_lexer_fallback = "plaintext" @code_language_labels = {} @page_markdown_action = true @mcp = true @search = true @search_path = "/docs/search" @search_shortcuts = DEFAULT_SEARCH_SHORTCUTS @api_base_url = "https://api.example.com" @api_auth_header = nil @api_clients = {} @app_link = nil @topbar_links = [] @openapi = nil @brand_logo = nil @brand_logo_raw = nil @topbar_brand = :always @versions = [] @repo_url = nil @snapshots_path = nil end |
Instance Attribute Details
#api_auth_header ⇒ Object
An example Authorization header line merged into every generated request snippet (e.g. "Authorization: Bearer sk_live_..."). Defaults to nil → no auth line, so a site with no auth example renders clean snippets.
178 179 180 |
# File 'lib/docs_kit/configuration.rb', line 178 def api_auth_header @api_auth_header end |
#api_base_url ⇒ Object
The API base URL prefixed onto a DocsUI::RequestExample path so copy-pasted snippets point at a real host. Defaults to a neutral example host; a site sets its own (e.g. "https://api.acme.com").
173 174 175 |
# File 'lib/docs_kit/configuration.rb', line 173 def api_base_url @api_base_url end |
#api_clients ⇒ Object
The effective client map for DocsUI::RequestExample: the four shipped defaults with site overrides/extensions merged over them. Hash#merge keeps a reused token in its original position and appends new tokens in declaration order, so tab order is stable and predictable.
457 458 459 |
# File 'lib/docs_kit/configuration.rb', line 457 def api_clients DocsKit::ApiClient::DEFAULTS.merge(@api_clients || {}) end |
#app_link ⇒ Object
The normalized App Home link (a DocsKit::TopbarLink), or nil when unset — absent config, absent link, exactly like every other opt-in knob.
341 342 343 344 345 |
# File 'lib/docs_kit/configuration.rb', line 341 def app_link return if @app_link.nil? DocsKit::TopbarLink.from(@app_link) end |
#brand ⇒ Object
The brand text shown in the topbar and sidebar header.
20 21 22 |
# File 'lib/docs_kit/configuration.rb', line 20 def brand @brand end |
#brand_href ⇒ Object
The href the topbar brand link points at. Defaults to "/" (site root). A site whose docs live under a subpath sets its own (e.g. "/docs") so the brand link is a one-line config change, not a Shell subclass.
31 32 33 |
# File 'lib/docs_kit/configuration.rb', line 31 def brand_href @brand_href end |
#code_language_labels ⇒ Object
Human labels for language tabs in DocsUI::Example, merged over the built-ins (e.g. { elixir: "Elixir", curl: "cURL" }). Unknown tokens humanize.
134 135 136 |
# File 'lib/docs_kit/configuration.rb', line 134 def code_language_labels @code_language_labels end |
#code_lexer_aliases ⇒ Object
Friendly-name → Rouge lexer aliases for code blocks, merged over the built-in defaults. Any language Rouge knows (~200) already works by its own name/alias; use this only to add or override (e.g. { curl: "console", dockerfile: "docker" }). Value is anything Rouge::Lexer.find accepts.
126 127 128 |
# File 'lib/docs_kit/configuration.rb', line 126 def code_lexer_aliases @code_lexer_aliases end |
#code_lexer_fallback ⇒ Object
The lexer used when a requested language can't be resolved. Default "plaintext" (no highlighting, never raises).
130 131 132 |
# File 'lib/docs_kit/configuration.rb', line 130 def code_lexer_fallback @code_lexer_fallback end |
#code_theme ⇒ Object
The Rouge theme class used by DocsUI::Code for inline syntax-highlight CSS. This is the BASE (light) theme, emitted un-scoped so it applies to every theme unless a dark override wins (see #code_theme_dark).
84 85 86 |
# File 'lib/docs_kit/configuration.rb', line 84 def code_theme @code_theme end |
#code_theme_dark ⇒ Object
An optional second Rouge theme (String name or Class) used for the site's DARK daisyUI themes. Default nil → single-theme behavior, fully backwards compatible. When set, DocsUI::Code additionally emits this theme's CSS scoped under [data-theme=X] .code-highlight for each shipped dark theme (see #dark_themes), so code blocks stay readable when the switcher flips to a dark theme — CSS-only, no JS, no flash.
92 93 94 |
# File 'lib/docs_kit/configuration.rb', line 92 def code_theme_dark @code_theme_dark end |
#dark_themes ⇒ Object
The theme names treated as DARK for #code_theme_dark scoping. Defaults to the built-in daisyUI dark themes (DEFAULT_DARK_THEMES). Intersected with #themes at render time (see #dark_themes_shipped) so only shipped themes generate CSS. Override to name custom dark themes (e.g. %w).
98 99 100 |
# File 'lib/docs_kit/configuration.rb', line 98 def dark_themes @dark_themes end |
#default_group_icon ⇒ Object
The lucide icon name used for a nav group with no explicit icon.
101 102 103 |
# File 'lib/docs_kit/configuration.rb', line 101 def default_group_icon @default_group_icon end |
#default_theme ⇒ Object
578 579 580 |
# File 'lib/docs_kit/configuration.rb', line 578 def default_theme @default_theme || Array(@themes).first end |
#icon_library ⇒ Object
The RailsIcons library docs-kit renders its OWN chrome icons from (the sidebar carets, search glyph, theme toggle, etc.). Defaults to "lucide" to match the lucide icon names docs-kit ships. This is independent of the host app's RailsIcons.configuration.default_library — a host whose default is phosphor/heroicons can leave this at "lucide" so the chrome keeps rendering, without flipping its global default. Set to nil to defer to the host's default_library.
110 111 112 |
# File 'lib/docs_kit/configuration.rb', line 110 def icon_library @icon_library end |
#mcp ⇒ Object
Whether the built-in read-only MCP endpoint (DocsKit::McpController, a
POST /mcp JSON-RPC server exposing list_pages / get_page / search_docs over
the same registry the docs render from) is active. Defaults to true, but the
endpoint only turns on when the optional mcp gem is ALSO present and the
host draws the route — #mcp_enabled? gates on both. Set false to keep the
endpoint off even on a site that bundles the gem. See DocsKit::McpServer.
148 149 150 |
# File 'lib/docs_kit/configuration.rb', line 148 def mcp @mcp end |
#nav ⇒ Object
A callable returning the sidebar nav as an ordered Hash of { "Heading" => { "Subgroup" => [items] } }. Each item must respond to the duck type the Sidebar renders (see DocsUI::Sidebar#nav_link): #href, #label, and optional #icon. Defaults to an empty nav.
Prefer #nav_registries for the common case — an explicit #nav lambda is only needed for bespoke nav (multiple registries interleaved, custom subgroups). When #nav is left at its default, the sidebar derives from #nav_registries instead.
55 56 57 |
# File 'lib/docs_kit/configuration.rb', line 55 def nav @nav end |
#nav_registries ⇒ Object
An ordered { "Heading" => registry_class } map. Each registry responds to .nav_items (Registry v2) → { group => [NavItem] } for its authored pages. #nav_groups derives the whole sidebar from this with zero site code, so a site never hand-writes the nav lambda. Defaults to {}. An explicit #nav lambda still wins (full backwards compatibility).
70 71 72 |
# File 'lib/docs_kit/configuration.rb', line 70 def nav_registries @nav_registries end |
#nav_storage_key ⇒ Object
547 548 549 |
# File 'lib/docs_kit/configuration.rb', line 547 def nav_storage_key @nav_storage_key || @brand.to_s.downcase.gsub(/[^a-z0-9]+/, "-").gsub(/\A-+|-+\z/, "") end |
#on_page_default ⇒ Object
The resolved default placement (a mode symbol or false). A bare true
default means :panel (the canonical default), never a self-reference.
480 481 482 483 484 |
# File 'lib/docs_kit/configuration.rb', line 480 def on_page_default raw = @on_page_default raw = :panel if raw == true coerce_on_page_mode(raw) end |
#openapi ⇒ Object
The OpenAPI spec the operation page helper / DocsUI::OpenApiOperation read
from: a String/Pathname path (.json parsed as JSON, else YAML) or an
already-parsed Hash. Defaults to nil → the bridge is off and a site that
doesn't set it is byte-identical to before. Read the loaded model via
#openapi_document (which memoizes + reloads on file change), never @openapi.
243 244 245 |
# File 'lib/docs_kit/configuration.rb', line 243 def openapi @openapi end |
#page_markdown_action ⇒ Object
Whether DocsUI::Page shows the "Markdown" masthead action — a link to the
page's .md twin that docs-nav enhances into copy-to-clipboard. Defaults to
true; set false to hide the affordance site-wide (the .md route still
works). See DocsKit::MarkdownExport / DocsKit::Controller#render_page.
140 141 142 |
# File 'lib/docs_kit/configuration.rb', line 140 def page_markdown_action @page_markdown_action end |
#repo_url ⇒ Object
The site's source repository root (e.g. "https://github.com/me/repo"), used for the GitHub compare link between two versions' refs (#compare_url). Defaults to nil → no compare link renders.
258 259 260 |
# File 'lib/docs_kit/configuration.rb', line 258 def repo_url @repo_url end |
#search ⇒ Object
Whether the topbar renders the docs-search form (and the docs-nav palette markup). Defaults to true. Set false to hide search site-wide — the route can stay drawn, but no affordance points at it. Gated together with a present #search_path by #search_enabled?, which the Shell reads.
154 155 156 |
# File 'lib/docs_kit/configuration.rb', line 154 def search @search end |
#search_path ⇒ Object
The path the topbar search form submits to (GET ?q=), and the base the
palette fetches .json from. Defaults to "/docs/search" — the route the
install generator draws. A site that mounts search elsewhere sets its own;
blank it to disable the affordance without touching #search.
160 161 162 |
# File 'lib/docs_kit/configuration.rb', line 160 def search_path @search_path end |
#search_shortcuts ⇒ Object
The parsed search-palette shortcuts (DocsKit::Shortcut list), with anything unparseable dropped. The topbar renders one per entry and docs-nav binds each; an empty list means no keyboard shortcut (the form still works).
574 575 576 |
# File 'lib/docs_kit/configuration.rb', line 574 def search_shortcuts DocsKit::Shortcut.parse_list(@search_shortcuts) end |
#snapshots_path ⇒ Object
The resolved snapshots directory: the configured value verbatim, else Rails.root/"docs_snapshots" under Rails, else nil (no Rails, no default — the standalone suite passes explicit paths).
405 406 407 408 409 |
# File 'lib/docs_kit/configuration.rb', line 405 def snapshots_path return @snapshots_path if @snapshots_path Rails.root.join("docs_snapshots") if defined?(Rails) && Rails.respond_to?(:root) && Rails.root end |
#stylesheets ⇒ Object
The stylesheet logical names linked in
, in order. Defaults to ["application"] (the Bun/Tailwind-compiled build). A site that ships extra stylesheets (e.g. a separate rouge theme) lists them here.
79 80 81 |
# File 'lib/docs_kit/configuration.rb', line 79 def stylesheets @stylesheets end |
#tagline ⇒ Object
A one-line site summary, rendered as the llms.txt blockquote
(> {tagline}) under the H1. Defaults to nil → the blockquote line is
omitted, so a site that never sets it still gets a valid llms.txt. Purely
for the AI-readable index (DocsKit::LlmsText); the chrome never shows it.
26 27 28 |
# File 'lib/docs_kit/configuration.rb', line 26 def tagline @tagline end |
#themes ⇒ Object
The themes offered by the ThemeSwitcher. The first is the page default unless #default_theme is set. Must match the themes enabled in the site's Tailwind @plugin "daisyui" { themes: ... } block.
40 41 42 |
# File 'lib/docs_kit/configuration.rb', line 40 def themes @themes end |
#title_suffix ⇒ Object
551 552 553 |
# File 'lib/docs_kit/configuration.rb', line 551 def title_suffix @title_suffix || @brand end |
#topbar_brand ⇒ Object
Where the topbar renders the brand: :always (the default — byte-compat), or :mobile_only, which hides it at the drawer-pinned breakpoint (lg:) where the sidebar brand is already visible, deduplicating the mark.
213 214 215 |
# File 'lib/docs_kit/configuration.rb', line 213 def @topbar_brand end |
#topbar_links ⇒ Object
The normalized topbar links (DocsKit::TopbarLink list), in declaration order. Each configured Hash/TopbarLink is coerced via TopbarLink.from, so the Shell only ever sees value objects. Blank/nil config yields [].
361 362 363 |
# File 'lib/docs_kit/configuration.rb', line 361 def Array(@topbar_links).map { |link| DocsKit::TopbarLink.from(link) } end |
#version_badge ⇒ Object
Optional callable returning a short version-badge string for the sidebar header (e.g. -> { "v#DaisyUI::VERSION" }). nil renders no badge.
74 75 76 |
# File 'lib/docs_kit/configuration.rb', line 74 def version_badge @version_badge end |
#versions ⇒ Object
The normalized version list (DocsKit::DocVersion list), in declaration order. Each configured Hash/DocVersion is coerced via DocVersion.from, so the switcher and the snapshot reader only ever see value objects. Blank/nil config yields [].
369 370 371 |
# File 'lib/docs_kit/configuration.rb', line 369 def versions Array(@versions).map { |version| DocsKit::DocVersion.from(version) } end |
Instance Method Details
#brand_logo ⇒ Object
The normalized shell brand mark (a DocsKit::BrandLogo), or nil when unset. Memoized (and invalidated on reassignment) — unlike #app_link's rebuild- per-read, because a file: mark shape-checks and reads its SVG on build; per-render re-normalization would repeat that IO. A malformed value raises here, on first read — loud, never a silently broken header.
352 353 354 355 356 |
# File 'lib/docs_kit/configuration.rb', line 352 def brand_logo return if @brand_logo_raw.nil? @brand_logo ||= DocsKit::BrandLogo.from(@brand_logo_raw) end |
#brand_logo=(value) ⇒ Object
The opt-in shell brand mark, rendered by BOTH the topbar and the sidebar header in place of the text #brand (which stays the accessible-name fallback). A Hash in exactly one of the DocsKit::BrandLogo forms — svg:/paths: (inline path-d, theme-adaptive via currentColor), markup:/file: (site-authored
205 206 207 208 |
# File 'lib/docs_kit/configuration.rb', line 205 def brand_logo=(value) @brand_logo = nil @brand_logo_raw = value end |
#code_theme_class ⇒ Object
The Rouge theme class resolved from #code_theme (String or class). A String name that doesn't resolve degrades to the default theme rather than raising NameError on every DocsUI::Code render.
620 621 622 623 624 |
# File 'lib/docs_kit/configuration.rb', line 620 def code_theme_class return @code_theme if @code_theme.is_a?(Class) resolve_theme(@code_theme) || Object.const_get(DEFAULT_CODE_THEME) end |
#code_theme_dark_class ⇒ Object
The dark Rouge theme class resolved from #code_theme_dark (String or class), or nil when unset — mirrors #code_theme_class. DocsUI::Code emits dark code CSS only when this is non-nil, so an unresolvable name degrades to nil (no dark restyle) rather than raising.
630 631 632 633 634 635 |
# File 'lib/docs_kit/configuration.rb', line 630 def code_theme_dark_class return if @code_theme_dark.nil? return @code_theme_dark if @code_theme_dark.is_a?(Class) resolve_theme(@code_theme_dark) end |
#compare_url(from, to) ⇒ Object
The GitHub compare URL between two versions' refs ("#repo_url/compare/DocsKit::Configuration.fromfrom.ref...DocsKit::Configuration.toto.ref"), or nil unless #repo_url and BOTH refs are present — absent value, absent link, never a broken one.
414 415 416 417 418 |
# File 'lib/docs_kit/configuration.rb', line 414 def compare_url(from, to) return if repo_url.nil? || from&.ref.nil? || to&.ref.nil? "#{repo_url.chomp('/')}/compare/#{from.ref}...#{to.ref}" end |
#current_version ⇒ Object
The version serving unprefixed at /docs: the entry marked current: true, else the first configured entry, else nil (an unversioned site).
375 376 377 |
# File 'lib/docs_kit/configuration.rb', line 375 def current_version versions.find(&:current?) || versions.first end |
#dark_themes_shipped ⇒ Object
The dark themes the site actually ships: #dark_themes intersected with #themes, in #themes declaration order. DocsUI::Code scopes the dark theme's CSS under [data-theme=X] for each of these, so a dark theme that isn't in the Tailwind build never emits dead CSS.
641 642 643 |
# File 'lib/docs_kit/configuration.rb', line 641 def dark_themes_shipped Array(@themes) & Array(@dark_themes) end |
#landing ⇒ Object
The landing-page knobs (DocsKit::LandingConfig), read by DocsUI::Landing.
Lazily built and memoized so a c.landing.title = ... block mutates the one
instance the component later reads. A site that never touches it still gets a
minimal hero + the doc index (see LandingConfig), so DocsUI::Landing is safe
to render with zero landing config.
434 435 436 |
# File 'lib/docs_kit/configuration.rb', line 434 def landing @landing ||= DocsKit::LandingConfig.new end |
#language_labels ⇒ Object
The effective label map (built-ins + site overrides), symbol-keyed.
467 468 469 |
# File 'lib/docs_kit/configuration.rb', line 467 def language_labels DEFAULT_LANGUAGE_LABELS.merge((@code_language_labels || {}).transform_keys(&:to_sym)) end |
#lexer_aliases ⇒ Object
The effective alias map (built-ins + site overrides), symbol-keyed.
462 463 464 |
# File 'lib/docs_kit/configuration.rb', line 462 def lexer_aliases DEFAULT_LEXER_ALIASES.merge((@code_lexer_aliases || {}).transform_keys(&:to_sym)) end |
#mcp_enabled? ⇒ Boolean
Whether the built-in MCP endpoint is active: the #mcp toggle is on AND the
optional mcp gem is loadable — the same "toggle AND capability" shape as
#search_enabled?. Read by DocsKit::LlmsText (to advertise /mcp in llms.txt)
and DocsKit::McpController (to 404 when off), so a site without the gem, or
one that set c.mcp = false, is byte-identical to before this feature.
560 561 562 |
# File 'lib/docs_kit/configuration.rb', line 560 def mcp_enabled? !!@mcp && mcp_gem_present? end |
#nav_groups ⇒ Object
The resolved nav Hash for this request. Always returns a Hash.
An ARCHIVED version in DocsKit::Scope wins outright: the sidebar derives from that version's snapshot manifest (hrefs already version-prefixed), so an archived page never links into the live docs — even a site's explicit #nav lambda describes the live pages, not the frozen ones. With no scope (or the current version) nothing changes: an explicit #nav lambda wins, else the sidebar derives from #nav_registries — each heading maps to its registry's .nav_items, and a heading whose pages are all unauthored (empty nav_items) is dropped so no empty group renders.
592 593 594 595 596 597 598 599 |
# File 'lib/docs_kit/configuration.rb', line 592 def nav_groups scope_version = DocsKit::Scope.version return DocsKit::Snapshot.for(scope_version, config: self).nav_groups if scope_version&.archived? return nav_groups_from_registries unless @nav_explicit result = @nav.respond_to?(:call) ? @nav.call : @nav result || {} end |
#normalize_on_page(value) ⇒ Object
Coerce a per-page on_page: value to a valid mode symbol or false. true
means "use the configured default".
488 489 490 491 492 |
# File 'lib/docs_kit/configuration.rb', line 488 def normalize_on_page(value) return on_page_default if value == true coerce_on_page_mode(value) end |
#openapi_document ⇒ Object
The loaded DocsKit::OpenApi::Document for #openapi. Memoized; when #openapi is a file path, the memo is invalidated on an mtime change so editing the spec in development is picked up without a server restart. Raises a DocsKit::Error naming the knob when read while #openapi is unset — a missing spec has nothing useful to degrade to.
443 444 445 446 447 448 449 450 451 |
# File 'lib/docs_kit/configuration.rb', line 443 def openapi_document raise DocsKit::Error, "no OpenAPI spec configured — set c.openapi to a path or Hash" if @openapi.nil? mtime = openapi_source_mtime return @openapi_document if defined?(@openapi_document) && @openapi_document_mtime == mtime @openapi_document_mtime = mtime @openapi_document = DocsKit::OpenApi.load(@openapi) end |
#resolve_version(id) ⇒ Object
The version a request's :version param resolves to: the strict #version lookup, falling back to #current_version for an unknown or missing id — one rule shared by DocsKit::Controller#render_page and the gem's own controllers (DocsKit::Scoping), so a bad param degrades to the current docs instead of 500ing.
391 392 393 |
# File 'lib/docs_kit/configuration.rb', line 391 def resolve_version(id) version(id) || current_version end |
#search_enabled? ⇒ Boolean
Whether the Shell renders the search affordance: search is on AND a path is set to submit to. A site with @search_path blanked (or nil) gets no form even if @search is true — there'd be nothing to submit to.
567 568 569 |
# File 'lib/docs_kit/configuration.rb', line 567 def search_enabled? !!@search && !@search_path.to_s.empty? end |
#seo ⇒ Object
The SEO / social-share knobs (DocsKit::SeoConfig), read by DocsUI::MetaTags.
Lazily built and memoized so a c.seo.description = ... block mutates the
one instance the Shell later reads. A site that never touches it gets the
backwards-safe defaults (see SeoConfig), so the head is a strict superset of
the pre-SEO markup.
425 426 427 |
# File 'lib/docs_kit/configuration.rb', line 425 def seo @seo ||= DocsKit::SeoConfig.new end |
#version(id) ⇒ Object
The configured version with this id, or nil when unknown (or nil id).
380 381 382 383 384 |
# File 'lib/docs_kit/configuration.rb', line 380 def version(id) return if id.nil? versions.find { |version| version.id.to_s == id.to_s } end |
#version_badge_text ⇒ Object
The resolved version badge string, or nil.
The rendered version badge. A callable is invoked; a plain String (or any
non-nil value) is coerced to its string form — so c.version_badge = "v1.2"
renders, not only a lambda.
605 606 607 608 609 610 |
# File 'lib/docs_kit/configuration.rb', line 605 def version_badge_text return if @version_badge.nil? return @version_badge.call if @version_badge.respond_to?(:call) @version_badge.to_s end |
#versioning_enabled? ⇒ Boolean
Whether the version chrome (switcher, llms.txt Versions block) renders. A single configured version is not worth a switcher, so this needs two — and an unconfigured site stays byte-identical to before.
398 399 400 |
# File 'lib/docs_kit/configuration.rb', line 398 def versioning_enabled? versions.size > 1 end |