mirror of
https://github.com/tiennm99/hugo-blox-builder.git
synced 2026-09-04 02:18:15 +00:00
feat(slides): add persistent branding with per-slide visibility control
- Add branding overlays: logo, title, author, and footer text - Use Reveal.js theme CSS variables for automatic color adaptation - Inline SVGs for currentColor support on any theme - Per-slide control via HTML comments: - <!-- no-branding -->: hide all elements - <!-- no-header -->: hide logo + title - <!-- no-footer -->: hide author + footer - Fix body-level CSS selectors for proper visibility - Add comprehensive documentation in example slides
This commit is contained in:
@@ -16,6 +16,76 @@ Supports math, syntax highlighting, diagrams, speaker notes, and much more!
|
||||
- path: github.com/HugoBlox/kit/modules/slides
|
||||
```
|
||||
|
||||
## Branding & Customization
|
||||
|
||||
### Logo and Overlays
|
||||
|
||||
Add consistent branding across all slides by configuring `slides.branding` in your site config or slide front matter:
|
||||
|
||||
```yaml
|
||||
# In hugo.yaml (site-wide) or slide front matter (per-deck)
|
||||
params:
|
||||
slides:
|
||||
branding:
|
||||
logo:
|
||||
filename: "logo.png" # File in assets/media/
|
||||
position: "top-left" # top-left, top-right, bottom-left, bottom-right
|
||||
width: "80px" # Logo width
|
||||
margin: "20px" # Distance from edges
|
||||
title:
|
||||
show: true # Show presentation title overlay
|
||||
text: "Short Title" # Optional: Override auto-detected title
|
||||
position: "bottom-left"
|
||||
author:
|
||||
show: true # Show author name overlay
|
||||
position: "bottom-right"
|
||||
footer:
|
||||
text: "© 2026 Copyright" # Footer text (e.g. copyright)
|
||||
position: "bottom-center" # bottom-center, bottom-left, bottom-right
|
||||
|
||||
```
|
||||
|
||||
### Hooks System
|
||||
|
||||
Inject custom content into presentations without modifying module files. Create partials in your project's `layouts/_partials/hooks/` directory:
|
||||
|
||||
| Hook | Location | Use Case |
|
||||
|------|----------|----------|
|
||||
| `slide-header/` | Top of presentation | Course code, session info |
|
||||
| `slide-footer/` | Bottom of presentation | Social handles, copyright |
|
||||
| `slide-head-end/` | End of `<head>` | Custom CSS, fonts, analytics |
|
||||
| `slide-body-end/` | End of `<body>` | Custom JS, Reveal.js plugins |
|
||||
|
||||
Example: Create `layouts/_partials/hooks/slide-footer/social.html`:
|
||||
|
||||
```html
|
||||
<div style="font-size: 0.5em; opacity: 0.6;">
|
||||
@yourhandle · yoursite.com
|
||||
</div>
|
||||
```
|
||||
|
||||
See `_example.html` files in each hook directory for more examples.
|
||||
|
||||
## Per-Slide Visibility
|
||||
|
||||
Control branding visibility on individual slides using HTML comments:
|
||||
|
||||
- `<!-- no-branding -->`: Hide all branding elements (logo, header, footer)
|
||||
- `<!-- no-header -->`: Hide only the header (and logo)
|
||||
- `<!-- no-footer -->`: Hide only the footer
|
||||
|
||||
Example:
|
||||
|
||||
```markdown
|
||||
---
|
||||
|
||||
<!-- no-branding -->
|
||||
|
||||
## Full Screen Image Slide
|
||||
|
||||
This slide will have no branding overlays.
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
[View the documentation](https://docs.hugoblox.com/content/slides/)
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* HugoBlox Slides Branding Styles
|
||||
*
|
||||
* Default styles for slide branding elements (logo, overlays, headers/footers).
|
||||
* These styles ensure branding elements don't interfere with slide content.
|
||||
*/
|
||||
|
||||
/* Logo container */
|
||||
#slide-logo {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.3s ease;
|
||||
color: var(--r-main-color, #fff);
|
||||
}
|
||||
|
||||
#slide-logo img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-height: 60px;
|
||||
}
|
||||
|
||||
#slide-logo svg {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-height: 60px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
/* Title and author overlays */
|
||||
#slide-title-overlay,
|
||||
#slide-author-overlay,
|
||||
#slide-footer-text-overlay {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
pointer-events: none;
|
||||
font-family: var(--r-main-font, inherit);
|
||||
color: var(--r-main-color, #fff);
|
||||
font-size: 0.7em;
|
||||
opacity: 0.8;
|
||||
max-width: 40%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
#slide-footer-text-overlay {
|
||||
font-size: 0.6em;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* Header and footer hook containers */
|
||||
.slide-header,
|
||||
.slide-footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
pointer-events: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.slide-header {
|
||||
top: 0;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.slide-footer {
|
||||
bottom: 0;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Visibility Control via data-state classes (applied to body by JS) */
|
||||
body.no-branding #slide-logo,
|
||||
body.no-branding #slide-title-overlay,
|
||||
body.no-branding #slide-author-overlay,
|
||||
body.no-branding #slide-footer-text-overlay,
|
||||
body.no-branding .slide-header,
|
||||
body.no-branding .slide-footer {
|
||||
/* biome-ignore lint/complexity/noImportantStyles: Required to override Reveal.js styles */
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
body.no-header .slide-header,
|
||||
body.no-header #slide-logo,
|
||||
body.no-header #slide-title-overlay {
|
||||
/* biome-ignore lint/complexity/noImportantStyles: Required to override Reveal.js styles */
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
body.no-footer .slide-footer,
|
||||
body.no-footer #slide-author-overlay,
|
||||
body.no-footer #slide-footer-text-overlay {
|
||||
/* biome-ignore lint/complexity/noImportantStyles: Required to override Reveal.js styles */
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Re-enable pointer events for interactive elements within header/footer */
|
||||
.slide-header a,
|
||||
.slide-header button,
|
||||
.slide-footer a,
|
||||
.slide-footer button {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* Hide branding in print mode for cleaner PDFs */
|
||||
@media print {
|
||||
#slide-logo,
|
||||
#slide-title-overlay,
|
||||
#slide-author-overlay,
|
||||
#slide-footer-text-overlay,
|
||||
.slide-header,
|
||||
.slide-footer {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
/* Respect Reveal.js overview mode */
|
||||
.reveal.overview #slide-logo,
|
||||
.reveal.overview #slide-title-overlay,
|
||||
.reveal.overview #slide-author-overlay,
|
||||
.reveal.overview #slide-footer-text-overlay,
|
||||
.reveal.overview .slide-header,
|
||||
.reveal.overview .slide-footer {
|
||||
display: none;
|
||||
}
|
||||
@@ -63,6 +63,30 @@ pluginOptions.plugins = enabledPlugins;
|
||||
|
||||
Reveal.initialize(pluginOptions);
|
||||
|
||||
// Handle data-state for branding visibility
|
||||
// Apply classes to body since branding elements are body-level siblings of .reveal
|
||||
const applySlideState = (event) => {
|
||||
const body = document.body;
|
||||
if (!body) return;
|
||||
|
||||
// Remove previous state classes from body
|
||||
body.classList.remove("no-branding", "no-header", "no-footer");
|
||||
|
||||
// Get current slide's data-state
|
||||
const currentSlide = event?.currentSlide || Reveal.getCurrentSlide();
|
||||
if (currentSlide) {
|
||||
const state = currentSlide.getAttribute("data-state");
|
||||
if (state) {
|
||||
state.split(" ").forEach((s) => {
|
||||
body.classList.add(s);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reveal.on("ready", applySlideState);
|
||||
Reveal.on("slidechanged", applySlideState);
|
||||
|
||||
// Disable Mermaid by default.
|
||||
if (typeof slides.diagram === "undefined") {
|
||||
slides.diagram = false;
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
{{/*
|
||||
Slide Branding Component
|
||||
|
||||
Renders persistent branding elements (logo, title overlay, etc.) that appear
|
||||
across all slides in a presentation.
|
||||
|
||||
Configuration (site.Params.slides.branding or .Params.slides.branding):
|
||||
logo:
|
||||
src: "media/logo.png" # Path to logo image
|
||||
alt: "Organization Logo" # Alt text
|
||||
position: "top-left" # top-left, top-right, bottom-left, bottom-right
|
||||
width: "100px" # Logo width
|
||||
margin: "20px" # Distance from edges
|
||||
title:
|
||||
show: true # Show presentation title
|
||||
position: "bottom-left" # Position of title text
|
||||
author:
|
||||
show: true # Show author/presenter name
|
||||
position: "bottom-right" # Position of author text
|
||||
*/}}
|
||||
|
||||
{{/* Merge page-level config with site-level defaults */}}
|
||||
{{ $site_branding := site.Params.slides.branding | default dict }}
|
||||
{{ $page_branding := .Params.slides.branding | default dict }}
|
||||
{{ $branding := merge $site_branding $page_branding }}
|
||||
|
||||
{{/* Logo rendering */}}
|
||||
{{ with $branding.logo }}
|
||||
{{ if .filename }}
|
||||
{{ $resource_path := printf "media/%s" .filename }}
|
||||
{{ $logo_resource := resources.Get $resource_path }}
|
||||
{{ with $logo_resource }}
|
||||
{{ $position := $branding.logo.position | default "top-left" }}
|
||||
{{ $width := $branding.logo.width | default "80px" }}
|
||||
{{ $margin := $branding.logo.margin | default "20px" }}
|
||||
{{ $alt := $branding.logo.alt | default "Logo" }}
|
||||
|
||||
{{/* Calculate CSS position based on position string */}}
|
||||
{{ $positionCSS := "" }}
|
||||
{{ if eq $position "top-left" }}
|
||||
{{ $positionCSS = printf "top: %s; left: %s;" $margin $margin }}
|
||||
{{ else if eq $position "top-right" }}
|
||||
{{ $positionCSS = printf "top: %s; right: %s;" $margin $margin }}
|
||||
{{ else if eq $position "bottom-left" }}
|
||||
{{ $positionCSS = printf "bottom: %s; left: %s;" $margin $margin }}
|
||||
{{ else if eq $position "bottom-right" }}
|
||||
{{ $positionCSS = printf "bottom: %s; right: %s;" $margin $margin }}
|
||||
{{ else }}
|
||||
{{/* Custom position - expect CSS string */}}
|
||||
{{ $positionCSS = $position }}
|
||||
{{ end }}
|
||||
|
||||
<div id="slide-logo" style="{{ $positionCSS | safeCSS }} width: {{ $width }};" aria-label="{{ $alt }}">
|
||||
{{/* Inline SVGs to enable currentColor, use img for other formats */}}
|
||||
{{ if strings.HasSuffix .Name ".svg" }}
|
||||
{{ .Content | safeHTML }}
|
||||
{{ else }}
|
||||
<img src="{{ .RelPermalink }}" alt="{{ $alt }}">
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{/* Title overlay (optional) */}}
|
||||
{{ if $branding.title }}
|
||||
{{ with $branding.title }}
|
||||
{{ if .show }}
|
||||
{{ $position := .position | default "bottom-left" }}
|
||||
{{ $margin := .margin | default "20px" }}
|
||||
|
||||
{{ $positionCSS := "" }}
|
||||
{{ if eq $position "top-left" }}
|
||||
{{ $positionCSS = printf "top: %s; left: %s;" $margin $margin }}
|
||||
{{ else if eq $position "top-right" }}
|
||||
{{ $positionCSS = printf "top: %s; right: %s;" $margin $margin }}
|
||||
{{ else if eq $position "bottom-left" }}
|
||||
{{ $positionCSS = printf "bottom: %s; left: %s;" $margin $margin }}
|
||||
{{ else if eq $position "bottom-right" }}
|
||||
{{ $positionCSS = printf "bottom: %s; right: %s;" $margin $margin }}
|
||||
{{ end }}
|
||||
|
||||
<div id="slide-title-overlay" style="{{ $positionCSS | safeCSS }}">
|
||||
{{ .text | default $.Title }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{/* Author overlay (optional) */}}
|
||||
{{ if $branding.author }}
|
||||
{{ with $branding.author }}
|
||||
{{ if .show }}
|
||||
{{ $position := .position | default "bottom-right" }}
|
||||
{{ $margin := .margin | default "20px" }}
|
||||
|
||||
{{ $positionCSS := "" }}
|
||||
{{ if eq $position "top-left" }}
|
||||
{{ $positionCSS = printf "top: %s; left: %s;" $margin $margin }}
|
||||
{{ else if eq $position "top-right" }}
|
||||
{{ $positionCSS = printf "top: %s; right: %s;" $margin $margin }}
|
||||
{{ else if eq $position "bottom-left" }}
|
||||
{{ $positionCSS = printf "bottom: %s; left: %s;" $margin $margin }}
|
||||
{{ else if eq $position "bottom-right" }}
|
||||
{{ $positionCSS = printf "bottom: %s; right: %s;" $margin $margin }}
|
||||
{{ end }}
|
||||
|
||||
{{/* Get author from page params or first author */}}
|
||||
{{ $author := "" }}
|
||||
{{ with $.Params.authors }}
|
||||
{{ if reflect.IsSlice . }}
|
||||
{{ $author = index . 0 }}
|
||||
{{ else }}
|
||||
{{ $author = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ with $.Params.author }}
|
||||
{{ $author = . }}
|
||||
{{ end }}
|
||||
|
||||
{{ if $author }}
|
||||
<div id="slide-author-overlay" style="{{ $positionCSS | safeCSS }}">
|
||||
{{ $author }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{/* Footer text overlay (optional) - e.g. for copyright */}}
|
||||
{{ if $branding.footer }}
|
||||
{{ with $branding.footer }}
|
||||
{{ if .text }}
|
||||
{{ $position := .position | default "bottom-center" }}
|
||||
{{ $margin := .margin | default "20px" }}
|
||||
|
||||
{{ $positionCSS := "" }}
|
||||
{{ if eq $position "top-left" }}
|
||||
{{ $positionCSS = printf "top: %s; left: %s;" $margin $margin }}
|
||||
{{ else if eq $position "top-right" }}
|
||||
{{ $positionCSS = printf "top: %s; right: %s;" $margin $margin }}
|
||||
{{ else if eq $position "bottom-left" }}
|
||||
{{ $positionCSS = printf "bottom: %s; left: %s;" $margin $margin }}
|
||||
{{ else if eq $position "bottom-right" }}
|
||||
{{ $positionCSS = printf "bottom: %s; right: %s;" $margin $margin }}
|
||||
{{ else if eq $position "bottom-center" }}
|
||||
{{ $positionCSS = printf "bottom: %s; left: 50%%; transform: translateX(-50%%);" $margin }}
|
||||
{{ end }}
|
||||
|
||||
<div id="slide-footer-text-overlay" style="{{ $positionCSS | safeCSS }}">
|
||||
{{ .text | markdownify }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
{{/*
|
||||
Slides Hook Loader - Independent Implementation
|
||||
|
||||
This is a self-contained hook system for the slides module that doesn't
|
||||
depend on the blox module. Users can create partials in their own project's
|
||||
layouts/_partials/hooks/{hook-name}/ directory.
|
||||
|
||||
Usage: {{ partial "functions/slides_get_hook" (dict "hook" "slide-header" "context" .) }}
|
||||
|
||||
Available hooks for slides:
|
||||
- slide-header: Top of presentation (inside .reveal, above .slides)
|
||||
- slide-footer: Bottom of presentation (inside .reveal, below .slides)
|
||||
- slide-head-end: End of <head> tag (for custom CSS/JS)
|
||||
- slide-body-end: End of <body> tag (for custom JS)
|
||||
|
||||
Input: dict with "hook" (string) and "context" (page context)
|
||||
Output: Renders all partials found in the hook directory
|
||||
*/}}
|
||||
|
||||
{{ $loaded := false }}
|
||||
{{ $partial_dir := printf "hooks/%s/" .hook }}
|
||||
{{ $context := .context }}
|
||||
{{ $hook_dir_path := path.Join "layouts/_partials" $partial_dir }}
|
||||
|
||||
{{/* Use try to gracefully handle missing directories */}}
|
||||
{{ with try (os.ReadDir $hook_dir_path) }}
|
||||
{{ with .Value }}
|
||||
{{ range . }}
|
||||
{{ if not .IsDir }}
|
||||
{{ $partial_path := path.Join $partial_dir .Name }}
|
||||
{{ partial $partial_path $context }}
|
||||
{{ $loaded = true }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{/* Debug: uncomment to see if hooks are loaded */}}
|
||||
{{/* return $loaded */}}
|
||||
@@ -0,0 +1,22 @@
|
||||
{{/*
|
||||
Example Slide Body-End Hook
|
||||
|
||||
This hook allows injecting custom JavaScript at the end of the <body>
|
||||
tag, after Reveal.js has been loaded. Useful for:
|
||||
- Custom Reveal.js plugins
|
||||
- Analytics tracking on slide changes
|
||||
- Custom keyboard shortcuts
|
||||
- Integration with other JS libraries
|
||||
|
||||
To use this hook, create a file at:
|
||||
layouts/_partials/hooks/slide-body-end/your-custom-script.html
|
||||
*/}}
|
||||
|
||||
{{/* Uncomment below to track slide changes with console logging */}}
|
||||
{{/*
|
||||
<script>
|
||||
Reveal.on('slidechanged', event => {
|
||||
console.log('Slide changed to:', event.indexh, event.indexv);
|
||||
});
|
||||
</script>
|
||||
*/}}
|
||||
@@ -0,0 +1,20 @@
|
||||
{{/*
|
||||
Example Slide Footer Hook
|
||||
|
||||
This is an example file showing how to create custom footer content
|
||||
that appears at the bottom of every slide in a presentation.
|
||||
|
||||
To use this hook, create a file at:
|
||||
layouts/_partials/hooks/slide-footer/your-custom-footer.html
|
||||
|
||||
The content will be rendered inside a <div class="slide-footer"> container.
|
||||
|
||||
Example usage: show social media handle or contact info
|
||||
*/}}
|
||||
|
||||
{{/* Uncomment below to show author's social handle in footer */}}
|
||||
{{/*
|
||||
<div style="font-size: 0.5em; color: rgba(255,255,255,0.5); padding: 10px; text-align: right; width: 100%;">
|
||||
@yourhandle
|
||||
</div>
|
||||
*/}}
|
||||
@@ -0,0 +1,25 @@
|
||||
{{/*
|
||||
Example Slide Head-End Hook
|
||||
|
||||
This hook allows injecting custom CSS or JavaScript into the <head>
|
||||
section of the presentation. Useful for:
|
||||
- Custom fonts
|
||||
- Additional CSS frameworks
|
||||
- Analytics scripts
|
||||
- Custom Reveal.js configurations
|
||||
|
||||
To use this hook, create a file at:
|
||||
layouts/_partials/hooks/slide-head-end/your-custom-head.html
|
||||
*/}}
|
||||
|
||||
{{/* Uncomment below to add custom font */}}
|
||||
{{/*
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fira+Code&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
.reveal pre code {
|
||||
font-family: 'Fira Code', monospace;
|
||||
}
|
||||
</style>
|
||||
*/}}
|
||||
@@ -0,0 +1,30 @@
|
||||
{{/*
|
||||
Example Slide Header Hook
|
||||
|
||||
This is an example file showing how to create custom header content
|
||||
that appears at the top of every slide in a presentation.
|
||||
|
||||
To use this hook, create a file at:
|
||||
layouts/_partials/hooks/slide-header/your-custom-header.html
|
||||
|
||||
The content will be rendered inside a <div class="slide-header"> container.
|
||||
|
||||
Available context variables:
|
||||
.Title - Presentation title
|
||||
.Params - All front matter parameters
|
||||
.Params.authors - List of authors
|
||||
.Params.course - Course code/name
|
||||
.Params.venue - Event venue
|
||||
.Date - Presentation date
|
||||
|
||||
Example usage:
|
||||
*/}}
|
||||
|
||||
{{/* Uncomment below to show course code in header */}}
|
||||
{{/*
|
||||
{{ with .Params.course }}
|
||||
<div style="font-size: 0.6em; color: rgba(255,255,255,0.6); padding: 10px;">
|
||||
{{ . }}{{ with $.Params.lecture_number }} · Lecture {{ . }}{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
*/}}
|
||||
@@ -26,7 +26,20 @@
|
||||
{{/* Each `<section>` defines a new slide. */}}
|
||||
{{/* Only begin new slide `<section>` if not already added by custom `slide` shortcode. */}}
|
||||
{{ if not (in . "data-noprocess") }}
|
||||
<section{{ if $isHidden }} data-visibility="hidden"{{ end }}>
|
||||
|
||||
{{/* Parse visibility comments */}}
|
||||
{{ $state := slice }}
|
||||
{{ if in . "<!-- no-branding -->" }}
|
||||
{{ $state = $state | append "no-branding" }}
|
||||
{{ end }}
|
||||
{{ if in . "<!-- no-header -->" }}
|
||||
{{ $state = $state | append "no-header" }}
|
||||
{{ end }}
|
||||
{{ if in . "<!-- no-footer -->" }}
|
||||
{{ $state = $state | append "no-footer" }}
|
||||
{{ end }}
|
||||
|
||||
<section{{ if $isHidden }} data-visibility="hidden"{{ end }} {{ if gt (len $state) 0 }}data-state="{{ delimit $state " " }}"{{ end }}>
|
||||
{{ end }}
|
||||
{{ $slideContent | safeHTML }}
|
||||
</section>
|
||||
@@ -35,4 +48,21 @@
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
{{/* Branding elements - placed inside .reveal but outside .slides to be persistent and fixed */}}
|
||||
|
||||
{{/* Branding overlay (logo, title, author) */}}
|
||||
{{ $pageContext := index . 0 }}
|
||||
{{ partial "components/slide-branding" $pageContext }}
|
||||
|
||||
{{/* Hook: slide-header */}}
|
||||
<div class="slide-header">
|
||||
{{ partial "functions/slides_get_hook" (dict "hook" "slide-header" "context" $pageContext) }}
|
||||
</div>
|
||||
|
||||
{{/* Hook: slide-footer */}}
|
||||
<div class="slide-footer">
|
||||
{{ partial "functions/slides_get_hook" (dict "hook" "slide-footer" "context" $pageContext) }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
{{/*
|
||||
Present Baseof - Presentation output only
|
||||
|
||||
Hook Points Available:
|
||||
- slide-head-end: End of <head> for custom CSS/JS
|
||||
- slide-header: Top of presentation (inside .reveal wrapper)
|
||||
- slide-footer: Bottom of presentation (inside .reveal wrapper)
|
||||
- slide-body-end: End of <body> for custom JS
|
||||
|
||||
Branding Configuration (site.Params.slides.branding or page front matter):
|
||||
logo:
|
||||
src: "media/logo.png"
|
||||
position: "top-left" # top-left, top-right, bottom-left, bottom-right
|
||||
width: "100px"
|
||||
title:
|
||||
show: true
|
||||
position: "bottom-left"
|
||||
author:
|
||||
show: true
|
||||
position: "bottom-right"
|
||||
*/}}
|
||||
|
||||
<!doctype html>
|
||||
@@ -38,6 +56,13 @@
|
||||
{{- $theme := $.Param "slides.theme" | default "black" -}}
|
||||
<link rel="stylesheet" href="{{ $cdn_url_reveal }}/dist/theme/{{ $theme }}.min.css">
|
||||
|
||||
{{/* Load branding CSS */}}
|
||||
{{ $branding_css := resources.Get "css/slides-branding.css" }}
|
||||
{{ with $branding_css }}
|
||||
{{ $branding_css = . | minify | fingerprint }}
|
||||
<link rel="stylesheet" href="{{ $branding_css.RelPermalink }}">
|
||||
{{ end }}
|
||||
|
||||
{{/* Hugo Chroma Syntax Highlighter */}}
|
||||
{{ $hl_theme := $.Param "slides.highlight_style" | default "dracula" }}
|
||||
{{ $hl_theme_path := printf "css/libs/chroma/%s.css" $hl_theme }}
|
||||
@@ -58,6 +83,10 @@
|
||||
document.head.appendChild(link);
|
||||
})();
|
||||
</script>
|
||||
|
||||
{{/* Hook: slide-head-end - Custom CSS/JS injection point */}}
|
||||
{{ partial "functions/slides_get_hook" (dict "hook" "slide-head-end" "context" .) }}
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -80,7 +109,8 @@
|
||||
{{ $slidejs := resources.Get "js/hugoblox-slides.js" | js.Build (dict "params" (dict "slides" $.Params.slides )) | fingerprint }}
|
||||
<script src="{{ $slidejs.RelPermalink }}"></script>
|
||||
|
||||
{{ partial "functions/get_hook" (dict "hook" "body-end" "context" .) }}
|
||||
{{/* Hook: slide-body-end - End of body for custom JS */}}
|
||||
{{ partial "functions/slides_get_hook" (dict "hook" "slide-body-end" "context" .) }}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Markdown</title><path fill="currentColor" d="M22.27 19.385H1.73A1.73 1.73 0 010 17.655V6.345a1.73 1.73 0 011.73-1.73h20.54A1.73 1.73 0 0124 6.345v11.308a1.73 1.73 0 01-1.73 1.731zM5.769 15.923v-4.5l2.308 2.885 2.307-2.885v4.5h2.308V8.078h-2.308l-2.307 2.885-2.308-2.885H3.46v7.847zM21.232 12h-2.309V8.077h-2.307V12h-2.308l3.461 4.039z"/></svg>
|
||||
|
After Width: | Height: | Size: 421 B |
@@ -1 +0,0 @@
|
||||
<svg id="visual" viewBox="0 0 960 540" width="960" height="540" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><path d="M0 104L87 158L175 125L262 131L349 163L436 163L524 168L611 174L698 136L785 104L873 125L960 147L960 0L873 0L785 0L698 0L611 0L524 0L436 0L349 0L262 0L175 0L87 0L0 0Z" fill="#003223"></path><path d="M0 185L87 195L175 212L262 217L349 206L436 239L524 233L611 222L698 185L785 147L873 190L960 190L960 145L873 123L785 102L698 134L611 172L524 166L436 161L349 161L262 129L175 123L87 156L0 102Z" fill="#013b2d"></path><path d="M0 228L87 249L175 287L262 309L349 303L436 336L524 298L611 282L698 260L785 255L873 287L960 255L960 188L873 188L785 145L698 183L611 220L524 231L436 237L349 204L262 215L175 210L87 193L0 183Z" fill="#014537"></path><path d="M0 357L87 395L175 347L262 368L349 428L436 449L524 363L611 390L698 352L785 379L873 368L960 401L960 253L873 285L785 253L698 258L611 280L524 296L436 334L349 301L262 307L175 285L87 247L0 226Z" fill="#024f42"></path><path d="M0 541L87 541L175 541L262 541L349 541L436 541L524 541L611 541L698 541L785 541L873 541L960 541L960 399L873 366L785 377L698 350L611 388L524 361L436 447L349 426L262 366L175 345L87 393L0 355Z" fill="#02594e"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -5,16 +5,45 @@ date: 2024-01-01
|
||||
type: slides
|
||||
summary: "A quick tour of recent research highlights: multimodal LLMs, efficient training, and responsible AI."
|
||||
slides:
|
||||
theme: black
|
||||
highlight_style: dracula
|
||||
diagram: true # Enable Mermaid diagrams
|
||||
theme: black # Options: black, white, league, beige, sky, night, serif, simple, solarized
|
||||
highlight_style: dracula # Code syntax highlighting theme
|
||||
diagram: true # Enable Mermaid diagrams for flowcharts, etc.
|
||||
reveal_options:
|
||||
controls: true
|
||||
progress: true
|
||||
slideNumber: true
|
||||
hash: true
|
||||
controls: true # Show navigation arrows
|
||||
progress: true # Show progress bar
|
||||
slideNumber: true # Show slide numbers
|
||||
hash: true # Update URL when navigating slides
|
||||
|
||||
# BRANDING: Add logo, title overlay, and footer to your presentation
|
||||
# All settings are optional - remove any you don't need
|
||||
branding:
|
||||
# LOGO: Display your organization's logo
|
||||
logo:
|
||||
filename: "slides-logo.svg" # File in assets/media/ folder (SVG recommended for any theme)
|
||||
position: "top-right" # Options: top-left, top-right, bottom-left, bottom-right
|
||||
width: "50px" # Logo width (height scales automatically)
|
||||
# margin: "20px" # Distance from edge (optional, default: 20px)
|
||||
|
||||
# TITLE OVERLAY: Show presentation title on every slide
|
||||
title:
|
||||
show: true # Set to false to hide
|
||||
position: "bottom-left" # Options: top-left, top-right, bottom-left, bottom-right
|
||||
# text: "Short Title" # Optional: override the page title with custom text
|
||||
# margin: "20px" # Distance from edge (optional)
|
||||
|
||||
# AUTHOR OVERLAY: Show author name on every slide
|
||||
# author:
|
||||
# show: true
|
||||
# position: "bottom-right"
|
||||
|
||||
# FOOTER TEXT: Display copyright, conference name, etc.
|
||||
footer:
|
||||
text: "© 2026 HugoBlox" # Supports Markdown (e.g., links)
|
||||
position: "bottom-center" # Options: top-left, top-right, bottom-left, bottom-right, bottom-center
|
||||
---
|
||||
|
||||
|
||||
<!-- no-branding -->
|
||||
# Example Talk
|
||||
### Dr. Alex Johnson · Meta AI
|
||||
|
||||
@@ -319,3 +348,138 @@ This slide won't appear in the presentation but remains in source for reference.
|
||||
|
||||
Note:
|
||||
Thank you for your attention! Feel free to reach out with questions or contributions.
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Branding Your Slides
|
||||
|
||||
Add your identity to every slide with simple configuration!
|
||||
|
||||
**What you can add:**
|
||||
|
||||
| Element | Position Options |
|
||||
|---------|-----------------|
|
||||
| Logo | top-left, top-right, bottom-left, bottom-right |
|
||||
| Title | Same as above |
|
||||
| Author | Same as above |
|
||||
| Footer Text | Same + bottom-center |
|
||||
|
||||
Edit the `branding:` section in your slide's front matter (top of file).
|
||||
|
||||
---
|
||||
|
||||
## 📁 Adding Your Logo
|
||||
|
||||
1. Place your logo in `assets/media/` folder
|
||||
2. Use SVG format for best results (auto-adapts to any theme!)
|
||||
3. Add to front matter:
|
||||
|
||||
```yaml
|
||||
branding:
|
||||
logo:
|
||||
filename: "your-logo.svg" # Must be in assets/media/
|
||||
position: "top-right"
|
||||
width: "60px"
|
||||
```
|
||||
|
||||
**Tip:** SVGs with `fill="currentColor"` automatically match theme colors!
|
||||
|
||||
---
|
||||
|
||||
## 📝 Title & Author Overlays
|
||||
|
||||
Show presentation title and/or author on every slide:
|
||||
|
||||
```yaml
|
||||
branding:
|
||||
title:
|
||||
show: true
|
||||
position: "bottom-left"
|
||||
text: "Short Title" # Optional: override long page title
|
||||
|
||||
author:
|
||||
show: true
|
||||
position: "bottom-right"
|
||||
```
|
||||
|
||||
Author is auto-detected from page front matter (`author:` or `authors:`).
|
||||
|
||||
---
|
||||
|
||||
## 📄 Footer Text
|
||||
|
||||
Add copyright, conference name, or any persistent text:
|
||||
|
||||
```yaml
|
||||
branding:
|
||||
footer:
|
||||
text: "© 2024 Your Name · ICML 2024"
|
||||
position: "bottom-center"
|
||||
```
|
||||
|
||||
**Tip:** Supports Markdown! Use `[Link](url)` for clickable links.
|
||||
|
||||
---
|
||||
|
||||
<!-- no-branding -->
|
||||
|
||||
## 🔇 Hiding Branding Per-Slide
|
||||
|
||||
Sometimes you want a clean slide (title slides, full-screen images).
|
||||
|
||||
Add this comment at the **start** of your slide content:
|
||||
|
||||
```markdown
|
||||
<!-- no-branding -->
|
||||
## My Clean Slide
|
||||
|
||||
Content here...
|
||||
```
|
||||
|
||||
☝️ **This slide uses `<!-- no-branding -->`** — notice no logo or overlays!
|
||||
|
||||
---
|
||||
|
||||
<!-- no-header -->
|
||||
|
||||
## 🔇 Selective Hiding
|
||||
|
||||
Hide just the header (logo + title):
|
||||
|
||||
```markdown
|
||||
<!-- no-header -->
|
||||
```
|
||||
|
||||
Or just the footer (author + footer text):
|
||||
|
||||
```markdown
|
||||
<!-- no-footer -->
|
||||
```
|
||||
|
||||
☝️ **This slide uses `<!-- no-header -->`** — footer still visible below!
|
||||
|
||||
---
|
||||
|
||||
<!-- no-footer -->
|
||||
|
||||
## ✅ Quick Reference
|
||||
|
||||
| Comment | Hides |
|
||||
|---------|-------|
|
||||
| `<!-- no-branding -->` | Everything (logo, title, author, footer) |
|
||||
| `<!-- no-header -->` | Logo + Title overlay |
|
||||
| `<!-- no-footer -->` | Author + Footer text |
|
||||
|
||||
☝️ **This slide uses `<!-- no-footer -->`** — logo still visible above!
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Get Started
|
||||
|
||||
1. Copy this example's front matter as a starting point
|
||||
2. Replace logo with yours in `assets/media/`
|
||||
3. Customize positions and text
|
||||
4. Use `<!-- no-branding -->` for special slides
|
||||
|
||||
**Pro tip:** Set site-wide defaults in `config/_default/params.yaml` under `slides.branding`!
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Markdown</title><path fill="currentColor" d="M22.27 19.385H1.73A1.73 1.73 0 010 17.655V6.345a1.73 1.73 0 011.73-1.73h20.54A1.73 1.73 0 0124 6.345v11.308a1.73 1.73 0 01-1.73 1.731zM5.769 15.923v-4.5l2.308 2.885 2.307-2.885v4.5h2.308V8.078h-2.308l-2.307 2.885-2.308-2.885H3.46v7.847zM21.232 12h-2.309V8.077h-2.307V12h-2.308l3.461 4.039z"/></svg>
|
||||
|
After Width: | Height: | Size: 421 B |
@@ -8,16 +8,36 @@ venue: "Hugo Blox Tutorial"
|
||||
featured: true
|
||||
type: slides
|
||||
slides:
|
||||
theme: black
|
||||
highlight_style: dracula
|
||||
diagram: true
|
||||
theme: black # Options: black, white, league, beige, sky, night, serif, simple, solarized
|
||||
highlight_style: dracula # Code syntax highlighting theme
|
||||
diagram: true # Enable Mermaid diagrams for flowcharts, etc.
|
||||
reveal_options:
|
||||
controls: true
|
||||
progress: true
|
||||
slideNumber: true
|
||||
hash: true
|
||||
controls: true # Show navigation arrows
|
||||
progress: true # Show progress bar
|
||||
slideNumber: true # Show slide numbers
|
||||
hash: true # Update URL when navigating slides
|
||||
|
||||
# BRANDING: Add logo, title overlay, and footer to your presentation
|
||||
# All settings are optional - remove any you don't need
|
||||
branding:
|
||||
# LOGO: Display your organization's logo
|
||||
logo:
|
||||
filename: "slides-logo.svg" # File in assets/media/ folder (SVG recommended for any theme)
|
||||
position: "top-right" # Options: top-left, top-right, bottom-left, bottom-right
|
||||
width: "50px" # Logo width (height scales automatically)
|
||||
|
||||
# TITLE OVERLAY: Show presentation title on every slide
|
||||
title:
|
||||
show: true # Set to false to hide
|
||||
position: "bottom-left" # Options: top-left, top-right, bottom-left, bottom-right
|
||||
|
||||
# FOOTER TEXT: Display copyright, conference name, etc.
|
||||
footer:
|
||||
text: "© 2026 HugoBlox" # Supports Markdown (e.g., links)
|
||||
position: "bottom-center" # Options: top-left, top-right, bottom-left, bottom-right, bottom-center
|
||||
---
|
||||
|
||||
<!-- no-branding -->
|
||||
# Markdown Slides
|
||||
|
||||
### Write in Markdown. Present Anywhere.
|
||||
@@ -164,3 +184,127 @@ Use `{{</* slide background-color="#hex" */>}}`
|
||||
- Docs: [docs.hugoblox.com](https://docs.hugoblox.com)
|
||||
|
||||
*Built with Markdown Slides*
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Branding Your Slides
|
||||
|
||||
Add your identity to every slide with simple configuration!
|
||||
|
||||
**What you can add:**
|
||||
|
||||
| Element | Position Options |
|
||||
|---------|-----------------|
|
||||
| Logo | top-left, top-right, bottom-left, bottom-right |
|
||||
| Title | Same as above |
|
||||
| Author | Same as above |
|
||||
| Footer Text | Same + bottom-center |
|
||||
|
||||
Edit the `branding:` section in your slide's front matter (top of file).
|
||||
|
||||
---
|
||||
|
||||
## 📁 Adding Your Logo
|
||||
|
||||
1. Place your logo in `assets/media/` folder
|
||||
2. Use SVG format for best results (auto-adapts to any theme!)
|
||||
3. Add to front matter:
|
||||
|
||||
```yaml
|
||||
branding:
|
||||
logo:
|
||||
filename: "your-logo.svg" # Must be in assets/media/
|
||||
position: "top-right"
|
||||
width: "60px"
|
||||
```
|
||||
|
||||
**Tip:** SVGs with `fill="currentColor"` automatically match theme colors!
|
||||
|
||||
---
|
||||
|
||||
## 📝 Title & Author Overlays
|
||||
|
||||
Show presentation title and/or author on every slide:
|
||||
|
||||
```yaml
|
||||
branding:
|
||||
title:
|
||||
show: true
|
||||
position: "bottom-left"
|
||||
text: "Short Title" # Optional: override long page title
|
||||
|
||||
author:
|
||||
show: true
|
||||
position: "bottom-right"
|
||||
```
|
||||
|
||||
Author is auto-detected from page front matter (`author:` or `authors:`).
|
||||
|
||||
---
|
||||
|
||||
## 📄 Footer Text
|
||||
|
||||
Add copyright, conference name, or any persistent text:
|
||||
|
||||
```yaml
|
||||
branding:
|
||||
footer:
|
||||
text: "© 2024 Your Name · ICML 2024"
|
||||
position: "bottom-center"
|
||||
```
|
||||
|
||||
**Tip:** Supports Markdown! Use `[Link](url)` for clickable links.
|
||||
|
||||
---
|
||||
|
||||
<!-- no-branding -->
|
||||
|
||||
## 🔇 Hiding Branding Per-Slide
|
||||
|
||||
Sometimes you want a clean slide (title slides, full-screen images).
|
||||
|
||||
Add this comment at the **start** of your slide content:
|
||||
|
||||
```markdown
|
||||
<!-- no-branding -->
|
||||
## My Clean Slide
|
||||
|
||||
Content here...
|
||||
```
|
||||
|
||||
☝️ **This slide uses `<!-- no-branding -->`** — notice no logo or overlays!
|
||||
|
||||
---
|
||||
|
||||
<!-- no-header -->
|
||||
|
||||
## 🔇 Selective Hiding
|
||||
|
||||
Hide just the header (logo + title):
|
||||
|
||||
```markdown
|
||||
<!-- no-header -->
|
||||
```
|
||||
|
||||
Or just the footer (author + footer text):
|
||||
|
||||
```markdown
|
||||
<!-- no-footer -->
|
||||
```
|
||||
|
||||
☝️ **This slide uses `<!-- no-header -->`** — footer still visible below!
|
||||
|
||||
---
|
||||
|
||||
<!-- no-footer -->
|
||||
|
||||
## ✅ Quick Reference
|
||||
|
||||
| Comment | Hides |
|
||||
|---------|-------|
|
||||
| `<!-- no-branding -->` | Everything (logo, title, author, footer) |
|
||||
| `<!-- no-header -->` | Logo + Title overlay |
|
||||
| `<!-- no-footer -->` | Author + Footer text |
|
||||
|
||||
☝️ **This slide uses `<!-- no-footer -->`** — logo still visible above!
|
||||
|
||||
|
||||
Reference in New Issue
Block a user