commit - 5a365c2607655acb416397319c5c362e1bbb4f15
commit + c3f5671b4eb04fba2cae977039bcf15265cb3b0e
blob - 8d00dd266fc4970b94aee4cc71061253377837bc
blob + 35887bf88046dd1ff00fb21ee83241b4d208ace8
--- README.md
+++ README.md
# Набор шаблонов для сайтов Hugo от Radium
-## Подключение темы на сайте
-Настройте [слияние](https://gohugo.io/configuration/introduction/#merge-configuration-settings) конфигурации в hugo.toml, указав:
+## Подключение темы
+Настройте [слияние конфигурации](https://gohugo.io/configuration/introduction/#merge-configuration-settings) в `hugo.toml`:
+
```toml
_merge = 'deep'
```
+Это позволяет переопределять параметры, заданные темой, в конфигурации сайта.
+
## Параметры
-Все используемые параметры должны содержаться в настройках сайта в .Params.radium
-publisher
-: ссылка на профиль публикатора для элементов JSON-LD.
-external_rel
-: rel по умолчанию для абсолютных ссылок.
+Все параметры темы находятся в пространстве имён `radium`:
-## render hooks
+```text
+.Params.radium
+```
+
+Параметры сайта доступны через:
+
+```go-html-template
+site.Params.radium
+```
+
+Параметры также могут быть переопределены для отдельной страницы через front matter.
+
+### Общие параметры
+
+`publisher`
+: ссылка на профиль издателя для элементов JSON-LD.
+
+`external_rel`
+: значение `rel` по умолчанию для абсолютных ссылок.
+
+### Изображения
+
+Параметры обработки изображений находятся в:
+
+```text
+.Params.radium.images
+```
+
+`widths`
+: набор ширин для генерации адаптивных изображений.
+
+`sizes`
+: значение атрибута `sizes` по умолчанию.
+
+`mode`
+: режим обработки изображения: `auto`, `lossy` или `lossless`.
+
+Параметры могут задаваться:
+
+1. в конфигурации темы;
+2. в конфигурации сайта;
+3. во front matter страницы;
+4. непосредственно при вызове `image`.
+
+Более специфичное значение имеет приоритет.
+
+## Render hooks
+
### render-link
-Вставляет ссылку с разрешённым назначением ссылки.
-Для абсолютных ссылок указывает rel из настроек сайта или значение по умолчанию `noopener noreferrer external`.
+Вставляет ссылку с разрешённым набором атрибутов.
+
+Для абсолютных ссылок устанавливает `rel` из настроек сайта или значение по умолчанию:
+
+```text
+noopener noreferrer external
+```
+
### render-blockquote
-[Вставляет](https://gohugo.io/render-hooks/blockquotes/) блок цитаты с указанием источника и заголовка, а также блок alert.
+[Вставляет](https://gohugo.io/render-hooks/blockquotes/) блок цитаты с указанием источника и заголовка, а также поддерживает блоки alert.
+
## Шаблоны
+
### baseof
-Базовый шаблон, включающий индексирование Pagefind только для main тега.
-Для тега html устанавливается язык и направление, если оно явно прописано в настройках языка.
-В шаблоне подключаются partial head, header, footer.
-Блок main должен быть переопределён в отдельных шаблонах.
-Блок head может быть переопределён в отдельных шаблонах, если требуется добавить что-то в тэг head.
+Базовый шаблон сайта.
+
+Включает индексирование Pagefind только для элемента `main`.
+
+Для элемента `html` устанавливает язык и направление текста, если направление явно указано в настройках языка.
+
+Подключает partials:
+
+* `head`;
+* `header`;
+* `footer`.
+
+Блок `main` должен быть переопределён в дочерних шаблонах.
+
+Блок `head` может быть переопределён, если требуется добавить дополнительные элементы в `<head>`.
+
## Partials
### attrs
-Рендерит словарь из ключей и значений в виде атрибутов тэга.
-Для булевых значений вставляется или не вставляется соответствующий ключ без значения.
+Преобразует `dict` атрибутов в строку HTML-атрибутов.
+
+Обычные значения выводятся в виде:
+
+```html
+class="example"
+```
+
+Булевы значения обрабатываются как HTML boolean attributes:
+
+* `true` — выводится только имя атрибута;
+* `false` — атрибут не выводится.
+
+Например:
+
+```go-html-template
+{{ partial "attrs.html" (dict
+ "class" "video"
+ "controls" true
+ "autoplay" false
+) }}
+```
+
+создаёт:
+
+```html
+class="video" controls
+```
+
### pick
-Отбирает из dict ключи, входящие в массив allowed.
+Возвращает новый `dict`, содержащий только ключи из переданного массива `allowed`.
+
+Например:
+
+```go-html-template
+{{- $attributes := partial "pick.html" (dict
+ "dict" .Params
+ "allowed" (slice "class" "id")
+) -}}
+```
+
+Значения `false`, `0` и пустые строки сохраняются.
+
### image
-Отображает изображение, передаваемое в .image.
-.image должен быть ресурсом, полученным через .Resources.Get* или resources.Get*.
-Для SVG изображений производит сжатие, а для всех остальных указывает ширину и высоту.
+Отображает изображение, переданное в параметре `image`.
-Если установлен .alt, то устанавливает атрибут alt.
+`image` должен быть Hugo image resource, например полученным через:
+```go-html-template
+.Resources.Get
+resources.Get
+resources.GetRemote
+```
+
+Для изображений, которые Hugo умеет обрабатывать, partial создаёт адаптивые варианты изображения.
+
+Лесенка размеров определяется параметром `widths`. Если он не передан, используются настройки страницы или сайта из:
+
+```text
+radium.images.widths
+```
+
+Размеры больше исходного изображения не создаются. Исходная ширина при этом всегда добавляется в `srcset`.
+
+Например, для исходного изображения шириной `4000px` и лесенки:
+
+```text
+480 768 1024 1440 1920
+```
+
+будут доступны варианты:
+
+```text
+480 768 1024 1440 1920 4000
+```
+
+Для исходного изображения шириной `1300px`:
+
+```text
+480 768 1024 1300
+```
+
+#### Lossy-изображения
+
+Для lossy-изображений создаются:
+
+* AVIF;
+* WebP.
+
+В HTML используется `<picture>`, где AVIF является предпочтительным форматом, а WebP — fallback.
+
+JPEG автоматически считается lossy.
+
+#### Lossless-изображения
+
+Для lossless-изображений создаётся lossless WebP.
+
+PNG и BMP автоматически считаются lossless.
+
+Для форматов, режим которых нельзя однозначно определить по MIME-типу, следует явно передать:
+
+```text
+mode = "lossy"
+```
+
+или:
+
+```text
+mode = "lossless"
+```
+
+#### Исходный формат
+
+Если исходное изображение уже находится в целевом формате и используется в исходном разрешении, оно не перекодируется повторно.
+
+#### SVG и другие необрабатываемые изображения
+
+Изображения, которые Hugo не умеет преобразовывать, передаются без изменения.
+
+SVG дополнительно минифицируется.
+
+Для SVG можно вручную передавать `width` и `height` через `attributes`.
+
+#### Атрибуты
+
+Дополнительные атрибуты `<img>` передаются через `attributes`:
+
+```go-html-template
+{{- partial "image.html" (dict
+ "image" $image
+ "page" .
+ "attributes" (dict
+ "alt" "Описание изображения"
+ "class" "photo"
+ "loading" "lazy"
+ "decoding" "async"
+ )
+) -}}
+```
+
+Если `width` и `height` не заданы, partial указывает размеры автоматически, когда Hugo может их определить.
+
+Если передан только один из этих атрибутов, второй вычисляется с сохранением соотношения сторон.
+
+Параметр `sizes` можно передать непосредственно:
+
+```go-html-template
+{{- partial "image.html" (dict
+ "image" $image
+ "page" .
+ "sizes" "(max-width: 900px) 100vw, 900px"
+) -}}
+```
+
### logo
+
Отображает логотип со ссылкой.
Параметры:
-- image - имя ресурса сайта с логотипом (img/logo.svg)
-- class - класс ссылки, содержащей логотип (logo)
-- link - ссылка, которая будет указана для логотипа (главная страница с учётом языка)
-- alt - атрибут alt изображения (Logo image)
+`image`
+: имя ресурса сайта с логотипом. По умолчанию `img/logo.svg`.
-### head/favicon, head/apple-touch-icon
-Связывают страницу с имеющимися favicon или apple-touch-icon.
-Для поиска favicon применяется маска {,**/}favicon.*, а для apple-touch-icon - {,**/}apple-touch-icon*.png
+`class`
+: класс ссылки, содержащей логотип. По умолчанию `logo`.
+`link`
+: ссылка логотипа. По умолчанию главная страница с учётом языка.
+
+`alt`
+: значение атрибута `alt`. По умолчанию `Logo image`.
+
+### head/favicon
+
+Связывает страницу с найденными favicon.
+
+Для поиска используется маска:
+
+```text
+{,**/}favicon.*
+```
+
+SVG-файлы минифицируются.
+
+Если Hugo может определить размеры растрового изображения, у `<link>` устанавливается атрибут `sizes`.
+
+### head/apple-touch-icon
+
+Связывает страницу с найденными Apple Touch Icon.
+
+Для поиска используется маска:
+
+```text
+{,**/}apple-touch-icon*.png
+```
+
### head/manifest
-Связывает страницу с manifest.json, находящимся в корне assets/
+Связывает страницу с `manifest.json`, находящимся в корне `assets/`.
+
### head/css
-Подключает css/main.css
+Подключает:
+
+```text
+css/main.css
+```
+
### head/js
-Подключает js/main.js
+Подключает:
+
+```text
+js/main.js
+```
+
### head/pagefind
-Подключение стилей и скрипта, если окружение не является разработкой.
+Подключает стили и скрипт Pagefind, если окружение не является development.
+
### head/alternate
-Указывает link alternate для других языков и форматом страницы.
+Добавляет `<link rel="alternate">` для других языков и форматов страницы.
+
### head/base
-Добавляет title, description и canonical в заголовок, а также meta charset + viewport.
+Добавляет в `<head>`:
+
+* `title`;
+* `description`;
+* canonical URL;
+* `meta charset`;
+* `viewport`.
+
### head/social
-Добавляет рендер встроенных шаблонов OpenGraph и Twitter Cards.
+Добавляет встроенные шаблоны Open Graph и Twitter Cards.
+
### schema
-Подключает JSON-LD схемы для связанных объектов.
-Принимает в контексте либо страницу, либо dict с ключами page и schema.
-Схема - это строка или массив строк.
+Подключает JSON-LD-схемы связанных объектов.
-Подключение в head:
+В контекст можно передать:
+
+* страницу;
+* `dict` с ключами `page` и `schema`.
+
+`schema` может быть строкой или массивом строк.
+
+Пример:
+
```go-html-template
{{- partial "schema/json-ld.html" . | safeHTML }}
```
-или
+
+С явным указанием схемы:
+
```go-html-template
-{{- partial "schema/json-ld.html" (dict "page" . "schema" "BreadcrumbList") | safeHTML }}
+{{- partial "schema/json-ld.html" (dict
+ "page" .
+ "schema" "BreadcrumbList"
+) | safeHTML }}
```
-Если в Page Bundle есть файл <тип>.jsonld (например, Person.jsonld), он будет добавлен в список schema.
+Если в Page Bundle находится файл `<тип>.jsonld`, например:
-Если по итогу для страницы список schema будет пустым, то будет отрендерен [встроенный](https://gohugo.io/templates/embedded/#schema) шаблон.
+```text
+Person.jsonld
+```
+соответствующая схема автоматически добавляется в список.
+
+Если в результате список схем пуст, используется [встроенный шаблон Hugo](https://gohugo.io/templates/embedded/#schema).
+
#### Статья
-Для указания publisher в статье укажите publisher в Params страницы, либо в настройках сайта.
+Для указания `publisher` укажите его в параметрах страницы либо в настройках сайта.
+
## Shortcodes
+
### include
-Позволяет [вставить](https://gohugo.io/render-hooks/blockquotes/#pageinner-details) другой markdown файл в текущий.
-Полезно при разделении частей страницы на несколько файлов.
+Позволяет [вставить](https://gohugo.io/render-hooks/blockquotes/#pageinner-details) другой Markdown-файл в текущий.
+
+Полезно для разделения большой страницы на несколько файлов.
+
### details
-Корректный details, позволяющий рендерить html.
-Аналогично [стандартному](https://gohugo.io/shortcodes/details/#article) shortcode, за исключением способа вызова — необходимо использовать вызов {{% details %}} для рендера внутреннего текста в качестве Markdown.
+Создаёт `<details>` с возможностью рендеринга внутреннего содержимого как HTML/Markdown.
+Аналогичен [стандартному shortcode Hugo](https://gohugo.io/shortcodes/details/#article), но для рендеринга внутреннего содержимого как Markdown следует использовать notation:
+
+```text
+{{% details %}}
+```
+
### a
-Создаёт ссылку с атрибутами href, class, id, rel.
-Полезно для установки rel.
+Создаёт ссылку `<a>`.
-Вызывает partial/element.
-Если необходимы другие атрибуты, то переопределите этот shortcode.
+Поддерживаются атрибуты:
+* `href`;
+* `title`;
+* `rel`;
+* `target`;
+* `class`;
+* `id`;
+* `download`;
+* `referrerpolicy`;
+* `hreflang`;
+* `type`;
+* `role`;
+* `tabindex`;
+* `aria-label`;
+* `aria-current`;
+* `aria-describedby`.
+
+Пример:
+
+```md
+{{< a href="/file.pdf" download=true rel="nofollow" >}}
+Скачать
+{{< /a >}}
+```
+
### section
-Создаёт секцию с атрибутами class, id.
-Поддерживает стандартную и markdown нотацию вызова.
+Создаёт элемент `<section>`.
+Поддерживаются атрибуты:
+
+* `class`;
+* `id`.
+
+Поддерживает обычную и Markdown-нотацию shortcode.
+
### video
-Вставляет видео.
-Поддерживает параметры:
-- class
-- poster
-- loading
-- height
-- width
-- src
-- tabindex
-- area-hidden
+Создаёт элемент `<video>`.
-В тэг вставляются следующие параметры, только если в атрибутах не передан false:
-- autoplay
-- loop
-- muted
-- playsinline
-- disablepictureinpicture
-- disableremoteplayback
+Поддерживаются обычные атрибуты:
-Если передать параметр controls с любым значением, кроме false, то будет вставлен этот атрибут.
+* `class`;
+* `poster`;
+* `height`;
+* `width`;
+* `src`;
+* `tabindex`;
+* `aria-hidden`.
+Следующие boolean attributes включены по умолчанию:
+
+* `autoplay`;
+* `loop`;
+* `muted`;
+* `playsinline`;
+* `disablepictureinpicture`;
+* `disableremoteplayback`.
+
+Их можно отключить, передав boolean `false`.
+
+`controls` по умолчанию отключён и может быть включён значением `true`.
+
+Например:
+
```md
-{{< video tabindex="-1" area-hidden="true" poster="https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217">}}
-{{< source codecs="avc1.4d002a">}}
+{{< video
+ tabindex="-1"
+ aria-hidden="true"
+ controls=true
+ poster="https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217"
+>}}
+{{< source codecs="avc1.4d002a" >}}
https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4
{{< /source >}}
{{< /video >}}
```
+Для boolean attributes рекомендуется передавать настоящие булевы значения без кавычек:
+
+```text
+controls=true
+autoplay=false
+```
+
+а не:
+
+```text
+controls="true"
+autoplay="false"
+```
+
### source
-Вставляет source для тэга video.
-Ссылку можно вставить параметром src или передав внутри тэга.
-Поддерживается вставка параметров:
-- srcset
-- sizes
-- media
-- width
-- height
-- type
+Создаёт `<source>`, предназначенный прежде всего для использования внутри `<video>`.
-Если type не задан, то тип будет определён автоматически.
+URL можно передать параметром `src`:
-При указании параметра codecs, он будет вставлен в type.
+```md
+{{< source src="/video.mp4" >}}
+```
+
+или внутренним содержимым shortcode:
+
+```md
+{{< source >}}
+/video.mp4
+{{< /source >}}
+```
+
+Поддерживаются атрибуты:
+
+* `srcset`;
+* `sizes`;
+* `media`;
+* `width`;
+* `height`.
+
+`src`, `type` и `codecs` обрабатываются отдельно.
+
+Если `type` не указан, shortcode пытается определить MIME-тип ресурса автоматически.
+
+При указании `codecs` значение добавляется к `type`, например:
+
+```html
+type="video/mp4; codecs=avc1.4d002a"
+```
blob - /dev/null
blob + 4c66731acc32bddd340dbc2d4cf063670ae1cb91 (mode 644)
--- /dev/null
+++ config/_default/params.toml
+[radium.images]
+widths = [480, 768, 1024, 1440, 1920]
+sizes = "100vw"
+mode = "auto"
blob - 00cb92cb03bf4a2f58a2ee978a74f1225ca819d8
blob + cbf1202e44f25e6afa8801855925e80f45231689
--- layouts/_partials/image.html
+++ layouts/_partials/image.html
-{{- $img := .image }}
-{{- $width := .width }}
-{{- $height := .height }}
-{{- if eq $img.MediaType.SubType "svg" }}
- {{- $img = $img | minify }}
-{{- else }}
- {{- $width = $width or $img.Width }}
- {{- $height = $height or $img.Height }}
-{{- end }}
-<img
- src="{{ $img.RelPermalink }}"
- {{- with $width }}
- width="{{ . }}"
- {{- end }}
- {{- with $height }}
- height="{{ . }}"
- {{- end }}
- {{ with .alt }}alt="{{ . }}"{{ end }}
->
+{{- $image := .image -}}
+{{- $page := .page -}}
+{{- $attributes := .attributes | default dict -}}
+
+{{- if not $image -}}
+ {{- errorf "image.html: image is required" -}}
+{{- end -}}
+
+{{- if not (reflect.IsImageResource $image) -}}
+ {{- errorf "image.html: %q is not an image resource" $image.Name -}}
+{{- end -}}
+
+
+{{/* Processable raster image */}}
+
+{{- if reflect.IsImageResourceProcessable $image -}}
+
+ {{/* Configuration: site -> page -> invocation */}}
+
+ {{- $config := site.Params.radium.images -}}
+
+ {{- with $page -}}
+ {{- with .Params.radium.images -}}
+ {{- $config = merge $config . -}}
+ {{- end -}}
+ {{- end -}}
+
+ {{- $widths := .widths | default $config.widths -}}
+ {{- $sizes := .sizes | default $config.sizes -}}
+ {{- $mode := .mode | default $config.mode | lower -}}
+
+
+ {{/* Normalize configured widths */}}
+
+ {{- $normalized := slice -}}
+
+ {{- range $widths -}}
+ {{- $width := int . -}}
+
+ {{- if gt $width 0 -}}
+ {{- $normalized = $normalized | append $width -}}
+ {{- end -}}
+ {{- end -}}
+
+ {{- $widths = collections.Sort (collections.Uniq $normalized) -}}
+
+ {{- if not $widths -}}
+ {{- errorf "image.html: width ladder is empty" -}}
+ {{- end -}}
+
+
+ {{/*
+ Build the actual ladder.
+
+ Never upscale configured variants, but always include
+ the original width.
+
+ 1300 + [480 768 1024 1440 1920]
+ -> [480 768 1024 1300]
+
+ 4000 + [480 768 1024 1440 1920]
+ -> [480 768 1024 1440 1920 4000]
+ */}}
+
+ {{- $targets := slice -}}
+
+ {{- range $widths -}}
+ {{- if le . $image.Width -}}
+ {{- $targets = $targets | append . -}}
+ {{- end -}}
+ {{- end -}}
+
+ {{- $targets = $targets | append $image.Width -}}
+ {{- $targets = collections.Sort (collections.Uniq $targets) -}}
+
+
+ {{/*
+ src gets the largest configured width that does not
+ exceed the original.
+
+ The original itself remains available through srcset.
+ */}}
+
+ {{- $fallbackWidth := $image.Width -}}
+ {{- $maxWidth := index $widths (sub (len $widths) 1) -}}
+
+ {{- if gt $image.Width $maxWidth -}}
+ {{- $fallbackWidth = $maxWidth -}}
+ {{- end -}}
+
+
+ {{/* Compression mode */}}
+
+ {{- if eq $mode "auto" -}}
+
+ {{- if eq $image.MediaType.Type "image/jpeg" -}}
+ {{- $mode = "lossy" -}}
+
+ {{- else if in
+ (slice "image/png" "image/bmp")
+ $image.MediaType.Type
+ -}}
+ {{- $mode = "lossless" -}}
+
+ {{- else -}}
+ {{- errorf
+ "image.html: cannot determine compression mode of %q (%s); specify mode"
+ $image.Name
+ $image.MediaType.Type
+ -}}
+ {{- end -}}
+
+ {{- else if not (in (slice "lossy" "lossless") $mode) -}}
+
+ {{- errorf
+ "image.html: invalid mode %q; expected auto, lossy, or lossless"
+ $mode
+ -}}
+
+ {{- end -}}
+
+
+ {{/* WebP variants */}}
+
+ {{- $webp := partial "image/variants.html" (dict
+ "image" $image
+ "widths" $targets
+ "format" "webp"
+ "mode" $mode
+ ) -}}
+
+ {{- $fallback := index
+ $webp.variants
+ (printf "%d" $fallbackWidth)
+ -}}
+
+
+ {{/* Width / height */}}
+
+ {{- $defaults := dict "alt" "" -}}
+
+ {{- $hasWidth := isset $attributes "width" -}}
+ {{- $hasHeight := isset $attributes "height" -}}
+
+ {{- if and (not $hasWidth) (not $hasHeight) -}}
+
+ {{- $defaults = merge $defaults (dict
+ "width" $fallback.Width
+ "height" $fallback.Height
+ ) -}}
+
+ {{- else if and $hasWidth (not $hasHeight) -}}
+
+ {{- $width := int $attributes.width -}}
+ {{- $height := int (math.Round (mul
+ $fallback.Height
+ (div (float $width) $fallback.Width)
+ )) -}}
+
+ {{- $defaults = merge $defaults (dict
+ "height" $height
+ ) -}}
+
+ {{- else if and $hasHeight (not $hasWidth) -}}
+
+ {{- $height := int $attributes.height -}}
+ {{- $width := int (math.Round (mul
+ $fallback.Width
+ (div (float $height) $fallback.Height)
+ )) -}}
+
+ {{- $defaults = merge $defaults (dict
+ "width" $width
+ ) -}}
+
+ {{- end -}}
+
+
+ {{/* User attributes override defaults.
+ Generated resource attributes override everything. */}}
+
+ {{- $attributes = merge
+ $defaults
+ $attributes
+ (dict
+ "src" $fallback.RelPermalink
+ "srcset" $webp.srcset
+ "sizes" $sizes
+ )
+ -}}
+
+
+ {{/* Lossy: AVIF + WebP fallback */}}
+
+ {{- if eq $mode "lossy" -}}
+
+ {{- $avif := partial "image/variants.html" (dict
+ "image" $image
+ "widths" $targets
+ "format" "avif"
+ "mode" "lossy"
+ ) -}}
+
+ <picture>
+ <source{{ partial "attrs.html" (dict
+ "type" "image/avif"
+ "srcset" $avif.srcset
+ "sizes" $sizes
+ ) }}>
+ <img{{ partial "attrs.html" $attributes }}>
+ </picture>
+
+ {{- else -}}
+
+ <img{{ partial "attrs.html" $attributes }}>
+
+ {{- end -}}
+
+
+{{/* Non-processable image */}}
+
+{{- else -}}
+
+ {{/* SVG can still be minified. */}}
+
+ {{- if eq $image.MediaType.Type "image/svg+xml" -}}
+ {{- $image = resources.Minify $image -}}
+ {{- end -}}
+
+ {{- $defaults := dict "alt" "" -}}
+
+
+ {{/*
+ Some non-processable formats have readable dimensions.
+ SVG and ICO, for example, don't.
+ */}}
+
+ {{- if reflect.IsImageResourceWithMeta $image -}}
+
+ {{- $hasWidth := isset $attributes "width" -}}
+ {{- $hasHeight := isset $attributes "height" -}}
+
+ {{- if and (not $hasWidth) (not $hasHeight) -}}
+
+ {{- $defaults = merge $defaults (dict
+ "width" $image.Width
+ "height" $image.Height
+ ) -}}
+
+ {{- else if and $hasWidth (not $hasHeight) -}}
+
+ {{- $width := int $attributes.width -}}
+ {{- $height := int (math.Round (mul
+ $image.Height
+ (div (float $width) $image.Width)
+ )) -}}
+
+ {{- $defaults = merge $defaults (dict
+ "height" $height
+ ) -}}
+
+ {{- else if and $hasHeight (not $hasWidth) -}}
+
+ {{- $height := int $attributes.height -}}
+ {{- $width := int (math.Round (mul
+ $image.Width
+ (div (float $height) $image.Height)
+ )) -}}
+
+ {{- $defaults = merge $defaults (dict
+ "width" $width
+ ) -}}
+
+ {{- end -}}
+
+ {{- end -}}
+
+ {{- $attributes = merge
+ $defaults
+ $attributes
+ (dict "src" $image.RelPermalink)
+ -}}
+
+ <img{{ partial "attrs.html" $attributes }}>
+
+{{- end -}}
blob - /dev/null
blob + cf14416326313a72f0b52d536393e2e8b916abea (mode 644)
--- /dev/null
+++ layouts/_partials/image/variants.html
+{{- $variants := dict -}}
+{{- $srcset := slice -}}
+{{- $mediaType := printf "image/%s" .format -}}
+
+{{- range .widths -}}
+ {{- $width := int . -}}
+ {{- $resource := $.image -}}
+
+ {{- $sameWidth := eq $width $.image.Width -}}
+ {{- $sameFormat := eq $.image.MediaType.Type $mediaType -}}
+
+ {{- if not (and $sameWidth $sameFormat) -}}
+ {{- if $sameWidth -}}
+ {{- $resource = $.image.Process (printf
+ "%s %s"
+ $.format
+ $.mode
+ ) -}}
+ {{- else -}}
+ {{- $resource = $.image.Process (printf
+ "resize %dx %s %s"
+ $width
+ $.format
+ $.mode
+ ) -}}
+ {{- end -}}
+ {{- end -}}
+
+ {{- $variants = merge $variants (dict
+ (printf "%d" $width)
+ $resource
+ ) -}}
+
+ {{- $srcset = $srcset | append (printf
+ "%s %dw"
+ $resource.RelPermalink
+ $resource.Width
+ ) -}}
+{{- end -}}
+
+{{- return (dict
+ "variants" $variants
+ "srcset" (delimit $srcset ", ")
+) -}}