Compare commits
14 Commits
ac5a0ea9d5
...
c91493ae83
| Author | SHA1 | Date |
|---|---|---|
|
|
c91493ae83 | 1 month ago |
|
|
a65d846135 | 1 month ago |
|
|
231831ebd7 | 1 month ago |
|
|
7fe8344056 | 1 month ago |
|
|
2a29098570 | 1 month ago |
|
|
e67dbba625 | 1 month ago |
|
|
c7d6ad75bd | 1 month ago |
|
|
5001ac8f05 | 1 month ago |
|
|
3c9a0ecdb9 | 1 month ago |
|
|
8e5c14917e | 1 month ago |
|
|
159cbc4022 | 1 month ago |
|
|
6a66776392 | 1 month ago |
|
|
0018fe4d79 | 1 month ago |
|
|
35c8084b76 | 1 month ago |
116 changed files with 1359 additions and 728 deletions
@ -1,3 +1,4 @@ |
|||||
--- |
--- |
||||
title: "Articles" |
title: "Articles" |
||||
|
description: "Technical articles about Kubernetes, OpenShift, API Management, Single Sign-On, containers and homelab, by Nicolas Massé." |
||||
--- |
--- |
||||
|
|||||
@ -1,5 +1,6 @@ |
|||||
--- |
--- |
||||
title: "Writing" |
title: "Writing" |
||||
|
description: "Articles written by Nicolas Massé as a guest author for other websites and for the specialized press." |
||||
--- |
--- |
||||
|
|
||||
I post articles from time to time on various websites as a guest. I have gathered a list of my recent posts below. |
I post articles from time to time on various websites as a guest. I have gathered a list of my recent posts below. |
||||
|
|||||
@ -1,3 +1,4 @@ |
|||||
--- |
--- |
||||
title: "Articles" |
title: "Articles" |
||||
|
description: "Articles techniques sur Kubernetes, OpenShift, l'API Management, le Single Sign-On, les conteneurs et le homelab, par Nicolas Massé." |
||||
--- |
--- |
||||
|
|||||
@ -0,0 +1,24 @@ |
|||||
|
{{- /* |
||||
|
-- Renders the fenced code blocks, optionally prefixed by a file name or a |
||||
|
-- title: |
||||
|
-- |
||||
|
-- ```yaml {filename="config.yaml" hl_lines="3-5"} |
||||
|
-- ```sh {title="CoreOS"} |
||||
|
*/ -}} |
||||
|
{{- $result := transform.HighlightCodeBlock . -}} |
||||
|
{{- $label := "" -}} |
||||
|
{{- with .Attributes.filename -}} |
||||
|
{{- $label = printf (i18n "file") . -}} |
||||
|
{{- else -}} |
||||
|
{{- with .Attributes.title -}}{{- $label = . -}}{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- /* The filename and title attributes must not be rendered on the wrapper */ -}} |
||||
|
{{- $highlighted := replaceRE `^<div class="highlight"[^>]*>` `<div class="highlight">` (string $result.Wrapped) 1 | safeHTML -}} |
||||
|
{{- if $label -}} |
||||
|
<div class="highlightedFile"> |
||||
|
<div class="filename">{{ $label }}</div> |
||||
|
{{- $highlighted -}} |
||||
|
</div> |
||||
|
{{- else -}} |
||||
|
{{- $highlighted -}} |
||||
|
{{- end -}} |
||||
@ -0,0 +1,88 @@ |
|||||
|
{{- /* |
||||
|
-- Renders the Markdown images. |
||||
|
-- |
||||
|
-- The image is resolved to a resource of the current page, or to a global |
||||
|
-- resource (assets, static/images). A standalone image is rendered as a |
||||
|
-- figure, with its title as caption (Markdown allowed): |
||||
|
-- |
||||
|
--  |
||||
|
-- |
||||
|
-- Raster images (JPEG, PNG, WebP) are converted to WebP in several widths |
||||
|
-- (srcset), so that the browser downloads the most appropriate one. |
||||
|
-- GIF (possibly animated) and SVG images are served as-is. |
||||
|
-- |
||||
|
-- All images get their dimensions (to avoid layout shifts) and are lazy |
||||
|
-- loaded, except the first one of the page. |
||||
|
*/ -}} |
||||
|
{{- $u := urls.Parse .Destination -}} |
||||
|
{{- $attrs := dict "src" .Destination "alt" .PlainText -}} |
||||
|
{{- $image := false -}} |
||||
|
{{- if not $u.IsAbs -}} |
||||
|
{{- with or (.Page.Resources.Get $u.Path) (resources.Get (strings.TrimPrefix "/" $u.Path)) -}} |
||||
|
{{- $image = . -}} |
||||
|
{{- else -}} |
||||
|
{{- if not (strings.HasPrefix $u.Path "/") -}} |
||||
|
{{- errorf "%s: image %q not found" .Page.String .Destination -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
|
||||
|
{{- with $image -}} |
||||
|
{{- /* Note: .RelPermalink publishes the original image, only done when it is served as-is */ -}} |
||||
|
{{- if in (slice "jpeg" "png" "webp") .MediaType.SubType -}} |
||||
|
{{- /* WebP variants, no wider than the original image */ -}} |
||||
|
{{- $hint := cond (eq .MediaType.SubType "png") "drawing" "photo" -}} |
||||
|
{{- $variants := slice -}} |
||||
|
{{- range $width := slice 480 800 1200 1600 -}} |
||||
|
{{- if lt $width $image.Width -}} |
||||
|
{{- $variants = $variants | append ($image.Resize (printf "%dx webp q80 %s" $width $hint)) -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- if lt (len $variants) 4 -}} |
||||
|
{{- /* The original width, when smaller than the largest variant */ -}} |
||||
|
{{- $variants = $variants | append ($image.Process (printf "webp q80 %s" $hint)) -}} |
||||
|
{{- end -}} |
||||
|
{{- $srcset := slice -}} |
||||
|
{{- range $variants -}} |
||||
|
{{- $srcset = $srcset | append (printf "%s %dw" .RelPermalink .Width) -}} |
||||
|
{{- end -}} |
||||
|
{{- $largest := index $variants (sub (len $variants) 1) -}} |
||||
|
{{- $attrs = merge $attrs (dict |
||||
|
"src" $largest.RelPermalink |
||||
|
"srcset" (delimit $srcset ", ") |
||||
|
"sizes" "(max-width: 1140px) 100vw, (max-width: 1280px) 75vw, (max-width: 1440px) 55vw, 50vw" |
||||
|
"width" $largest.Width |
||||
|
"height" $largest.Height |
||||
|
) -}} |
||||
|
{{- else if eq .MediaType.SubType "gif" -}} |
||||
|
{{- $attrs = merge $attrs (dict "src" .RelPermalink "width" .Width "height" .Height) -}} |
||||
|
{{- else -}} |
||||
|
{{- $attrs = merge $attrs (dict "src" .RelPermalink) -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
|
||||
|
{{- /* The first image of the page is often the largest visible element */ -}} |
||||
|
{{- if eq .Ordinal 0 -}} |
||||
|
{{- $attrs = merge $attrs (dict "fetchpriority" "high") -}} |
||||
|
{{- else -}} |
||||
|
{{- $attrs = merge $attrs (dict "loading" "lazy" "decoding" "async") -}} |
||||
|
{{- end -}} |
||||
|
|
||||
|
{{- $img := "" -}} |
||||
|
{{- range $k, $v := $attrs -}} |
||||
|
{{- $img = printf `%s %s="%s"` $img $k (string $v | htmlEscape) -}} |
||||
|
{{- end -}} |
||||
|
{{- $img = printf "<img%s>" $img | safeHTML -}} |
||||
|
|
||||
|
{{- if .IsBlock -}} |
||||
|
<figure> |
||||
|
{{ $img }} |
||||
|
{{- with .Title }} |
||||
|
<figcaption> |
||||
|
{{- . | markdownify -}} |
||||
|
</figcaption> |
||||
|
{{- end }} |
||||
|
</figure> |
||||
|
{{- else -}} |
||||
|
{{ $img }} |
||||
|
{{- end -}} |
||||
@ -0,0 +1,64 @@ |
|||||
|
{{- /* |
||||
|
-- Renders the Markdown links. |
||||
|
-- |
||||
|
-- Internal links are resolved, in this order: |
||||
|
-- 1. to a resource of the current page (attached file), which is then |
||||
|
-- published: [the slides](slides.pdf) |
||||
|
-- 2. to a page of the current site, then of the other site (language). |
||||
|
-- A flag is displayed when the target page is in a different language |
||||
|
-- than the current page. When the link text is empty, the title of the |
||||
|
-- target page is used: [](/blog/my-article.md) |
||||
|
-- 3. relative links (../other-article/) are made relative to the site root, |
||||
|
-- so that they also work in the RSS feeds. |
||||
|
-- |
||||
|
-- The output must not contain any extra whitespace since the link is |
||||
|
-- usually embedded in a sentence. |
||||
|
*/ -}} |
||||
|
{{- $u := urls.Parse .Destination -}} |
||||
|
{{- $href := .Destination -}} |
||||
|
{{- /* |
||||
|
-- An image wrapped in a link ([](URL)) is rendered as a |
||||
|
-- figure by the image render hook: a figure is not allowed in a link, so |
||||
|
-- only the image is kept. |
||||
|
*/ -}} |
||||
|
{{- $text := replaceRE `^\s*<figure>\s*(<img[^>]*>)\s*</figure>\s*$` "$1" .Text -}} |
||||
|
{{- $flag := "" -}} |
||||
|
{{- /* Links whose destination is a shortcode are left as-is (placeholder) */ -}} |
||||
|
{{- if and (not $u.IsAbs) $u.Path (not (strings.Contains .Destination "HAHAHUGOSHORTCODE")) -}} |
||||
|
{{- $fragment := cond (ne $u.Fragment "") (printf "#%s" $u.Fragment) "" -}} |
||||
|
{{- $currentPage := .Page -}} |
||||
|
{{- $currentLang := .Page.Lang -}} |
||||
|
|
||||
|
{{- /* 1. Resources of the current page (attached files) */ -}} |
||||
|
{{- with .Page.Resources.Get $u.Path -}} |
||||
|
{{- $href = printf "%s%s" .RelPermalink $fragment -}} |
||||
|
{{- else -}} |
||||
|
{{- /* 2. Pages of the current site first, then of the other site */ -}} |
||||
|
{{- $target := $currentPage.GetPage $u.Path -}} |
||||
|
{{- if and (not $target) (strings.HasPrefix $u.Path "/") -}} |
||||
|
{{- range hugo.Sites -}} |
||||
|
{{- if and (not $target) (ne .Language.Lang $currentLang) -}} |
||||
|
{{- with .GetPage $u.Path -}}{{- $target = . -}}{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
|
||||
|
{{- if $target -}} |
||||
|
{{- $href = printf "%s%s" $target.RelPermalink $fragment -}} |
||||
|
{{- if not $text -}}{{- $text = $target.Title | htmlEscape -}}{{- end -}} |
||||
|
{{- if and (eq $currentLang "en") (eq $target.Lang "fr") -}} |
||||
|
{{- $flag = partial "icons/fr.svg" $target -}} |
||||
|
{{- else if eq $currentLang "fr" -}} |
||||
|
{{- partial "lang-detection.html" $target -}} |
||||
|
{{- if $target.Store.Get "en_article_in_fr_site" -}} |
||||
|
{{- $flag = partial "icons/en.svg" $target -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- else if not (strings.HasPrefix $u.Path "/") -}} |
||||
|
{{- /* 3. Relative links */ -}} |
||||
|
{{- $href = printf "%s%s%s" (path.Join $currentPage.RelPermalink $u.Path) (cond (strings.HasSuffix $u.Path "/") "/" "") $fragment -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
<a href="{{ $href | safeURL }}"{{ with .Title }} title="{{ . }}"{{ end }}>{{ $text | safeHTML }}</a> |
||||
|
{{- with $flag }} {{ . | strings.TrimSpace | safeHTML }}{{ end -}} |
||||
|
Before Width: | Height: | Size: 676 B After Width: | Height: | Size: 689 B |
@ -1,15 +1,22 @@ |
|||||
{{ if and .IsPage .IsTranslated (eq .Lang "fr") }} |
{{- /* |
||||
<!-- Try to compare files by SH256 fingerprint. --> |
-- Detects the english articles published as-is in the french site and |
||||
{{ if and (index .AllTranslations 0).File (index .AllTranslations 1).File }} |
-- sets "en_article_in_fr_site" in the page store. |
||||
{{ $file0 := readFile (index .AllTranslations 0).File.Filename }} |
-- |
||||
{{ $file1 := readFile (index .AllTranslations 1).File.Filename }} |
-- This partial must not output anything since it is also called from |
||||
{{ if eq (sha256 $file0) (sha256 $file1) }} |
-- inline contexts (internalLink shortcode, article headlines). |
||||
{{ .Store.Set "en_article_in_fr_site" true }} |
*/ -}} |
||||
{{ end }} |
{{- if and .IsPage .IsTranslated (eq .Lang "fr") -}} |
||||
{{ else }} |
{{- if and (index .AllTranslations 0).File (index .AllTranslations 1).File -}} |
||||
<!-- Sometimes there is no file though. In that case, compare the content. --> |
{{- /* Try to compare files by SHA256 fingerprint. */ -}} |
||||
{{ if eq (index .AllTranslations 0).Plain (index .AllTranslations 1).Plain }} |
{{- $file0 := readFile (index .AllTranslations 0).File.Filename -}} |
||||
{{ .Store.Set "en_article_in_fr_site" true }} |
{{- $file1 := readFile (index .AllTranslations 1).File.Filename -}} |
||||
{{ end }} |
{{- if eq (sha256 $file0) (sha256 $file1) -}} |
||||
{{ end }} |
{{- .Store.Set "en_article_in_fr_site" true -}} |
||||
{{ end }} |
{{- end -}} |
||||
|
{{- else -}} |
||||
|
{{- /* Sometimes there is no file though. In that case, compare the content. */ -}} |
||||
|
{{- if eq (index .AllTranslations 0).Plain (index .AllTranslations 1).Plain -}} |
||||
|
{{- .Store.Set "en_article_in_fr_site" true -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
|||||
@ -0,0 +1,82 @@ |
|||||
|
{{- /* |
||||
|
-- Based on the Hugo embedded opengraph.html partial (v0.167.0). |
||||
|
-- |
||||
|
-- Changes: the description comes from page-description.html and the image |
||||
|
-- from social-image.html (JPEG, 1200 px wide max). |
||||
|
*/ -}} |
||||
|
<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 partialCached "page-description.html" . .Permalink }} |
||||
|
<meta property="og:description" content="{{ . }}"> |
||||
|
{{- end }} |
||||
|
|
||||
|
{{- with or .Params.locale site.Language.Locale }} |
||||
|
<meta property="og:locale" content="{{ replace . `-` `_` }}"> |
||||
|
{{- 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 }} |
||||
|
|
||||
|
{{- with (partialCached "social-image.html" . .Permalink).image }} |
||||
|
<meta property="og:image" content="{{ .Permalink }}"> |
||||
|
<meta property="og:image:type" content="{{ .MediaType.Type }}"> |
||||
|
<meta property="og:image:width" content="{{ .Width }}"> |
||||
|
<meta property="og:image:height" content="{{ .Height }}"> |
||||
|
<meta property="og:image:alt" content="{{ $.Title | plainify }}"> |
||||
|
{{- 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 }} |
||||
@ -0,0 +1,28 @@ |
|||||
|
{{- /* |
||||
|
-- Returns the description of a page (plain text), used by the meta |
||||
|
-- description, Open Graph, Twitter cards and structured data. |
||||
|
-- |
||||
|
-- In order of preference: |
||||
|
-- 1. the "description" front matter parameter |
||||
|
-- 2. the description of the site, for the home page |
||||
|
-- 3. "Articles related to <term>" for the taxonomy term pages |
||||
|
-- 4. the summary of the page, truncated to ~160 characters |
||||
|
-- 5. the description of the site |
||||
|
-- 6. the title of the page |
||||
|
*/ -}} |
||||
|
{{- $description := "" -}} |
||||
|
{{- if .Description -}} |
||||
|
{{- $description = .Description -}} |
||||
|
{{- else if and .IsHome site.Params.description -}} |
||||
|
{{- $description = site.Params.description -}} |
||||
|
{{- else if eq .Kind "term" -}} |
||||
|
{{- $description = printf "%s %s" (i18n "articles_related_to" | strings.TrimSpace) .Title -}} |
||||
|
{{- else -}} |
||||
|
{{- $summary := .Summary | replaceRE `(?s)\s*<svg.*?</svg>` "" | plainify | htmlUnescape | replaceRE `\s+` " " | strings.TrimSpace -}} |
||||
|
{{- with $summary -}} |
||||
|
{{- $description = truncate 160 . -}} |
||||
|
{{- else -}} |
||||
|
{{- $description = or site.Params.description .Title -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- return ($description | plainify | htmlUnescape | strings.TrimSpace) -}} |
||||
@ -0,0 +1,81 @@ |
|||||
|
{{- /* |
||||
|
-- Returns the image used when the page is shared on social networks |
||||
|
-- (Open Graph, Twitter cards) and in the structured data, as a dict: |
||||
|
-- - image: the processed image resource |
||||
|
-- - isDefault: true if the default image of the site is used |
||||
|
-- |
||||
|
-- The image is chosen in this order: |
||||
|
-- 1. the first image of the "images" front matter parameter |
||||
|
-- 2. a page resource named *feature*, *cover* or *thumbnail* |
||||
|
-- 3. the first image displayed in the page content |
||||
|
-- 4. the first image of the "images" site parameter |
||||
|
-- |
||||
|
-- The image is converted to JPEG (WebP is not supported everywhere) and |
||||
|
-- resized to 1200 px wide max, without cropping: the social networks crop |
||||
|
-- it to their own aspect ratio. |
||||
|
*/ -}} |
||||
|
{{- $formats := slice "jpeg" "png" "webp" "gif" "bmp" "tiff" -}} |
||||
|
{{- $images := slice -}} |
||||
|
{{- range .Resources.ByType "image" -}} |
||||
|
{{- if in $formats .MediaType.SubType -}} |
||||
|
{{- $images = $images | append . -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
|
||||
|
{{- $source := false -}} |
||||
|
{{- $isDefault := false -}} |
||||
|
|
||||
|
{{- /* 1. The "images" front matter parameter */ -}} |
||||
|
{{- range $name := .Params.images -}} |
||||
|
{{- if not $source -}} |
||||
|
{{- range $images -}} |
||||
|
{{- if and (not $source) (eq .Name $name) -}}{{- $source = . -}}{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
|
||||
|
{{- /* 2. A page resource named *feature*, *cover* or *thumbnail* */ -}} |
||||
|
{{- if not $source -}} |
||||
|
{{- range $images -}} |
||||
|
{{- if and (not $source) (findRE `(?i)(feature|cover|thumbnail)` .Name) -}}{{- $source = . -}}{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
|
||||
|
{{- /* 3. The first image displayed in the page content */ -}} |
||||
|
{{- if and (not $source) $images -}} |
||||
|
{{- /* |
||||
|
-- The images are compared by name (without extension) since the image |
||||
|
-- render hook serves processed variants (name_hu_<hash>.webp). Do not use |
||||
|
-- .RelPermalink here: it would publish all the images of the page. |
||||
|
*/ -}} |
||||
|
{{- range findRESubmatch `<img[^>]*\ssrc="([^"]+)"` .Content -}} |
||||
|
{{- $name := index . 1 | path.Base | replaceRE `_hu_[0-9a-f]+\.\w+$` "" | replaceRE `\.\w+$` "" -}} |
||||
|
{{- if not $source -}} |
||||
|
{{- range $images -}} |
||||
|
{{- if and (not $source) (eq (replaceRE `\.\w+$` "" (path.Base .Name)) $name) -}}{{- $source = . -}}{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
|
||||
|
{{- /* 4. The default image of the site */ -}} |
||||
|
{{- if not $source -}} |
||||
|
{{- with index site.Params.images 0 -}} |
||||
|
{{- with resources.Get (strings.TrimPrefix "/" .) -}} |
||||
|
{{- $source = . -}} |
||||
|
{{- $isDefault = true -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
{{- end -}} |
||||
|
|
||||
|
{{- $result := dict -}} |
||||
|
{{- with $source -}} |
||||
|
{{- $image := . -}} |
||||
|
{{- if gt .Width 1200 -}} |
||||
|
{{- $image = .Resize "1200x jpg q85" -}} |
||||
|
{{- else -}} |
||||
|
{{- $image = .Process "jpg q85" -}} |
||||
|
{{- end -}} |
||||
|
{{- $result = dict "image" $image "isDefault" $isDefault -}} |
||||
|
{{- end -}} |
||||
|
{{- return $result -}} |
||||
@ -0,0 +1,36 @@ |
|||||
|
{{- /* |
||||
|
-- Based on the Hugo embedded twitter_cards.html partial (v0.167.0). |
||||
|
-- |
||||
|
-- Changes: the description comes from page-description.html and the image |
||||
|
-- from social-image.html (JPEG, 1200 px wide max). |
||||
|
*/ -}} |
||||
|
{{- /* The default image (avatar) is better displayed as a small card. */}} |
||||
|
{{- $social := partialCached "social-image.html" . .Permalink }} |
||||
|
{{- with $social.image }} |
||||
|
<meta name="twitter:card" content="{{ cond $social.isDefault "summary" "summary_large_image" }}"> |
||||
|
<meta name="twitter:image" content="{{ .Permalink }}"> |
||||
|
<meta name="twitter:image:alt" content="{{ $.Title | plainify }}"> |
||||
|
{{- else }} |
||||
|
<meta name="twitter:card" content="summary"> |
||||
|
{{- end }} |
||||
|
|
||||
|
{{- with or .Title site.Title site.Params.title | plainify }} |
||||
|
<meta name="twitter:title" content="{{ . }}"> |
||||
|
{{- end }} |
||||
|
|
||||
|
{{- with partialCached "page-description.html" . .Permalink }} |
||||
|
<meta name="twitter:description" content="{{ . }}"> |
||||
|
{{- 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 }} |
||||
@ -1,11 +0,0 @@ |
|||||
<!-- This shortcode renders an HTML figure based on a page resource --> |
|
||||
{{- $filename := .Get "src" -}} |
|
||||
{{- $image := .Page.Resources.GetMatch (printf "%s" $filename) -}} |
|
||||
<figure> |
|
||||
<img src="{{ $image.RelPermalink }}" alt="{{- .Get "title" | plainify -}}"> |
|
||||
{{- with .Get "title" }} |
|
||||
<figcaption> |
|
||||
{{- . | markdownify -}} |
|
||||
</figcaption> |
|
||||
{{- end }} |
|
||||
</figure> |
|
||||
@ -1,7 +0,0 @@ |
|||||
<!-- This shortcode renders an code block prefixed by a filename --> |
|
||||
<div class="highlightedFile"> |
|
||||
{{- with .Get 0 -}} |
|
||||
<div class="filename">{{ printf (i18n "file") . | safeHTML }}</div> |
|
||||
{{- end -}} |
|
||||
{{- highlight (trim .Inner "\n") (.Get 1) (.Get 2) -}} |
|
||||
</div> |
|
||||
@ -1,7 +0,0 @@ |
|||||
<!-- This shortcode renders an code block prefixed by a filename --> |
|
||||
<div class="highlightedFile"> |
|
||||
{{- with .Get 0 -}} |
|
||||
<div class="filename">{{ . | safeHTML }}</div> |
|
||||
{{- end -}} |
|
||||
{{- highlight (trim .Inner "\n") (.Get 1) (.Get 2) -}} |
|
||||
</div> |
|
||||
@ -1,31 +0,0 @@ |
|||||
<!-- This shortcode generates the HTML link to an internal resource, which can be translated or not. |
|
||||
-- It displays a country flag when the target page is in a different language than the current page. |
|
||||
-- Currently, this shortcode can only handle Hugo sites with two languages. --> |
|
||||
{{ $path := .Get "path" }} |
|
||||
{{ $currentLang := .Page.Lang }} |
|
||||
{{ $title := .Get "title" }} |
|
||||
{{ $sites := hugo.Sites }} |
|
||||
{{ if ne $currentLang (index hugo.Sites 0).Language.Lang }} |
|
||||
{{ $sites = collections.Reverse hugo.Sites }} |
|
||||
{{ end }} |
|
||||
{{ range $sites }} |
|
||||
{{ with .GetPage $path }} |
|
||||
<a href="{{ .RelPermalink }}"> |
|
||||
{{ if ne $title "" }} |
|
||||
{{ $title }} |
|
||||
{{ else }} |
|
||||
{{ .Title }} |
|
||||
{{ end }} |
|
||||
</a> |
|
||||
{{ if and (eq $currentLang "en") (eq .Lang "fr") }} |
|
||||
{{- partial "icons/fr.svg" . -}} |
|
||||
{{ end }} |
|
||||
{{ if (eq $currentLang "fr") }} |
|
||||
{{- partial "lang-detection.html" . -}} |
|
||||
{{ if .Store.Get "en_article_in_fr_site" }} |
|
||||
{{- partial "icons/en.svg" . -}} |
|
||||
{{ end }} |
|
||||
{{ end }} |
|
||||
{{ break }} |
|
||||
{{ end }} |
|
||||
{{ end }} |
|
||||
@ -1,6 +0,0 @@ |
|||||
<!-- This shortcode renders an image linked to a resource somewhere --> |
|
||||
{{- $filename := .Get "src" -}} |
|
||||
{{- $image := .Page.Resources.GetMatch (printf "%s" $filename) -}} |
|
||||
<a href="{{- .Get "href" | plainify -}}"> |
|
||||
<img src="{{ $image.RelPermalink }}"> |
|
||||
</a> |
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue