snapshot of https://github.com/ThreeDotsLabs/watermill.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
master / ci (push) Failing after 0s
Some checks failed
master / ci (push) Failing after 0s
This commit is contained in:
1
docs/layouts/_default/_markup/render-link.html
Normal file
1
docs/layouts/_default/_markup/render-link.html
Normal file
@@ -0,0 +1 @@
|
||||
<a href="{{ .Destination | safeURL }}"{{ with .Title}} title="{{ . }}"{{ end }}{{ if or (strings.HasPrefix .Destination "http") (strings.HasPrefix .Destination "https") }} target="_blank"{{ end }} >{{ .Text | safeHTML }}</a>
|
||||
38
docs/layouts/_default/learn.html
Normal file
38
docs/layouts/_default/learn.html
Normal file
@@ -0,0 +1,38 @@
|
||||
{{ define "main" }}
|
||||
<div class="learn-container">
|
||||
<div class="learn-header">
|
||||
<h1 class="learn-main-title">Learn Watermill</h1>
|
||||
</div>
|
||||
|
||||
<div class="learn-section">
|
||||
<h2 class="learn-section-title">How do you like to learn?</h2>
|
||||
<div class="learn-row">
|
||||
{{ range $index, $option := .Params.learning_options }}
|
||||
<a href="{{ .link }}" class="learn-card">
|
||||
<div class="learn-card-icon">
|
||||
{{ .icon | safeHTML }}
|
||||
</div>
|
||||
<h3>{{ .title }}</h3>
|
||||
<span class="learn-card-secondary">{{ .subtitle }}</span>
|
||||
<p>{{ .description }}</p>
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="learn-section">
|
||||
<h2 class="learn-section-title">Dive Deeper</h2>
|
||||
<div class="learn-row">
|
||||
{{ range .Params.deeper_options }}
|
||||
<a href="{{ .link }}" class="learn-card" {{ if .external }}target="_blank" rel="noopener"{{ end }}>
|
||||
<div class="learn-card-icon">
|
||||
{{ .icon | safeHTML }}
|
||||
</div>
|
||||
<h3>{{ .title }}</h3>
|
||||
<p>{{ .description }}</p>
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
12
docs/layouts/_default/quickstart.html
Normal file
12
docs/layouts/_default/quickstart.html
Normal file
@@ -0,0 +1,12 @@
|
||||
{{ define "main" }}
|
||||
<div class="quickstart-container">
|
||||
<div class="quickstart-header">
|
||||
<h1 class="quickstart-main-title">{{ .Title }}</h1>
|
||||
<p class="quickstart-subtitle">{{ .Params.description }}</p>
|
||||
</div>
|
||||
|
||||
<div class="quickstart-content">
|
||||
{{ .Content }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
217
docs/layouts/index.html
Normal file
217
docs/layouts/index.html
Normal file
@@ -0,0 +1,217 @@
|
||||
{{ define "main" }}
|
||||
<section class="section container-fluid mt-n3 pb-3">
|
||||
<div class="row justify-content-center">
|
||||
<div class="text-center mb-4">
|
||||
<img src="/img/gopher.svg" alt="Logo" style="width: 220px" />
|
||||
</div>
|
||||
<div class="col-lg-12 text-center">
|
||||
<h1>{{ .Title }}</h1>
|
||||
</div>
|
||||
<div class="col-lg-9 col-xl-8 text-center">
|
||||
<p class="lead">{{ .Params.lead | safeHTML }}</p>
|
||||
<a class="btn btn-primary btn-cta rounded-pill btn-lg m-3" href="/learn/" role="button">
|
||||
Get Started
|
||||
</a>
|
||||
<a class="btn btn-outline-primary btn-cta rounded-pill btn-lg my-3" href="https://github.com/ThreeDotsLabs/watermill" role="button">
|
||||
See on GitHub
|
||||
</a>
|
||||
{{ .Content }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section py-5 homepage-features">
|
||||
<div class="container">
|
||||
<!-- EventBus Section -->
|
||||
<div class="row justify-content-center mb-5 pb-5 homepage-section-gradient">
|
||||
<div class="col-lg-11 col-xl-10 text-center">
|
||||
<h2 class="display-4 fw-bold mb-4 gradient-text-1">Publish Events</h2>
|
||||
<p class="lead text-muted mb-5">Work with Go structs.<br/>
|
||||
Decouple your services with asynchronous processing.
|
||||
</p>
|
||||
|
||||
<div class="expressive-code homepage-code-block">
|
||||
<figure class="frame not-content">
|
||||
{{ highlight `event := UserRegistered{
|
||||
UserID: id,
|
||||
Email: email,
|
||||
JoinedAt: time.Now(),
|
||||
}
|
||||
|
||||
err := eventBus.Publish(ctx, event)` "go" "" }}
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- EventProcessor Section -->
|
||||
<div class="row justify-content-center mb-5 pb-5 homepage-section-gradient">
|
||||
<div class="col-lg-11 col-xl-10 text-center">
|
||||
<h2 class="display-4 fw-bold mb-4 gradient-text-1">Handle Events</h2>
|
||||
<p class="lead text-muted mb-5">Focus on the business logic.<br/>
|
||||
Watermill handles routing, serialization and low-level details.
|
||||
</p>
|
||||
|
||||
<div class="expressive-code homepage-code-block">
|
||||
<figure class="frame not-content">
|
||||
{{ highlight `eventProcessor.AddHandlers(
|
||||
cqrs.NewEventHandler("SendWelcomeEmail", sendWelcomeEmail),
|
||||
)
|
||||
|
||||
func sendWelcomeEmail(ctx context.Context, event *UserRegistered) error {
|
||||
return emailService.Send(event.Email, "Welcome!")
|
||||
}` "go" "" }}
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Router Middleware Section -->
|
||||
<div class="row justify-content-center mb-5 pb-5 homepage-section-gradient">
|
||||
<div class="col-lg-11 col-xl-10 text-center">
|
||||
<h2 class="display-4 fw-bold mb-4 gradient-text-1">Simple API you already know</h2>
|
||||
<p class="lead text-muted mb-5">Use the familiar concepts, similar to an HTTP Router with support for middleware.</p>
|
||||
<div class="expressive-code homepage-code-block">
|
||||
<figure class="frame not-content">
|
||||
{{ highlight `router.AddMiddleware(
|
||||
middleware.Recoverer,
|
||||
middleware.CorrelationID,
|
||||
middleware.Timeout(30 * time.Second),
|
||||
)` "go" "" }}
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pub/Sub Support Section -->
|
||||
<div class="row justify-content-center pb-5 homepage-section-gradient">
|
||||
<div class="col-lg-11 col-xl-10 text-center">
|
||||
<h2 class="display-4 fw-bold mb-4 gradient-text-1">Use your favorite Pub/Sub</h2>
|
||||
<p class="lead text-muted mb-5">Work with Kafka, RabbitMQ, PostgreSQL, Redis, and more Pub/Subs with the same API. Switch providers without changing your application code.</p>
|
||||
|
||||
<!-- Pub/Sub Logos Collage -->
|
||||
<div class="pubsub-logos-container mb-5">
|
||||
<div class="pubsub-logos-grid">
|
||||
<a href="/pubsubs/aws/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/aws.png" alt="AWS SQS/SNS" />
|
||||
<span>AWS SNS/SQS</span>
|
||||
</a>
|
||||
<a href="/pubsubs/bolt/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/bolt.png" alt="BoltDB" />
|
||||
<span>BoltDB</span>
|
||||
</a>
|
||||
<a href="/pubsubs/firestore/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/firestore.png" alt="Google Firestore" />
|
||||
<span>Firestore</span>
|
||||
</a>
|
||||
<a href="/pubsubs/gochannel/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/gochannel.png" alt="Go Channel" />
|
||||
<span>Go Channel</span>
|
||||
</a>
|
||||
<a href="/pubsubs/googlecloud/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/gcp.png" alt="Google Cloud Pub/Sub" />
|
||||
<span>Google Cloud Pub/Sub</span>
|
||||
</a>
|
||||
<a href="/pubsubs/http/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/http.png" alt="HTTP" />
|
||||
<span>HTTP</span>
|
||||
</a>
|
||||
<a href="/pubsubs/io/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/io.png" alt="I/O" />
|
||||
<span>I/O</span>
|
||||
</a>
|
||||
<a href="/pubsubs/kafka/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/kafka.png" alt="Apache Kafka" />
|
||||
<span>Kafka</span>
|
||||
</a>
|
||||
<a href="/pubsubs/sql/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/mysql.png" alt="MySQL" />
|
||||
<span>MySQL</span>
|
||||
</a>
|
||||
<a href="/pubsubs/nats/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/nats.png" alt="NATS" />
|
||||
<span>NATS</span>
|
||||
</a>
|
||||
<a href="/pubsubs/sql/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/postgresql.png" alt="PostgreSQL" />
|
||||
<span>PostgreSQL</span>
|
||||
</a>
|
||||
<a href="/pubsubs/amqp/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/rabbitmq.png" alt="RabbitMQ" />
|
||||
<span>RabbitMQ</span>
|
||||
</a>
|
||||
<a href="/pubsubs/redisstream/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/redis.png" alt="Redis" />
|
||||
<span>Redis</span>
|
||||
</a>
|
||||
<a href="/pubsubs/sqlite/" class="pubsub-logo-item">
|
||||
<img src="/img/pubsub-logos/sqlite.png" alt="SQLite" />
|
||||
<span>SQLite</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Library vs Framework Section -->
|
||||
<div class="row justify-content-center mb-5 pb-5 homepage-section-gradient">
|
||||
<div class="col-md-12 col-lg-11 col-xl-10 text-center">
|
||||
<h2 class="display-4 fw-bold mb-4 gradient-text-1">Library ≠ Framework</h2>
|
||||
<p class="lead text-muted mb-5">Use any architecture you want. No vendor lock-in.</p>
|
||||
<div class="expressive-code homepage-code-block">
|
||||
<figure class="frame not-content">
|
||||
{{ highlight `func (h *Handler) RegisterUser(w http.ResponseWriter, r *http.Request) {
|
||||
user := createUser(r)
|
||||
|
||||
// Your existing business logic
|
||||
err := h.userRepo.Save(user)
|
||||
if err != nil {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Publish an event using Watermill
|
||||
err := h.eventBus.Publish(r.Context(), &UserRegistered{...})
|
||||
// ...
|
||||
}` "go" "" }}
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Get Started Section -->
|
||||
<div class="row justify-content-center text-center pt-5 mt-5 homepage-section-gradient">
|
||||
<div class="col-lg-11 col-xl-10">
|
||||
<img src="/img/gopher.svg" alt="Watermill Logo" style="width: 160px;" class="mb-2" />
|
||||
<h2 class="display-5 fw-bold mb-4">Start building</h2>
|
||||
<div class="mt-3">
|
||||
<a class="btn btn-primary btn-cta rounded-pill btn-lg" href="/learn/" role="button">
|
||||
Get Started
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
||||
|
||||
{{ define "sidebar-prefooter" }}
|
||||
{{ if site.Params.doks.backgroundDots -}}
|
||||
<div class="d-flex justify-content-start">
|
||||
<div class="bg-dots"></div>
|
||||
</div>
|
||||
{{ end -}}
|
||||
{{ end }}
|
||||
|
||||
{{ define "sidebar-footer" }}
|
||||
{{ if site.Params.doks.sectionFooter -}}
|
||||
<section class="section section-md container-fluid bg-light">
|
||||
<div class="row justify-content-center text-center">
|
||||
<div class="col-lg-7">
|
||||
<h2 class="mt-2">Start building with Doks today</h2>
|
||||
<a class="btn btn-primary rounded-pill px-4 my-2" href="/docs/{{ if site.Params.doks.docsVersioning }}{{ site.Params.doks.docsVersion }}/{{ end }}prologue/introduction/" role="button">{{ i18n "get-started" }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{ end -}}
|
||||
{{ end }}
|
||||
37
docs/layouts/partials/footer/footer.html
Normal file
37
docs/layouts/partials/footer/footer.html
Normal file
@@ -0,0 +1,37 @@
|
||||
{{- if not (or .IsHome .Params.HideBanner) -}}
|
||||
<div class="text-center mb-5 event-driven-banner">
|
||||
<a href="https://threedots.tech/event-driven/?utm_source=watermill-docs">
|
||||
<img width="400" src="https://threedots.tech/event-driven-banner.png">
|
||||
<br>
|
||||
Check our online hands-on training
|
||||
</a>
|
||||
</div>
|
||||
{{- end -}}
|
||||
|
||||
<footer class="footer text-muted">
|
||||
<div class="container-{{ site.Params.doks.containerBreakpoint | default "lg" }}">
|
||||
<div class="row">
|
||||
<div class="col-lg-8 text-center text-lg-start">
|
||||
<a href="https://threedots.tech">
|
||||
<img class="only-dark" fetchpriority="high" decoding="async" width="200" height="31" src="https://threedots.tech/images/logo-darkmode.svg" alt="Three Dots Labs">
|
||||
<img class="only-light" fetchpriority="high" decoding="async" width="200" height="31" src="https://threedots.tech/images/logo.svg" alt="Three Dots Labs">
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-lg-8 text-center text-lg-end">
|
||||
<p>© Three Dots Labs 2014 — {{ dateFormat "2006" now }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-5">
|
||||
<p>
|
||||
</p>
|
||||
|
||||
<p><small>
|
||||
Watermill is open-source software and is not backed by venture capital.
|
||||
<br>
|
||||
We are an independent, bootstrapped company.
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
16
docs/layouts/partials/footer/script-footer-custom.html
Normal file
16
docs/layouts/partials/footer/script-footer-custom.html
Normal file
@@ -0,0 +1,16 @@
|
||||
{{/* Put your custom <script></script> tags here */}}
|
||||
|
||||
{{/* EXAMPLE - only load script for production
|
||||
{{ if eq (hugo.Environment) "production" -}}
|
||||
{{ partial "footer/esbuild" (dict "src" "js/instantpage.js" "load" "async" "transpile" false) -}}
|
||||
{{ end -}}
|
||||
*/}}
|
||||
|
||||
{{/* EXAMPLE - only load script for a page type e.g. contact or gallery
|
||||
{{ if eq .Type "gallery" -}}
|
||||
{{ partial "footer/esbuild" (dict "src" "js/gallery.js" "load" "async" "transpile" false) -}}
|
||||
{{ end -}}
|
||||
*/}}
|
||||
|
||||
<script defer data-domain="watermill.io" src="https://threedots.tech/js/po.js"></script>
|
||||
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
|
||||
16
docs/layouts/partials/head/custom-head.html
Normal file
16
docs/layouts/partials/head/custom-head.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!-- Custom head -->
|
||||
|
||||
<!-- google fonts -->
|
||||
{{ $pf:= "Heebo:wght@400;600" }}
|
||||
{{ $sf:= "Quicksand:wght@700" }}
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<script>
|
||||
(function () {
|
||||
const googleFont = document.createElement("link");
|
||||
googleFont.href = "https://fonts.googleapis.com/css2?family={{$pf | safeURL}}{{with $sf}}&family={{. | safeURL}}{{end}}&display=swap";
|
||||
googleFont.type = "text/css";
|
||||
googleFont.rel = "stylesheet";
|
||||
document.head.appendChild(googleFont);
|
||||
})();
|
||||
</script>
|
||||
3
docs/layouts/partials/head/resource-hints.html
Normal file
3
docs/layouts/partials/head/resource-hints.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<link rel="preload" href="{{ "fonts/quicksand/quicksand-v31-latin-regular.woff2" | absURL }}" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="{{ "fonts/quicksand/quicksand-v31-latin-500.woff2" | absURL }}" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="{{ "fonts/quicksand/quicksand-v31-latin-700.woff2" | absURL }}" as="font" type="font/woff2" crossorigin>
|
||||
1
docs/layouts/partials/head/script-header.html
Normal file
1
docs/layouts/partials/head/script-header.html
Normal file
@@ -0,0 +1 @@
|
||||
<!-- Insert scripts NOT needed by stylesheets here -->
|
||||
276
docs/layouts/partials/header/header.html
Normal file
276
docs/layouts/partials/header/header.html
Normal file
@@ -0,0 +1,276 @@
|
||||
{{ if site.Params.doks.alert -}}
|
||||
{{ partial "header/alert.html" . }}
|
||||
{{ end -}}
|
||||
|
||||
{{ if site.Params.doks.navbarSticky -}}
|
||||
<div class="sticky-top">
|
||||
{{ end -}}
|
||||
|
||||
{{ if site.Params.doks.headerBar -}}
|
||||
<div class="header-bar"></div>
|
||||
{{ end -}}
|
||||
|
||||
<header class="navbar navbar-expand-lg">
|
||||
{{ with site.Params.doks.containerBreakpoint -}}
|
||||
<div class="container-{{ . }}">
|
||||
{{ else -}}
|
||||
<div class="container">
|
||||
{{ end -}}
|
||||
|
||||
<!-- Site title -->
|
||||
<a class="navbar-brand me-auto me-lg-3" href="{{ relLangURL "" }}">{{ .Site.Title }}</a>
|
||||
|
||||
<!-- FlexSearch mobile -->
|
||||
{{ partial "main/showFlexSearch" . }}
|
||||
{{ $showFlexSearch := .Scratch.Get "showFlexSearch" -}}
|
||||
{{ if $showFlexSearch -}}
|
||||
<button type="button" id="searchToggleMobile" class="btn btn-link nav-link mx-2 d-lg-none" aria-label="Search website">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-search" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<circle cx="10" cy="10" r="7"></circle>
|
||||
<line x1="21" y1="21" x2="15" y2="15"></line>
|
||||
</svg>
|
||||
</button>
|
||||
{{ end -}}
|
||||
|
||||
<!-- Section navigation -->
|
||||
{{ if (in site.Params.doks.sectionNav .Section) -}}
|
||||
<button class="btn btn-link d-lg-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavSection" aria-controls="offcanvasNavSection" aria-label="Open section navigation menu">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-dots-vertical" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path>
|
||||
<path d="M12 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path>
|
||||
<path d="M12 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="offcanvas offcanvas-start d-lg-none" tabindex="-1" id="offcanvasNavSection" aria-labelledby="offcanvasNavSectionLabel">
|
||||
{{ if site.Params.doks.headerBar -}}
|
||||
<div class="header-bar"></div>
|
||||
{{ end -}}
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="offcanvasNavSectionLabel">{{ .Section | humanize }}</h5>
|
||||
<button type="button" class="btn btn-link nav-link p-0 ms-auto" data-bs-dismiss="offcanvas" aria-label="Close">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-x" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M18 6l-12 12"></path>
|
||||
<path d="M6 6l12 12"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<aside class="doks-sidebar mt-n3">
|
||||
<nav id="doks-docs-nav" aria-label="Tertiary navigation">
|
||||
{{ partial "sidebar/section-menu.html" . }}
|
||||
</nav>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
{{ end -}}
|
||||
|
||||
<!-- Main navigation button -->
|
||||
<button class="btn btn-link nav-link mx-2 order-3 d-lg-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavMain" aria-controls="offcanvasNavMain" aria-label="Open main navigation menu">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-menu" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<line x1="4" y1="8" x2="20" y2="8"></line>
|
||||
<line x1="4" y1="16" x2="20" y2="16"></line>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- Main navigation -->
|
||||
<div class="offcanvas offcanvas-end h-auto" tabindex="-1" id="offcanvasNavMain" aria-labelledby="offcanvasNavMainLabel">
|
||||
{{ if site.Params.doks.headerBar -}}
|
||||
<div class="header-bar d-lg-none"></div>
|
||||
{{ end -}}
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="offcanvasNavMainLabel">{{ site.Title }}</h5>
|
||||
<button type="button" class="btn btn-link nav-link p-0 ms-auto" data-bs-dismiss="offcanvas" aria-label="Close">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-x" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M18 6l-12 12"></path>
|
||||
<path d="M6 6l12 12"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<!--
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title fw-bold" id="offcanvasNavMainLabel">{{ .Site.Params.Title }}</h5>
|
||||
<button class="btn btn-link nav-link ms-auto" type="button" data-bs-dismiss="offcanvas" aria-label="Close menu">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-x" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M18 6l-12 12"></path>
|
||||
<path d="M6 6l12 12"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
-->
|
||||
<div class="offcanvas-body d-flex flex-column flex-lg-row justify-content-between">
|
||||
<ul class="navbar-nav flex-grow-1">
|
||||
{{- $current := . -}}
|
||||
{{- $section := $current.Section -}}
|
||||
{{ range .Site.Menus.main -}}
|
||||
{{- $active := or ($current.IsMenuCurrent "main" .) ($current.HasMenuCurrent "main" .) -}}
|
||||
{{- $active = or $active (eq .Name $current.Title) -}}
|
||||
{{- $active = or $active (and (eq .Name ($section | humanize)) (eq $current.Section $section)) -}}
|
||||
{{- $active = or $active (and (eq .Name "Blog") (eq $current.Section "blog" "authors")) -}}
|
||||
{{ if .HasChildren -}}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{ .Name -}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-chevron-down" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M6 9l6 6l6 -6"></path>
|
||||
</svg>
|
||||
</a>
|
||||
<ul class="dropdown-menu shadow rounded border-0">
|
||||
{{ range .Children -}}
|
||||
{{- $active = eq .Name $current.Title -}}
|
||||
<li><a class="dropdown-item{{ if $active }} active{{ end }}" href="{{ .URL | absURL }}"{{ if $active }} aria-current="true"{{ end }}>{{ .Name }}</a></li>
|
||||
{{ end -}}
|
||||
</ul>
|
||||
</li>
|
||||
{{ else -}}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{{ if $active }} active{{ end }}" href="{{ .URL | absURL }}"{{ if $active }} aria-current="true"{{ end }}>{{ .Name }}{{ .Post | safeHTML }}</a>
|
||||
</li>
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
</ul>
|
||||
|
||||
<!-- FlexSearch desktop -->
|
||||
{{ partial "main/showFlexSearch" . }}
|
||||
{{ $showFlexSearch := .Scratch.Get "showFlexSearch" -}}
|
||||
{{ if $showFlexSearch -}}
|
||||
<button type="button" id="searchToggleDesktop" class="btn btn-link nav-link p-2 d-none d-lg-block" aria-label="Search website">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-search" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<circle cx="10" cy="10" r="7"></circle>
|
||||
<line x1="21" y1="21" x2="15" y2="15"></line>
|
||||
</svg>
|
||||
</button>
|
||||
{{ end -}}
|
||||
|
||||
<!-- Language dropdown -->
|
||||
{{ if eq site.Params.doks.multilingualMode true -}}
|
||||
|
||||
<div class="dropdown mt-1 order-lg-2">
|
||||
<button class="btn btn-dropdown dropdown-toggle" id="doks-languages" data-bs-toggle="dropdown" aria-expanded="false" data-bs-display="static">
|
||||
<span class="dropdown-caret">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-language" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M4 5h7"></path>
|
||||
<path d="M9 3v2c0 4.418 -2.239 8 -5 8"></path>
|
||||
<path d="M5 9c0 2.144 2.952 3.908 6.7 4"></path>
|
||||
<path d="M12 20l4 -9l4 9"></path>
|
||||
<path d="M19.1 18h-6.2"></path>
|
||||
</svg>
|
||||
<span id="doks-language-current">{{ .Site.Language.LanguageName }}</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-chevron-down" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M6 9l6 6l6 -6"></path>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-lg-end me-lg-2 shadow rounded border-0" aria-labelledby="doks-languages">
|
||||
|
||||
<li><span class="dropdown-item current" aria-current="true">{{ .Site.Language.LanguageName }}</span></li>
|
||||
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
|
||||
{{ if site.Params.doks.showMissingLanguages -}}
|
||||
{{ $translatedLangs := slice -}}
|
||||
{{ range .Translations -}}
|
||||
{{ $translatedLangs = $translatedLangs | append .Lang }}
|
||||
{{- end }}
|
||||
{{ range site.Languages -}}
|
||||
{{ if and (ne $.Lang .Lang) (not (in $.Params.skipTranslations .Lang)) -}}
|
||||
{{ $isTranslated := in $translatedLangs .Lang -}}
|
||||
<li><a class="dropdown-item {{ if not $isTranslated }}untranslated{{ end }}" rel="alternate" href="{{ if $isTranslated }}{{ (index (where $.Translations "Lang" .Lang) 0).RelPermalink }}{{ else }}{{ .Lang | relURL }}{{ end }}" hreflang="{{ .Lang }}" lang="{{ .Lang }}">{{ .LanguageName }}</a></li>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{ else -}}
|
||||
{{ range .Translations -}}
|
||||
<li><a class="dropdown-item" rel="alternate" href="{{ .RelPermalink }}" hreflang="{{ .Lang }}" lang="{{ .Lang }}">{{ .Language.LanguageName }}</a></li>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
<!--
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item" href="/docs/contributing/how-to-contribute/">Help Translate</a></li>
|
||||
-->
|
||||
</ul>
|
||||
</div>
|
||||
{{ end -}}
|
||||
|
||||
<!-- Versioning dropdown -->
|
||||
{{ if eq site.Params.doks.docsVersioning true -}}
|
||||
|
||||
<div class="dropdown mt-1 order-lg-3">
|
||||
<button class="btn btn-dropdown dropdown-toggle" id="doks-versions" data-bs-toggle="dropdown" aria-expanded="false" data-bs-display="static" aria-label="Toggle version menu">
|
||||
<span class="d-none">Doks</span> v{{ site.Params.doks.docsVersion }}
|
||||
<span class="dropdown-caret">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-chevron-down" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M6 9l6 6l6 -6"></path>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-lg-end me-lg-2 shadow rounded border-0" aria-labelledby="doks-versions">
|
||||
<li><a class="dropdown-item current" aria-current="true" href="/docs/{{ site.Params.doks.docsVersion }}/prologue/introduction/">Latest ({{ site.Params.doks.docsVersion }}.x)</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item" href="/docs/0.2/prologue/introduction/">v0.2.x</a></li>
|
||||
<li><a class="dropdown-item" href="/docs/0.1/prologue/introduction/">v0.1.x</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item" href="/docs/versions/">All versions</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{{ end -}}
|
||||
|
||||
<!-- Color mode toggler -->
|
||||
{{ if and (eq site.Params.doks.colorMode "auto") site.Params.doks.colorModeToggler -}}
|
||||
<button id="buttonColorMode" class="btn btn-link mx-auto nav-link p-0 ms-lg-2 me-lg-1" type="button" aria-label="Toggle theme">
|
||||
<svg data-bs-theme-value="dark" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-moon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
|
||||
</svg>
|
||||
<svg data-bs-theme-value="light" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-sun" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0m-5 0h1m8 -9v1m8 8h1m-9 8v1m-6.4 -15.4l.7 .7m12.1 -.7l-.7 .7m0 11.4l.7 .7m-12.1 -.7l-.7 .7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
{{ end -}}
|
||||
|
||||
<!-- Social menu -->
|
||||
{{ if .Site.Menus.social -}}
|
||||
<ul id="socialMenu" class="nav mx-auto flex-row order-lg-4">
|
||||
{{ range .Site.Menus.social -}}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link social-link" href="{{ .URL | relURL }}">{{ .Pre | safeHTML }}<small class="ms-2 visually-hidden">{{ .Name | safeHTML }}</small></a>
|
||||
</li>
|
||||
{{ end -}}
|
||||
</ul>
|
||||
{{ end -}}
|
||||
|
||||
|
||||
<!-- Navbar button mobile -->
|
||||
{{ if site.Params.doks.navBarButton -}}
|
||||
<a class="btn btn-primary rounded-pill mt-2 btn-block d-lg-none" href="{{ site.Params.doks.navBarButtonUrl | absURL }}" role="button">{{ site.Params.doks.navBarButtonText }}</a>
|
||||
{{ end -}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Navbar button desktop -->
|
||||
{{ if site.Params.doks.navBarButton -}}
|
||||
<a class="btn btn-primary rounded-pill ms-3 me-2 px-4 order-lg-3 d-none d-lg-block" href="{{ site.Params.doks.navBarButtonUrl | absURL }}" role="button">{{ site.Params.doks.navBarButtonText }}</a>
|
||||
{{ end -}}
|
||||
|
||||
</div>
|
||||
</header>
|
||||
{{ if site.Params.doks.navbarSticky -}}
|
||||
</div>
|
||||
{{ end -}}
|
||||
|
||||
<!-- Search modal -->
|
||||
{{ if site.Params.doks.flexSearch -}}
|
||||
{{ partial "header/search-modal" . }}
|
||||
{{ end -}}
|
||||
|
||||
|
||||
39
docs/layouts/partials/main/edit-page.html
Normal file
39
docs/layouts/partials/main/edit-page.html
Normal file
@@ -0,0 +1,39 @@
|
||||
{{ $parts := slice site.Params.doks.docsRepo }}
|
||||
|
||||
{{ if (eq site.Params.doks.repoHost "GitHub") }}
|
||||
{{ $parts = $parts | append "edit" site.Params.doks.docsRepoBranch }}
|
||||
{{ else if (eq site.Params.doks.repoHost "Gitea") }}
|
||||
{{ $parts = $parts | append "_edit" site.Params.doks.docsRepoBranch }}
|
||||
{{ else if (eq site.Params.doks.repoHost "GitLab") }}
|
||||
{{ $parts = $parts | append "-/blob" site.Params.doks.docsRepoBranch }}
|
||||
{{ else if (eq site.Params.doks.repoHost "Bitbucket") }}
|
||||
{{ $parts = $parts | append "src" site.Params.doks.docsRepoBranch }}
|
||||
{{ else if (eq site.Params.doks.repoHost "BitbucketServer") }}
|
||||
{{ $parts = $parts | append "browse" site.Params.doks.docsRepoBranch }}
|
||||
{{ end }}
|
||||
|
||||
{{ if isset .Site.Params "docsRepoSubPath" }}
|
||||
{{ if not (eq site.Params.doks.docsRepoSubPath "") }}
|
||||
{{ $parts = $parts | append site.Params.doks.docsRepoSubPath }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ $filePath := replace .File.Path "\\" "/" }}
|
||||
|
||||
{{ $lang := "" }}
|
||||
{{ if site.Params.doks.multilingualMode }}
|
||||
{{ $lang = .Lang }}
|
||||
{{ end }}
|
||||
|
||||
{{ $parts = $parts | append "docs/content" $filePath }}
|
||||
|
||||
{{ $url := delimit $parts "/" }}
|
||||
|
||||
<div class="edit-page">
|
||||
<a href="{{ $url }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-edit-2">
|
||||
<path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"></path>
|
||||
</svg>
|
||||
Help us improve this page
|
||||
</a>
|
||||
</div>
|
||||
5
docs/layouts/partials/private/has-headings.html
Normal file
5
docs/layouts/partials/private/has-headings.html
Normal file
@@ -0,0 +1,5 @@
|
||||
{{ $hasHeadings := false }}
|
||||
{{ if (isset .Fragments "Headings") }}
|
||||
{{ $hasHeadings = gt (len .Fragments.Headings) 0 }}
|
||||
{{ end }}
|
||||
{{ $hasHeadings }}
|
||||
50
docs/layouts/partials/seo/opengraph.html
Normal file
50
docs/layouts/partials/seo/opengraph.html
Normal file
@@ -0,0 +1,50 @@
|
||||
{{/* Based on: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/opengraph.html */}}
|
||||
<meta property="og:title" content="{{ .Title }}">
|
||||
<meta property="og:description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}">
|
||||
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}">
|
||||
<meta property="og:url" content="{{ .Permalink }}">
|
||||
|
||||
{{ $imagePermalink := (printf "https://academy-api.threedots.tech/ssr/image.png?%s" (collections.Querify "url" .Permalink) ) }}
|
||||
<meta property="og:image" content="{{ $imagePermalink }}">
|
||||
|
||||
{{- if .IsPage }}
|
||||
{{- $iso8601 := "2006-01-02T15:04:05-07:00" -}}
|
||||
<meta property="article:section" content="{{ .Section }}">
|
||||
{{ with .PublishDate }}<meta property="article:published_time" {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }}>{{ end }}
|
||||
{{ with .Lastmod }}<meta property="article:modified_time" {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }}>{{ end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- with .Params.audio }}<meta property="og:audio" content="{{ . }}">{{ end }}
|
||||
{{- with .Params.locale }}<meta property="og:locale" content="{{ . }}">{{ end }}
|
||||
{{- with .Site.Params.title }}<meta property="og:site_name" content="{{ . }}">{{ end }}
|
||||
{{- with .Params.videos }}{{- range . }}
|
||||
<meta property="og:video" content="{{ . | absURL }}">
|
||||
{{ end }}{{ end }}
|
||||
|
||||
{{- /* If it is part of a series, link to related articles */}}
|
||||
{{- $permalink := .Permalink }}
|
||||
{{- $siteSeries := .Site.Taxonomies.series }}
|
||||
{{- if $siteSeries }}
|
||||
{{ with .Params.series }}{{- range $name := . }}
|
||||
{{- $series := index $siteSeries ($name | urlize) }}
|
||||
{{- range $page := first 6 $series.Pages }}
|
||||
{{- if ne $page.Permalink $permalink }}<meta property="og:see_also" content="{{ $page.Permalink }}">{{ end }}
|
||||
{{- end }}
|
||||
{{ end }}{{ end }}
|
||||
{{- end }}
|
||||
|
||||
{{- /* Deprecate site.Social.facebook_admin in favor of site.Params.social.facebook_admin */}}
|
||||
{{- $facebookAdmin := "" }}
|
||||
{{- with site.Params.social }}
|
||||
{{- if reflect.IsMap . }}
|
||||
{{- $facebookAdmin = .facebook_admin }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- with site.Social.facebook_admin }}
|
||||
{{- $facebookAdmin = . }}
|
||||
{{- warnf "The social key in site configuration is deprecated. Use params.social.facebook_admin instead." }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- /* Facebook Page Admin ID for Domain Insights */}}
|
||||
{{ with $facebookAdmin }}<meta property="fb:admins" content="{{ . }}">{{ end }}
|
||||
30
docs/layouts/partials/seo/twitter.html
Normal file
30
docs/layouts/partials/seo/twitter.html
Normal file
@@ -0,0 +1,30 @@
|
||||
{{/* Based on: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/twitter_cards.html */}}
|
||||
|
||||
{{ $imagePermalink := (printf "https://academy-api.threedots.tech/ssr/image.png?%s" (collections.Querify "url" .Permalink) ) }}
|
||||
<meta name="twitter:image" content="{{ $imagePermalink }}">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
|
||||
|
||||
<meta name="twitter:title" content="{{ .Title }}">
|
||||
<meta name="twitter:description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end -}}">
|
||||
|
||||
{{- /* Deprecate site.Social.twitter in favor of site.Params.social.twitter */}}
|
||||
{{- $twitterSite := "" }}
|
||||
{{- with site.Params.social }}
|
||||
{{- if reflect.IsMap . }}
|
||||
{{- $twitterSite = .twitter }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- with site.Social.twitter }}
|
||||
{{- $twitterSite = . }}
|
||||
{{- warnf "The social key in site configuration is deprecated. Use params.social.twitter instead." }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- with $twitterSite }}
|
||||
{{- $content := . }}
|
||||
{{- if not (strings.HasPrefix . "@") }}
|
||||
{{- $content = printf "@%v" $twitterSite }}
|
||||
{{- end }}
|
||||
<meta name="twitter:site" content="{{ $content }}">
|
||||
{{- end }}
|
||||
7
docs/layouts/partials/sidebar/section-menu.html
Normal file
7
docs/layouts/partials/sidebar/section-menu.html
Normal file
@@ -0,0 +1,7 @@
|
||||
{{- with site.Menus.sidebar }}
|
||||
{{ partial "sidebar/render-section-menu.html" (dict "currentPage" $ "nodes" .) }}
|
||||
{{- else }}
|
||||
{{- with (.Site.GetPage "section" .Section).Sections }}
|
||||
{{ partial "sidebar/render-section-menu.html" (dict "currentPage" $ "nodes" .) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
114
docs/layouts/shortcodes/load-snippet-partial.html
Normal file
114
docs/layouts/shortcodes/load-snippet-partial.html
Normal file
@@ -0,0 +1,114 @@
|
||||
{{ $file := (.Get "file") }}
|
||||
{{ $content := readFile $file }}
|
||||
|
||||
{{ $first_line_contains := (.Get "first_line_contains") }}
|
||||
{{ $last_line_contains := (.Get "last_line_contains") }}
|
||||
{{ $last_line_equals := (.Get "last_line_equals") }}
|
||||
|
||||
{{ $show_line := false }}
|
||||
|
||||
{{/*if true, first or last line was not found*/}}
|
||||
{{ $first_line_found := false}}
|
||||
{{ $last_line_found := false}}
|
||||
|
||||
{{ $padding_after := (.Get "padding_after" | default "0" | int) }}
|
||||
|
||||
{{ $first_line_num := 0 }}
|
||||
{{ $last_line_num := 0 }}
|
||||
|
||||
{{ $linkFile := $file }}
|
||||
{{ $repo := "watermill" }}
|
||||
|
||||
{{ if in $file "src-link/watermill-" }}
|
||||
{{ $repo = index (findRE "watermill-[a-z]+" $linkFile) 0 }}
|
||||
{{ $linkFile = replace $linkFile $repo "" }}
|
||||
{{ $linkFile = replace $linkFile "src-link//" "" }}
|
||||
{{ else if in $linkFile "src-link/" }}
|
||||
{{ $linkFile = replace $linkFile "src-link/" "" }}
|
||||
{{ else }}
|
||||
{{ $linkFile = print "docs/content/" $linkFile }}
|
||||
{{ end }}
|
||||
|
||||
{{ $lines := slice }}
|
||||
|
||||
{{ range $elem_key, $elem_val := split $content "\n" }}
|
||||
{{ $line_num := (add $elem_key 1) }}
|
||||
|
||||
{{ if and (not $first_line_found) (in $elem_val $first_line_contains) }}
|
||||
{{ if ne $elem_key 0 }}
|
||||
{{ $lines = $lines | append "// ..." }}
|
||||
{{ end }}
|
||||
|
||||
{{ $show_line = true }}
|
||||
{{ $first_line_found = true}}
|
||||
{{ $first_line_num = $line_num }}
|
||||
{{ end }}
|
||||
|
||||
{{ if $show_line }}
|
||||
{{ $lines = $lines | append $elem_val }}
|
||||
{{ end }}
|
||||
|
||||
{{ if and ($first_line_found) (in $elem_val $last_line_contains) (ne $last_line_contains "") }}
|
||||
{{ $last_line_found = true }}
|
||||
{{ end }}
|
||||
|
||||
{{ if and ($first_line_found) (eq $elem_val $last_line_equals) (ne $last_line_equals "") }}
|
||||
{{ $last_line_found = true }}
|
||||
{{ end }}
|
||||
|
||||
{{ if and $last_line_found $show_line }}
|
||||
{{ if gt $padding_after 0 }}
|
||||
{{ $padding_after = sub $padding_after 1}}
|
||||
{{ else }}
|
||||
{{ $lines = $lines | append "// ..." }}
|
||||
{{ $show_line = false }}
|
||||
{{ $last_line_num = $line_num }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{/* Calculate minimum indentation (common whitespace) */}}
|
||||
{{ $min_indent := 999999 }}
|
||||
{{ range $lines }}
|
||||
{{ if and (ne . "// ...") (ne (trim . " \t") "") }}
|
||||
{{ $leading := 0 }}
|
||||
{{ range $i, $char := split . "" }}
|
||||
{{ if or (eq $char " ") (eq $char "\t") }}
|
||||
{{ $leading = add $leading 1 }}
|
||||
{{ else }}
|
||||
{{ break }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if lt $leading $min_indent }}
|
||||
{{ $min_indent = $leading }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{/* Remove common leading whitespace from all lines */}}
|
||||
{{ $normalized_lines := slice }}
|
||||
{{ range $lines }}
|
||||
{{ if or (eq . "// ...") (eq (trim . " \t") "") }}
|
||||
{{ $normalized_lines = $normalized_lines | append . }}
|
||||
{{ else if gt $min_indent 0 }}
|
||||
{{ $normalized_lines = $normalized_lines | append (substr . $min_indent) }}
|
||||
{{ else }}
|
||||
{{ $normalized_lines = $normalized_lines | append . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
<div class="expressive-code">
|
||||
<figure class="frame not-content">
|
||||
{{ transform.Highlight (delimit $normalized_lines "\n" | safeHTML) (.Get "type" | default "go") }}
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<small class="smaller">Full source: [github.com/ThreeDotsLabs/{{ $repo }}/{{ $linkFile }}](https://github.com/ThreeDotsLabs/{{ $repo }}/tree/master/{{ $linkFile }}{{ if ne $first_line_num 0 }}#L{{ $first_line_num }}{{ end }})</small>
|
||||
|
||||
{{if not $first_line_found }}
|
||||
{{ errorf "`first_line_contains` %s not found in %s snippet" $first_line_contains $file }}
|
||||
{{end}}
|
||||
|
||||
{{if and (not $last_line_found) (ne $last_line_contains "") }}
|
||||
{{ errorf "`last_line_contains` %s not found in %s snippet" $last_line_contains $file }}
|
||||
{{end}}
|
||||
37
docs/layouts/shortcodes/load-snippet.html
Normal file
37
docs/layouts/shortcodes/load-snippet.html
Normal file
@@ -0,0 +1,37 @@
|
||||
{{ $file := (.Get "file") }}
|
||||
{{ $content := readFile $file }}
|
||||
|
||||
{{ $start_line := (.Get "start_line") | default "0" }}
|
||||
{{ $end_line := (.Get "end_line") | default "0" }}
|
||||
|
||||
{{ $has_start_line := (ne $start_line "0") }}
|
||||
{{ $has_end_line := (ne $end_line "0") }}
|
||||
|
||||
{{ $lines := slice }}
|
||||
|
||||
{{ $linkFile := $file }}
|
||||
{{ $repo := "watermill" }}
|
||||
|
||||
{{ if in $file "src-link/watermill-" }}
|
||||
{{ $repo = index (findRE "watermill-[a-z]+" $linkFile) 0 }}
|
||||
{{ $linkFile = replace $linkFile $repo "" }}
|
||||
{{ $linkFile = replace $linkFile "src-link//" "" }}
|
||||
{{ else if in $linkFile "src-link/" }}
|
||||
{{ $linkFile = replace $linkFile "src-link/" "" }}
|
||||
{{ else }}
|
||||
{{ $linkFile = print "docs/content/" $linkFile }}
|
||||
{{ end }}
|
||||
|
||||
{{ range $elem_key, $elem_val := split $content "\n" }}
|
||||
{{if and (or (not $has_start_line) (ge (add $elem_key 1) ($start_line | int))) (or (not $has_end_line) (le (add $elem_key 1) ($end_line | int)))}}
|
||||
{{ $lines = $lines | append $elem_val }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
<div class="expressive-code">
|
||||
<figure class="frame not-content">
|
||||
{{ transform.Highlight (delimit $lines "\n" | safeHTML) (.Get "type" | default "go") }}
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<small class="smaller">Full source: [{{ $linkFile }}](https://github.com/ThreeDotsLabs/watermill/tree/master/{{ $linkFile }})</small>
|
||||
6
docs/layouts/shortcodes/readfile.html
Normal file
6
docs/layouts/shortcodes/readfile.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{{$file := .Get "file"}}
|
||||
{{- if eq (.Get "markdown") "true" -}}
|
||||
{{- $file | readFile | markdownify -}}
|
||||
{{- else -}}
|
||||
{{ $file | readFile | safeHTML }}
|
||||
{{- end -}}
|
||||
17
docs/layouts/shortcodes/tab.html
Normal file
17
docs/layouts/shortcodes/tab.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!--
|
||||
Source: https://github.com/alex-shpak/hugo-book/blob/master/layouts/shortcodes/tab.html
|
||||
-->
|
||||
|
||||
{{ if .Parent -}}
|
||||
{{ $name := .Get 0 }}
|
||||
{{ $slug := .Get 1 }}
|
||||
{{ $group := printf "tabs-%s" (.Parent.Get 0) }}
|
||||
|
||||
{{ if not (.Parent.Scratch.Get $group) }}
|
||||
{{ .Parent.Scratch.Set $group slice }}
|
||||
{{ end }}
|
||||
|
||||
{{ .Parent.Scratch.Add $group (dict "Name" $name "Slug" $slug "Content" .Inner) }}
|
||||
{{ else -}}
|
||||
{{ errorf "%q: 'tab' shortcode must be inside 'tabs' shortcode" .Page.Path }}
|
||||
{{ end -}}
|
||||
25
docs/layouts/shortcodes/tabs.html
Normal file
25
docs/layouts/shortcodes/tabs.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!--
|
||||
Based on: https://github.com/alex-shpak/hugo-book/blob/master/layouts/shortcodes/tabs.html
|
||||
-->
|
||||
|
||||
{{ if .Inner }}{{ end }}
|
||||
{{ $id := .Get 0 }}
|
||||
{{ $group := printf "tabs-%s" $id }}
|
||||
|
||||
<nav>
|
||||
<div class="nav nav-tabs" id="nav-tab" role="tablist">
|
||||
{{ range $index, $tab := .Scratch.Get $group -}}
|
||||
<button data-toggle-tab="{{ $tab.Slug }}" class="nav-link{{ if not $index }} active{{ end }}" id="{{ printf "%s-%d" $group $index }}-tab" data-bs-toggle="tab" data-bs-target="#{{ printf "%s-%d" $group $index }}" type="button" role="tab" aria-controls="{{ printf "%s-%d" $group $index }}" aria-selected="true">
|
||||
{{ $tab.Name -}}
|
||||
</button>
|
||||
{{ end -}}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="tab-content" id="nav-tabContent">
|
||||
{{ range $index, $tab := .Scratch.Get $group -}}
|
||||
<div data-pane="{{ $tab.Slug }}" class="tab-pane fade{{ if not $index }} show active{{ end }}" id="{{ printf "%s-%d" $group $index }}" role="tabpanel" aria-labelledby="{{ printf "%s-%d" $group $index }}-tab" tabindex="0">
|
||||
{{ .Content | $.Page.RenderString -}}
|
||||
</div>
|
||||
{{ end -}}
|
||||
</div>
|
||||
Reference in New Issue
Block a user