Skip to content

Commit

Permalink
Added ability to reference global resources (mfg92#84)
Browse files Browse the repository at this point in the history
* Added ability to reference "global" resources
* Updated README to include info about the globalMatch.

---------

Co-authored-by: mfg92 <[email protected]>
  • Loading branch information
2 people authored and alexvanderberkel committed Aug 22, 2024
1 parent d3d1b42 commit a3973cc
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 19 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
71 changes: 62 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# hugo-shortcode-gallery

This is a theme component for hugo.
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 and all images can be
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 and all images can be
viewed full screen.

# Demo
Expand All @@ -33,20 +33,20 @@ hugo mod get -u
```

### Method B - Install via git
Clone this git repository into your *themes* folder.
Clone this git repository into your *themes* folder.

```
git clone https://github.com/mfg92/hugo-shortcode-gallery.git
```

Next edit your projects
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
To read about hugo's theme components and how to use them have a look at
https://gohugo.io/hugo-modules/theme-components/.

To update to the latest version run inside *themes/hugo-shortcode-gallery*:
Expand Down Expand Up @@ -113,19 +113,72 @@ The text of the buttons and the regex used to filter has to be specified in a JS

Additionally to the filter buttons, a button to activate full screen mode of the gallery is added.

An example of the `filterOptions` JSON:
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.
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`.

### Using repeating images across pages

If you need to use the same images across pages/sections of the website, you can
place the repeating images under `/assets` and use the `globalMatch` instead
of the `match` parameter. The `match` parameter will only look locally to the
page to find resources, while `globalMatch` will look for global resources,
as detailed below.

For example, if your Hugo project looks like this:

```
.
├── archetypes
├── assets
│   ├── css
│   └── images
│   └── something
│   ├── test1.png
│   ├── test1.png.meta
├── config.toml
├── content
│   ├── gallery
│   │   └── index.md
│   ├── news
│   │   ├── some_news
│   │   │   └── index.md
├── static
└── themes
```

In both `content/gallery/index.md` and `content/news/some_news/index.md` you can then include the following:

```
{{<gallery
globalMatch="images/something/*"
sortOrder="asec"
rowHeight="150"
margins="5"
thumbnailResizeOptions="600x600 q90 Lanczos"
showExif=true
previewType="blur"
embedPreview=true
loadJQuery=true
>}}
```

Note the `globalMatch` parameter, and the path `images/something/*` relative
to `/assets`.
Both pages will then render the same images. It's important that your repeating
images are placed under `/assets`, as this is what is considered as "global"
resources for Hugo. If both `match` and `globalMatch` parameters are present in
your shortcode, the priority is given to the local `match`.

## 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:
Expand Down
32 changes: 22 additions & 10 deletions layouts/shortcodes/gallery.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
{{ $currentPage := . }}

{{ $images := slice }}
{{ if .Get "match"}}
{{ $images = (.Page.Resources.Match (.Get "match")) }}
{{ $globalMatch := .Get "globalMatch" }}
{{ $localMatch := .Get "match" }}

{{ if $localMatch }}
{{ $images = (.Page.Resources.Match $localMatch )}}
{{ else if $globalMatch }}
{{ $images = (resources.Match (.Get "globalMatch")) }}
{{ else }}
{{ $images = (.Page.Resources.ByType "image") }}
{{ end }}
Expand Down Expand Up @@ -54,7 +59,7 @@
{{ if $loadJQuery }}
<script src="{{ "shortcode-gallery/jquery-3.7.1.min.js" | relURL }}"></script>
{{ end }}

{{ if not (eq $previewType "none") }}
<script src="{{ "shortcode-gallery/lazy/jquery.lazy.min.js" | relURL }}"></script>
{{ end }}
Expand Down Expand Up @@ -97,7 +102,14 @@

{{/* Get metadata from sidecar file, if present. Else an empty dictionary is used. */}}
{{ $metaFileName := print $original.Name ".meta"}}
{{ $metadata := $currentPage.Page.Resources.GetMatch ($metaFileName) }}

{{ $metadata := slice }}
{{ if and $globalMatch (not $localMatch) }}
{{ $metadata = resources.GetMatch ($metaFileName) }}
{{ else }}
{{ $metadata = $currentPage.Page.Resources.GetMatch ($metaFileName) }}
{{ end }}

{{ if $metadata }}
{{ $metadata = $metadata.Content }}
{{ $metadata = $metadata | unmarshal }}
Expand Down Expand Up @@ -262,7 +274,7 @@
// if there is at least one filter option
{{ if not (eq $filterOptions "[]") }}
// we first show no images at all
// till the code way below selects a filter and applies it
// till the code way below selects a filter and applies it
// this prevent creating the layout twice
filter : () => false
{{ end }}
Expand All @@ -279,7 +291,7 @@
return (entry, index, array) => {
let meta = $(entry).find("a").attr("data-meta");
meta = meta ? JSON.parse(meta) : {};

let include = filterFunction(meta);

// only those images visible in justified gallery should be displayed
Expand Down Expand Up @@ -333,9 +345,9 @@
});
};


const filterOptions = {{ $filterOptions | safeJS }};

// insert a div for inserting filter buttons before the gallery
const filterBar = $("<div class='justified-gallery-filterbar'/>");
gallery.before(filterBar);
Expand Down Expand Up @@ -381,7 +393,7 @@
filterBar.find('.selected').removeClass('selected');
filterButton.addClass("selected");
};

// check if the url contains an instruction to apply a specific filter
// eg. example.com/images/#gallery-filter=Birds
const params = new URLSearchParams(location.hash.replace(/^\#/,""));
Expand All @@ -391,7 +403,7 @@
activeFilter = filterOptions[0].label;
}

// create a button for each filter entry
// create a button for each filter entry
filterOptions.forEach(filterConfig => {
let filter; // create a filter function based on the available attributes of filterConfig
if(filterConfig.tags) {
Expand Down

0 comments on commit a3973cc

Please sign in to comment.