init
This commit is contained in:
parent
2fe0c9a830
commit
7b9c07b83e
1444 changed files with 11476 additions and 42112 deletions
10
layouts/404.html
Executable file
10
layouts/404.html
Executable file
|
@ -0,0 +1,10 @@
|
|||
{{- define "main" }}
|
||||
<style>
|
||||
.not-found {
|
||||
position : relative;
|
||||
}
|
||||
|
||||
</style>
|
||||
<div class="not-found">404</div>
|
||||
<div class="not-found" style="font-size: 1.5em;">Ouais désolé je sais pas ce que tu cherches mais c'est pas ici en tous cas</div>
|
||||
{{- end }}{{/* end main */ -}}
|
22
layouts/_default/_markup/render-image.html
Executable file
22
layouts/_default/_markup/render-image.html
Executable file
|
@ -0,0 +1,22 @@
|
|||
{{- $u := urls.Parse .Destination -}}
|
||||
{{- $src := $u.String -}}
|
||||
{{- if not $u.IsAbs -}}
|
||||
{{- $path := strings.TrimPrefix "./" $u.Path }}
|
||||
{{- with or (.PageInner.Resources.Get $path) (resources.Get $path) -}}
|
||||
{{- $src = .RelPermalink -}}
|
||||
{{- with $u.RawQuery -}}
|
||||
{{- $src = printf "%s?%s" $src . -}}
|
||||
{{- end -}}
|
||||
{{- with $u.Fragment -}}
|
||||
{{- $src = printf "%s#%s" $src . -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- $attributes := merge .Attributes (dict "alt" .Text "src" $src "title" (.Title | transform.HTMLEscape) "loading" "lazy") -}}
|
||||
<img
|
||||
{{- range $k, $v := $attributes -}}
|
||||
{{- if $v -}}
|
||||
{{- printf " %s=%q" $k $v | safeHTMLAttr -}}
|
||||
{{- end -}}
|
||||
{{- end -}}>
|
||||
{{- /**/ -}}
|
83
layouts/_default/archives.html
Executable file
83
layouts/_default/archives.html
Executable file
|
@ -0,0 +1,83 @@
|
|||
{{- define "main" }}
|
||||
|
||||
<header class="page-header">
|
||||
<h1>
|
||||
{{ .Title }}
|
||||
{{- if (.Param "ShowRssButtonInSectionTermList") }}
|
||||
{{- $rss := (.OutputFormats.Get "rss") }}
|
||||
{{- if (eq .Kind `page`) }}
|
||||
{{- $rss = (.Parent.OutputFormats.Get "rss") }}
|
||||
{{- end }}
|
||||
{{- with $rss }}
|
||||
<a href="{{ .RelPermalink }}" title="RSS" aria-label="RSS">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round" height="23">
|
||||
<path d="M4 11a9 9 0 0 1 9 9" />
|
||||
<path d="M4 4a16 16 0 0 1 16 16" />
|
||||
<circle cx="5" cy="19" r="1" />
|
||||
</svg>
|
||||
</a>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</h1>
|
||||
{{- if .Description }}
|
||||
<div class="post-description">
|
||||
{{ .Description }}
|
||||
</div>
|
||||
{{- end }}
|
||||
</header>
|
||||
|
||||
{{- $pages := where site.RegularPages "Type" "in" site.Params.mainSections }}
|
||||
|
||||
{{- if site.Params.ShowAllPagesInArchive }}
|
||||
{{- $pages = site.RegularPages }}
|
||||
{{- end }}
|
||||
|
||||
{{- range $pages.GroupByPublishDate "2006" }}
|
||||
{{- if ne .Key "0001" }}
|
||||
<div class="archive-year">
|
||||
{{- $year := replace .Key "0001" "" }}
|
||||
<h2 class="archive-year-header" id="{{ $year }}">
|
||||
<a class="archive-header-link" href="#{{ $year }}">
|
||||
{{- $year -}}
|
||||
</a>
|
||||
<sup class="archive-count"> {{ len .Pages }}</sup>
|
||||
</h2>
|
||||
{{- range .Pages.GroupByDate "January" }}
|
||||
<div class="archive-month">
|
||||
<h3 class="archive-month-header" id="{{ $year }}-{{ .Key }}">
|
||||
<a class="archive-header-link" href="#{{ $year }}-{{ .Key }}">
|
||||
{{- .Key -}}
|
||||
</a>
|
||||
<sup class="archive-count"> {{ len .Pages }}</sup>
|
||||
</h3>
|
||||
<div class="archive-posts">
|
||||
{{- range .Pages }}
|
||||
{{- if eq .Kind "page" }}
|
||||
<div class="archive-entry">
|
||||
<h3 class="archive-entry-title entry-hint-parent">
|
||||
{{- .Title | markdownify }}
|
||||
{{- if .Draft }}
|
||||
<span class="entry-hint" title="Draft">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="15" viewBox="0 -960 960 960" fill="currentColor">
|
||||
<path
|
||||
d="M160-410v-60h300v60H160Zm0-165v-60h470v60H160Zm0-165v-60h470v60H160Zm360 580v-123l221-220q9-9 20-13t22-4q12 0 23 4.5t20 13.5l37 37q9 9 13 20t4 22q0 11-4.5 22.5T862.09-380L643-160H520Zm300-263-37-37 37 37ZM580-220h38l121-122-18-19-19-18-122 121v38Zm141-141-19-18 37 37-18-19Z" />
|
||||
</svg>
|
||||
</span>
|
||||
{{- end }}
|
||||
</h3>
|
||||
<div class="archive-meta">
|
||||
{{- partial "post_meta.html" . -}}
|
||||
</div>
|
||||
<a class="entry-link" aria-label="post link to {{ .Title | plainify }}" href="{{ .Permalink }}"></a>
|
||||
</div>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</div>
|
||||
</div>
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- end }}{{/* end main */}}
|
29
layouts/_default/baseof.html
Executable file
29
layouts/_default/baseof.html
Executable file
|
@ -0,0 +1,29 @@
|
|||
{{- if lt hugo.Version "0.125.7" }}
|
||||
{{- errorf "=> hugo v0.125.7 or greater is required for hugo-PaperMod to build " }}
|
||||
{{- end -}}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ site.Language }}" dir="{{ .Language.LanguageDirection | default "auto" }}">
|
||||
|
||||
<head>
|
||||
{{- partial "head.html" . }}
|
||||
</head>
|
||||
|
||||
<body class="
|
||||
{{- if (or (ne .Kind `page` ) (eq .Layout `archives`) (eq .Layout `search`)) -}}
|
||||
{{- print "list" -}}
|
||||
{{- end -}}
|
||||
{{- if eq site.Params.defaultTheme `dark` -}}
|
||||
{{- print " dark" }}
|
||||
{{- end -}}
|
||||
" id="top">
|
||||
<div class="main-content">
|
||||
{{- partialCached "header.html" . .Page -}}
|
||||
<main class="main">
|
||||
{{- block "main" . }}{{ end }}
|
||||
</main>
|
||||
{{ partialCached "footer.html" . .Layout .Kind (.Param "hideFooter") (.Param "ShowCodeCopyButtons") -}}
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
7
layouts/_default/index.json
Executable file
7
layouts/_default/index.json
Executable file
|
@ -0,0 +1,7 @@
|
|||
{{- $.Scratch.Add "index" slice -}}
|
||||
{{- range site.RegularPages -}}
|
||||
{{- if and (not .Params.searchHidden) (ne .Layout `archives`) (ne .Layout `search`) }}
|
||||
{{- $.Scratch.Add "index" (dict "title" .Title "content" .Plain "permalink" .Permalink "summary" .Summary) -}}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
{{- $.Scratch.Get "index" | jsonify -}}
|
121
layouts/_default/list.html
Executable file
121
layouts/_default/list.html
Executable file
|
@ -0,0 +1,121 @@
|
|||
{{- define "main" }}
|
||||
|
||||
{{- if (and site.Params.profileMode.enabled .IsHome) }}
|
||||
{{- partial "index_profile.html" . }}
|
||||
{{- else }} {{/* if not profileMode */}}
|
||||
|
||||
{{- if not .IsHome | and .Title }}
|
||||
<header class="page-header">
|
||||
{{- partial "breadcrumbs.html" . }}
|
||||
<h1>
|
||||
{{ .Title }}
|
||||
{{- if and (or (eq .Kind `term`) (eq .Kind `section`)) (.Param "ShowRssButtonInSectionTermList") }}
|
||||
{{- with .OutputFormats.Get "rss" }}
|
||||
<a href="{{ .RelPermalink }}" title="RSS" aria-label="RSS">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round" height="23">
|
||||
<path d="M4 11a9 9 0 0 1 9 9" />
|
||||
<path d="M4 4a16 16 0 0 1 16 16" />
|
||||
<circle cx="5" cy="19" r="1" />
|
||||
</svg>
|
||||
</a>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</h1>
|
||||
{{- if .Description }}
|
||||
<div class="post-description">
|
||||
{{ .Description | markdownify }}
|
||||
</div>
|
||||
{{- end }}
|
||||
</header>
|
||||
{{- end }}
|
||||
|
||||
{{- if .Content }}
|
||||
<div class="post-content">
|
||||
{{- if not (.Param "disableAnchoredHeadings") }}
|
||||
{{- partial "anchored_headings.html" .Content -}}
|
||||
{{- else }}{{ .Content }}{{ end }}
|
||||
</div>
|
||||
{{- end }}
|
||||
|
||||
{{- $pages := union .RegularPages .Sections }}
|
||||
|
||||
{{- if .IsHome }}
|
||||
{{- $pages = where site.RegularPages "Type" "in" site.Params.mainSections }}
|
||||
{{- $pages = where $pages "Params.hiddenInHomeList" "!=" "true" }}
|
||||
{{- end }}
|
||||
|
||||
{{- $paginator := .Paginate $pages }}
|
||||
|
||||
{{- if and .IsHome site.Params.homeInfoParams (eq $paginator.PageNumber 1) }}
|
||||
{{- partial "home_info.html" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- $term := .Data.Term }}
|
||||
{{- range $index, $page := $paginator.Pages }}
|
||||
|
||||
{{- $class := "post-entry" }}
|
||||
|
||||
{{- $user_preferred := or site.Params.disableSpecial1stPost site.Params.homeInfoParams }}
|
||||
{{- if (and $.IsHome (eq $paginator.PageNumber 1) (eq $index 0) (not $user_preferred)) }}
|
||||
{{- $class = "first-entry" }}
|
||||
{{- else if $term }}
|
||||
{{- $class = "post-entry tag-entry" }}
|
||||
{{- end }}
|
||||
|
||||
<article class="{{ $class }}">
|
||||
{{- $isHidden := (.Param "cover.hiddenInList") | default (.Param "cover.hidden") | default false }}
|
||||
{{- partial "cover.html" (dict "cxt" . "IsSingle" false "isHidden" $isHidden) }}
|
||||
<header class="entry-header">
|
||||
<h2 class="entry-hint-parent">
|
||||
{{- .Title }}
|
||||
{{- if .Draft }}
|
||||
<span class="entry-hint" title="Draft">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" fill="currentColor">
|
||||
<path
|
||||
d="M160-410v-60h300v60H160Zm0-165v-60h470v60H160Zm0-165v-60h470v60H160Zm360 580v-123l221-220q9-9 20-13t22-4q12 0 23 4.5t20 13.5l37 37q9 9 13 20t4 22q0 11-4.5 22.5T862.09-380L643-160H520Zm300-263-37-37 37 37ZM580-220h38l121-122-18-19-19-18-122 121v38Zm141-141-19-18 37 37-18-19Z" />
|
||||
</svg>
|
||||
</span>
|
||||
{{- end }}
|
||||
</h2>
|
||||
</header>
|
||||
{{- if (ne (.Param "hideSummary") true) }}
|
||||
<div class="entry-content">
|
||||
<p>{{ .Summary | plainify | htmlUnescape }}{{ if .Truncated }}...{{ end }}</p>
|
||||
</div>
|
||||
{{- end }}
|
||||
{{- if not (.Param "hideMeta") }}
|
||||
<footer class="entry-footer">
|
||||
{{- partial "post_meta.html" . -}}
|
||||
</footer>
|
||||
{{- end }}
|
||||
<a class="entry-link" aria-label="post link to {{ .Title | plainify }}" href="{{ .Permalink }}"></a>
|
||||
</article>
|
||||
{{- end }}
|
||||
|
||||
{{- if gt $paginator.TotalPages 1 }}
|
||||
<footer class="page-footer">
|
||||
<nav class="pagination">
|
||||
{{- if $paginator.HasPrev }}
|
||||
<a class="prev" href="{{ $paginator.Prev.URL | absURL }}">
|
||||
« {{ i18n "prev_page" }}
|
||||
{{- if (.Param "ShowPageNums") }}
|
||||
{{- sub $paginator.PageNumber 1 }}/{{ $paginator.TotalPages }}
|
||||
{{- end }}
|
||||
</a>
|
||||
{{- end }}
|
||||
{{- if $paginator.HasNext }}
|
||||
<a class="next" href="{{ $paginator.Next.URL | absURL }}">
|
||||
{{- i18n "next_page" }}
|
||||
{{- if (.Param "ShowPageNums") }}
|
||||
{{- add 1 $paginator.PageNumber }}/{{ $paginator.TotalPages }}
|
||||
{{- end }} »
|
||||
</a>
|
||||
{{- end }}
|
||||
</nav>
|
||||
</footer>
|
||||
{{- end }}
|
||||
|
||||
{{- end }}{{/* end profileMode */}}
|
||||
|
||||
{{- end }}{{- /* end main */ -}}
|
29
layouts/_default/search.html
Executable file
29
layouts/_default/search.html
Executable file
|
@ -0,0 +1,29 @@
|
|||
{{- define "main" }}
|
||||
|
||||
<header class="page-header">
|
||||
<h1>{{- (printf "%s " .Title ) | htmlUnescape -}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="11" cy="11" r="8"></circle>
|
||||
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||
</svg>
|
||||
</h1>
|
||||
{{- if .Description }}
|
||||
<div class="post-description">
|
||||
{{ .Description }}
|
||||
</div>
|
||||
{{- end }}
|
||||
{{- if not (.Param "hideMeta") }}
|
||||
<div class="post-meta">
|
||||
{{- partial "translation_list.html" . -}}
|
||||
</div>
|
||||
{{- end }}
|
||||
</header>
|
||||
|
||||
<div id="searchbox">
|
||||
<input id="searchInput" autofocus placeholder="{{ .Params.placeholder | default (printf "%s ↵" .Title) }}"
|
||||
aria-label="search" type="search" autocomplete="off" maxlength="64">
|
||||
<ul id="searchResults" aria-label="search results"></ul>
|
||||
</div>
|
||||
|
||||
{{- end }}{{/* end main */}}
|
76
layouts/_default/single.html
Executable file
76
layouts/_default/single.html
Executable file
|
@ -0,0 +1,76 @@
|
|||
{{- define "main" }}
|
||||
|
||||
<article class="post-single">
|
||||
<header class="post-header">
|
||||
{{ partial "breadcrumbs.html" . }}
|
||||
<h1 class="post-title entry-hint-parent">
|
||||
{{ .Title }}
|
||||
{{- if .Draft }}
|
||||
<span class="entry-hint" title="Draft">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="35" viewBox="0 -960 960 960" fill="currentColor">
|
||||
<path
|
||||
d="M160-410v-60h300v60H160Zm0-165v-60h470v60H160Zm0-165v-60h470v60H160Zm360 580v-123l221-220q9-9 20-13t22-4q12 0 23 4.5t20 13.5l37 37q9 9 13 20t4 22q0 11-4.5 22.5T862.09-380L643-160H520Zm300-263-37-37 37 37ZM580-220h38l121-122-18-19-19-18-122 121v38Zm141-141-19-18 37 37-18-19Z" />
|
||||
</svg>
|
||||
</span>
|
||||
{{- end }}
|
||||
</h1>
|
||||
{{- if .Description }}
|
||||
<div class="post-description">
|
||||
{{ .Description }}
|
||||
</div>
|
||||
{{- end }}
|
||||
{{- if not (.Param "hideMeta") }}
|
||||
<div class="post-meta">
|
||||
{{- partial "post_meta.html" . -}}
|
||||
{{- partial "translation_list.html" . -}}
|
||||
{{- partial "edit_post.html" . -}}
|
||||
{{- partial "post_canonical.html" . -}}
|
||||
</div>
|
||||
{{- end }}
|
||||
</header>
|
||||
{{- $isHidden := (.Param "cover.hiddenInSingle") | default (.Param "cover.hidden") | default false }}
|
||||
{{- partial "cover.html" (dict "cxt" . "IsSingle" true "isHidden" $isHidden) }}
|
||||
{{- if (.Param "ShowToc") }}
|
||||
{{- partial "toc.html" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Content }}
|
||||
|
||||
<div class="flex-wrapper">
|
||||
<!-- if the page is a collection item, add the infobox -->
|
||||
{{- if eq .Section "collection" }}
|
||||
{{ partial "encadre-maec.html" . }}
|
||||
{{- end }}
|
||||
<!-- if the page is a book, add the infobox -->
|
||||
{{- if eq .Section "livres" }}
|
||||
{{ partial "encadre-livre.html" . }}
|
||||
{{- end }}
|
||||
<div class="post-content">
|
||||
{{- if not (.Param "disableAnchoredHeadings") }}
|
||||
{{- partial "anchored_headings.html" .Content -}}
|
||||
{{- else }}{{ .Content }}{{ end }}
|
||||
</div>
|
||||
{{- end }}
|
||||
</div>
|
||||
|
||||
<footer class="post-footer">
|
||||
{{- $tags := .Language.Params.Taxonomies.tag | default "tags" }}
|
||||
<ul class="post-tags">
|
||||
{{- range ($.GetTerms $tags) }}
|
||||
<li><a href="{{ .Permalink }}">{{ .LinkTitle }}</a></li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
{{- if (.Param "ShowPostNavLinks") }}
|
||||
{{- partial "post_nav_links.html" . }}
|
||||
{{- end }}
|
||||
{{- if (and site.Params.ShowShareButtons (ne .Params.disableShare true)) }}
|
||||
{{- partial "share_icons.html" . -}}
|
||||
{{- end }}
|
||||
</footer>
|
||||
|
||||
{{- if (.Param "comments") }}
|
||||
{{- partial "comments.html" . }}
|
||||
{{- end }}
|
||||
</article>
|
||||
|
||||
{{- end }}{{/* end main */}}
|
27
layouts/_default/terms.html
Executable file
27
layouts/_default/terms.html
Executable file
|
@ -0,0 +1,27 @@
|
|||
{{- define "main" }}
|
||||
|
||||
{{- if .Title }}
|
||||
<header class="page-header">
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{- if .Description }}
|
||||
<div class="post-description">
|
||||
{{ .Description }}
|
||||
</div>
|
||||
{{- end }}
|
||||
</header>
|
||||
{{- end }}
|
||||
|
||||
<ul class="terms-tags">
|
||||
{{- $type := .Type }}
|
||||
{{- range $key, $value := .Data.Terms.Alphabetical }}
|
||||
{{- $name := .Name }}
|
||||
{{- $count := .Count }}
|
||||
{{- with site.GetPage (printf "/%s/%s" $type $name) }}
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">{{ .Name }} <sup><strong><sup>{{ $count }}</sup></strong></sup> </a>
|
||||
</li>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</ul>
|
||||
|
||||
{{- end }}{{/* end main */ -}}
|
147
layouts/collection/list.html
Executable file
147
layouts/collection/list.html
Executable file
|
@ -0,0 +1,147 @@
|
|||
{{- define "main" }}
|
||||
|
||||
{{- if (and site.Params.profileMode.enabled .IsHome) }}
|
||||
{{- partial "index_profile.html" . }}
|
||||
{{- else }} {{/* if not profileMode */}}
|
||||
|
||||
{{- if not .IsHome | and .Title }}
|
||||
<header class="page-header">
|
||||
{{- partial "breadcrumbs.html" . }}
|
||||
<h1>
|
||||
{{ .Title }}
|
||||
{{- if and (or (eq .Kind `term`) (eq .Kind `section`)) (.Param "ShowRssButtonInSectionTermList") }}
|
||||
{{- with .OutputFormats.Get "rss" }}
|
||||
<a href="{{ .RelPermalink }}" title="RSS" aria-label="RSS">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round" height="23">
|
||||
<path d="M4 11a9 9 0 0 1 9 9" />
|
||||
<path d="M4 4a16 16 0 0 1 16 16" />
|
||||
<circle cx="5" cy="19" r="1" />
|
||||
</svg>
|
||||
</a>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</h1>
|
||||
{{- if .Description }}
|
||||
<div class="post-description">
|
||||
{{ .Description | markdownify }}
|
||||
</div>
|
||||
{{- end }}
|
||||
</header>
|
||||
{{- end }}
|
||||
|
||||
<style>
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); /* Responsive grid */
|
||||
gap: 10px; /* Space between grid items */
|
||||
margin: 0 0;
|
||||
}
|
||||
|
||||
.post-entry {
|
||||
padding: 0;
|
||||
border-radius: 8px;
|
||||
background-color: var(--entry);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.entry-cover {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.entry-header {
|
||||
font-size: 1.1rem;
|
||||
display: inline-block;
|
||||
margin: 10px 16px 10px 16px;
|
||||
}
|
||||
|
||||
.post-entry p {
|
||||
margin: 0;
|
||||
color: #555;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
{{- if .Content }}
|
||||
<div class="post-content">
|
||||
{{- if not (.Param "disableAnchoredHeadings") }}
|
||||
{{- partial "anchored_headings.html" .Content -}}
|
||||
{{- else }}{{ .Content }}{{ end }}
|
||||
</div>
|
||||
{{- end }}
|
||||
|
||||
|
||||
<div class="grid-container">
|
||||
{{- range .Pages }}
|
||||
<a href="{{ .Permalink }}" class="post-entry">
|
||||
|
||||
|
||||
{{- $isHidden := (.Param "cover.hiddenInList") | default (.Param "cover.hidden") | default false }}
|
||||
{{- partial "cover.html" (dict "cxt" . "IsSingle" false "isHidden" $isHidden) }}
|
||||
<header class="entry-header">
|
||||
<h2 class="entry-hint-parent">
|
||||
<span>{{ .Title }}</span>
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
|
||||
</a>
|
||||
{{- end }}
|
||||
</div>
|
||||
|
||||
|
||||
{{- $pages := union .RegularPages .Sections }}
|
||||
|
||||
{{- if .IsHome }}
|
||||
{{- $pages = where site.RegularPages "Type" "in" site.Params.mainSections }}
|
||||
{{- $pages = where $pages "Params.hiddenInHomeList" "!=" "true" }}
|
||||
{{- end }}
|
||||
|
||||
{{- $paginator := .Paginate $pages }}
|
||||
|
||||
{{- if and .IsHome site.Params.homeInfoParams (eq $paginator.PageNumber 1) }}
|
||||
{{- partial "home_info.html" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- $term := .Data.Term }}
|
||||
{{- range $index, $page := $paginator.Pages }}
|
||||
|
||||
{{- $class := "post-entry" }}
|
||||
|
||||
{{- $user_preferred := or site.Params.disableSpecial1stPost site.Params.homeInfoParams }}
|
||||
{{- if (and $.IsHome (eq $paginator.PageNumber 1) (eq $index 0) (not $user_preferred)) }}
|
||||
{{- $class = "first-entry" }}
|
||||
{{- else if $term }}
|
||||
{{- $class = "post-entry tag-entry" }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- end }}
|
||||
|
||||
{{- if gt $paginator.TotalPages 1 }}
|
||||
<footer class="page-footer">
|
||||
<nav class="pagination">
|
||||
{{- if $paginator.HasPrev }}
|
||||
<a class="prev" href="{{ $paginator.Prev.URL | absURL }}">
|
||||
« {{ i18n "prev_page" }}
|
||||
{{- if (.Param "ShowPageNums") }}
|
||||
{{- sub $paginator.PageNumber 1 }}/{{ $paginator.TotalPages }}
|
||||
{{- end }}
|
||||
</a>
|
||||
{{- end }}
|
||||
{{- if $paginator.HasNext }}
|
||||
<a class="next" href="{{ $paginator.Next.URL | absURL }}">
|
||||
{{- i18n "next_page" }}
|
||||
{{- if (.Param "ShowPageNums") }}
|
||||
{{- add 1 $paginator.PageNumber }}/{{ $paginator.TotalPages }}
|
||||
{{- end }} »
|
||||
</a>
|
||||
{{- end }}
|
||||
</nav>
|
||||
</footer>
|
||||
{{- end }}
|
||||
|
||||
{{- end }}{{/* end profileMode */}}
|
||||
|
||||
{{- end }}{{- /* end main */ -}}
|
207
layouts/home.html
Executable file
207
layouts/home.html
Executable file
|
@ -0,0 +1,207 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ site.Language }}" dir="{{ .Language.LanguageDirection | default "auto" }}">
|
||||
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta charset="utf-8">
|
||||
<!-- Include core CSS files -->
|
||||
<link rel="stylesheet" href="{{ "css/core/reset.css" | relURL }}">
|
||||
<link rel="stylesheet" href="{{ "css/core/theme-vars.css" | relURL }}">
|
||||
<link rel="stylesheet" href="{{ "css/core/zmedia.css" | relURL }}">
|
||||
<!-- Include home page specific styles -->
|
||||
<link rel="stylesheet" href="{{ "css/home.css" | relURL }}">
|
||||
|
||||
<!-- Include concatenated and minified stylesheet -->
|
||||
{{- $theme_vars := (resources.Get "css/core/theme-vars.css") }}
|
||||
{{- $reset := (resources.Get "css/core/reset.css") }}
|
||||
{{- $media := (resources.Get "css/core/zmedia.css") }}
|
||||
{{- $common := (resources.Match "css/common/*.css") | resources.Concat "assets/css/common.css" }}
|
||||
{{- $extended := (resources.Match "css/extended/*.css") | resources.Concat "assets/css/extended.css" }}
|
||||
{{- $core := (slice $theme_vars $reset $common $media $extended) | resources.Concat "assets/css/core.css" | resources.Minify }}
|
||||
<link rel="stylesheet" href="{{ $core.RelPermalink }}">
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<header>
|
||||
<!-- Script to automatically toggle to the right theme -->
|
||||
{{- /* theme-toggle is enabled */}}
|
||||
{{- if (not site.Params.disableThemeToggle) }}
|
||||
{{- /* theme is light */}}
|
||||
{{- if (eq site.Params.defaultTheme "light") }}
|
||||
<script>
|
||||
if (localStorage.getItem("pref-theme") === "dark") {
|
||||
document.body.classList.add('dark');
|
||||
}
|
||||
</script>
|
||||
{{- /* theme is dark */}}
|
||||
{{- else if (eq site.Params.defaultTheme "dark") }}
|
||||
<script>
|
||||
if (localStorage.getItem("pref-theme") === "light") {
|
||||
document.body.classList.remove('dark')
|
||||
}
|
||||
</script>
|
||||
{{- else }}
|
||||
{{- /* theme is auto */}}
|
||||
<script>
|
||||
if (localStorage.getItem("pref-theme") === "dark") {
|
||||
document.body.classList.add('dark');
|
||||
} else if (localStorage.getItem("pref-theme") === "light") {
|
||||
document.body.classList.remove('dark')
|
||||
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
document.body.classList.add('dark');
|
||||
}
|
||||
</script>
|
||||
{{- end }}
|
||||
{{- /* theme-toggle is disabled and theme is auto */}}
|
||||
{{- else if (and (ne site.Params.defaultTheme "light") (ne site.Params.defaultTheme "dark"))}}
|
||||
<script>
|
||||
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
document.body.classList.add('dark');
|
||||
}
|
||||
</script>
|
||||
{{- end }}
|
||||
</header>
|
||||
|
||||
<body>
|
||||
<div class="main-screen">
|
||||
<div class="side-screen">
|
||||
{{ partial "posts-defile.html" (dict "context" . "direction" "up") }}
|
||||
</div>
|
||||
<div class="main-content">
|
||||
<div class="header">
|
||||
<div class="title-wrapper">
|
||||
<h1 class="site-title">Achille<br/>Toupin</h1>
|
||||
<div class="site-logo">
|
||||
<img src="favicon.svg" alt="Logo de machine à écrire">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="navigation">
|
||||
{{ partial "menu.html" }}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="center-content">
|
||||
<div class="presentation">
|
||||
{{ .Content }}
|
||||
</div>
|
||||
<div class="side-content-column">
|
||||
<div class="dernier-article">
|
||||
{{ range first 1 (where .Site.RegularPages.ByDate.Reverse "Section" "blog") }}
|
||||
{{- $image := .Resources.GetMatch (printf "%s" .Params.cover.image) -}}
|
||||
{{- if $image -}}
|
||||
{{- $optimizedImage := $image.Fill "150x150 webp q95 Center" -}}
|
||||
<a href="{{ .RelPermalink }}">
|
||||
<h2>Mon dernier article :</h2>
|
||||
<h3>{{ .Title }}</h3>
|
||||
<div class="excerpt">
|
||||
<div class="excerpt-text">
|
||||
<small>{{ .Date.Format "January 2, 2006" }}</small>
|
||||
<p>{{ .Plain | plainify | truncate 100 }}</p>
|
||||
</div>
|
||||
<img src="{{ $optimizedImage.RelPermalink }}" alt="{{ .Title }} cover image"></img>
|
||||
</div>
|
||||
</a>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="dernier-article">
|
||||
{{ range first 1 (where .Site.RegularPages.ByDate.Reverse "Section" "collection") }}
|
||||
{{- $image := .Resources.GetMatch (printf "%s" .Params.cover.image) -}}
|
||||
{{- if $image -}}
|
||||
{{- $optimizedImage := $image.Fit "150x150 webp q95 Center" -}}
|
||||
<a href="{{ .RelPermalink }}">
|
||||
<h2>Une belle machine :</h2>
|
||||
<h3>{{ .Title }}</h3>
|
||||
<div class="excerpt">
|
||||
<div class="excerpt-text">
|
||||
<small>{{ .Date.Format "January 2, 2006" }}</small>
|
||||
<p>{{ .Plain | plainify | truncate 100 }}</p>
|
||||
</div>
|
||||
<img src="{{ $optimizedImage.RelPermalink }}" alt="{{ .Title }} cover image"></img>
|
||||
</div>
|
||||
</a>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<div class="dernier-livre">
|
||||
{{ range first 1 (where .Site.RegularPages.ByDate.Reverse "Section" "livres") }}
|
||||
{{- $image := .Resources.GetMatch (printf "%s" .Params.cover.image) -}}
|
||||
{{- if $image -}}
|
||||
{{- $optimizedImage := $image.Fit "150x150 webp q95 Center" -}}
|
||||
<a href="{{ .RelPermalink }}">
|
||||
<h2>Lecture du moment :</h2>
|
||||
<h3>{{ .Title }}</h3>
|
||||
<div class="excerpt">
|
||||
<div class="excerpt-text">
|
||||
<small>{{ .Date.Format "January 2, 2006" }}</small>
|
||||
<p>{{ .Plain | plainify | truncate 100 }}</p>
|
||||
</div>
|
||||
<img src="{{ $optimizedImage.RelPermalink }}" alt="{{ .Title }} cover image"></img>
|
||||
</div>
|
||||
</a>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ partial "buttons.html"}}
|
||||
{{ partialCached "footer.html" . .Layout .Kind (.Param "hideFooter") (.Param "ShowCodeCopyButtons") -}}
|
||||
</div>
|
||||
<div class="side-screen">
|
||||
{{ partial "posts-defile.html" (dict "context" . "direction" "down") }}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<footer>
|
||||
<!-- Script to toggle theme. has to be at the end of the page -->
|
||||
{{- if (not site.Params.disableThemeToggle) }}
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const themeToggleButton = document.getElementById("theme-toggle");
|
||||
if (themeToggleButton) {
|
||||
themeToggleButton.addEventListener("click", () => {
|
||||
if (document.body.className.includes("dark")) {
|
||||
document.body.classList.remove('dark');
|
||||
localStorage.setItem("pref-theme", 'light');
|
||||
} else {
|
||||
document.body.classList.add('dark');
|
||||
localStorage.setItem("pref-theme", 'dark');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error("Theme toggle button not found");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
const observer = new MutationObserver(() => {
|
||||
const themeToggleButton = document.getElementById("theme-toggle");
|
||||
if (themeToggleButton) {
|
||||
observer.disconnect(); // Stop observing once the button is found. Explanation :
|
||||
/*
|
||||
the .theme-toggle button is being rendered dynamically (e.g., via a Hugo partial or JavaScript),
|
||||
so it might not exist in the DOM when the script runs.
|
||||
To handle this, you can use a MutationObserver to detect when the button is added to the DOM
|
||||
*/
|
||||
themeToggleButton.addEventListener("click", () => {
|
||||
if (document.body.className.includes("dark")) {
|
||||
document.body.classList.remove('dark');
|
||||
localStorage.setItem("pref-theme", 'light');
|
||||
} else {
|
||||
document.body.classList.add('dark');
|
||||
localStorage.setItem("pref-theme", 'dark');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
</script>
|
||||
{{- end }}
|
||||
</footer>
|
||||
|
||||
</html>
|
2
layouts/partials/anchored_headings.html
Executable file
2
layouts/partials/anchored_headings.html
Executable file
|
@ -0,0 +1,2 @@
|
|||
{{- /* formats .Content headings by adding an anchor */ -}}
|
||||
{{ . | replaceRE "(<h[1-6] id=\"([^\"]+)\".+)(</h[1-6]+>)" "${1}<a hidden class=\"anchor\" aria-hidden=\"true\" href=\"#${2}\">#</a>${3}" | safeHTML }}
|
9
layouts/partials/author.html
Executable file
9
layouts/partials/author.html
Executable file
|
@ -0,0 +1,9 @@
|
|||
{{- if or .Params.author site.Params.author }}
|
||||
{{- $author := (.Params.author | default site.Params.author) }}
|
||||
{{- $author_type := (printf "%T" $author) }}
|
||||
{{- if (or (eq $author_type "[]string") (eq $author_type "[]interface {}")) }}
|
||||
{{- (delimit $author ", " ) }}
|
||||
{{- else }}
|
||||
{{- $author }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
19
layouts/partials/breadcrumbs.html
Executable file
19
layouts/partials/breadcrumbs.html
Executable file
|
@ -0,0 +1,19 @@
|
|||
{{- if (.Param "ShowBreadCrumbs") -}}
|
||||
<div class="breadcrumbs">
|
||||
{{- $url := replace .Parent.Permalink (printf "%s" site.Home.Permalink) "" }}
|
||||
{{- $lang_url := strings.TrimPrefix (printf "%s/" .Lang) $url -}}
|
||||
|
||||
<a href="{{ "" | absLangURL }}">{{ i18n "home" | default "Home" }}</a>
|
||||
{{- $scratch := newScratch }}
|
||||
{{- range $index, $element := split $lang_url "/" }}
|
||||
|
||||
{{- $scratch.Add "path" (printf "%s/" $element )}}
|
||||
{{- $bc_pg := site.GetPage ($scratch.Get "path") -}}
|
||||
|
||||
{{- if (and ($bc_pg) (gt (len . ) 0))}}
|
||||
{{- print " » " | safeHTML -}}<a href="{{ $bc_pg.Permalink }}">{{ $bc_pg.Name }}</a>
|
||||
{{- end }}
|
||||
|
||||
{{- end -}}
|
||||
</div>
|
||||
{{- end -}}
|
34
layouts/partials/buttons.html
Executable file
34
layouts/partials/buttons.html
Executable file
|
@ -0,0 +1,34 @@
|
|||
<style>
|
||||
.buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
max-width: 100vw; /* Make the container as wide as the viewport */
|
||||
gap: 3px;
|
||||
margin: 20px 0 0 0; /* Remove any default margin */
|
||||
padding: 0; /* Remove any default padding */
|
||||
}
|
||||
.button {
|
||||
display: inline-block;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
background: none;
|
||||
image-rendering: auto;
|
||||
image-rendering: crisp-edges;
|
||||
image-rendering: pixelated;
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="buttons"> <!-- https://88x31.nl/ -->
|
||||
<a href="https://www.mozilla.org/fr/firefox/new/"> <img class="button" src="/buttons/firefox-now.png" alt="Bouton Firefox" title="Ils ont été vilains tho"/></a>
|
||||
<a href="https://www.blender.org/download/"> <img class="button" src="/buttons/get-blender-2.8.png" alt="Bouton Blender" title="Je connais les raccourcis clavier"/></a>
|
||||
<a href="https://xkcd.com/1179/"> <img class="button" src="/buttons/iso-8601.png" alt="Bouton ISO 8601" title="Par pitié, tout le monde pareil"/></a>
|
||||
<a href="https://notepad-plus-plus.org/"> <img class="button" src="/buttons/made-with-notepad++.png" alt="Bouton Notepad++" title="Je veux le même pour Linux"/></a>
|
||||
<a href="https://polymc.org/"> <img class="button" src="/buttons/minecraft.png" alt="Bouton Minecraft" title="Tfarcenim TMTC"/></a>
|
||||
<a href="https://teegarten-miniatures.ch/"> <img class="button" src="/buttons/tea-powered.png" alt="Bouton Tea Powered" title="Nan vraiment, j'aime bien le thé"/></a>
|
||||
<a href="https://ubuntu.com/download"> <img class="button" src="/buttons/ubuntu.png" alt="Bouton Ubuntu" title="Ce site vous est servi depuis Ubuntu"/></a>
|
||||
<a href="https://www.linuxmint.com/"> <img class="button" src="/buttons/devOnMintGreen.png" alt="Bouton Linux Mint" title="Ce site a été développé sur Linux Mint"/></a>
|
||||
</div>
|
0
layouts/partials/comments.html
Executable file
0
layouts/partials/comments.html
Executable file
65
layouts/partials/cover.html
Executable file
65
layouts/partials/cover.html
Executable file
|
@ -0,0 +1,65 @@
|
|||
{{- with .cxt}} {{/* Apply proper context from dict */}}
|
||||
{{- if (and .Params.cover.image (not $.isHidden)) }}
|
||||
<figure class="entry-cover">
|
||||
{{- $loading := cond $.IsSingle "eager" "lazy" }}
|
||||
{{- $addLink := (and site.Params.cover.linkFullImages $.IsSingle) }}
|
||||
{{- $prod := (hugo.IsProduction | or (eq site.Params.env "production")) }}
|
||||
{{- $alt := (.Params.cover.alt | default .Params.cover.caption | plainify) }}
|
||||
{{- $responsiveImages := (.Params.cover.responsiveImages | default site.Params.cover.responsiveImages) | default true }}
|
||||
|
||||
{{- $pageBundleCover := (.Resources.ByType "image").GetMatch (printf "*%s*" (.Params.cover.image)) }}
|
||||
{{- $globalResourcesCover := (resources.ByType "image").GetMatch (printf "*%s*" (.Params.cover.image)) }}
|
||||
{{- $cover := (or $pageBundleCover $globalResourcesCover)}}
|
||||
{{- /* We are not using the .Param.cover.relative to decide the location of image */}}
|
||||
{{- /* If we have the image in pageBundle or globalResources we can process the image */}}
|
||||
|
||||
{{- $sizes := (slice "360" "480" "720" "1080" "1500") }}
|
||||
{{- $processableFormats := (slice "jpg" "jpeg" "png" "tif" "bmp" "gif") -}}
|
||||
{{- if hugo.IsExtended -}}
|
||||
{{- $processableFormats = $processableFormats | append "webp" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $imgdl := (.Params.cover.image) | absURL }}
|
||||
{{- if $cover -}}
|
||||
{{- $imgdl = $cover.Permalink }}
|
||||
{{- end -}}
|
||||
|
||||
{{- if $addLink }}
|
||||
<a href="{{ $imgdl }}" target="_blank" rel="noopener noreferrer">
|
||||
{{- end }}
|
||||
|
||||
{{- if $cover -}}
|
||||
{{/* i.e it is present in page bundle */}}
|
||||
{{- if (and (in $processableFormats $cover.MediaType.SubType) ($responsiveImages) (eq $prod true)) }}
|
||||
<img loading="{{$loading}}"
|
||||
srcset='{{- range $size := $sizes -}}
|
||||
{{- if (ge $cover.Width $size) }}
|
||||
{{- printf "%s %s" (($cover.Resize (printf "%sx" $size)).Permalink) (printf "%sw," $size) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- printf "%s %dw" ($cover.Permalink) ($cover.Width) }}'
|
||||
src="{{ $cover.Permalink }}"
|
||||
sizes="(min-width: 768px) 720px, 100vw"
|
||||
width="{{ $cover.Width }}" height="{{ $cover.Height }}"
|
||||
alt="{{ $alt }}">
|
||||
{{- else }}{{/* Unprocessable image or responsive images disabled */}}
|
||||
<img loading="{{ $loading }}" src="{{ $imgdl }}" alt="{{ $alt }}">
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- /* For absolute urls and external links, no img processing here */}}
|
||||
<img loading="{{ $loading }}" src="{{ $imgdl }}" alt="{{ $alt }}">
|
||||
{{- end }}
|
||||
|
||||
{{- if $addLink }}
|
||||
</a>
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Display Caption */}}
|
||||
{{- if $.IsSingle }}
|
||||
{{ with .Params.cover.caption -}}
|
||||
<figcaption>{{ . | markdownify }}</figcaption>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</figure>
|
||||
{{- end }}{{/* End image */}}
|
||||
{{- end -}}{{/* End context */ -}}
|
28
layouts/partials/donnees-chargement.html
Executable file
28
layouts/partials/donnees-chargement.html
Executable file
|
@ -0,0 +1,28 @@
|
|||
<!--
|
||||
Code volé chez lucien
|
||||
https://git.shenanigans.cc/globuzma/blog/commit/695e63b275ca03ec53a099d68f274c9466d0539f
|
||||
-->
|
||||
|
||||
<span class="small-text" id="data-used">0kB chargés</span>
|
||||
<script>
|
||||
window.addEventListener('load', function () {
|
||||
let totalTransferSize = 0;
|
||||
|
||||
performance.getEntriesByType('resource').map((resource) => {
|
||||
const data = resource.toJSON();
|
||||
totalTransferSize += data.transferSize;
|
||||
});
|
||||
|
||||
console.log((totalTransferSize / 1024)/1024)
|
||||
console.log(totalTransferSize/(1024*1024))
|
||||
|
||||
sizeString = totalTransferSize + "B"
|
||||
if( totalTransferSize / (1024*1024) > 1) {
|
||||
sizeString = Math.round(100*totalTransferSize/(1024*1024))/100 + "MB"
|
||||
} else if (totalTransferSize / 1024 > 1) {
|
||||
sizeString = Math.round(100*totalTransferSize / 1024)/100 + "kB"
|
||||
}
|
||||
|
||||
document.getElementById("data-used").innerHTML = "<em>" + sizeString + "</em> chargés"
|
||||
})
|
||||
</script>
|
8
layouts/partials/edit_post.html
Executable file
8
layouts/partials/edit_post.html
Executable file
|
@ -0,0 +1,8 @@
|
|||
{{- if and (or .Params.editPost.URL site.Params.editPost.URL) (not (.Param "editPost.disabled")) -}}
|
||||
{{- $fileUrlPath := path.Join .File.Path }}
|
||||
|
||||
{{- if or .Params.author site.Params.author (.Param "ShowReadingTime") (not .Date.IsZero) .IsTranslated }} | {{- end -}}
|
||||
<a href="{{ .Params.editPost.URL | default site.Params.editPost.URL }}{{ if .Params.editPost.appendFilePath | default ( site.Params.editPost.appendFilePath | default false ) }}/{{ $fileUrlPath }}{{ end }}" rel="noopener noreferrer" target="_blank">
|
||||
{{- .Params.editPost.Text | default (site.Params.editPost.Text | default (i18n "edit_post" | default "Edit")) -}}
|
||||
</a>
|
||||
{{- end }}
|
106
layouts/partials/encadre-livre.html
Executable file
106
layouts/partials/encadre-livre.html
Executable file
|
@ -0,0 +1,106 @@
|
|||
<!-- Pour montrer des infos sur le livre sur la page -->
|
||||
|
||||
<style>
|
||||
.encadre-livre {
|
||||
width: 300px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ccc;
|
||||
float: right;
|
||||
margin-left: 20px;
|
||||
clear: right;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
.encadre-livre .title {
|
||||
text-align: center;
|
||||
margin: 0 0 20px 0;
|
||||
}
|
||||
.encadre-livre figure img {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
{{ $specs := .Page.Params.BookData }}
|
||||
{{ if $specs }}
|
||||
<div class="encadre-livre">
|
||||
<h3 class="title">{{$specs.title}}</h3>
|
||||
<figure>
|
||||
{{- if $specs.cover -}}
|
||||
<!-- First try to get the image as a page resource (for page bundles) -->
|
||||
{{- $coverResource := .Page.Resources.GetMatch $specs.cover -}}
|
||||
{{- if not $coverResource -}}
|
||||
<!-- If not found in page resources, try the global assets directory -->
|
||||
{{- $coverResource = resources.Get $specs.cover -}}
|
||||
{{- end -}}
|
||||
{{- if $coverResource -}}
|
||||
{{- $thumbCover := $coverResource.Fit "200x200 webp q85" -}}
|
||||
<img src="{{ $thumbCover.RelPermalink }}" alt="1ère de couverture de {{ $specs.title }} par {{ $specs.author }}">
|
||||
{{- else -}}
|
||||
<!-- Cover resource not found anywhere -->
|
||||
<div class="error">Image non trouvée : {{ $specs.cover }}</div>
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
<!-- No cover specified in frontmatter -->
|
||||
<div class="error">No cover image specified</div>
|
||||
{{- end -}}
|
||||
</figure>
|
||||
<table>
|
||||
<tbody>
|
||||
{{ if $specs.publishDate }}
|
||||
<tr>
|
||||
<th>Date de publication</th>
|
||||
<td>{{ $specs.publishDate }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
|
||||
{{ if $specs.author }}
|
||||
<tr>
|
||||
<th>Auteur</th>
|
||||
<td>{{ $specs.author }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
|
||||
{{ if $specs.ISBN }}
|
||||
<tr>
|
||||
<th>ISBN</th>
|
||||
<td>{{ $specs.ISBN }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
|
||||
{{ if $specs.worldCat }}
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<a href="{{ $specs.worldCat }}">Lien WorldCat</a>
|
||||
</th>
|
||||
</tr>
|
||||
{{ end }}
|
||||
|
||||
{{ if $specs.starGrade }}
|
||||
<tr>
|
||||
<th>Note perso</th>
|
||||
<td>
|
||||
{{ range seq 1 $specs.starGrade }}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 441" width="16px" height="16px">
|
||||
<path d="M 48 261 L 228 430 L 48 261 L 228 430 Q 240 441 256 441 Q 272 441 284 430 L 464 261 L 464 261 Q 511 217 512 152 L 512 146 L 512 146 Q 511 92 478 54 Q 445 15 393 5 Q 358 0 325 10 Q 293 20 268 45 L 256 57 L 256 57 L 244 45 L 244 45 Q 219 20 187 10 Q 154 0 119 5 Q 67 15 34 54 Q 1 92 0 146 L 0 152 L 0 152 Q 1 217 48 261 L 48 261 Z" />
|
||||
</svg>
|
||||
{{ end }}
|
||||
{{ if ne $specs.starGrade 5 }}
|
||||
{{ range seq 1 (sub 5 $specs.starGrade) }}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 445" width="16px" height="16px">
|
||||
<path d="M 226 433 L 223 431 L 226 433 L 223 431 L 48 268 L 48 268 Q 1 223 0 158 L 0 155 L 0 155 Q 1 101 34 61 Q 66 22 119 11 Q 181 0 231 35 Q 245 44 256 57 Q 262 50 270 44 Q 275 39 281 35 Q 281 35 281 35 Q 281 35 281 35 Q 331 0 393 10 Q 446 21 478 61 Q 511 101 512 155 L 512 158 L 512 158 Q 511 223 464 268 L 289 431 L 289 431 L 286 433 L 286 433 Q 273 445 256 445 Q 239 445 226 433 L 226 433 Z M 239 110 Q 239 110 238 109 L 238 109 L 238 109 Q 238 109 238 109 L 220 89 L 220 89 L 220 89 L 220 89 Q 220 89 220 89 Q 202 69 178 61 Q 154 53 128 58 Q 93 65 71 92 Q 49 118 48 155 L 48 158 L 48 158 Q 49 202 81 233 L 256 396 L 256 396 L 431 233 L 431 233 Q 463 202 464 158 L 464 155 L 464 155 Q 463 118 441 92 Q 419 65 384 58 Q 358 53 334 61 Q 310 69 292 89 Q 292 89 292 89 Q 292 89 292 89 L 274 109 L 274 109 Q 274 109 273 110 Q 273 110 273 110 Q 266 117 256 117 Q 246 117 239 110 L 239 110 Z" />
|
||||
</svg>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ else }}
|
||||
<div class="notice warning">
|
||||
<p>Pas d'informations trouvées :(</p>
|
||||
</div>
|
||||
{{ end }}
|
108
layouts/partials/encadre-maec.html
Executable file
108
layouts/partials/encadre-maec.html
Executable file
|
@ -0,0 +1,108 @@
|
|||
<!-- Pour montrer des infos sur la machine sur la page -->
|
||||
|
||||
<style>
|
||||
.encadre-maec {
|
||||
width: 300px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ccc;
|
||||
float: right;
|
||||
margin-left: 20px;
|
||||
clear: right;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
.encadre-maec .title {
|
||||
text-align: center;
|
||||
margin: 0 0 20px 0;
|
||||
}
|
||||
.encadre-maec figure img {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
</style>
|
||||
{{ $specs := .Page.Params.machineSpecs }}
|
||||
|
||||
{{ if $specs }}
|
||||
<div class="encadre-maec">
|
||||
<h3 class="title">{{$specs.make}} {{$specs.model}}</h3>
|
||||
|
||||
<figure>
|
||||
{{- if $specs.image -}}
|
||||
<!-- First try to get the image as a page resource (for page bundles) -->
|
||||
{{- $imageResource := .Page.Resources.GetMatch $specs.image -}}
|
||||
{{- if not $imageResource -}}
|
||||
<!-- If not found in page resources, try the global assets directory -->
|
||||
{{- $imageResource = resources.Get $specs.image -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if $imageResource -}}
|
||||
{{- $thumbimage := $imageResource.Fit "200x200 webp q85" -}}
|
||||
<img src="{{ $thumbimage.RelPermalink }}" alt="1ère de couverture de {{ $specs.title }} par {{ $specs.author }}">
|
||||
{{- else -}}
|
||||
<!-- image resource not found anywhere -->
|
||||
<div class="error">Image non trouvée : {{ $specs.image }}</div>
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
<!-- No image specified in frontmatter -->
|
||||
<div class="error">No image image specified</div>
|
||||
{{- end -}}
|
||||
</figure>
|
||||
<table>
|
||||
<tbody>
|
||||
{{ if $specs.make }}
|
||||
<tr>
|
||||
<th>Marque</th>
|
||||
<td>{{ $specs.make }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ if $specs.model }}
|
||||
<tr>
|
||||
<th>Modèle</th>
|
||||
<td>{{ $specs.model }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ if $specs.type }}
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<td>{{ $specs.type }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ if $specs.dateManufactured }}
|
||||
<tr>
|
||||
<th>Date de fabrication</th>
|
||||
<td>{{ $specs.dateManufactured }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ if $specs.massKg }}
|
||||
<tr>
|
||||
<th>Masse</th>
|
||||
<td>{{ $specs.massKg }} kg</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ if $specs.widthCm }}
|
||||
<tr>
|
||||
<th>Largeur</th>
|
||||
<td>{{ $specs.widthCm }} cm</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ if $specs.serialNumber }}
|
||||
<tr>
|
||||
<th>N° de série</th>
|
||||
<td>{{ $specs.serialNumber }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ if $specs.linkTpdb }}
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<a href="{{ $specs.linkTpdb }}">Typewriter Database</a>
|
||||
</th>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ else }}
|
||||
<div class="notice warning">
|
||||
<p>Pas d'informations trouvées :(</p>
|
||||
</div>
|
||||
{{ end }}
|
3
layouts/partials/extend_footer.html
Executable file
3
layouts/partials/extend_footer.html
Executable file
|
@ -0,0 +1,3 @@
|
|||
{{- /* Footer custom content area start */ -}}
|
||||
{{- /* Insert any custom code web-analytics, resources, etc. here */ -}}
|
||||
{{- /* Footer custom content area end */ -}}
|
4
layouts/partials/extend_head.html
Executable file
4
layouts/partials/extend_head.html
Executable file
|
@ -0,0 +1,4 @@
|
|||
{{- /* Head custom content area start */ -}}
|
||||
{{- /* Insert any custom code (web-analytics, resources, etc.) - it will appear in the <head></head> section of every page. */ -}}
|
||||
{{- /* Can be overwritten by partial with the same name in the global layouts. */ -}}
|
||||
{{- /* Head custom content area end */ -}}
|
185
layouts/partials/footer.html
Executable file
185
layouts/partials/footer.html
Executable file
|
@ -0,0 +1,185 @@
|
|||
{{- if not (.Param "hideFooter") }}
|
||||
<footer class="footer">
|
||||
{{- if not site.Params.footer.hideCopyright }}
|
||||
{{- if site.Copyright }}
|
||||
<span>{{ site.Copyright | markdownify }}</span>
|
||||
{{- else }}
|
||||
<span>© {{ now.Year }} <a href="{{ "" | absLangURL }}">{{ site.Title }}</a></span>
|
||||
{{- end }}
|
||||
{{- print " · "}}
|
||||
{{- end }}
|
||||
|
||||
{{- with site.Params.footer.text }}
|
||||
{{ . | markdownify }}
|
||||
{{- print " · "}}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- partial "donnees-chargement.html" -}}
|
||||
|
||||
{{- print " · "}}
|
||||
<!-- Lord forgive me for I have sinned -->
|
||||
<style>
|
||||
.rss-icon path {
|
||||
stroke: var(--primary);
|
||||
}
|
||||
|
||||
.rss-link {
|
||||
color: var(--primary);
|
||||
}
|
||||
</style>
|
||||
<a href="/feed.xml" class="rss-link">
|
||||
<svg width="16px" height="16px" stroke-width="2" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" class="rss-icon">
|
||||
<path d="M12 19C12 14.8 9.2 12 5 12" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M19 19C19 10.6 13.4 5 5 5" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M5 19.01L5.01 18.9989" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
</svg>
|
||||
<span>Flux RSS</span>
|
||||
</a>
|
||||
|
||||
{{- print " · "}}
|
||||
|
||||
{{ with (readFile "data/gitinfo.txt") }}
|
||||
{{ $raw := . }}
|
||||
{{ $lines := slice }}
|
||||
{{ range split (replace $raw "\r\n" "\n") "\n" }}
|
||||
{{ if ne . "" }}
|
||||
{{ $lines = $lines | append . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ if ge (len $lines) 4 }}
|
||||
<span>
|
||||
Mis à jour le {{ index $lines 0 }} à {{ index $lines 1 }}
|
||||
</span>
|
||||
{{ else }}
|
||||
<span>Information de mise à jour non disponible</span>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<span>Fichier gitinfo non trouvé</span>
|
||||
{{ end }}
|
||||
|
||||
</footer>
|
||||
{{- end }}
|
||||
|
||||
{{- if (not site.Params.disableScrollToTop) }}
|
||||
<a href="#top" aria-label="go to top" title="Go to Top (Alt + G)" class="top-link" id="top-link" accesskey="g">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 6" fill="currentColor">
|
||||
<path d="M12 6H0l6-6z" />
|
||||
</svg>
|
||||
</a>
|
||||
{{- end }}
|
||||
|
||||
{{- partial "extend_footer.html" . }}
|
||||
|
||||
|
||||
<script>
|
||||
let menu = document.getElementById('menu')
|
||||
if (menu) {
|
||||
menu.scrollLeft = localStorage.getItem("menu-scroll-position");
|
||||
menu.onscroll = function () {
|
||||
localStorage.setItem("menu-scroll-position", menu.scrollLeft);
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
var id = this.getAttribute("href").substr(1);
|
||||
if (!window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||||
document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView({
|
||||
behavior: "smooth"
|
||||
});
|
||||
} else {
|
||||
document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView();
|
||||
}
|
||||
if (id === "top") {
|
||||
history.replaceState(null, null, " ");
|
||||
} else {
|
||||
history.pushState(null, null, `#${id}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
{{- if (not site.Params.disableScrollToTop) }}
|
||||
<script>
|
||||
var mybutton = document.getElementById("top-link");
|
||||
window.onscroll = function () {
|
||||
if (document.body.scrollTop > 800 || document.documentElement.scrollTop > 800) {
|
||||
mybutton.style.visibility = "visible";
|
||||
mybutton.style.opacity = "1";
|
||||
} else {
|
||||
mybutton.style.visibility = "hidden";
|
||||
mybutton.style.opacity = "0";
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
{{- end }}
|
||||
|
||||
{{- if (not site.Params.disableThemeToggle) }}
|
||||
<script>
|
||||
document.getElementById("theme-toggle").addEventListener("click", () => {
|
||||
if (document.body.className.includes("dark")) {
|
||||
document.body.classList.remove('dark');
|
||||
localStorage.setItem("pref-theme", 'light');
|
||||
} else {
|
||||
document.body.classList.add('dark');
|
||||
localStorage.setItem("pref-theme", 'dark');
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
{{- end }}
|
||||
|
||||
{{- if (and (eq .Kind "page") (ne .Layout "archives") (ne .Layout "search") (.Param "ShowCodeCopyButtons")) }}
|
||||
<script>
|
||||
document.querySelectorAll('pre > code').forEach((codeblock) => {
|
||||
const container = codeblock.parentNode.parentNode;
|
||||
|
||||
const copybutton = document.createElement('button');
|
||||
copybutton.classList.add('copy-code');
|
||||
copybutton.innerHTML = '{{- i18n "code_copy" | default "copy" }}';
|
||||
|
||||
function copyingDone() {
|
||||
copybutton.innerHTML = '{{- i18n "code_copied" | default "copied!" }}';
|
||||
setTimeout(() => {
|
||||
copybutton.innerHTML = '{{- i18n "code_copy" | default "copy" }}';
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
copybutton.addEventListener('click', (cb) => {
|
||||
if ('clipboard' in navigator) {
|
||||
navigator.clipboard.writeText(codeblock.textContent);
|
||||
copyingDone();
|
||||
return;
|
||||
}
|
||||
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(codeblock);
|
||||
const selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
copyingDone();
|
||||
} catch (e) { };
|
||||
selection.removeRange(range);
|
||||
});
|
||||
|
||||
if (container.classList.contains("highlight")) {
|
||||
container.appendChild(copybutton);
|
||||
} else if (container.parentNode.firstChild == container) {
|
||||
// td containing LineNos
|
||||
} else if (codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName == "TABLE") {
|
||||
// table containing LineNos and code
|
||||
codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(copybutton);
|
||||
} else {
|
||||
// code blocks not having highlight as parent class
|
||||
codeblock.parentNode.appendChild(copybutton);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{{- end }}
|
155
layouts/partials/head.html
Executable file
155
layouts/partials/head.html
Executable file
|
@ -0,0 +1,155 @@
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
{{- if hugo.IsProduction | or (eq site.Params.env "production") | and (ne .Params.robotsNoIndex true) }}
|
||||
<meta name="robots" content="index, follow">
|
||||
{{- else }}
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
{{- end }}
|
||||
|
||||
{{- /* Title */}}
|
||||
<title>{{ if .IsHome }}{{ else }}{{ if .Title }}{{ .Title }} | {{ end }}{{ end }}{{ site.Title }}</title>
|
||||
|
||||
{{- /* Meta */}}
|
||||
{{- if .IsHome }}
|
||||
{{ with site.Params.keywords -}}<meta name="keywords" content="{{- range $i, $e := . }}{{ if $i }}, {{ end }}{{ $e }}{{ end }}">{{ end }}
|
||||
{{- else }}
|
||||
<meta name="keywords" content="{{ if .Params.keywords -}}
|
||||
{{- range $i, $e := .Params.keywords }}{{ if $i }}, {{ end }}{{ $e }}{{ end }} {{- else }}
|
||||
{{- range $i, $e := .Params.tags }}{{ if $i }}, {{ end }}{{ $e }}{{ end }} {{- end -}}">
|
||||
{{- end }}
|
||||
<meta name="description" content="{{- with .Description }}{{ . }}{{- else }}{{- if or .IsPage .IsSection}}
|
||||
{{- .Summary | default (printf "%s - %s" .Title site.Title) }}{{- else }}
|
||||
{{- with site.Params.description }}{{ . }}{{- end }}{{- end }}{{- end -}}">
|
||||
<meta name="author" content="{{ (partial "author.html" . ) }}">
|
||||
<link rel="canonical" href="{{ if .Params.canonicalURL -}} {{ trim .Params.canonicalURL " " }} {{- else -}} {{ .Permalink }} {{- end }}">
|
||||
{{- if site.Params.analytics.google.SiteVerificationTag }}
|
||||
<meta name="google-site-verification" content="{{ site.Params.analytics.google.SiteVerificationTag }}">
|
||||
{{- end }}
|
||||
{{- if site.Params.analytics.yandex.SiteVerificationTag }}
|
||||
<meta name="yandex-verification" content="{{ site.Params.analytics.yandex.SiteVerificationTag }}">
|
||||
{{- end }}
|
||||
{{- if site.Params.analytics.bing.SiteVerificationTag }}
|
||||
<meta name="msvalidate.01" content="{{ site.Params.analytics.bing.SiteVerificationTag }}">
|
||||
{{- end }}
|
||||
{{- if site.Params.analytics.naver.SiteVerificationTag }}
|
||||
<meta name="naver-site-verification" content="{{ site.Params.analytics.naver.SiteVerificationTag }}">
|
||||
{{- end }}
|
||||
|
||||
{{- /* Styles */}}
|
||||
|
||||
{{- /* includes */}}
|
||||
{{- $includes := slice }}
|
||||
{{- $includes = $includes | append (" " | resources.FromString "includes-blank.css")}}
|
||||
|
||||
{{- if not (eq site.Params.assets.disableScrollBarStyle true) }}
|
||||
{{- $ScrollStyle := (resources.Get "css/includes/scroll-bar.css") }}
|
||||
{{- $includes = (append $ScrollStyle $includes) }}
|
||||
{{- end }}
|
||||
|
||||
{{- $includes_all := $includes | resources.Concat "includes.css" }}
|
||||
|
||||
{{- $theme_vars := (resources.Get "css/core/theme-vars.css") }}
|
||||
{{- $reset := (resources.Get "css/core/reset.css") }}
|
||||
{{- $media := (resources.Get "css/core/zmedia.css") }}
|
||||
{{- $common := (resources.Match "css/common/*.css") | resources.Concat "common.css" }}
|
||||
|
||||
{{- /* markup.highlight.noClasses should be set to `false` */}}
|
||||
{{- $chroma_styles := (resources.Get "css/includes/chroma-styles.css") }}
|
||||
{{- $chroma_mod := (resources.Get "css/includes/chroma-mod.css") }}
|
||||
|
||||
{{- /* order is important */}}
|
||||
{{- $core := (slice $theme_vars $reset $common $chroma_styles $chroma_mod $includes_all $media) | resources.Concat "core.css" | resources.Minify }}
|
||||
{{- $extended := (resources.Match "css/extended/*.css") | resources.Concat "extended.css" | resources.Minify }}
|
||||
|
||||
{{- /* bundle all required css */}}
|
||||
{{- /* Add extended css after theme style */ -}}
|
||||
{{- $stylesheet := (slice $core $extended) | resources.Concat "stylesheet.css" }}
|
||||
|
||||
{{- if not site.Params.assets.disableFingerprinting }}
|
||||
{{- $stylesheet := $stylesheet | fingerprint }}
|
||||
<link crossorigin="anonymous" href="{{ $stylesheet.RelPermalink }}" integrity="{{ $stylesheet.Data.Integrity }}" rel="preload stylesheet" as="style">
|
||||
{{- else }}
|
||||
<link crossorigin="anonymous" href="{{ $stylesheet.RelPermalink }}" rel="preload stylesheet" as="style">
|
||||
{{- end }}
|
||||
|
||||
{{- /* Search */}}
|
||||
{{- if (eq .Layout `search`) -}}
|
||||
<link crossorigin="anonymous" rel="preload" as="fetch" href="../index.json">
|
||||
{{- $fastsearch := resources.Get "js/fastsearch.js" | js.Build (dict "params" (dict "fuseOpts" site.Params.fuseOpts)) | resources.Minify }}
|
||||
{{- $fusejs := resources.Get "js/fuse.basic.min.js" }}
|
||||
{{- if not site.Params.assets.disableFingerprinting }}
|
||||
{{- $search := (slice $fusejs $fastsearch ) | resources.Concat "search.js" | fingerprint }}
|
||||
<script defer crossorigin="anonymous" src="{{ $search.RelPermalink }}" integrity="{{ $search.Data.Integrity }}"></script>
|
||||
{{- else }}
|
||||
{{- $search := (slice $fusejs $fastsearch ) | resources.Concat "search.js" }}
|
||||
<script defer crossorigin="anonymous" src="{{ $search.RelPermalink }}"></script>
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Favicons */}}
|
||||
<link rel="icon" href="{{ site.Params.assets.favicon | default "favicon.ico" | absURL }}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{{ site.Params.assets.favicon16x16 | default "favicon-16x16.png" | absURL }}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{{ site.Params.assets.favicon32x32 | default "favicon-32x32.png" | absURL }}">
|
||||
<link rel="apple-touch-icon" href="{{ site.Params.assets.apple_touch_icon | default "apple-touch-icon.png" | absURL }}">
|
||||
<link rel="mask-icon" href="{{ site.Params.assets.safari_pinned_tab | default "safari-pinned-tab.svg" | absURL }}">
|
||||
<meta name="theme-color" content="{{ site.Params.assets.theme_color | default "#2e2e33" }}">
|
||||
<meta name="msapplication-TileColor" content="{{ site.Params.assets.msapplication_TileColor | default "#2e2e33" }}">
|
||||
|
||||
{{- /* RSS */}}
|
||||
{{ range .AlternativeOutputFormats -}}
|
||||
<link rel="{{ .Rel }}" type="{{ .MediaType.Type | html }}" href="{{ .Permalink | safeURL }}">
|
||||
{{ end -}}
|
||||
{{- range .AllTranslations -}}
|
||||
<link rel="alternate" hreflang="{{ .Lang }}" href="{{ .Permalink }}">
|
||||
{{ end -}}
|
||||
|
||||
<noscript>
|
||||
<style>
|
||||
#theme-toggle,
|
||||
.top-link {
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
{{- if (and (ne site.Params.defaultTheme "light") (ne site.Params.defaultTheme "dark")) }}
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--theme: rgb(29, 30, 32);
|
||||
--entry: rgb(46, 46, 51);
|
||||
--primary: rgb(218, 218, 219);
|
||||
--secondary: rgb(155, 156, 157);
|
||||
--tertiary: rgb(65, 66, 68);
|
||||
--content: rgb(196, 196, 197);
|
||||
--code-block-bg: rgb(46, 46, 51);
|
||||
--code-bg: rgb(55, 56, 62);
|
||||
--border: rgb(51, 51, 51);
|
||||
}
|
||||
|
||||
.list {
|
||||
background: var(--theme);
|
||||
}
|
||||
|
||||
.list:not(.dark)::-webkit-scrollbar-track {
|
||||
background: 0 0;
|
||||
}
|
||||
|
||||
.list:not(.dark)::-webkit-scrollbar-thumb {
|
||||
border-color: var(--theme);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
{{- end }}
|
||||
</noscript>
|
||||
|
||||
{{- partial "extend_head.html" . -}}
|
||||
|
||||
{{- /* Misc */}}
|
||||
{{- if hugo.IsProduction | or (eq site.Params.env "production") }}
|
||||
{{- template "_internal/google_analytics.html" . }}
|
||||
{{- template "partials/templates/opengraph.html" . }}
|
||||
{{- template "partials/templates/twitter_cards.html" . }}
|
||||
{{- template "partials/templates/schema_json.html" . }}
|
||||
{{- end -}}
|
121
layouts/partials/header.html
Executable file
121
layouts/partials/header.html
Executable file
|
@ -0,0 +1,121 @@
|
|||
{{- /* theme-toggle is enabled */}}
|
||||
{{- if (not site.Params.disableThemeToggle) }}
|
||||
{{- /* theme is light */}}
|
||||
{{- if (eq site.Params.defaultTheme "light") }}
|
||||
<script>
|
||||
if (localStorage.getItem("pref-theme") === "dark") {
|
||||
document.body.classList.add('dark');
|
||||
}
|
||||
|
||||
</script>
|
||||
{{- /* theme is dark */}}
|
||||
{{- else if (eq site.Params.defaultTheme "dark") }}
|
||||
<script>
|
||||
if (localStorage.getItem("pref-theme") === "light") {
|
||||
document.body.classList.remove('dark')
|
||||
}
|
||||
|
||||
</script>
|
||||
{{- else }}
|
||||
{{- /* theme is auto */}}
|
||||
<script>
|
||||
if (localStorage.getItem("pref-theme") === "dark") {
|
||||
document.body.classList.add('dark');
|
||||
} else if (localStorage.getItem("pref-theme") === "light") {
|
||||
document.body.classList.remove('dark')
|
||||
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
document.body.classList.add('dark');
|
||||
}
|
||||
|
||||
</script>
|
||||
{{- end }}
|
||||
{{- /* theme-toggle is disabled and theme is auto */}}
|
||||
{{- else if (and (ne site.Params.defaultTheme "light") (ne site.Params.defaultTheme "dark"))}}
|
||||
<script>
|
||||
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
document.body.classList.add('dark');
|
||||
}
|
||||
|
||||
</script>
|
||||
{{- end }}
|
||||
|
||||
{{- if (not site.Params.disableThemeToggle) }}
|
||||
<script>
|
||||
// Initialize all theme toggle buttons when the DOM is loaded
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const themeToggles = document.querySelectorAll('.theme-toggle-button');
|
||||
|
||||
themeToggles.forEach(function(button) {
|
||||
button.addEventListener('click', function() {
|
||||
if (document.body.classList.contains('dark')) {
|
||||
document.body.classList.remove('dark');
|
||||
localStorage.setItem("pref-theme", "light");
|
||||
} else {
|
||||
document.body.classList.add('dark');
|
||||
localStorage.setItem("pref-theme", "dark");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{{- end }}
|
||||
|
||||
<header class="header">
|
||||
<nav class="nav">
|
||||
<div class="logo">
|
||||
{{- $label_text := (site.Params.label.text | default site.Title) }}
|
||||
{{- if site.Title }}
|
||||
<a href="{{ "" | absLangURL }}" accesskey="h" title="{{ $label_text }} (Alt + H)">
|
||||
{{- if site.Params.label.icon }}
|
||||
{{- $img := resources.Get site.Params.label.icon }}
|
||||
{{- if $img }}
|
||||
{{- $processableFormats := (slice "jpg" "jpeg" "png" "tif" "bmp" "gif") -}}
|
||||
{{- if hugo.IsExtended -}}
|
||||
{{- $processableFormats = $processableFormats | append "webp" -}}
|
||||
{{- end -}}
|
||||
{{- $prod := (hugo.IsProduction | or (eq site.Params.env "production")) }}
|
||||
{{- if and (in $processableFormats $img.MediaType.SubType) (eq $prod true)}}
|
||||
{{- if site.Params.label.iconHeight }}
|
||||
{{- $img = $img.Resize (printf "x%d" site.Params.label.iconHeight) }}
|
||||
{{ else }}
|
||||
{{- $img = $img.Resize "x30" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
<img src="{{ $img.Permalink }}" alt="" aria-label="logo"
|
||||
height="{{- site.Params.label.iconHeight | default "30" -}}">
|
||||
{{- else }}
|
||||
<img src="{{- site.Params.label.icon | absURL -}}" alt="" aria-label="logo"
|
||||
height="{{- site.Params.label.iconHeight | default "30" -}}">
|
||||
{{- end -}}
|
||||
{{- else if hasPrefix site.Params.label.iconSVG "<svg" }}
|
||||
{{ site.Params.label.iconSVG | safeHTML }}
|
||||
{{- end -}}
|
||||
{{- $label_text -}}
|
||||
<img src="/favicon.svg" alt="favicon" class="site-logo">
|
||||
</a>
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- $currentPage := . }}
|
||||
<!-- Desktop menu -->
|
||||
<div class="menu-wrapper">
|
||||
{{ partial "menu.html" }}
|
||||
</div>
|
||||
|
||||
<!-- Hamburger Menu -->
|
||||
<!-- Icon -->
|
||||
<label for="menu-toggle" class="hamburger-menu" aria-label="Toggle menu">
|
||||
<img src="/icons/hamburger-menu.svg" alt="Menu" width="24" height="24">
|
||||
</label>
|
||||
<!-- Hidden checkbox for toggling menu -->
|
||||
<input type="checkbox" id="menu-toggle">
|
||||
<!-- Menu overlay -->
|
||||
<div class="menu-overlay">
|
||||
<div class="mobile-menu">
|
||||
<label for="menu-toggle" class="mobile-menu-close" aria-label="Close menu">
|
||||
<img src="/icons/close-menu.svg" alt="Close Menu" width="24" height="24">
|
||||
</label>
|
||||
{{ partial "menu.html" }}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
13
layouts/partials/home_info.html
Executable file
13
layouts/partials/home_info.html
Executable file
|
@ -0,0 +1,13 @@
|
|||
{{- with site.Params.homeInfoParams }}
|
||||
<article class="first-entry home-info">
|
||||
<header class="entry-header">
|
||||
<h1>{{ .Title | markdownify }}</h1>
|
||||
</header>
|
||||
<div class="entry-content">
|
||||
{{ .Content | markdownify }}
|
||||
</div>
|
||||
<footer class="entry-footer">
|
||||
{{ partial "social_icons.html" (dict "align" site.Params.homeInfoParams.AlignSocialIconsTo) }}
|
||||
</footer>
|
||||
</article>
|
||||
{{- end -}}
|
58
layouts/partials/index_profile.html
Executable file
58
layouts/partials/index_profile.html
Executable file
|
@ -0,0 +1,58 @@
|
|||
<div class="profile">
|
||||
{{- with site.Params.profileMode }}
|
||||
<div class="profile_inner">
|
||||
{{- if .imageUrl -}}
|
||||
{{- $img := "" }}
|
||||
{{- if not (urls.Parse .imageUrl).IsAbs }}
|
||||
{{- $img = resources.Get .imageUrl }}
|
||||
{{- end }}
|
||||
{{- if $img }}
|
||||
{{- $processableFormats := (slice "jpg" "jpeg" "png" "tif" "bmp" "gif") -}}
|
||||
{{- if hugo.IsExtended -}}
|
||||
{{- $processableFormats = $processableFormats | append "webp" -}}
|
||||
{{- end -}}
|
||||
{{- $prod := (hugo.IsProduction | or (eq site.Params.env "production")) }}
|
||||
{{- if and (in $processableFormats $img.MediaType.SubType) (eq $prod true)}}
|
||||
{{- if (not (and (not .imageHeight) (not .imageWidth))) }}
|
||||
{{- $img = $img.Resize (printf "%dx%d" .imageWidth .imageHeight) }}
|
||||
{{- else if .imageHeight }}
|
||||
{{- $img = $img.Resize (printf "x%d" .imageHeight) }}
|
||||
{{ else if .imageWidth }}
|
||||
{{- $img = $img.Resize (printf "%dx" .imageWidth) }}
|
||||
{{ else }}
|
||||
{{- $img = $img.Resize "150x150" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
<img draggable="false" src="{{ $img.Permalink }}" alt="{{ .imageTitle | default "profile image" }}" title="{{ .imageTitle }}"
|
||||
height="{{ .imageHeight | default 150 }}" width="{{ .imageWidth | default 150 }}" />
|
||||
{{- else }}
|
||||
<img draggable="false" src="{{ .imageUrl | absURL }}" alt="{{ .imageTitle | default "profile image" }}" title="{{ .imageTitle }}"
|
||||
height="{{ .imageHeight | default 150 }}" width="{{ .imageWidth | default 150 }}" />
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
<h1>{{ .title | default site.Title | markdownify }}</h1>
|
||||
<span>{{ .subtitle | markdownify }}</span>
|
||||
{{- partial "social_icons.html" -}}
|
||||
|
||||
{{- with .buttons }}
|
||||
<div class="buttons">
|
||||
{{- range . }}
|
||||
<a class="button" href="{{ trim .url " " }}" rel="noopener" title="{{ .name }}">
|
||||
<span class="button-inner">
|
||||
{{ .name }}
|
||||
{{- if (findRE "://" .url) }}
|
||||
<svg fill="none" shape-rendering="geometricPrecision" stroke="currentColor" stroke-linecap="round"
|
||||
stroke-linejoin="round" stroke-width="2.5" viewBox="0 0 24 24" height="14" width="14">
|
||||
<path d="M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"></path>
|
||||
<path d="M15 3h6v6"></path>
|
||||
<path d="M10 14L21 3"></path>
|
||||
</svg>
|
||||
{{- end }}
|
||||
</span>
|
||||
</a>
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- end}}
|
||||
</div>
|
91
layouts/partials/menu.html
Executable file
91
layouts/partials/menu.html
Executable file
|
@ -0,0 +1,91 @@
|
|||
<ul class="menu">
|
||||
<li>
|
||||
<a href="/blog">
|
||||
<img class="icon" src="/icons/bulle.svg" alt="Blog">
|
||||
<span>Blog</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/collection">
|
||||
<img class="icon" src="/favicon.svg" alt="Machines">
|
||||
<span>Machines</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/livres">
|
||||
<img class="icon" src="/icons/livre.svg" alt="Lectures">
|
||||
<span>Lectures</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/liens">
|
||||
<img class="icon" src="/icons/lien.svg" alt="Liens">
|
||||
<span>Liens</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/a-propos">
|
||||
<img class="icon" src="/icons/a-propos.svg" alt="A propos">
|
||||
<span>A propos</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/contact">
|
||||
<img class="icon" src="/icons/lettre.svg" alt="Contact">
|
||||
<span>Contact</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/feed.xml">
|
||||
<img class="icon" src="/icons/rss.svg" alt="RSS">
|
||||
<span>RSS</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="logo-switches">
|
||||
{{- if (not site.Params.disableThemeToggle) }}
|
||||
<button class="theme-toggle-button" accesskey="t" title="(Alt + T)" aria-label="Toggle theme">
|
||||
<svg class="moon-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
|
||||
</svg>
|
||||
<svg class="sun-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="5"></circle>
|
||||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||||
</svg>
|
||||
</button>
|
||||
{{- end }}
|
||||
|
||||
{{- $lang := .Lang}}
|
||||
{{- with site.Home.Translations }}
|
||||
<ul class="lang-switch">
|
||||
{{- range . -}}
|
||||
{{- if ne $lang .Lang }}
|
||||
<li>
|
||||
<a href="{{- .Permalink -}}" title="{{ .Language.Params.languageAltTitle | default (.Language.LanguageName | emojify) | default (.Lang | title) }}"
|
||||
aria-label="{{ .Language.LanguageName | default (.Lang | title) }}">
|
||||
{{- if (and site.Params.displayFullLangName (.Language.LanguageName)) }}
|
||||
{{- .Language.LanguageName | emojify -}}
|
||||
{{- else }}
|
||||
{{- .Lang | title -}}
|
||||
{{- end -}}
|
||||
</a>
|
||||
</li>
|
||||
{{- end -}}
|
||||
{{- end}}
|
||||
</ul>
|
||||
{{- end }}
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
9
layouts/partials/post_canonical.html
Executable file
9
layouts/partials/post_canonical.html
Executable file
|
@ -0,0 +1,9 @@
|
|||
{{ if and (.Params.canonicalURL) (.Params.ShowCanonicalLink ) -}}
|
||||
{{ $url := urls.Parse .Params.canonicalURL }}
|
||||
|
||||
{{- if or .Params.author site.Params.author (.Param "ShowReadingTime") (not .Date.IsZero) .IsTranslated (or .Params.editPost.URL site.Params.editPost.URL) }} | {{- end -}}
|
||||
<span>
|
||||
{{- (site.Params.CanonicalLinkText | default .Params.CanonicalLinkText) | default "Originally published at" -}}
|
||||
<a href="{{ trim .Params.canonicalURL " " }}" title="{{ trim .Params.canonicalURL " " }}" target="_blank" rel="noopener noreferrer">{{ $url.Host }}</a>
|
||||
</span>
|
||||
{{- end }}
|
23
layouts/partials/post_meta.html
Executable file
23
layouts/partials/post_meta.html
Executable file
|
@ -0,0 +1,23 @@
|
|||
{{- $scratch := newScratch }}
|
||||
|
||||
{{- if not .Date.IsZero -}}
|
||||
{{- $scratch.Add "meta" (slice (printf "<span title='%s'>%s</span>" (.Date) (.Date | time.Format (default "January 2, 2006" site.Params.DateFormat)))) }}
|
||||
{{- end }}
|
||||
|
||||
{{- if (.Param "ShowReadingTime") -}}
|
||||
{{- $scratch.Add "meta" (slice (i18n "read_time" .ReadingTime | default (printf "%d min" .ReadingTime))) }}
|
||||
{{- end }}
|
||||
|
||||
{{- if (.Param "ShowWordCount") -}}
|
||||
{{- $scratch.Add "meta" (slice (i18n "words" .WordCount | default (printf "%d words" .WordCount))) }}
|
||||
{{- end }}
|
||||
|
||||
{{- if not (.Param "hideAuthor") -}}
|
||||
{{- with (partial "author.html" .) }}
|
||||
{{- $scratch.Add "meta" (slice .) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- with ($scratch.Get "meta") }}
|
||||
{{- delimit . " · " | safeHTML -}}
|
||||
{{- end -}}
|
19
layouts/partials/post_nav_links.html
Executable file
19
layouts/partials/post_nav_links.html
Executable file
|
@ -0,0 +1,19 @@
|
|||
{{- $pages := where site.RegularPages "Type" "in" site.Params.mainSections }}
|
||||
{{- if and (gt (len $pages) 1) (in $pages . ) }}
|
||||
<nav class="paginav">
|
||||
{{- with $pages.Next . }}
|
||||
<a class="prev" href="{{ .Permalink }}">
|
||||
<span class="title">« {{ i18n "prev_page" }}</span>
|
||||
<br>
|
||||
<span>{{- .Name -}}</span>
|
||||
</a>
|
||||
{{- end }}
|
||||
{{- with $pages.Prev . }}
|
||||
<a class="next" href="{{ .Permalink }}">
|
||||
<span class="title">{{ i18n "next_page" }} »</span>
|
||||
<br>
|
||||
<span>{{- .Name -}}</span>
|
||||
</a>
|
||||
{{- end }}
|
||||
</nav>
|
||||
{{- end }}
|
141
layouts/partials/posts-defile.html
Executable file
141
layouts/partials/posts-defile.html
Executable file
|
@ -0,0 +1,141 @@
|
|||
{{ $direction := .direction | default "up" }}
|
||||
{{ $context := .context }}
|
||||
|
||||
<div class="scrolling-posts-container">
|
||||
|
||||
<div class="scrolling-posts-inner">
|
||||
|
||||
<div class="scrolling-posts {{ $direction }}-scroll">
|
||||
{{- $pages := first 20 (sort (where $context.Site.RegularPages "Section" "ne" "") "Date" "desc") -}}
|
||||
{{- range (sort $pages "Date" "desc") -}}
|
||||
|
||||
{{- $image := .Resources.GetMatch (printf "%s" .Params.cover.image) -}}
|
||||
{{- if $image -}}
|
||||
|
||||
{{- $fittedImage := $image.Fill "400x400 smart webp q95" -}}
|
||||
{{- $optimizedBlurredImage := $fittedImage.Filter (images.GaussianBlur 3) -}}
|
||||
<a href="{{ .RelPermalink }}" class="scrolling-posts-item" style="background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0.2)), url('{{ $optimizedBlurredImage.RelPermalink }}');">
|
||||
<span class="section-badge">{{ .Section }}</span>
|
||||
<span class="scrolling-posts-item-title">{{ .Title }}</span>
|
||||
<p class="scrolling-posts-date">{{ .Date.Format "2006-01-02" }}</p>
|
||||
</a>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
</div>
|
||||
|
||||
|
||||
<div class="scrolling-posts {{ $direction }}-scroll">
|
||||
{{- $pages := first 20 (sort (where $context.Site.RegularPages "Section" "ne" "") "Date" "desc") -}}
|
||||
{{- range (sort $pages "Date" "desc") -}}
|
||||
|
||||
{{- $image := .Resources.GetMatch (printf "%s" .Params.cover.image) -}}
|
||||
{{- if $image -}}
|
||||
|
||||
{{- $fittedImage := $image.Fill "400x400 smart webp q95" -}}
|
||||
{{- $optimizedBlurredImage := $fittedImage.Filter (images.GaussianBlur 3) -}}
|
||||
<a href="{{ .RelPermalink }}" class="scrolling-posts-item" style="background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0.2)), url('{{ $optimizedBlurredImage.RelPermalink }}');">
|
||||
<span class="section-badge">{{ .Section }}</span>
|
||||
<span class="scrolling-posts-item-title">{{ .Title }}</span>
|
||||
<p class="scrolling-posts-date">{{ .Date.Format "2006-01-02" }}</p>
|
||||
</a>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
.scrolling-posts-container {
|
||||
width: 100%;
|
||||
border: none;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.scrolling-posts-inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
white-space: nowrap;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.scrolling-posts {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.scrolling-posts > a:nth-child(1) {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.scrolling-posts-item {
|
||||
padding: 10px;
|
||||
border: solid 1px #ccc;
|
||||
background: var(--entry);
|
||||
border-radius: var(--radius);
|
||||
border: 1px solid var(--border);
|
||||
height: 100px;
|
||||
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.scrolling-posts-item-title {
|
||||
font-size: 1em;
|
||||
margin: 0;
|
||||
color: #ccc;
|
||||
font-weight: 400;
|
||||
line-height: 1.5em;
|
||||
text-decoration: none;
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrolling-posts-date {
|
||||
font-size: 0.8em;
|
||||
color: #ccc;
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.section-badge {
|
||||
display: inline-block;
|
||||
font-size: 0.8em;
|
||||
padding: 2px 6px;
|
||||
margin-right: 5px;
|
||||
background-color: var(--theme);
|
||||
border-radius: 3px;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.up-scroll {
|
||||
animation: scrollUp 50s linear infinite;
|
||||
}
|
||||
|
||||
.down-scroll {
|
||||
animation: scrollDown 50s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes scrollUp {
|
||||
0% {
|
||||
transform: translateY(0%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
}
|
||||
@keyframes scrollDown {
|
||||
0% {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
</style>
|
19
layouts/partials/posts-recents-carte.html
Executable file
19
layouts/partials/posts-recents-carte.html
Executable file
|
@ -0,0 +1,19 @@
|
|||
{{ $n := 1 }} <!-- Change this value to set the number of posts to display -->
|
||||
{{ range first $n (where .Site.RegularPages.ByDate.Reverse "Section" "blog") }}
|
||||
|
||||
{{- $image := .Resources.GetMatch (printf "%s" .Params.cover.image) -}}
|
||||
{{- if $image -}}
|
||||
|
||||
{{- $optimizedImage := $image.Fill "100x100 webp q95 Center" -}}
|
||||
<a href="{{ .RelPermalink }}" >
|
||||
<h3>{{ .Title }}</h3>
|
||||
<img src="{{ $optimizedImage.RelPermalink }}" alt="{{ .Title }} cover image"></img>
|
||||
<small>{{ .Date.Format "January 2, 2006" }}</small>
|
||||
<p>{{ .Summary | truncate 100 }}</p>
|
||||
|
||||
</a>
|
||||
{{ end }}
|
||||
|
||||
|
||||
{{ end }}
|
||||
|
983
layouts/partials/svg.html
Executable file
983
layouts/partials/svg.html
Executable file
File diff suppressed because one or more lines are too long
47
layouts/partials/templates/_funcs/get-page-images.html
Executable file
47
layouts/partials/templates/_funcs/get-page-images.html
Executable file
|
@ -0,0 +1,47 @@
|
|||
{{- $imgs := slice }}
|
||||
{{- $imgParams := .Params.images }}
|
||||
{{- $resources := .Resources.ByType "image" -}}
|
||||
{{/* Find featured image resources if the images parameter is empty. */}}
|
||||
{{- if not $imgParams }}
|
||||
{{- $featured := $resources.GetMatch "*feature*" -}}
|
||||
{{- if not $featured }}{{ $featured = $resources.GetMatch "{*cover*,*thumbnail*}" }}{{ end -}}
|
||||
{{- with $featured }}
|
||||
{{- $imgs = $imgs | append (dict
|
||||
"Image" .
|
||||
"RelPermalink" .RelPermalink
|
||||
"Permalink" .Permalink) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{/* Use the first one of site images as the fallback. */}}
|
||||
{{- if and (not $imgParams) (not $imgs) }}
|
||||
{{- with site.Params.images }}
|
||||
{{- $imgParams = first 1 . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{/* Parse page's images parameter. */}}
|
||||
{{- range $imgParams }}
|
||||
{{- $img := . }}
|
||||
{{- $url := urls.Parse $img }}
|
||||
{{- if eq $url.Scheme "" }}
|
||||
{{/* Internal image. */}}
|
||||
{{- with $resources.GetMatch $img -}}
|
||||
{{/* Image resource. */}}
|
||||
{{- $imgs = $imgs | append (dict
|
||||
"Image" .
|
||||
"RelPermalink" .RelPermalink
|
||||
"Permalink" .Permalink) }}
|
||||
{{- else }}
|
||||
{{- $imgs = $imgs | append (dict
|
||||
"RelPermalink" (relURL $img)
|
||||
"Permalink" (absURL $img)
|
||||
) }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{/* External image */}}
|
||||
{{- $imgs = $imgs | append (dict
|
||||
"RelPermalink" $img
|
||||
"Permalink" $img
|
||||
) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- return $imgs }}
|
86
layouts/partials/templates/opengraph.html
Executable file
86
layouts/partials/templates/opengraph.html
Executable file
|
@ -0,0 +1,86 @@
|
|||
<meta property="og:url" content="{{ .Permalink }}">
|
||||
|
||||
{{- with or site.Title site.Params.title | plainify }}
|
||||
<meta property="og:site_name" content="{{ . }}">
|
||||
{{- end }}
|
||||
|
||||
{{- with or .Title site.Title site.Params.title | plainify }}
|
||||
<meta property="og:title" content="{{ . }}">
|
||||
{{- end }}
|
||||
|
||||
{{- with or .Description .Summary site.Params.description | plainify | htmlUnescape | chomp }}
|
||||
<meta property="og:description" content="{{ . }}">
|
||||
{{- end }}
|
||||
|
||||
{{- with or .Params.locale site.Language.LanguageCode site.Language.Lang }}
|
||||
<meta property="og:locale" content="{{ . }}">
|
||||
{{- end }}
|
||||
|
||||
{{- if .IsPage }}
|
||||
<meta property="og:type" content="article">
|
||||
{{- with .Section }}
|
||||
<meta property="article:section" content="{{ . }}">
|
||||
{{- end }}
|
||||
{{- $ISO8601 := "2006-01-02T15:04:05-07:00" }}
|
||||
{{- 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 }}
|
||||
{{- range .GetTerms "tags" | first 6 }}
|
||||
<meta property="article:tag" content="{{ .Page.Title | plainify }}">
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
<meta property="og:type" content="website">
|
||||
{{- end }}
|
||||
|
||||
{{- if .Params.cover.image -}}
|
||||
{{- if (ne .Params.cover.relative true) }}
|
||||
<meta property="og:image" content="{{ .Params.cover.image | absURL }}">
|
||||
{{- else}}
|
||||
<meta property="og:image" content="{{ (path.Join .RelPermalink .Params.cover.image ) | absURL }}">
|
||||
{{- end}}
|
||||
{{- else }}
|
||||
{{- with partial "_funcs/get-page-images" . }}
|
||||
{{- range . | first 6 }}
|
||||
<meta property="og:image" content="{{ .Permalink }}">
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- with .Params.audio }}
|
||||
{{- range . | first 6 }}
|
||||
<meta property="og:audio" content="{{ . | absURL }}">
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- with .Params.videos }}
|
||||
{{- range . | first 6 }}
|
||||
<meta property="og:video" content="{{ . | absURL }}">
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- range .GetTerms "series" }}
|
||||
{{- range .Pages | first 7 }}
|
||||
{{- if ne $ . }}
|
||||
<meta property="og:see_also" content="{{ .Permalink }}">
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- with site.Params.social }}
|
||||
{{- if reflect.IsMap . }}
|
||||
{{- with .facebook_app_id }}
|
||||
<meta property="fb:app_id" content="{{ . }}">
|
||||
{{- else }}
|
||||
{{- with .facebook_admin }}
|
||||
<meta property="fb:admins" content="{{ . }}">
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- with (.Param "social.fediverse_creator") }}
|
||||
<meta name="fediverse:creator" content="{{ . }}">
|
||||
{{- end }}
|
128
layouts/partials/templates/schema_json.html
Executable file
128
layouts/partials/templates/schema_json.html
Executable file
|
@ -0,0 +1,128 @@
|
|||
{{ if .IsHome }}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "{{- ( site.Params.schema.publisherType | default "Organization") | title -}}",
|
||||
"name": {{ site.Title }},
|
||||
"url": {{ site.Home.Permalink }},
|
||||
"description": {{ site.Params.description | plainify | truncate 180 | safeHTML }},
|
||||
{{- if (eq site.Params.schema.publisherType "Person") }}
|
||||
"image": {{ site.Params.assets.favicon | default "favicon.ico" | absURL }},
|
||||
{{- else }}
|
||||
"logo": {{ site.Params.assets.favicon | default "favicon.ico" | absURL }},
|
||||
{{- end }}
|
||||
"sameAs": [
|
||||
{{- if site.Params.schema.sameAs }}
|
||||
{{ range $i, $e := site.Params.schema.sameAs }}{{ if $i }}, {{ end }}{{ trim $e " " }}{{ end }}
|
||||
{{- else}}
|
||||
{{ range $i, $e := site.Params.SocialIcons }}{{ if $i }}, {{ end }}{{ trim $e.url " " | safeURL }}{{ end }}
|
||||
{{- end}}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
{{- else if (or .IsPage .IsSection) }}
|
||||
{{/* BreadcrumbList */}}
|
||||
{{- $url := replace .Parent.Permalink ( printf "%s" site.Home.Permalink) "" }}
|
||||
{{- $lang_url := strings.TrimPrefix ( printf "%s/" .Lang) $url }}
|
||||
{{- $bc_list := (split $lang_url "/")}}
|
||||
|
||||
{{- $scratch := newScratch }}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [
|
||||
{{- range $index, $element := $bc_list }}
|
||||
|
||||
{{- $scratch.Add "path" (printf "%s/" $element ) | safeJS }}
|
||||
{{- $bc_pg := site.GetPage ($scratch.Get "path") -}}
|
||||
|
||||
{{- if (and ($bc_pg) (gt (len . ) 0))}}
|
||||
{{- if (and $index)}}, {{end }}
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": {{ add 1 $index }},
|
||||
"name": {{ $bc_pg.Name }},
|
||||
"item": {{ $bc_pg.Permalink | safeHTML }}
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
{{- end }}
|
||||
{{- /* self-page addition */ -}}
|
||||
{{- if (ge (len $bc_list) 2) }}, {{end }}
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": {{len $bc_list}},
|
||||
"name": {{ .Name }},
|
||||
"item": {{ .Permalink | safeHTML }}
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
{{- if .IsPage }}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
"headline": {{ .Title | plainify}},
|
||||
"name": "{{ .Title | plainify }}",
|
||||
"description": {{ with .Description | plainify }}{{ . }}{{ else }}{{ .Summary | plainify }}{{ end -}},
|
||||
"keywords": [
|
||||
{{- if .Params.keywords }}
|
||||
{{ range $i, $e := .Params.keywords }}{{ if $i }}, {{ end }}{{ $e }}{{ end }}
|
||||
{{- else }}
|
||||
{{ range $i, $e := .Params.tags }}{{ if $i }}, {{ end }}{{ $e }}{{ end }}
|
||||
{{- end }}
|
||||
],
|
||||
"articleBody": {{ .Content | safeJS | htmlUnescape | plainify }},
|
||||
"wordCount" : "{{ .WordCount }}",
|
||||
"inLanguage": {{ .Language.Lang | default "en-us" }},
|
||||
{{ if .Params.cover.image -}}
|
||||
"image":
|
||||
{{- if (ne .Params.cover.relative true) -}}
|
||||
{{ .Params.cover.image | absURL }},
|
||||
{{- else -}}
|
||||
{{ (path.Join .RelPermalink .Params.cover.image ) | absURL }},
|
||||
{{- end}}
|
||||
{{- else }}
|
||||
{{- $images := partial "templates/_funcs/get-page-images" . -}}
|
||||
{{- with index $images 0 -}}
|
||||
"image": {{ .Permalink }},
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
"datePublished": {{ .PublishDate }},
|
||||
"dateModified": {{ .Lastmod }},
|
||||
{{- with (.Params.author | default site.Params.author) }}
|
||||
"author":
|
||||
{{- if (or (eq (printf "%T" .) "[]string") (eq (printf "%T" .) "[]interface {}")) -}}
|
||||
[{{- range $i, $v := . -}}
|
||||
{{- if $i }}, {{end -}}
|
||||
{
|
||||
"@type": "Person",
|
||||
"name": {{ $v }}
|
||||
}
|
||||
{{- end }}],
|
||||
{{- else -}}
|
||||
{
|
||||
"@type": "Person",
|
||||
"name": {{ . }}
|
||||
},
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
"mainEntityOfPage": {
|
||||
"@type": "WebPage",
|
||||
"@id": {{ .Permalink | safeHTML }}
|
||||
},
|
||||
"publisher": {
|
||||
"@type": "{{- ( site.Params.schema.publisherType | default "Organization") | title -}}",
|
||||
"name": {{ site.Title }},
|
||||
"logo": {
|
||||
"@type": "ImageObject",
|
||||
"url": {{ site.Params.assets.favicon | default "favicon.ico" | absURL }}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{{- end }}{{/* .IsPage end */}}
|
||||
|
||||
{{- end -}}
|
31
layouts/partials/templates/twitter_cards.html
Executable file
31
layouts/partials/templates/twitter_cards.html
Executable file
|
@ -0,0 +1,31 @@
|
|||
{{- if .Params.cover.image -}}
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
{{- if (ne $.Params.cover.relative true) }}
|
||||
<meta name="twitter:image" content="{{ .Params.cover.image | absURL }}">
|
||||
{{- else }}
|
||||
<meta name="twitter:image" content="{{ (path.Join .RelPermalink .Params.cover.image ) | absURL }}">
|
||||
{{- end}}
|
||||
{{- else }}
|
||||
{{- $images := partial "templates/_funcs/get-page-images" . -}}
|
||||
{{- with index $images 0 -}}
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:image" content="{{ .Permalink }}">
|
||||
{{- else -}}
|
||||
<meta name="twitter:card" content="summary">
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
<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 -}}">
|
||||
|
||||
{{- $twitterSite := "" }}
|
||||
{{- with site.Params.social }}
|
||||
{{- if reflect.IsMap . }}
|
||||
{{- with .twitter }}
|
||||
{{- $content := . }}
|
||||
{{- if not (strings.HasPrefix . "@") }}
|
||||
{{- $content = printf "@%v" . }}
|
||||
{{- end }}
|
||||
<meta name="twitter:site" content="{{ $content }}">
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
97
layouts/partials/toc.html
Executable file
97
layouts/partials/toc.html
Executable file
|
@ -0,0 +1,97 @@
|
|||
{{- $headers := findRE "<h[1-6].*?>(.|\n])+?</h[1-6]>" .Content -}}
|
||||
{{- $has_headers := ge (len $headers) 1 -}}
|
||||
{{- if $has_headers -}}
|
||||
<div class="toc">
|
||||
<details {{if (.Param "TocOpen") }} open{{ end }}>
|
||||
<summary accesskey="c" title="(Alt + C)">
|
||||
<span class="details">{{- i18n "toc" | default "Table of Contents" }}</span>
|
||||
</summary>
|
||||
|
||||
<div class="inner">
|
||||
{{- if (.Param "UseHugoToc") }}
|
||||
{{- .TableOfContents -}}
|
||||
{{- else }}
|
||||
{{- $largest := 6 -}}
|
||||
{{- range $headers -}}
|
||||
{{- $headerLevel := index (findRE "[1-6]" . 1) 0 -}}
|
||||
{{- $headerLevel := len (seq $headerLevel) -}}
|
||||
{{- if lt $headerLevel $largest -}}
|
||||
{{- $largest = $headerLevel -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $firstHeaderLevel := len (seq (index (findRE "[1-6]" (index $headers 0) 1) 0)) -}}
|
||||
|
||||
{{- $.Scratch.Set "bareul" slice -}}
|
||||
<ul>
|
||||
{{- range seq (sub $firstHeaderLevel $largest) -}}
|
||||
<ul>
|
||||
{{- $.Scratch.Add "bareul" (sub (add $largest .) 1) -}}
|
||||
{{- end -}}
|
||||
{{- range $i, $header := $headers -}}
|
||||
{{- $headerLevel := index (findRE "[1-6]" . 1) 0 -}}
|
||||
{{- $headerLevel := len (seq $headerLevel) -}}
|
||||
|
||||
{{/* get id="xyz" */}}
|
||||
{{- $id := index (findRE "(id=\"(.*?)\")" $header 9) 0 }}
|
||||
|
||||
{{- /* strip id="" to leave xyz, no way to get regex capturing groups in hugo */ -}}
|
||||
{{- $cleanedID := replace (replace $id "id=\"" "") "\"" "" }}
|
||||
{{- $header := replaceRE "<h[1-6].*?>((.|\n])+?)</h[1-6]>" "$1" $header -}}
|
||||
|
||||
{{- if ne $i 0 -}}
|
||||
{{- $prevHeaderLevel := index (findRE "[1-6]" (index $headers (sub $i 1)) 1) 0 -}}
|
||||
{{- $prevHeaderLevel := len (seq $prevHeaderLevel) -}}
|
||||
{{- if gt $headerLevel $prevHeaderLevel -}}
|
||||
{{- range seq $prevHeaderLevel (sub $headerLevel 1) -}}
|
||||
<ul>
|
||||
{{/* the first should not be recorded */}}
|
||||
{{- if ne $prevHeaderLevel . -}}
|
||||
{{- $.Scratch.Add "bareul" . -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
</li>
|
||||
{{- if lt $headerLevel $prevHeaderLevel -}}
|
||||
{{- range seq (sub $prevHeaderLevel 1) -1 $headerLevel -}}
|
||||
{{- if in ($.Scratch.Get "bareul") . -}}
|
||||
</ul>
|
||||
{{/* manually do pop item */}}
|
||||
{{- $tmp := $.Scratch.Get "bareul" -}}
|
||||
{{- $.Scratch.Delete "bareul" -}}
|
||||
{{- $.Scratch.Set "bareul" slice}}
|
||||
{{- range seq (sub (len $tmp) 1) -}}
|
||||
{{- $.Scratch.Add "bareul" (index $tmp (sub . 1)) -}}
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
</ul>
|
||||
</li>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
<li>
|
||||
<a href="#{{- $cleanedID -}}" aria-label="{{- $header | plainify | safeHTML -}}">{{- $header | plainify | safeHTML -}}</a>
|
||||
{{- else }}
|
||||
<li>
|
||||
<a href="#{{- $cleanedID -}}" aria-label="{{- $header | plainify | safeHTML -}}">{{- $header | plainify | safeHTML -}}</a>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
<!-- {{- $firstHeaderLevel := len (seq (index (findRE "[1-6]" (index $headers 0) 1) 0)) -}} -->
|
||||
{{- $firstHeaderLevel := $largest }}
|
||||
{{- $lastHeaderLevel := len (seq (index (findRE "[1-6]" (index $headers (sub (len $headers) 1)) 1) 0)) }}
|
||||
</li>
|
||||
{{- range seq (sub $lastHeaderLevel $firstHeaderLevel) -}}
|
||||
{{- if in ($.Scratch.Get "bareul") (add . $firstHeaderLevel) }}
|
||||
</ul>
|
||||
{{- else }}
|
||||
</ul>
|
||||
</li>
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
</ul>
|
||||
{{- end }}
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
{{- end }}
|
19
layouts/partials/translation_list.html
Executable file
19
layouts/partials/translation_list.html
Executable file
|
@ -0,0 +1,19 @@
|
|||
{{- if .IsTranslated -}}
|
||||
{{- if (ne .Layout "search") }}
|
||||
{{- if or .Params.author site.Params.author (.Param "ShowReadingTime") (not .Date.IsZero) }} | {{- end -}}
|
||||
{{- end }}
|
||||
{{- i18n "translations" | default "Translations" }}:
|
||||
<ul class="i18n_list">
|
||||
{{- range .Translations }}
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">
|
||||
{{- if (and site.Params.displayFullLangName (.Language.LanguageName)) }}
|
||||
{{- .Language.LanguageName | emojify -}}
|
||||
{{- else }}
|
||||
{{- .Lang | title -}}
|
||||
{{- end -}}
|
||||
</a>
|
||||
</li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
{{- end -}}
|
7
layouts/robots.txt
Executable file
7
layouts/robots.txt
Executable file
|
@ -0,0 +1,7 @@
|
|||
User-agent: *
|
||||
{{- if hugo.IsProduction | or (eq site.Params.env "production") }}
|
||||
Disallow:
|
||||
{{- else }}
|
||||
Disallow: /
|
||||
{{- end }}
|
||||
Sitemap: {{ "sitemap.xml" | absURL }}
|
100
layouts/rss.xml
Executable file
100
layouts/rss.xml
Executable file
|
@ -0,0 +1,100 @@
|
|||
{{- /* Deprecate site.Author.email in favor of site.Params.author.email */}}
|
||||
{{- $authorEmail := "" }}
|
||||
{{- with site.Params.author }}
|
||||
{{- if reflect.IsMap . }}
|
||||
{{- with .email }}
|
||||
{{- $authorEmail = . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- with site.Author.email }}
|
||||
{{- $authorEmail = . }}
|
||||
{{- warnf "The author key in site configuration is deprecated. Use params.author.email instead." }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- /* Deprecate site.Author.name in favor of site.Params.author.name */}}
|
||||
{{- $authorName := "" }}
|
||||
{{- with site.Params.author }}
|
||||
{{- if reflect.IsMap . }}
|
||||
{{- with .name }}
|
||||
{{- $authorName = . }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- $authorName = . }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- with site.Author.name }}
|
||||
{{- $authorName = . }}
|
||||
{{- warnf "The author key in site configuration is deprecated. Use params.author.name instead." }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- /* Define allowed sections for RSS feed */}}
|
||||
{{- $allowedSections := slice "blog" "collection" "livres" }}
|
||||
|
||||
{{- $pctx := . }}
|
||||
{{- if .IsHome }}{{ $pctx = site }}{{ end }}
|
||||
{{- $pages := slice }}
|
||||
{{- if or $.IsHome $.IsSection }}
|
||||
{{- $pages = $pctx.RegularPages }}
|
||||
{{- else }}
|
||||
{{- $pages = $pctx.Pages }}
|
||||
{{- end }}
|
||||
{{- $limit := site.Config.Services.RSS.Limit }}
|
||||
{{- if ge $limit 1 }}
|
||||
{{- $pages = $pages | first $limit }}
|
||||
{{- end }}
|
||||
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
|
||||
<channel>
|
||||
<title>{{ if eq .Title site.Title }}{{ site.Title }}{{ else }}{{ with .Title }}{{ . }} on {{ end }}{{ site.Title }}{{ end }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<description>{{ site.Params.description }}</description>
|
||||
{{- with site.Params.images }}
|
||||
<image>
|
||||
<title>{{ site.Title }}</title>
|
||||
<url>{{ index . 0 | absURL }}</url>
|
||||
<link>{{ index . 0 | absURL }}</link>
|
||||
</image>
|
||||
{{- end }}
|
||||
<generator>Hugo -- {{ hugo.Version }}</generator>
|
||||
<language>{{ site.Language.LanguageCode }}</language>{{ with $authorEmail }}
|
||||
<managingEditor>{{.}}{{ with $authorName }} ({{ . }}){{ end }}</managingEditor>{{ end }}{{ with $authorEmail }}
|
||||
<webMaster>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</webMaster>{{ end }}{{ with site.Copyright }}
|
||||
<copyright>{{ . | markdownify | plainify | strings.TrimPrefix "© " }}</copyright>{{ end }}{{ if not .Date.IsZero }}
|
||||
<lastBuildDate>{{ (index $pages.ByLastmod.Reverse 0).Lastmod.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
|
||||
{{- with .OutputFormats.Get "RSS" }}
|
||||
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
|
||||
{{- end }}
|
||||
{{- range $pages }}
|
||||
{{- $section := .Section }}
|
||||
{{- if in $allowedSections $section }}
|
||||
<item>
|
||||
<title>{{ .Title }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<pubDate>{{ .PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
|
||||
{{- with $authorEmail }}<author>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</author>{{ end }}
|
||||
<guid>{{ .Permalink }}</guid>
|
||||
|
||||
{{- /* Process content to fix image URLs */}}
|
||||
{{- $summary := "" }}
|
||||
{{- with .Description }}
|
||||
{{- $summary = . }}
|
||||
{{- else }}
|
||||
{{- $summary = .Summary }}
|
||||
{{- end }}
|
||||
|
||||
{{- $baseURLWithoutTrailing := strings.TrimSuffix "/" site.BaseURL }}
|
||||
<description>{{ $summary | html }}</description>
|
||||
|
||||
{{- if site.Params.ShowFullTextinRSS }}
|
||||
{{- $content := .Content }}
|
||||
{{- $content := $content | replaceRE `src="(/[^"]*)"` (printf `src="%s$1"` $baseURLWithoutTrailing) }}
|
||||
<content:encoded>{{ (printf "<![CDATA[%s]]>" $content) | safeHTML }}</content:encoded>
|
||||
{{- end }}
|
||||
</item>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</channel>
|
||||
</rss>
|
91
layouts/shortcodes/blogroll.html
Executable file
91
layouts/shortcodes/blogroll.html
Executable file
|
@ -0,0 +1,91 @@
|
|||
{{ $csvFile := readFile "content/liens/blogroll.csv" }}
|
||||
{{ $lines := split $csvFile "\n" }}
|
||||
{{ $headers := split (index $lines 0) ";" }}
|
||||
|
||||
<style>
|
||||
.blogroll {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); /* Responsive grid */
|
||||
gap: 10px; /* Space between grid items */
|
||||
margin: 0 0;
|
||||
}
|
||||
.blogroll-item a {
|
||||
text-decoration: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.blogroll-item {
|
||||
padding: 0;
|
||||
border-radius: 8px;
|
||||
background-color: var(--entry);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
}
|
||||
.blogroll-name {
|
||||
font-weight: bold;
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
text-decoration: none;
|
||||
color: var(--primary);
|
||||
}
|
||||
.blogroll a:hover {
|
||||
color: var(--secondary);
|
||||
text-decoration: underline;
|
||||
text-decoration-thickness: 1.5px;
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
.blogroll img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
object-fit: contain;
|
||||
vertical-align: middle;
|
||||
margin-right: 10px;
|
||||
float: left;
|
||||
}
|
||||
.blogroll-desc {
|
||||
flex-grow: 1; /* Allow description to take available space */
|
||||
font-size: 0.9rem;
|
||||
color: var(--secondary);
|
||||
}
|
||||
.blogroll-desc p {
|
||||
margin: 0;
|
||||
}
|
||||
.blogroll-feed {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="blogroll">
|
||||
{{ range $i, $line := $lines }}
|
||||
{{ if and (ne $i 0) (ne $line "") }}
|
||||
{{ $cells := split $line ";" }}
|
||||
{{ $rowData := dict }}
|
||||
|
||||
{{ range $j, $header := $headers }}
|
||||
{{ $cellValue := index $cells $j | default "" }}
|
||||
{{ $rowData = merge $rowData (dict $header $cellValue) }}
|
||||
{{ end }}
|
||||
|
||||
<div class="blogroll-item">
|
||||
<div class="blogroll-title">
|
||||
{{ $siteUrl := index $rowData "url-site" }}
|
||||
{{ $domain := replaceRE `^https?://([^/]+)/?.*$` "$1" $siteUrl }}
|
||||
{{ $domain = replaceRE `\.[^.]+$` "" $domain }}
|
||||
<img src="/blogroll-favicons/{{ $domain }}.png" alt="Favicon for {{ $domain }}" >
|
||||
<a href="{{ index $rowData "url-site" }}" target="_blank">{{ index $rowData "nom" }}</a>
|
||||
<span> - </span>
|
||||
{{ if isset $rowData "url-feed" }}
|
||||
<a class="blogroll-feed" href="{{ index $rowData "url-feed" }}" target="_blank">Feed</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="blogroll-feed">
|
||||
</div>
|
||||
<div class="blogroll-desc">
|
||||
<p>{{ index $rowData "description" }}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
2
layouts/shortcodes/cassette-player.html
Executable file
2
layouts/shortcodes/cassette-player.html
Executable file
|
@ -0,0 +1,2 @@
|
|||
<!-- Include all content from static/cassette-player/index.html -->
|
||||
{{ readFile "static/cassette-player/index.html" }}
|
8
layouts/shortcodes/collapse.html
Executable file
8
layouts/shortcodes/collapse.html
Executable file
|
@ -0,0 +1,8 @@
|
|||
{{ if .Get "summary" }}
|
||||
{{ else }}
|
||||
{{ warnf "missing value for param 'summary': %s" .Position }}
|
||||
{{ end }}
|
||||
<p><details {{ if (eq (.Get "openByDefault") true) }} open=true {{ end }}>
|
||||
<summary markdown="span">{{ .Get "summary" | markdownify }}</summary>
|
||||
{{ .Inner | markdownify }}
|
||||
</details></p>
|
38
layouts/shortcodes/figure.html
Executable file
38
layouts/shortcodes/figure.html
Executable file
|
@ -0,0 +1,38 @@
|
|||
<!--
|
||||
Put this file in /layouts/shortcodes/figure.html
|
||||
NB this overrides Hugo's built-in "figure" shortcode but is backwards compatible
|
||||
Documentation and licence at https://github.com/liwenyip/hugo-easy-gallery/
|
||||
-->
|
||||
<!-- count how many times we've called this shortcode -->
|
||||
{{- if not ($.Page.Scratch.Get "figurecount") }}{{ end }}
|
||||
{{- $.Page.Scratch.Add "figurecount" 1 -}}
|
||||
<!-- use either src or link-thumb for thumbnail image -->
|
||||
{{- $thumb := .Get "src" | default (printf "%s." (.Get "thumb") | replace (.Get "link") ".") }}
|
||||
{{- $thumbResource := $.Page.Resources.GetMatch $thumb }}
|
||||
{{- $fitSize := .Get "size" | default "500" }}
|
||||
{{- if $thumbResource }}
|
||||
{{- if eq $thumbResource.MediaType.SubType "gif" }}
|
||||
{{- /* Don't process GIFs to preserve animation */ -}}
|
||||
{{- else }}
|
||||
{{- $thumbResource = $thumbResource.Fit (printf "%[1]sx%[1]s webp q85" $fitSize) -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
<div class="box{{ with .Get "caption-position" }} fancy-figure caption-position-{{.}}{{end}}{{ with .Get "caption-effect" }} caption-effect-{{.}}{{end}}" {{ with .Get "width" }}style="max-width:{{.}}"{{end}}>
|
||||
<figure {{ with .Get "class" }}class="{{.}}"{{ end }} itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
|
||||
<div class="img"{{ if .Parent }} style="background-image: url('{{ if $thumbResource }}{{ $thumbResource.RelPermalink }}{{ else }}{{ $thumb | relURL }}{{ end }}');"{{ end }}{{ with .Get "size" }} data-size="{{.}}"{{ end }}>
|
||||
<img itemprop="thumbnail" src="{{ if $thumbResource }}{{ $thumbResource.RelPermalink }}{{ else }}{{ $thumb | relURL }}{{ end }}" {{ with .Get "alt" | default (.Get "caption") }}alt="{{.}}"{{ end }}/><!-- <img> hidden if in .gallery -->
|
||||
</div>
|
||||
{{ with .Get "link" | default (.Get "src") }}<a href="{{ if $thumbResource }}{{ $thumbResource.RelPermalink }}{{ else }}{{ . | relURL }}{{ end }}" itemprop="contentUrl"></a>{{ end }}
|
||||
{{- if or (or (.Get "title") (.Get "caption")) (.Get "attr")}}
|
||||
<figcaption>
|
||||
{{- with .Get "title" }}<h4>{{.}}</h4>{{ end }}
|
||||
{{- if or (.Get "caption") (.Get "attr")}}
|
||||
<p>
|
||||
{{- .Get "caption" -}}
|
||||
{{- with .Get "attrlink"}}<a href="{{.}}">{{ .Get "attr" }}</a>{{ else }}{{ .Get "attr"}}{{ end -}}
|
||||
</p>
|
||||
{{- end }}
|
||||
</figcaption>
|
||||
{{- end }}
|
||||
</figure>
|
||||
</div>
|
41
layouts/shortcodes/gallery.html
Executable file
41
layouts/shortcodes/gallery.html
Executable file
|
@ -0,0 +1,41 @@
|
|||
<!--
|
||||
Put this file in /layouts/shortcodes/gallery.html
|
||||
Documentation and licence at https://github.com/liwenyip/hugo-easy-gallery/
|
||||
-->
|
||||
<!-- count how many times we've called this shortcode -->
|
||||
{{- if not ($.Page.Scratch.Get "figurecount") }}{{ end }}
|
||||
{{- $.Page.Scratch.Add "figurecount" 1 }}
|
||||
{{ $baseURL := .Site.BaseURL }}
|
||||
<div class="gallery caption-position-{{ with .Get "caption-position" | default "bottom" }}{{.}}{{end}} caption-effect-{{ with .Get "caption-effect" | default "none" }}{{.}}{{end}} hover-effect-{{ with .Get "hover-effect" | default "zoom" }}{{.}}{{end}} {{ if ne (.Get "hover-transition") "none" }}hover-transition{{end}}" itemscope itemtype="http://schema.org/ImageGallery">
|
||||
{{- with (.Get "dir") -}}
|
||||
<!-- If a directory was specified, generate figures for all of the images in the directory -->
|
||||
{{- $files := readDir (print "/static/" .) }}
|
||||
{{- range $files -}}
|
||||
<!-- skip files that aren't images, or that include the thumb suffix in their name -->
|
||||
{{- $thumbext := $.Get "thumb" | default "-thumb" }}
|
||||
{{- $isthumb := .Name | findRE ($thumbext | printf "%s\\.") }}<!-- is the current file a thumbnail image? -->
|
||||
{{- $isimg := lower .Name | findRE "\\.(gif|jpg|jpeg|tiff|png|bmp|webp|avif|jxl)" }}<!-- is the current file an image? -->
|
||||
{{- if and $isimg (not $isthumb) }}
|
||||
{{- $caption := .Name | replaceRE "\\..*" "" | humanize }}<!-- humanized filename without extension -->
|
||||
{{- $linkURL := print $baseURL ($.Get "dir") "/" .Name | absURL }}<!-- absolute URL to hi-res image -->
|
||||
{{- $thumb := .Name | replaceRE "(\\.)" ($thumbext | printf "%s.") }}<!-- filename of thumbnail image -->
|
||||
{{- $thumbexists := where $files "Name" $thumb }}<!-- does a thumbnail image exist? -->
|
||||
{{- $thumbURL := print $baseURL ($.Get "dir") "/" $thumb | absURL }}<!-- absolute URL to thumbnail image -->
|
||||
<div class="box">
|
||||
<figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
|
||||
<div class="img" style="background-image: url('{{ if $thumbexists }}{{ $thumbURL }}{{ else }}{{ $linkURL }}{{ end }}');" >
|
||||
<img itemprop="thumbnail" src="{{ if $thumbexists }}{{ $thumbURL }}{{ else }}{{ $linkURL }}{{ end }}" alt="{{ $caption }}" /><!-- <img> hidden if in .gallery -->
|
||||
</div>
|
||||
<figcaption>
|
||||
<h4>{{ $caption }}</h4>
|
||||
</figcaption>
|
||||
<a href="{{ $linkURL }}" itemprop="contentUrl"></a><!-- put <a> last so it is stacked on top -->
|
||||
</figure>
|
||||
</div>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else -}}
|
||||
<!-- If no directory was specified, include any figure shortcodes called within the gallery -->
|
||||
{{ .Inner }}
|
||||
{{- end }}
|
||||
</div>
|
284
layouts/shortcodes/image-gallery.html
Executable file
284
layouts/shortcodes/image-gallery.html
Executable file
|
@ -0,0 +1,284 @@
|
|||
<!--
|
||||
trouvé ici : https://github.com/thisdev/hugo-gallery-shortcode
|
||||
|
||||
modifié pour accepter les images dans le répertoire de la page
|
||||
|
||||
ne supporte que 5 images max (pourquoi ?)
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<style>
|
||||
/* Gallery Grid */
|
||||
.image-gallery {
|
||||
overflow: auto;
|
||||
margin-left: -1% !important;
|
||||
}
|
||||
|
||||
.image-gallery li {
|
||||
float: left;
|
||||
display: block;
|
||||
margin: 0 0 1% 1%;
|
||||
}
|
||||
|
||||
/* Dynamic widths based on image count */
|
||||
.image-gallery[data-count="2"] li {
|
||||
width: 49%;
|
||||
}
|
||||
|
||||
.image-gallery[data-count="3"] li {
|
||||
width: 32%;
|
||||
}
|
||||
|
||||
.image-gallery[data-count="4"] li {
|
||||
width: 24%;
|
||||
}
|
||||
|
||||
.image-gallery[data-count="5"] li {
|
||||
width: 19%;
|
||||
}
|
||||
|
||||
/* Override PaperMod theme link styles */
|
||||
.post-content .image-gallery a {
|
||||
box-shadow: none;
|
||||
box-decoration-break: none;
|
||||
-webkit-box-decoration-break: none;
|
||||
}
|
||||
|
||||
.image-gallery li a {
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: #777;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.image-gallery li a span {
|
||||
display: block;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
padding: 3px 0;
|
||||
}
|
||||
|
||||
.image-gallery li a img {
|
||||
width: 100%;
|
||||
aspect-ratio: 1 / 1;
|
||||
display: block;
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
background: #f5f5f5;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.image-gallery li a:hover img {
|
||||
transform: scale(1.01);
|
||||
}
|
||||
|
||||
/* Simple Lightbox */
|
||||
.simple-lightbox {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
.simple-lightbox.active {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.lightbox-content {
|
||||
position: relative;
|
||||
max-width: 90%;
|
||||
max-height: 90vh;
|
||||
}
|
||||
|
||||
.lightbox-content img {
|
||||
max-width: 100%;
|
||||
max-height: 90vh;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.lightbox-caption {
|
||||
position: absolute;
|
||||
bottom: -60px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.lightbox-close {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
color: white;
|
||||
font-size: 30px;
|
||||
cursor: pointer;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.lightbox-nav {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: white;
|
||||
font-size: 30px;
|
||||
cursor: pointer;
|
||||
padding: 20px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.lightbox-prev {
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
.lightbox-next {
|
||||
right: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
{{ $dir := .Get "gallery_dir" }}
|
||||
<div class="simple-lightbox">
|
||||
<div class="lightbox-content">
|
||||
<img src="" alt="">
|
||||
<div class="lightbox-caption"></div>
|
||||
</div>
|
||||
<div class="lightbox-close">×</div>
|
||||
<div class="lightbox-nav lightbox-prev"><</div>
|
||||
<div class="lightbox-nav lightbox-next">></div>
|
||||
</div>
|
||||
|
||||
<ul class="image-gallery">
|
||||
{{ $localPath := string (.Get "gallery_dir") }}
|
||||
{{ $displayTitle := ne (.Get "disp_title") "no" }}
|
||||
|
||||
<!-- Get images from page resources, looking in the specified directory -->
|
||||
{{ $files := .Page.Resources.Match (printf "%s/*" $localPath) }}
|
||||
|
||||
<!-- For debugging
|
||||
{{ $count := len $files }}
|
||||
<div style="color: #666; font-size: 0.8em; margin-bottom: 10px;">
|
||||
Found {{ $count }} images in "{{ $localPath }}" directory
|
||||
</div>
|
||||
-->
|
||||
|
||||
{{ $imageFiles := slice }}
|
||||
{{ range $files }}
|
||||
{{- $ext := path.Ext .Name | lower -}}
|
||||
{{- if in (slice ".jpg" ".jpeg" ".png" ".gif" ".webp") $ext -}}
|
||||
{{ $imageFiles = $imageFiles | append . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ if and (ge (len $imageFiles) 2) (le (len $imageFiles) 5) }}
|
||||
{{ range $imageFiles }}
|
||||
{{- $imagetitle := index (split .Name ".") 0 -}}
|
||||
<li>
|
||||
<a href="{{ .RelPermalink }}" title="{{ $imagetitle }}" class="gallery-image"
|
||||
data-caption="{{ $imagetitle }}">
|
||||
<img src="{{ .RelPermalink }}" alt="{{ $imagetitle }}" title="{{ $imagetitle }}">
|
||||
{{ if $displayTitle }}
|
||||
<span>{{ $imagetitle }}</span>
|
||||
{{ end }}
|
||||
</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
{{ else if eq (len $imageFiles) 0 }}
|
||||
<div style="background: #fff3cd; color: #856404; padding: 10px; border-radius: 5px;">
|
||||
<strong>Note:</strong> No images found in "{{ $localPath }}" directory. Make sure your images are in the correct location.
|
||||
</div>
|
||||
{{ else if eq (len $imageFiles) 1 }}
|
||||
<div style="background: #fff3cd; color: #856404; padding: 10px; border-radius: 5px;">
|
||||
<strong>Note:</strong> Only one image found in "{{ $localPath }}" directory. Gallery needs at least 2 images.
|
||||
</div>
|
||||
{{ else }}
|
||||
<div style="background: #fff3cd; color: #856404; padding: 10px; border-radius: 5px;">
|
||||
<strong>Note:</strong> Too many images found ({{ len $imageFiles }}). Maximum supported is 5 images.
|
||||
</div>
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const lightbox = document.querySelector('.simple-lightbox');
|
||||
const lightboxImg = lightbox.querySelector('img');
|
||||
const lightboxCaption = lightbox.querySelector('.lightbox-caption');
|
||||
const gallery = document.querySelector('.image-gallery');
|
||||
let currentIndex = 0;
|
||||
let images = [];
|
||||
|
||||
// Set data-count attribute for CSS styling
|
||||
const imageCount = gallery.querySelectorAll('.gallery-image').length;
|
||||
gallery.setAttribute('data-count', imageCount.toString());
|
||||
|
||||
// collect all images
|
||||
gallery.querySelectorAll('.gallery-image').forEach((link, index) => {
|
||||
images.push({
|
||||
src: link.href,
|
||||
title: link.getAttribute('data-caption')
|
||||
});
|
||||
|
||||
// click event for each image
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
currentIndex = index;
|
||||
showImage(currentIndex);
|
||||
});
|
||||
});
|
||||
|
||||
// show image in lightbox
|
||||
function showImage(index) {
|
||||
lightboxImg.src = images[index].src;
|
||||
lightboxCaption.textContent = images[index].title;
|
||||
lightbox.classList.add('active');
|
||||
}
|
||||
|
||||
// close button
|
||||
lightbox.querySelector('.lightbox-close').addEventListener('click', () => {
|
||||
lightbox.classList.remove('active');
|
||||
});
|
||||
|
||||
// navigation
|
||||
lightbox.querySelector('.lightbox-prev').addEventListener('click', () => {
|
||||
currentIndex = (currentIndex - 1 + images.length) % images.length;
|
||||
showImage(currentIndex);
|
||||
});
|
||||
|
||||
lightbox.querySelector('.lightbox-next').addEventListener('click', () => {
|
||||
currentIndex = (currentIndex + 1) % images.length;
|
||||
showImage(currentIndex);
|
||||
});
|
||||
|
||||
// keyboard navigation
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (!lightbox.classList.contains('active')) return;
|
||||
|
||||
if (e.key === 'Escape') {
|
||||
lightbox.classList.remove('active');
|
||||
} else if (e.key === 'ArrowLeft') {
|
||||
currentIndex = (currentIndex - 1 + images.length) % images.length;
|
||||
showImage(currentIndex);
|
||||
} else if (e.key === 'ArrowRight') {
|
||||
currentIndex = (currentIndex + 1) % images.length;
|
||||
showImage(currentIndex);
|
||||
}
|
||||
});
|
||||
|
||||
// click anywhere to close lightbox
|
||||
lightbox.addEventListener('click', (e) => {
|
||||
if (e.target === lightbox) {
|
||||
lightbox.classList.remove('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
5
layouts/shortcodes/inTextImg.html
Executable file
5
layouts/shortcodes/inTextImg.html
Executable file
|
@ -0,0 +1,5 @@
|
|||
{{- $Img := (.Get "url") }}
|
||||
{{- $height := (.Get "height") }}
|
||||
{{- $alt := (.Get "alt") }}
|
||||
|
||||
<img class="in-text" height="{{ $height | default `15` }}" src="{{$Img}}" alt="{{$alt}}">
|
32
layouts/shortcodes/inline-spoiler.html
Executable file
32
layouts/shortcodes/inline-spoiler.html
Executable file
|
@ -0,0 +1,32 @@
|
|||
<!-- https://oostens.me/posts/hugo-inline-spoiler-shortcode/ -->
|
||||
|
||||
<style>
|
||||
.inline-spoiler {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.inline-spoiler::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 1px;
|
||||
color: white;
|
||||
background: black;
|
||||
opacity: 1;
|
||||
transition: opacity 0.7s ease, transform 0.3s ease;
|
||||
}
|
||||
|
||||
.inline-spoiler:hover::before {
|
||||
opacity: 0;
|
||||
transform: translateY(-50%)rotateX(80deg);
|
||||
transition: opacity 1.0s ease, transform 0.5s ease;
|
||||
transition-delay: 0.3s;
|
||||
}
|
||||
</style>
|
||||
|
||||
<span class="inline-spoiler">{{- .Inner | safeHTML -}}</span>
|
8
layouts/shortcodes/liste-categories.html
Executable file
8
layouts/shortcodes/liste-categories.html
Executable file
|
@ -0,0 +1,8 @@
|
|||
{{range $name, $taxonomy := .Site.Taxonomies.tags}} {{ $cnt := .Count }}
|
||||
{{ with $.Site.GetPage (printf "/tags/%s" $name) }}
|
||||
<div class="tagbutton">
|
||||
<a href={{ .RelPermalink }} title="All pages with tag <i>{{$name}}</i>">{{$name}}</a>
|
||||
<sup>{{$cnt}}</sup>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
75
layouts/shortcodes/load-photoswipe-theme.html
Executable file
75
layouts/shortcodes/load-photoswipe-theme.html
Executable file
|
@ -0,0 +1,75 @@
|
|||
<!--
|
||||
Put this file in /layouts/shortcodes/load-photoswipe.html
|
||||
Documentation and licence at https://github.com/liwenyip/hugo-easy-gallery/
|
||||
-->
|
||||
|
||||
<!-- prevent this shortcode from being loaded more than once per page -->
|
||||
{{ if not ($.Page.Scratch.Get "photoswipeloaded") }}
|
||||
{{ $.Page.Scratch.Set "photoswipeloaded" 1 }}
|
||||
|
||||
<!--
|
||||
*** jQuery must be loaded before load-photoswipe.js ***
|
||||
- If your template already loads jQuery in the header then you don't need to load it again here.
|
||||
- If your template already loads jQuery in the footer, then you could load load-photoswipe.js from the footer instead
|
||||
-->
|
||||
<!-- these files are loaded in the theme footer
|
||||
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
|
||||
<script src="/js/load-photoswipe.js"></script>
|
||||
-->
|
||||
|
||||
<!-- Photoswipe css/js libraries -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.1/photoswipe.min.css" integrity="sha256-sCl5PUOGMLfFYctzDW3MtRib0ctyUvI9Qsmq2wXOeBY=" crossorigin="anonymous" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.1/default-skin/default-skin.min.css" integrity="sha256-BFeI1V+Vh1Rk37wswuOYn5lsTcaU96hGaI7OUVCLjPc=" crossorigin="anonymous" />
|
||||
<!-- these files are loaded in the theme footer
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.1/photoswipe.min.js" integrity="sha256-UplRCs9v4KXVJvVY+p+RSo5Q4ilAUXh7kpjyIP5odyc=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.1/photoswipe-ui-default.min.js" integrity="sha256-PWHOlUzc96pMc8ThwRIXPn8yH4NOLu42RQ0b9SpnpFk=" crossorigin="anonymous"></script>
|
||||
-->
|
||||
|
||||
<!-- Root element of PhotoSwipe. Must have class pswp. -->
|
||||
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<!-- Background of PhotoSwipe.
|
||||
It's a separate element, as animating opacity is faster than rgba(). -->
|
||||
<div class="pswp__bg"></div>
|
||||
<!-- Slides wrapper with overflow:hidden. -->
|
||||
<div class="pswp__scroll-wrap">
|
||||
<!-- Container that holds slides.
|
||||
PhotoSwipe keeps only 3 of them in DOM to save memory.
|
||||
Don't modify these 3 pswp__item elements, data is added later on. -->
|
||||
<div class="pswp__container">
|
||||
<div class="pswp__item"></div>
|
||||
<div class="pswp__item"></div>
|
||||
<div class="pswp__item"></div>
|
||||
</div>
|
||||
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
|
||||
<div class="pswp__ui pswp__ui--hidden">
|
||||
<div class="pswp__top-bar">
|
||||
<!-- Controls are self-explanatory. Order can be changed. -->
|
||||
<div class="pswp__counter"></div>
|
||||
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
|
||||
<button class="pswp__button pswp__button--share" title="Share"></button>
|
||||
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
|
||||
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
|
||||
<!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
|
||||
<!-- element will get class pswp__preloader--active when preloader is running -->
|
||||
<div class="pswp__preloader">
|
||||
<div class="pswp__preloader__icn">
|
||||
<div class="pswp__preloader__cut">
|
||||
<div class="pswp__preloader__donut"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
|
||||
<div class="pswp__share-tooltip"></div>
|
||||
</div>
|
||||
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
|
||||
</button>
|
||||
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
|
||||
</button>
|
||||
<div class="pswp__caption">
|
||||
<div class="pswp__caption__center"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
71
layouts/shortcodes/load-photoswipe.html
Executable file
71
layouts/shortcodes/load-photoswipe.html
Executable file
|
@ -0,0 +1,71 @@
|
|||
<!--
|
||||
Put this file in /layouts/shortcodes/load-photoswipe.html
|
||||
Documentation and licence at https://github.com/liwenyip/hugo-easy-gallery/
|
||||
-->
|
||||
|
||||
<!-- prevent this shortcode from being loaded more than once per page -->
|
||||
{{ if not ($.Page.Scratch.Get "photoswipeloaded") }}
|
||||
{{ $.Page.Scratch.Set "photoswipeloaded" 1 }}
|
||||
|
||||
<!--
|
||||
*** jQuery must be loaded before load-photoswipe.js ***
|
||||
- If your template already loads jQuery in the header then you don't need to load it again here.
|
||||
- If your template already loads jQuery in the footer, then you could load load-photoswipe.js from the footer instead
|
||||
-->
|
||||
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
|
||||
<script src={{ "js/load-photoswipe.js" | relURL }}></script>
|
||||
|
||||
<!-- Photoswipe css/js libraries -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.1/photoswipe.min.css" integrity="sha256-sCl5PUOGMLfFYctzDW3MtRib0ctyUvI9Qsmq2wXOeBY=" crossorigin="anonymous" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.1/default-skin/default-skin.min.css" integrity="sha256-BFeI1V+Vh1Rk37wswuOYn5lsTcaU96hGaI7OUVCLjPc=" crossorigin="anonymous" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.1/photoswipe.min.js" integrity="sha256-UplRCs9v4KXVJvVY+p+RSo5Q4ilAUXh7kpjyIP5odyc=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.1/photoswipe-ui-default.min.js" integrity="sha256-PWHOlUzc96pMc8ThwRIXPn8yH4NOLu42RQ0b9SpnpFk=" crossorigin="anonymous"></script>
|
||||
|
||||
<!-- Root element of PhotoSwipe. Must have class pswp. -->
|
||||
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<!-- Background of PhotoSwipe.
|
||||
It's a separate element, as animating opacity is faster than rgba(). -->
|
||||
<div class="pswp__bg"></div>
|
||||
<!-- Slides wrapper with overflow:hidden. -->
|
||||
<div class="pswp__scroll-wrap">
|
||||
<!-- Container that holds slides.
|
||||
PhotoSwipe keeps only 3 of them in DOM to save memory.
|
||||
Don't modify these 3 pswp__item elements, data is added later on. -->
|
||||
<div class="pswp__container">
|
||||
<div class="pswp__item"></div>
|
||||
<div class="pswp__item"></div>
|
||||
<div class="pswp__item"></div>
|
||||
</div>
|
||||
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
|
||||
<div class="pswp__ui pswp__ui--hidden">
|
||||
<div class="pswp__top-bar">
|
||||
<!-- Controls are self-explanatory. Order can be changed. -->
|
||||
<div class="pswp__counter"></div>
|
||||
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
|
||||
<button class="pswp__button pswp__button--share" title="Share"></button>
|
||||
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
|
||||
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
|
||||
<!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
|
||||
<!-- element will get class pswp__preloader--active when preloader is running -->
|
||||
<div class="pswp__preloader">
|
||||
<div class="pswp__preloader__icn">
|
||||
<div class="pswp__preloader__cut">
|
||||
<div class="pswp__preloader__donut"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
|
||||
<div class="pswp__share-tooltip"></div>
|
||||
</div>
|
||||
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
|
||||
</button>
|
||||
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
|
||||
</button>
|
||||
<div class="pswp__caption">
|
||||
<div class="pswp__caption__center"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
15
layouts/shortcodes/ltr.html
Executable file
15
layouts/shortcodes/ltr.html
Executable file
|
@ -0,0 +1,15 @@
|
|||
{{ $.Scratch.Set "md" false }}
|
||||
|
||||
{{ if .IsNamedParams }}
|
||||
{{ $.Scratch.Set "md" (.Get "md") }}
|
||||
{{ else }}
|
||||
{{ $.Scratch.Set "md" (.Get 0) }}
|
||||
{{ end }}
|
||||
|
||||
<div dir="ltr">
|
||||
{{ if eq ($.Scratch.Get "md") false }}
|
||||
{{ .Inner }}
|
||||
{{ else }}
|
||||
{{ .Inner | markdownify }}
|
||||
{{ end }}
|
||||
</div>
|
1
layouts/shortcodes/posts-compteur.html
Executable file
1
layouts/shortcodes/posts-compteur.html
Executable file
|
@ -0,0 +1 @@
|
|||
{{ len (where .Site.RegularPages "Section" "blog") }}
|
8
layouts/shortcodes/posts-recents.html
Executable file
8
layouts/shortcodes/posts-recents.html
Executable file
|
@ -0,0 +1,8 @@
|
|||
{{- $count := .Get 0 | default "5" -}}
|
||||
<ul>
|
||||
{{- range first (int $count) (sort (where .Site.RegularPages "Section" "blog") "Date" "desc") -}}
|
||||
<li>
|
||||
({{ .Date.Format "2006-01-02" }}) <a href="{{ .RelPermalink }}">{{ .Title }}</a>
|
||||
</li>
|
||||
{{- end -}}
|
||||
</ul>
|
2
layouts/shortcodes/rawhtml.html
Executable file
2
layouts/shortcodes/rawhtml.html
Executable file
|
@ -0,0 +1,2 @@
|
|||
<!-- raw html -->
|
||||
{{- .Inner -}}
|
15
layouts/shortcodes/rtl.html
Executable file
15
layouts/shortcodes/rtl.html
Executable file
|
@ -0,0 +1,15 @@
|
|||
{{ $.Scratch.Set "md" false }}
|
||||
|
||||
{{ if .IsNamedParams }}
|
||||
{{ $.Scratch.Set "md" (.Get "md") }}
|
||||
{{ else }}
|
||||
{{ $.Scratch.Set "md" (.Get 0) }}
|
||||
{{ end }}
|
||||
|
||||
<div dir="rtl">
|
||||
{{ if eq ($.Scratch.Get "md") false }}
|
||||
{{ .Inner }}
|
||||
{{ else }}
|
||||
{{ .Inner | markdownify }}
|
||||
{{ end }}
|
||||
</div>
|
74
layouts/shortcodes/video.html
Executable file
74
layouts/shortcodes/video.html
Executable file
|
@ -0,0 +1,74 @@
|
|||
<!-- https://github.com/martignoni/hugo-video -->
|
||||
|
||||
{{- /* hugo-video shortcode
|
||||
/*
|
||||
/* This file is part of hugo-video shortcode.
|
||||
/* A Hugo component shortcode to embed videos using the HTML video element.
|
||||
/*
|
||||
/* @copyright @2019 onwards Nicolas Martignoni (nicolas@martignoni.net)
|
||||
/* @source https://github.com/martignoni/hugo-video
|
||||
/* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
/*
|
||||
*/ -}}
|
||||
|
||||
{{- $video_src := .Get "src" -}}
|
||||
{{- $video_mp4 := "" -}}
|
||||
{{- $video_webm := "" -}}
|
||||
{{- $video_ogg := "" -}}
|
||||
{{- $video_dl := "" -}}
|
||||
{{- $width := "100%" -}}
|
||||
{{- $filenotfound := true -}}
|
||||
{{- $unsupportedfile := true -}}
|
||||
|
||||
{{- /* Find all files with filename (without suffix) matching "src" parameter. */ -}}
|
||||
{{- $video_files := (.Page.Resources.Match (printf "%s*" $video_src)) -}}
|
||||
|
||||
{{- /* Find first image file with filename (without suffix) matching "src" parameter. */ -}}
|
||||
{{- $poster := ((.Page.Resources.ByType "image").GetMatch (printf "%s*" $video_src)) -}}
|
||||
|
||||
{{- /* Find in page bundle all valid video files with matching name. */ -}}
|
||||
{{- with $video_files -}}
|
||||
{{- $filenotfound = false -}}
|
||||
{{- range . -}}
|
||||
{{- if or (in .MediaType.Suffixes "mp4") (in .MediaType.Suffixes "m4v") -}}
|
||||
{{- $unsupportedfile = false -}}
|
||||
{{- $video_mp4 = . -}}
|
||||
{{- end -}}
|
||||
{{- if (in .MediaType.Suffixes "webm") -}}
|
||||
{{- $unsupportedfile = false -}}
|
||||
{{- $video_webm = . -}}
|
||||
{{- end -}}
|
||||
{{- if (in .MediaType.Suffixes "ogv") -}}
|
||||
{{- $unsupportedfile = false -}}
|
||||
{{- $video_ogg = . -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if $filenotfound -}}
|
||||
{{- /* No file of given name was found, we stop here. */ -}}
|
||||
{{- errorf "No file with filename %q found." $video_src -}}
|
||||
{{- else if $unsupportedfile -}}
|
||||
{{- errorf "No valid video file with filename %q found." $video_src -}}
|
||||
{{- else -}}
|
||||
<figure class="video-figure">
|
||||
<video {{ if ne (.Get "controls") "false" }}controls {{ end }}preload="auto" width="{{ or (.Get "width") $width }}" {{ with .Get "height" }}height="{{.}}"{{ end }} {{ if eq (.Get "autoplay") "true" }}autoplay {{ end }}{{ if eq (.Get "loop") "true" }}loop {{ end }}{{ if eq (.Get "muted") "true" }}muted {{ end }}{{ with $poster }}poster="{{ .RelPermalink }}" {{ end }} playsinline class="html-video">
|
||||
{{- with $video_webm }}
|
||||
<source src="{{ .RelPermalink }}" type="video/webm">
|
||||
{{- $video_dl = . -}}
|
||||
{{- end }}
|
||||
{{- with $video_ogg }}
|
||||
<source src="{{ .RelPermalink }}" type="video/ogg">
|
||||
{{- $video_dl = . -}}
|
||||
{{- end }}
|
||||
{{- with $video_mp4 }}
|
||||
<source src="{{ .RelPermalink }}" type="video/mp4">
|
||||
{{- $video_dl = . -}}
|
||||
{{- end }}
|
||||
<span>{{ i18n "videoUnsupported" $video_dl | safeHTML}}</span>
|
||||
</video>
|
||||
{{- with .Get "title" }}
|
||||
<figcaption class="video-caption">{{ . }}</figcaption>
|
||||
{{- end }}
|
||||
</figure>
|
||||
{{- end -}}
|
12
layouts/shortcodes/youtubepl.html
Executable file
12
layouts/shortcodes/youtubepl.html
Executable file
|
@ -0,0 +1,12 @@
|
|||
<!-- https://stackoverflow.com/questions/72065012/how-to-embed-a-youtube-playlist-in-hugo-website -->
|
||||
|
||||
{{- $pc := .Page.Site.Config.Privacy.YouTube -}}
|
||||
{{- if not $pc.Disable -}}
|
||||
{{- $ytHost := cond $pc.PrivacyEnhanced "www.youtube-nocookie.com" "www.youtube.com" -}}
|
||||
{{- $id := .Get "id" | default (.Get 0) -}}
|
||||
{{- $class := .Get "class" | default (.Get 1) -}}
|
||||
{{- $title := .Get "title" | default "YouTube Video" }}
|
||||
<div {{ with $class }}class="{{ . }}"{{ else }}style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"{{ end }}>
|
||||
<iframe src="https://{{ $ytHost }}/embed/videoseries?list={{ $id }}{{ with .Get "autoplay" }}{{ if eq . "true" }}&autoplay=1{{ end }}{{ end }}" {{ if not $class }}style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" {{ end }}allowfullscreen title="{{ $title }}"></iframe>
|
||||
</div>
|
||||
{{ end -}}
|
Loading…
Add table
Add a link
Reference in a new issue