diff --git a/src/config.yml b/src/config.yml index 6b3e7f7..6805895 100644 --- a/src/config.yml +++ b/src/config.yml @@ -1,12 +1,18 @@ baseURL: 'https://oscarmlage.com' languageCode: 'en-us' title: 'oscarmlage' -theme: 'oscar' +theme: + - 'oscar' + - 'hugo-shortcode-gallery' pygmentsStyle: "monokai" canonifyurls: true paginate: 15 summarylength: 30 +timeout: 60000 +params: + galleryLoadJQuery: true + defaultContentLanguage: "en" markup: diff --git a/src/themes/hugo-shortcode-gallery/README.md b/src/themes/hugo-shortcode-gallery/README.md new file mode 100644 index 0000000..2fe0e3a --- /dev/null +++ b/src/themes/hugo-shortcode-gallery/README.md @@ -0,0 +1,134 @@ +# hugo-shortcode-gallery + +This is a theme component for hugo. + +This component contains a shortcode to include a gallery in your .md files. + +The gallery is rendered using autogenerated thumbnails arranged in a +[grid](http://miromannino.github.io/Justified-Gallery/). With a click on the images +a [lightbox](http://brutaldesign.github.io/swipebox/) is opened an all images can be +viewed fullscreen. + +# Demo + +You can see this shortcode-gallery in action on [my website](https://matze.rocks/images/). + +## Installation + +Clone this git repository into your *themes* folder. + +``` +git clone https://github.com/mfg92/hugo-shortcode-gallery.git +``` + +Next edit your projects +*config.toml* and add this theme component to your themes: + +``` +theme = ["your-main-theme", "hugo-shortcode-gallery"] +``` + +To read about hugo's theme components and how to use them have a look at +https://gohugo.io/hugo-modules/theme-components/. + + +## Usage Example + +Here is an usage example: + +``` +{{< gallery match="images/*" sortOrder="desc" rowHeight="150" margins="5" thumbnailResizeOptions="600x600 q90 Lanczos" showExif=true previewType="blur" embedPreview="true" >}} +``` + +This shortcode will generate a gallery containing all images of the folder *images*. +The folder must be next to the .md file where this gallery is used in. This uses [page bundles](https://gohugo.io/content-management/page-bundles/) +so the directory layout should look like this: + +``` +new-post-name/ + index.md + images/ + DSC_0001.jpg + DSC_0002.jpg +``` + +The parameter `sortOrder` decides whether the images are sorted ascending ("asc") or descending ("desc"). + +The `rowHeight` parameter determines the height of the rows that are displayed while the +`margin` parameter defines the gap between the images. + +A thumbnail is generated using the `thumbnailResizeOptions` parameter, they are handed over +to *Hugo's* [image processing](https://gohugo.io/content-management/image-processing/) +function using the fit method. In the example above, the generated thumbnails have a width of max 600 pixel and +a height of max 600, the actual width and height depend on the original aspect ratio. The JPEG image quality is 90% and the +scaling uses the high quality *Lanczos* filter. + +If `previewType` is set to "blur" (or "color"), a very low resolution image (or a single pixel image) will be loaded for every image in the gallery first. +The hight resolution thumbnail images (see `thumbnailResizeOptions`) will only be loaded if they are on the currently visible part of the page (or close to it). +This leads to a faster loading page. You can set `previewType` to "none" to disable this feature and all thumbnails will be directly loaded. + +Enable `embedPreview` to let hugo embed the tiny preview image directly in the page HTML as a base64 strings. This reduces the amount of required network round trip times. + +The setting `thumbnailHoverEffect` configures what should happen when the mouse hovers above a thumbnail in the gallery. +It defaults to "none", but it can be set to "enlarge", in that case the image is scaled up (x1.1) in a short smooth animation. + +The size of the image as shown in the gallery can be customised using the (optional) `imageResizeOptions` parameter. The syntax is the same as for `thumbnailResizeOptions`. If ommited, the image will be displayed in its original size. + +The setting `lastRow` configures the justification of the last row of the grid. When set to "justify", the entire grid including the last row will be fully-justified, right and left. This parameter respects all of the `lastRow` options of Justified Gallery, including "nojustify" and "hide". + +When the users clicks on an image, a lightbox shows up displaying the clicked image in large using the whole available space. +If the image contains a title/description in the EXIF metadata field _ImageDescription_ or a title is defined in the image's sidecar file (see section below) there will be a top bar displaying that. +If the `showExif` option is set to `true` (without quotes), some parts of the image's EXIF data will be shown on the bottom bar e.g.: "Canon EOS 80D + EF100-400mm f/4.5-5.6L IS II USM 400mm f/8 1/400sec ISO 2500". +The EXIF display will only work if you add following lines to your *config.toml*: +```TOML +[imaging.exif] + includeFields = ".*" +``` + +An advanced setting is `filterOptions`: It allows the user to filter the displayed images by using buttons. +The text of the buttons and the regex used to filter has to be specified in a JSON array of objects. Currently it is only supported to filter by EXIF tags, image description, start rating or color labels. In the future it will be possible to filter by image name or other EXIF fields (pull requests are welcome). In addition to the metadata of the EXIF embedded in the image, a metadata sidecar file (see section below) can be used to add metadata for filtering. + +Additionally to the filter buttons, a button to activate full screen mode of the gallery is added. + +An example of the `filterOptions` JSON: +``` +filterOptions="[{label: 'All', tags: '.*'}, {label: 'Birds', tags: 'bird'}, {label: 'Macro', tags: 'macro'}, {label: 'Insects', tags: 'insect'}]" +``` + +When `filterOptions` is used, the switch `storeSelectedFilterInUrl` can be set to `true`. This will instruct the gallery to append the name of the filter to the url displayed in the browser when a filter button is clicked. This has two purposes: The user can share this link and recipients will see the gallery with the same filter as the original user. Furthermore the selected filter is stored in the browsers history. + +As many websites/themes already include *jQuery*, this theme component will use the available *jQuery* lib. +If the page does not already use *jQuery* the parameter `loadJQuery=true` must be used to +instruct the theme component to load the provided *jQuery* lib. + +All settings can be done globally in the site's *config.toml*, for that the prefix `gallery` has to be used. E.g. `galleryLoadJQuery` instead of `loadJQuery`. + +## Sidecar files + +The metadata embedded in a image can be extended/overshadowed by a metadata sidecar file. The file must have the same name as the image plus ".meta" (e.g. "image.jpg.meta"). The content has to be a *JSON* like: + +```JSON +{ +"Tags": ["macro","insect"], +"Title": "Maya the Bee", +"ColorLabels": "RG", +"Rating": 3 +} + ``` + +## Requirements + +This component requires a hugo version >= 0.59. + +## Dependencies + +The component uses (and includes) [*Justified Gallery*](http://miromannino.github.io/Justified-Gallery/) +to render the images between the text and [*Swipebox*](http://brutaldesign.github.io/swipebox/) +to show them full screen. These dependencies are included in this repository. + +## Troubleshooting + +When bigger galleries are processed it can be required to set hugo's timeout property in the *config.toml* to a higher value: +``` +timeout = 60000 # This is required for larger galleries to be build (60 sec) +``` diff --git a/src/themes/hugo-shortcode-gallery/assets/shortcode-gallery/filterbar.sass b/src/themes/hugo-shortcode-gallery/assets/shortcode-gallery/filterbar.sass new file mode 100644 index 0000000..808f801 --- /dev/null +++ b/src/themes/hugo-shortcode-gallery/assets/shortcode-gallery/filterbar.sass @@ -0,0 +1,51 @@ +/* Changes made here sadly only apply after restarting hugo server */ + +/* make 5px space between the button(filter options) in the filter bar +.justified-gallery-filterbar + display: flex + justify-content: flex-start + flex-wrap: wrap + gap: 5px + + button + padding: 6px + border: 1px solid #fff + border-radius: 5px + background-color: transparent + font-weight: bold + color: #fff + line-height: 1em + + &:hover + text-decoration: underline + + &.selected + text-decoration: underline + background-color: #fff3 + + svg + width: 1em + height: 1em + transform: rotate(90deg) + transition: transform .2s linear + + &:hover svg + transform: rotate(90deg) scale(1.3) + + +.fulltab + position: absolute + top: 0 + left: 0 + z-index: 100 + min-height: 100% + background-color: #222 + + &.justified-gallery-filterbar + position: sticky + top: 0 + left: 0 + z-index: 101 + background-color: #222 + padding: 5px + margin: 0px \ No newline at end of file diff --git a/src/themes/hugo-shortcode-gallery/assets/shortcode-gallery/font-awesome/compress-alt-solid.svg b/src/themes/hugo-shortcode-gallery/assets/shortcode-gallery/font-awesome/compress-alt-solid.svg new file mode 100644 index 0000000..4625a19 --- /dev/null +++ b/src/themes/hugo-shortcode-gallery/assets/shortcode-gallery/font-awesome/compress-alt-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/themes/hugo-shortcode-gallery/assets/shortcode-gallery/font-awesome/expand-alt-solid.svg b/src/themes/hugo-shortcode-gallery/assets/shortcode-gallery/font-awesome/expand-alt-solid.svg new file mode 100644 index 0000000..14f859b --- /dev/null +++ b/src/themes/hugo-shortcode-gallery/assets/shortcode-gallery/font-awesome/expand-alt-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/themes/hugo-shortcode-gallery/assets/shortcode-gallery/font-awesome/license.txt b/src/themes/hugo-shortcode-gallery/assets/shortcode-gallery/font-awesome/license.txt new file mode 100644 index 0000000..c27f229 --- /dev/null +++ b/src/themes/hugo-shortcode-gallery/assets/shortcode-gallery/font-awesome/license.txt @@ -0,0 +1 @@ +https://fontawesome.com/license/free \ No newline at end of file diff --git a/src/themes/hugo-shortcode-gallery/config.toml b/src/themes/hugo-shortcode-gallery/config.toml new file mode 100644 index 0000000..f1d0165 --- /dev/null +++ b/src/themes/hugo-shortcode-gallery/config.toml @@ -0,0 +1,3 @@ +# this allows to use resources.Get to get resources of the folder "assets" +# see https://github.com/gohugoio/hugo/commit/dea71670c059ab4d5a42bd22503f18c087dd22d4 +assetDir = "assets" \ No newline at end of file diff --git a/src/themes/hugo-shortcode-gallery/layouts/shortcodes/gallery.html b/src/themes/hugo-shortcode-gallery/layouts/shortcodes/gallery.html new file mode 100644 index 0000000..73e447a --- /dev/null +++ b/src/themes/hugo-shortcode-gallery/layouts/shortcodes/gallery.html @@ -0,0 +1,412 @@ +{{ $currentPage := . }} + +{{ $images := (.Page.Resources.ByType "image") }} +{{ if .Get "match"}} + {{ $images = (.Page.Resources.Match (.Get "match")) }} +{{ end }} + +{{ $filterOptions := .Get "filterOptions" | default (.Site.Params.galleryFilterOptions | default "[]") }} +{{ if not $filterOptions }} + {{ $filterOptions = "[]" }} +{{ end }} + +{{ $storeSelectedFilterInUrl := .Get "storeSelectedFilterInUrl" | default (.Site.Params.storeSelectedFilterInUrl | default false) }} + +{{ $sortOrder := .Get "sortOrder" | default (.Site.Params.gallerySortOrder | default "asc") }} + +{{ $rowHeight := .Get "rowHeight" | default (.Site.Params.galleryRowHeight | default 150) }} + +{{ $margins := .Get "margins" | default (.Site.Params.galleryRowMargins | default 5) }} + +{{ $thumbnailResizeOptions := .Get "thumbnailResizeOptions" | default (.Site.Params.galleryThumbnailResizeOptions | default "300x150 q85 Lanczos") }} + +{{ $imageResizeOptions := .Get "imageResizeOptions" | default .Site.Params.galleryImageResizeOptions }} + +{{ $loadJQuery := .Get "loadJQuery" | default (.Site.Params.galleryLoadJQuery | default false) }} + +{{ $showExif := .Get "showExif" | default (.Site.Params.galleryShowExif | default false) }} + +{{ $justifiedGalleryParameters := .Get "justifiedGalleryParameters" | default (.Site.Params.galleryJustifiedGalleryParameters | default "") }} + +{{ $previewType := .Get "previewType" | default (.Site.Params.galleryPreviewType | default "blur") }} + +{{ $embedPreview := .Get "embedPreview" | default (.Site.Params.galleryEmbedPreview | default true) }} + +{{ $thumbnailHoverEffect := .Get "thumbnailHoverEffect" | default (.Site.Params.galleryThumbnailHoverEffect | default "none") }} + + +{{ $thumbnailResourceDir := printf "%s%s" (.Site.Params.resourceDir | default "resources") "/_gen/images/" }} + + +{{ if not (.Page.Scratch.Get "galleryLoaded") }} + {{ .Page.Scratch.Set "galleryLoaded" true }} + + + {{ if $loadJQuery }} + + {{ end }} + + {{ if not (eq $previewType "none") }} + + {{ end }} + + + + + + +{{ end }} + + + + +{{ $galleryId := (printf "gallery-%v-%v" .Page.File.UniqueID .Ordinal)}} +{{ $galleryWrapperId := (printf "gallery-%v-%v-wrapper" .Page.File.UniqueID .Ordinal)}} + +