This commit is contained in:
gribse 2025-10-06 19:21:06 +02:00
parent 2fe0c9a830
commit 7b9c07b83e
1444 changed files with 11476 additions and 42112 deletions

View 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>

View file

@ -0,0 +1,2 @@
<!-- Include all content from static/cassette-player/index.html -->
{{ readFile "static/cassette-player/index.html" }}

View 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
View 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
View 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>

View 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">&times;</div>
<div class="lightbox-nav lightbox-prev">&lt;</div>
<div class="lightbox-nav lightbox-next">&gt;</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>

View 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}}">

View 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>

View 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}}

View 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 }}

View 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
View 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>

View file

@ -0,0 +1 @@
{{ len (where .Site.RegularPages "Section" "blog") }}

View 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>

View file

@ -0,0 +1,2 @@
<!-- raw html -->
{{- .Inner -}}

15
layouts/shortcodes/rtl.html Executable file
View 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
View 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 -}}

View 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 -}}