Initial commit

This commit is contained in:
Nasir Anthony Montalvo
2025-11-13 14:48:58 -06:00
committed by GitHub
commit 526096840e
2349 changed files with 19464 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
{% comment %}
Bootstrap accordion feature, https://getbootstrap.com/docs/5.1/components/accordion/
e.g. --> {% include feature/accordion.html title1="Example section" text1=example1 title2="Section two" text2=example2 title3="Section three" text3=example3 %}
Options:
- "title1", "title2", "title3" = title for each section of accordion (max three)
- "text1", "text2", "text3" = text for each section of accordion (max three). You will probably want to capture the text using a Liquid capture, then use the variable to provide text to this include.
- "open" = optional, by default is "false". Add "true" to have the first section of the accordion open.
- "heading_level" = customize the level of the heading if necessary for accessibility, choose "h1", "h2", "h3", etc (optional, default "h3")
{%- endcomment -%}
<div class="accordion mb-3 narrow-content" id="accordionInclude">
<div class="accordion-item">
<{{ include.heading_level | default: 'h3' | strip }} class="accordion-header" id="headingOne">
<button class="accordion-button{% unless include.open %} collapsed{% endunless %}" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="{% if include.open == true %}true{% else %}false{% endif %}" aria-controls="collapseOne">
{{ include.title1 }}
</button>
</{{ include.heading_level | default: 'h3' | strip }}>
<div id="collapseOne" class="accordion-collapse collapse{% if include.open == true %} show{% endif %}" aria-labelledby="headingOne" data-bs-parent="#accordionInclude">
<div class="accordion-body">
{{ include.text1 | markdownify }}
</div>
</div>
</div>
{% if include.title2 %}
<div class="accordion-item">
<{{ include.heading_level | default: 'h3' | strip }} class="accordion-header" id="headingTwo">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
{{ include.title2 }}
</button>
</{{ include.heading_level | default: 'h3' | strip }}>
<div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#accordionInclude">
<div class="accordion-body">
{{ include.text2 | markdownify }}
</div>
</div>
</div>
{% endif %}
{% if include.title3 %}
<div class="accordion-item">
<{{ include.heading_level | default: 'h3' | strip }} class="accordion-header" id="headingThree">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
{{ include.title3 }}
</button>
</{{ include.heading_level | default: 'h3' | strip }}>
<div id="collapseThree" class="accordion-collapse collapse" aria-labelledby="headingThree" data-bs-parent="#accordionInclude">
<div class="accordion-body">
{{ include.text3 | markdownify }}
</div>
</div>
</div>
{% endif %}
</div>

View File

@@ -0,0 +1,17 @@
{% comment %}
Bootstrap Alert, https://getbootstrap.com/docs/5.1/components/alerts/
E.G. --> {% include feature/alert.html text="example text" color="warning" align="center" %}
Options:
- "text" = text for alert, can use Markdown.
- "color" = a Bootstrap color (primary, secondary, success, danger, warning, info, light, dark)
- "align" = text alignment (center, right, left)
{%- endcomment -%}
<div class="narrow-content">
<div class="alert alert-{{ include.color | default: 'primary' }} feature-alert {% if include.align %}text-{{ include.align | default: 'center' }}{% endif %}" role="alert">
{{ include.text | markdownify }}
</div>
</div>

View File

@@ -0,0 +1,97 @@
{% comment %}
Audio modal feature from an item's objectid or external link.
This include adds a card featuring the thumb image, title, and description of an audio item--when clicked it opens a modal containing the audio embed. The modal displays audio information, transcript, link to item. This is especially useful feature if you would like multiple videos on one page.
E.G. --> {% include feature/audio-modal.html objectid="demo_003" %}
It requires an "objectid" with the include, which is used to find the audio details. Alternatively, a URL to an external audio file can be used in "objectid".
Options:
- "objectid" = several options below (required)
- an objectid of an audio item in this collection, e.g. "demo_003"
- an external link to an MP3 file hosted elsewhere, e.g. "https://www.lib.uidaho.edu/digital/mp3s/Clouds.mp3"
- a relative link to an MP3 file somewhere else in this repository, e.g. "/assets/{{ includeid }}.mp3"
- "title" = by default automatically adds the title from item metadata, which will be used for the modal btn and modal title. Manually set by using the title option. (optional)
- "heading_level" = customize the level of the heading if necessary for accessibility, choose "h1", "h2", "h3", etc (optional, default "h2")
- "caption" = by default the figure include automatically uses the description of the item from your metadata. The caption option allows you to manually add a different caption, or give the value false for none. (optional)
- "image" = by default if using an objectid, if the item has a image_small value, the image will be used on the card. The image option allows you to manually add a image for non-collection videos. Give "false" to not display an image (optional)
- "transcript" = by default if using an objectid, if the item has a object_transcript value, the view transcript button will automatically be added. The transcript option allows you to manually add a different transcript or provide one for non-collection videos. (optional)
Note: if you have issues make sure the item is a audio item.
Audio file may not play correctly from dev server on Chrome browser! It will work in production.
{% endcomment %}
{% if include.objectid contains "/" %}
{%- capture src -%}{{ include.objectid | relative_url }}{%- endcapture -%}
{%- capture audio_link -%}{{ src }}{%- endcapture -%}
{%- capture audio_caption -%}{{ include.caption }}{%- endcapture -%}
{%- capture audio_title -%}{{ include.title }}{%- endcapture -%}
{% capture audio_transcript %}{{ include.transcript }}{% endcapture %}
{% capture audio_poster %}{% if include.image == false %}{% else %}{{ include.image | relative_url | default: '' }}{% endif %}{% endcapture %}
{% else %}
{%- assign item = site.data[site.metadata] | where: "objectid", include.objectid | first -%}
{%- capture audio_link -%}{{ '/items/' | relative_url }}{% if item.parentid %}{{ item.parentid }}.html#{{ item.objectid }}{% else %}{{ item.objectid }}.html{% endif %}{%- endcapture -%}
{%- capture src -%}{{ item.object_location | relative_url }}{% endcapture %}
{%- capture audio_caption -%}{% if include.caption %}{{ include.caption }}{% else %}{{ item.description }}{% endif %}{%- endcapture -%}
{%- capture audio_title -%}{% if include.title %}{{ include.title }}{% else %}{{ item.title }}{% endif %}{%- endcapture -%}
{% capture audio_transcript %}{{ include.transcript | default: item.object_transcript }}{% endcapture %}
{% capture audio_poster %}{% if include.image == false %}{% else %}{{ include.image | default: item.image_small | relative_url | default: '' }}{% endif %}{% endcapture %}
{% endif %}
{% capture includeid %}{% if include.objectid.size > 10 %}{{ include.objectid | slice: -10, 10 | slugify }}{% else %}{{ include.objectid | slugify }}{% endif %}{% endcapture %}
<div class="card my-3 narrow-content">
{% if audio_poster != "" %}<img src="{{ audio_poster | relative_url }}" class="card-img-top" alt="{{ audio_title | escape }}">{% endif %}
<div class="card-body text-center">
<{{ include.heading_level | default: 'h2' | strip }} class="card-title h2">{{ audio_title }}</{{ include.heading_level | default: 'h2' | strip }}>
<p class="card-text">{{ audio_caption }}</p>
<button class="btn btn-sm btn-primary stretched-link" type="button" data-bs-toggle="modal" data-bs-target="#{{ includeid }}Modal">
Listen to Audio
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi icon-sprite" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
<path d="M6.271 5.055a.5.5 0 0 1 .52.038l3.5 2.5a.5.5 0 0 1 0 .814l-3.5 2.5A.5.5 0 0 1 6 10.5v-5a.5.5 0 0 1 .271-.445"/>
</svg>
</button>
</div>
</div>
<div class="modal fade" id="{{ includeid }}Modal" tabindex="-1" aria-labelledby="{{ includeid }}ModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="{{ includeid }}ModalLabel">{{ audio_title }}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="document.querySelector('#{{ includeid }}ModalAudio').pause();"></button>
</div>
<div class="modal-body">
<p class="text-center my-3">
<audio controls class="w-100" preload="metadata" id="{{ includeid }}ModalAudio">
<source src="{{ src }}" >
Your browser does not support the audio element, please <a href="{{ audio_link }}">download the file to listen</a>.
</audio>
{% if audio_poster != "" %}<img src="{{ audio_poster | relative_url }}" class="img-fluid" alt="{{ audio_title | escape }}">{% endif %}
{% unless include.caption == false %}<p class="figure-caption">
{{ audio_caption }}
</p>{% endunless %}
</p>
</div>
<div class="modal-footer">
{% if audio_transcript != '' %}
<div class="collapse mt-3 w-100" id="collapseTranscript{{ includeid }}">
<div class="card card-body text-start">
{% assign transcript_type = audio_transcript | slice: 0,1 %}
{% if transcript_type == '/' %}
{% assign transcript_location = audio_transcript | remove_first: '/' %}
{% assign transcript = site.pages | where: 'path', transcript_location | first %}
{{ transcript.content | markdownify }}
{% else %}
{{ audio_transcript | markdownify }}
{% endif %}
</div>
</div>
<button class="btn btn-outline-primary m-2" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTranscript{{ includeid }}" aria-expanded="false" aria-controls="collapseTranscript{{ includeid }}">View Transcript</button>
{% endif %}
{% unless include.objectid contains '/' %}
<a href="{{ audio_link }}" class="btn btn-outline-dark m-2">Visit Item Page</a>{% endunless %}
<button type="button" class="btn btn-dark" data-bs-dismiss="modal" onclick="document.querySelector('#{{ includeid }}ModalAudio').pause();">Close</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,37 @@
{% comment %}
Audio embed from an item's objectid or external link.
This include adds a audio embed to the page using the html "audio" element.
E.G. --> {% include feature/audio.html objectid="demo_003" %}
It requires an "objectid" with the include, which is used to find the audio details. Alternatively, a URL to an external audio file can be used in "objectid".
Options:
- "objectid" = several options below (required)
- an objectid of an audio item in this collection, e.g. "demo_003"
- an external link to an MP3 file hosted elsewhere, e.g. "https://www.lib.uidaho.edu/digital/mp3s/Clouds.mp3"
- a relative link to an MP3 file somewhere else in this repository, e.g. "/assets/example.mp3"
- "caption" = by default the figure include automatically adds the title of the item from your metadata. The caption option allows you to manually add a different caption, or give the value false for none. (optional)
Note: if you have issues make sure the item is a audio item.
Audio file may not play correctly from dev server on Chrome browser! It will work in production.
{%- endcomment -%}
{% if include.objectid contains "/" %}
{%- capture src -%}{{ include.objectid | relative_url }}{%- endcapture -%}
{%- capture audio_link -%}{{ src }}{%- endcapture -%}
{%- capture audio_caption -%}{{ include.caption }}{%- endcapture -%}
{% else %}
{%- assign item = site.data[site.metadata] | where: "objectid", include.objectid | first -%}
{%- capture audio_link -%}{{ '/items/' | relative_url }}{% if item.parentid %}{{ item.parentid }}.html#{{ item.objectid }}{% else %}{{ item.objectid }}.html{% endif %}{%- endcapture -%}
{%- capture src -%}{{ item.object_location | relative_url }}{% endcapture %}
{%- capture audio_caption -%}{% if include.caption %}{{ include.caption }}{% else %}{{ item.title }}{% endif %}{%- endcapture -%}
{% endif %}
<p class="text-center my-3">
<audio controls class="w-100">
<source src="{{ src }}" >
Your browser does not support the audio element.
</audio>
{% unless include.caption == false %}<small class="figure-caption"><a href="{{ audio_link }}">{{ audio_caption }}</a></small>{% endunless %}
</p>

View File

@@ -0,0 +1,23 @@
{% comment %}
Block quote
E.G. --> {% include feature/blockquote.html text="Knowledge comes, but wisdom lingers" speaker="Alfred Lord Tennyson" source="Locksley Hall" %}
Options:
- "text" = quote text, can use Markdown (required, hint: use a capture statement to add more complex text!)
- "speaker" = name of the person who said the quote (optional)
- "source" = title of the quote's source (optional)
- "link" = link to source, will be added to speaker/source (note: will not be added unless you have a speaker or source value!)
{%- endcomment -%}
<figure class="my-3 narrow-content">
<blockquote class="blockquote fs-3">
{{ include.text | markdownify }}
</blockquote>
{% if include.speaker or include.source %}
<figcaption class="blockquote-footer text-end fs-4">{% if include.link %}<a href="{{ include.link | relative_url }}">{% endif %}
{% if include.speaker %}{{ include.speaker }}{% if include.source %}, {% endif %}{% endif %}
{% if include.source %}<cite title="Source Title">{{ include.source }}</cite>{% endif %}
{% if include.link %}</a>{% endif %}</figcaption>{% endif %}
</figure>

View File

@@ -0,0 +1,19 @@
{% comment %}
Bootstrap button link, https://getbootstrap.com/docs/5.1/components/buttons/
E.G. --> {% include feature/button.html text="Example Button Link" link="https://example.com" color="success" %}
Options:
- "text" = main button text
- "link" = button link
- "color" = a bootstrap color (primary, secondary, success, danger, warning, info, light, dark)
- "size" = optional btn size, choose from "lg", "sm" (defaults to normal size)
- "width" = will use Bootstrap sizing to set the % size, choose from "25", "50", "75", or "100"
- "centered" = give "true" to add the button to a div and center on page
- "float" = will use Bootstrap float utility to add float, choose from "start" (left) or "end" (right) (not recommended)
{%- endcomment -%}
{% if include.centered %}<p class="text-center mb-3">{%- endif -%}
<a class="btn{% if include.size %} btn-{{ include.size }}{% endif %} btn-{{ include.color | default: 'secondary' }}{% if include.float %} float-{{ include.float }}{% endif %}{% if include.width %} w-{{ include.width }}{% endif %}" href="{{ include.link }}">{{ include.text }}</a>
{% if include.centered %}</p>{%- endif -%}

View File

@@ -0,0 +1,36 @@
{% comment %}
Bootstrap Card, https://getbootstrap.com/docs/5.1/components/card/
E.G. --> {% include feature/card.html text="Some text" header="Example item" objectid="demo_004" %}
Options:
- "text" = main card text, can use markdown formatting (tip: use a Liquid capture to add more complex content)
- "header" = card header text (in bar above card content)
- "title" = card title text inside card content area
- "heading_level" = customize the level of the heading if necessary for accessibility, choose "h1", "h2", "h3", etc (optional, default "h2")
- "objectid" = the given object or link to external image will create a card cap image
- "alt" = if adding an external image using objectid option, provide alt text for image
- "width" = will use responsive sizing to set the % size on desktop (will be 100% on mobile), choose from "25", "50", "75", or "100"
- "centered" = give "true" to add mx-auto class on the card to center it (don't use with float!)
- "float" = will use responsive float utility to add float on desktop (will not float on mobile), choose from "start" (left) or "end" (right)
{%- endcomment -%}
{%- if include.objectid contains '/' -%}
{%- capture src -%}{{ include.objectid | relative_url }}{% endcapture %}
{%- capture alt -%}{{ include.alt | default: include.title }}{% endcapture %}
{%- elsif include.objectid -%}
{%- assign item = site.data[site.metadata] | where: "objectid", include.objectid | first -%}
{%- capture src -%}{{ item.image_small | default: item.object_location | relative_url }}{% endcapture %}
{%- capture alt -%}{{ item.image_alt_text | default: item.description | default: item.title }}{% endcapture %}
{%- endif -%}
<div class="narrow-content">
<div class="card mb-3{% if include.float %} feature-float-{{ include.float }}{% endif %}{% if include.width %} feature-w-{{ include.width }}{% endif %}{% if include.centered %} mx-auto{% endif %}">
{% if src %}<img class="card-img-top" src="{{ src }}" alt="{{ alt | escape }}">{%- endif -%}
{% if include.header %}<{{ include.heading_level | default: 'h2' | strip }} class="card-header">{{ include.header }}</{{ include.heading_level | default: 'h2' | strip }}>{%- endif -%}
<div class="card-body">
{% if include.title %}<{{ include.heading_level | default: 'h2' | strip }} class="card-title">{{ include.title }}</{{ include.heading_level | default: 'h2' | strip }}>{%- endif -%}
<div class="card-text">{{ include.text | markdownify }}</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,19 @@
{% comment %}
Term cloud.
This include adds a word cloud feature based on one more metadata fields. Cloud will work best with multi-value (separated by semicolon ; ) controlled vocab type fields, such as "subject".
E.G. --> {% include feature/cloud.html fields="subject;creator" min=2 %}
Options:
- "fields" = one or more metadata fields to include in the cloud. (required)
- "min" = minimum number of times a term must appear in metadata to be displayed. Too many terms will increase load time and size of element. (optional, default 1)
- "stopwords" = words to remove from cloud terms (optional)
- "shuffle" = if "true" terms will be shuffled in random order (optional, default is alphabetical)
- "background" = change the background to a different a bootstrap color (primary, secondary, success, danger, warning, info, light, dark)
- "button" = change the button to a different a bootstrap button option (primary, secondary, success, danger, warning, info, light, dark, outline-primary, outline-secondary, outline-success, outline-danger, outline-warning, outline-info, outline-light, outline-dark)
{%- endcomment -%}
{% assign cloud_id = "cloud-div-" | append: include.fields | slugify %}
<div id="{{ cloud_id }}" class="text-center my-4 bg-{{ include.background | default: 'light' }} border rounded p-2"></div>
{% include js/cloud-js.html id=cloud_id fields=include.fields min=include.min stopwords=include.stopwords shuffle=include.shuffle button=include.button %}

View File

@@ -0,0 +1,22 @@
{% comment %}
Bootstrap collapse feature, https://getbootstrap.com/docs/5.3/components/collapse/
e.g. --> {% include feature/collapse.html button="Learn More" color="success" text="Such an interesting story!" %}
Options:
- "button" = text of the button that triggers the collapse to open (required)
- "text" = text inside the collapse, Markdown is supported (required, hint: use a capture statement to add more complex text!)
- "color" = color for the trigger button (optional, default: primary)
{%- endcomment -%}
<p>
<button class="btn btn-{{ include.color | default: 'primary' }}" type="button" data-bs-toggle="collapse" data-bs-target="#collapse{{ include.button | slugify }}" aria-expanded="false" aria-controls="collapse{{ include.button | slugify }}">
{{ include.button }}
</button>
</p>
<div class="collapse narrow-content mb-3" id="collapse{{ include.button | slugify }}">
<div class="card card-body">
{{ include.text | markdownify }}
</div>
</div>

View File

@@ -0,0 +1,73 @@
{% comment %}
Gallery, grid of images to be used as it's own page or within an about page.
E.G. --> (3 examples below)
{% include feature/gallery.html image-heading="demo_008" heading="Items after 1900" captions=false filter="item.date > '1900'" %}
{% include feature/gallery.html heading="All the Videos" child-objects=true gallery-type="video" %}
{% include feature/gallery.html image-heading="demo_018" heading="Items that have the subject postcard and are in Spokane" context="This uses a complex liquid filter to specify specif items." filter="item.subject contains 'postcard' and item.location contains 'Spokane'" %}
*Note that filters are CASE-SENSITIVE so if you're constructing one, either using the filter itself or the filter-field and filter-value you will need to match the case of the string search. this is unlike our browse page.*
Options:
- "filter" = logic statement (in the templating language liquid -- non liquid option indented below) that filters out most of the collection to display only select items. The first part of the statement must start with an "item." and then the category you'd like filtered, followed by an operator (https://shopify.github.io/liquid/basics/operators/) and the string or value you'd like to filter by e.g. "item.date contains '2019'".
If needed you can use the below options to construct a filter statement
- "filter-field" = the metadata field by which you'd like to filter items in your collection. i.e. title, subject, date, etc.
- "filter-value" = logic statement (in liquid) that filters out most of the collection to display only select items.
- "heading" = the heading text above the gallery (optional)
- "image-heading" = one objectid for a photo object in this collection, a relative path to an image in this project, or a full url to any image. This will include a feature/jumbotron.html includes at the top of the gallery
- "context" = a paragraph explanation of the gallery contents (optional)
- "caption" = If you don't want captions for your items, add --> captions=false with no quotations. Captions are on by default
- "item-size" = tiny, small, medium, large; default is medium, which is 3 items per row on a laptop screen size.
- "gallery-type" = this will determine how the items appear, so choosing 'video' will cause the gallery to display all items as embedded videos options: image, video, pdf, audio. Default is "image" (optional)
- container-styles = adds css classes to allow you to style the container in which the gallery appears, e.g. "w-75 mx-auto"
- item-styles = adds css classes to allow you to style the container in which the individual items appears, e.g. "card py-3"
- "image-size" - will adjust the size of the images used in the gallery, options: original, small, thumb. Default is "small" (optional)
- "child-objects" = include child items in count or only parents, true or false (optional, default false)
- "limit" will limit the number of items featured to the number included, default 50 (optional)
{%- endcomment -%}
{% if include.child-objects == true %}
{%- assign gallery-items = site.data[site.metadata] | where_exp: 'item','item.objectid' -%}
{% else %}
{%- assign gallery-items = site.data[site.metadata] | where_exp: 'item','item.objectid and item.parentid == nil' -%}
{% endif %}
{% if include.gallery-type %}
{%- assign gallery-items = gallery-items | where_exp: "item","item.display_template == include.gallery-type" -%}
{% else %}
{%- assign gallery-items = gallery-items | where_exp: "item","item.image_small != nil or item.image_thumb != nil" -%}
{% endif %}
{%- if include.filter-field and include.filter-value -%}
{%- assign gallery-items = gallery-items | where_exp: 'item','item[include.filter-field] contains include.filter-value' -%}
{%- elsif include.filter -%}
{%- assign gallery-items = gallery-items | where_exp: 'item',include.filter -%}
{% endif %}
{% assign gallery-limit = include.limit | default: 50 %}
{% capture captions %}{{ include.captions | default: "true" }}{% endcapture %}
{% if include.image-heading and include.heading%}
{% include feature/jumbotron.html objectid=include.image-heading heading=include.heading text=false padding="5rem" %}
{% elsif include.image-heading %}
{% include feature/jumbotron.html objectid=include.image-heading %}
{% elsif include.heading %}
<h2>{{ include.heading }}</h2>{% endif %}
<div class="row my-3 py-3 {{ include.container-styles }}">
{% if include.context %}<p> {{include.context}} </p>{% endif %}
{% for item in gallery-items limit:gallery-limit %}
<div class="{% if include.item-size == 'tiny' %}col-lg-2 col-sm-4 col-xs-6{% elsif include.item-size == 'small' %}col-lg-3 col-sm-6{% elsif include.item-size == 'large' %}col-xl-4 col-lg-6{% else %}col-lg-4 col-sm-6{% endif %} {{ include.item-styles }}">
{% if include.gallery-type == "video" %}
{% include feature/video.html objectid=item.objectid caption=include.captions %}
{% elsif include.gallery-type == "pdf" %}
{% include feature/pdf.html objectid=item.objectid caption=include.captions %}
{% elsif include.gallery-type == "audio" %}
{% include feature/audio.html objectid=item.objectid caption=include.captions %}
{% else %}
{% include feature/image.html objectid=item.objectid caption=include.captions %}{% endif %}
</div>
{% endfor %}
</div>

View File

@@ -0,0 +1,15 @@
{%- comment -%}
Bootstrap Icons, https://icons.getbootstrap.com/
This include adds a bootstrap icon using the SVG Sprite approach. This works similar to Icon Fonts. The svg will inherit font size and color from the parent, so can be used with other text.
E.G. --> {% include feature/icon.html icon="file-play" label="Audio file" %}
Options:
- "icon" = a Bootstrap Icon name, e.g. "file-image", "file-play"
- "label" = a label for accessibility (optional)
- "class" = extra classes to add directly to the svg element (optional)
{%- endcomment -%}
<svg class="bi icon-sprite {% if include.class %}{{ include.class }}{% endif %}" {% if include.label %}role="img" aria-label="{{ include.label | escape }}"{% else %}aria-hidden="true"{% endif %}><use xlink:href="{{ site.lib-assets | default: '/assets/lib' | relative_url }}/icons/bootstrap-icons.svg#{{ include.icon }}" href="{{ site.lib-assets | default: '/assets/lib' | relative_url }}/icons/bootstrap-icons.svg#{{ include.icon }}"></use></svg>

View File

@@ -0,0 +1,50 @@
{% comment %}
Image embed from an item's objectid or external link.
This include adds a figure to the page styled using bootstrap, https://getbootstrap.com/docs/5.1/content/figures/
It requires an "objectid" with the include, which is used to find the object title and image (for collection items). If multiple collection objectids are included (separated by ; ), they will be added to a "col-md" in a row which will automatically divided equally.
Alternatively, a URL to an external image can be used in "objectid".
E.G. --> {% include feature/image.html objectid="demo_001" %}
Options:
- "objectid" = several options below (required)
1. one or more objectids from this collection, separated by semicolon, e.g. "demo_001" or "demo_001;demo_005"
2. a full URL to an external image file, e.g. "https://www.lib.uidaho.edu/digital/images/fluffyclouds.jpg"
3. a relative link to an image file stored in this repository (that is not included in the collection), i.e. "/assets/img/evan.jpg"
IMPORTANT NOTE: Options 2 and 3 require you to add an "alt" option (or "alt" options for multiple images) in order to allow for the accessibility enabled by the "alt" tag
- "alt" = alternative text describing the image. This is a required accessibility feature IF you are using an external URL or a relative link (options 2 and 3 above)--it will be automatically filled if providing an objectid. For multiple alts, split using a semi-colon. If you do not fill this in but fill in the "caption" option, the "caption" will be included as the images alt value. (optional)
- "caption" = for option 1 above, the figure include automatically adds the title of the item from your metadata. The caption option allows you to manually add a different caption for that option, or give the value false ('caption=false' - no quotes around false) for none. For options 2 and 3, captions will only be added if the caption variable is set. For multiple images of any option, you can also use multiple captions, by splitting them with a semi-colons (optional)
- "link" = for option 1 above, the figure include automatically links to the item from your metadata. The link option allows you to manually add a different link for that image. For options 2 and 3, link will only be added if the link variable is set; otherwise, the link will be set to the external or relative image file. For multiple images of any option, you can also use multiple links, by splitting them with a semi-colons (optional)
- "width" = will use responsive sizing to set the % size on desktop (will be 100% on mobile), choose from "25", "50", "75", or "100" (optional)
{%- endcomment -%}
{%- assign figures = include.objectid | split: ";" %}
{%- assign figcount = figures | size -%}
{%- assign captions = include.caption | split: ";" %}
{%- assign alts = include.alt | split: ";" -%}
{%- assign links = include.link | split: ";" -%}
<div class="row feature-include">
{% for i in figures %}
{% if i contains "/" %}
{%- capture image_src -%}{{ i | relative_url }}{%- endcapture -%}
{%- capture image_caption -%}{{ captions[forloop.index0] }}{%- endcapture -%}
{%- capture image_alt -%}{{ alts[forloop.index0] }}{%- endcapture -%}
{%- capture image_link -%}{{ links[forloop.index0] | default: image_src }}{%- endcapture -%}
{% else %}
{%- assign figure = site.data[site.metadata] | where: "objectid", i | first -%}
{%- capture image_link -%}{{ '/items/' | relative_url }}{% if figure.parentid %}{{ figure.parentid }}.html#{{ figure.objectid }}{% else %}{{ figure.objectid }}.html{% endif %}{% endcapture %}
{%- capture image_caption -%}{{ captions[forloop.index0] | default: figure.title }}{%- endcapture -%}
{%- capture image_alt -%}{{ alts[forloop.index0] | default: figure.image_alt_text | default: figure.description | default: figure.title }}{%- endcapture -%}
{%- capture image_src -%}{{ figure.image_small | default: figure.object_location | relative_url }}{% endcapture %}
{% endif %}
<div class="col-md {% if figcount == 1 %}{% elsif forloop.first %}text-md-end{% elsif forloop.last %}text-md-start{% else %}text-center{% endif %}">
<figure class="figure {% if include.width %}feature-w-{{ include.width }}{% endif %}">
<a href="{{ image_link | default: image_src }}">
<img class="figure-img img-fluid rounded lazyload w-100" alt="{{ image_alt | default: image_caption | escape }}" title="click to see item" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 3 2'%3E%3C/svg%3E" data-src="{{ image_src }}" >
</a>
{% unless include.caption == false %}<figcaption class="figure-caption text-center">{% if i contains "/" %}{{ image_caption }}{% else %}<a href="{{ image_link }}">{{ image_caption }}</a>{% endif %}</figcaption>{% endunless %}
</figure>
</div>{% endfor %}
</div>

View File

@@ -0,0 +1,63 @@
{% comment %}
Bootstrap Jumbotron, https://getbootstrap.com/docs/5.1/examples/jumbotron/
This include adds a Jumbotron feature from an objectid.
E.G. --> {% include feature/jumbotron.html objectid="demo_001" %}
Options:
- "objectid" = one objectid for a photo object in this collection, a relative path to an image in this project, or a full url to any image. If left blank, by default this the image will be the featured-image set in theme.yml.
- "position" = set background-position, "center", "top", "bottom"
- "heading" = major heading to display. By default this will be the site title. Give the value false for no heading.
- "text" = paragraph text below heading. By default this will be the site tagline. Give the value false for no text.
- "padding" = additional padding added to the feature to increase size. Give value in em or px, e.g. "5em".
- "heading_level" = customize the level of the heading if necessary for accessibility, choose "h1", "h2", "h3", etc (optional, default "h2")
Note: if using a YouTube item and an error image appears, the video may not have a "maxresdefault" image available. Replace "maxresdefault.jpg" in the code below with "hqdefault.jpg"
{%- endcomment -%}
{% assign jumbo_div_id = "j-" | append: include.objectid | slugify | truncate: 12, "" %}
{% assign jumboId = include.objectid | default: site.data.featured_item.src %}
{% if jumboId contains '/' %}
{% assign jumboSrc = jumboId | relative_url %}
{% else %}
{% assign jumboItem = site.data[site.metadata] | where: "objectid", jumboId | first %}
{% capture jumboSrc %}{{ jumboItem.object_location | default: jumboItem.image_small | relative_url }}{% endcapture %}
{%- endif -%}
<style>
.jumbotron {
padding: 4rem 2rem;
margin-bottom: 2rem;
background-color: #e9ecef;
border-radius: 0.3rem;
}
#{{ jumbo_div_id }} {
background-image: url({{ jumboSrc }});
background-size: cover;
background-repeat: no-repeat;
background-position: {{ include.position | default: 'center' }};
}
{% if include.padding %}
.jumbo-title-box {
padding-top: {{ include.padding }};
padding-bottom: {{ include.padding }};
}
{%- endif -%}
@media screen and (max-width: 576px) {
.jumbo-title-box {
max-height: 500px;
}
.jumbo-tagline { font-size:.85em; }
}
</style>
<div class="jumbotron feature px-0 border" id="{{ jumbo_div_id }}">
<div class="jumbo-title-box">
{% unless include.heading == false and include.text == false %}
<div class="p-2 text-center text-white bg-dark bg-opacity-75">
{% unless include.heading == false %}<{{ include.heading_level | default: 'h2' | strip }} class="display-4">{{ include.heading | default: site.title }}</{{ include.heading_level | default: 'h2' | strip }}>{% endunless %}
{% unless include.text == false %}<p class="jumbo-tagline">{{ include.text | default: site.tagline }}</p>{% endunless %}
</div>
{% endunless %}
</div>
</div>

View File

@@ -0,0 +1,67 @@
{% comment %}
Mini Leaflet Map item feature.
This include adds a small leaflet map.
E.G> --> {% include feature/mini-map.html latitude="46.725562" longitude="-117.009633" %}
Options:
- "objectid" = feature a specific item from your metadata that has lat long. Using this option will set the map center and add a single marker to the map.
- "latitude" = center of map, required if not using objectid
- "longitude" = center of map, required if not using objectid
- "height" = height of the mini map in px (default 400px)
- "map-zoom" = provide a zoom level, default 10
- "map-link" = true/false, add a button link to the collection's default full map page (default false)
- "basemap" = set basemap option, Esri_WorldStreetMap, Esri_NatGeoWorldMap, Esri_WorldImagery. default Esri_WorldImagery.
{% endcomment %}
{% capture map_id %}mini-map_{{ include.latitude | slugify }}{% endcapture %}
{% assign map-item = site.data[site.metadata] | where: "objectid", include.objectid | first %}
<style>
#{{ map_id }} { height: {{ include.height | default: '400px' }}; z-index: 98; }
</style>
<div id="{{ map_id }}"></div>
{% if include.map-link == true %}
<a href="{{ '/map.html' | relative_url }}?location={{ map-item.latitude | default: include.latitude }},{{ map-item.longitude | default: include.longitude }}{%if include.objectid %}&marker={{ include.objectid }}{% endif %}" class="btn btn-outline-primary my-3">View on Full Map</a>{% endif %}
<!-- load leaflet dependencies -->
<link rel="stylesheet" href="{{ site.lib-assets | default: '/assets/lib' | relative_url }}/leaflet/leaflet.css">
<link rel="stylesheet" href="{{ site.lib-assets | default: '/assets/lib' | relative_url }}/leaflet/leaflet.fullscreen.css">
<script src="{{ site.lib-assets | default: '/assets/lib' | relative_url }}/leaflet/leaflet.js"></script>
<script src="{{ site.lib-assets | default: '/assets/lib' | relative_url }}/leaflet/Leaflet.fullscreen.min.js"></script>
<script>
// initial start point
var mapCenter = [{{ map-item.latitude | default: include.latitude }}, {{ map-item.longitude | default: include.longitude }}];
var mapZoom = {{ include.map-zoom | default: 10 }};
/* init map, set center and zoom */
var map = L.map('{{ map_id }}').setView(mapCenter, mapZoom);
/* add map layer options */
var Esri_WorldStreetMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012'
});
var Esri_NatGeoWorldMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC',
maxZoom: 16
});
var Esri_WorldImagery = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
});
/* add base map switcher */
var baseMaps = {
"Esri World StreetMap": Esri_WorldStreetMap,
"Esri National Geo": Esri_NatGeoWorldMap,
"Esri Imagery": Esri_WorldImagery
};
L.control.layers(baseMaps).addTo(map);
/* load base map */
{{ include.basemap | default: 'Esri_WorldImagery' }}.addTo(map);
/* add fullscreen control */
map.addControl(new L.Control.Fullscreen());
{% if include.objectid %}
/* add marker */
L.marker(mapCenter).addTo(map)
.bindPopup('{{ map-item.title | escape }}');{% endif %}
</script>

View File

@@ -0,0 +1,31 @@
{% comment %}
Bootstrap Modal, https://getbootstrap.com/docs/5.1/components/modal/
E.G. --> {% include feature/modal.html button="More Info" color="info" title="Information" text="Example text" %}
Options:
- "button" = text of button to trigger modal
- "color" = color of modal button (primary, secondary, success, danger, warning, info, light, dark)
- "title" = header text for modal pop up
- "text" = body text for modal pop up, can use markdown formatting (tip: use a Liquid capture to add more complex content)
{%- endcomment -%}
<!-- Button trigger modal -->
<p class="text-center mb-3">
<button type="button" class="btn btn-{{ include.color | default: 'primary' }}" data-bs-toggle="modal" data-bs-target="#{{ include.button | slugify }}Modal">{{ include.button }}</button>
</p>
<!-- Modal -->
<div class="modal fade" id="{{ include.button | slugify }}Modal" tabindex="-1" role="dialog" aria-labelledby="{{ include.button | slugify }}ModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title" id="{{ include.button | slugify }}ModalLabel">{{ include.title }}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" >
{{ include.text | markdownify }}
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,17 @@
{% comment %}
About Page Nav Menu include,
add a basic nav at top of About page.
E.G. --> {% include feature/nav-menu.html sections="Background;Timeline;More Information" %}
Options:
- "sections" = headers to be added to the nav separated by semicolon (;), exactly copy text from any header written in markdown on the page (i.e. ## Example header)
Note: styling in _sass/_pages.scss adds 100px margin to top of h2 on the about page to accommodate the sticky-top option of this element. If you add headers other than h2 to this nav, they will likely overlap under the element when jumping to the section. Similarly, if more than a handful of sections or long section titles are added, the box will overlap the headers when jumping. Modify the spacing in the scss, or remove the "sticky-top" class to fix.
{%- endcomment -%}
{% assign sections = include.sections | split: ';'%}
<p class="h6 shadow-sm p-3 about-nav sticky-top bg-white">
Contents: {% for section in sections %}<a class="mx-2" href="#{{ section | slugify }}">{{ section }}</a> {% unless forloop.last %}| {% endunless %}{% endfor %}{% if page.credits == true %}| <a class="mx-2" href="#technical">Tech</a>{% endif %}
</p>

View File

@@ -0,0 +1,43 @@
{% comment %}
Item PDF embed from objectid or external link.
This include adds a PDF embed to the page using html5 "object" element.
E.G. --> {% include feature/pdf.html objectid="demo_002" %}
It requires an "objectid" with the include, which is used to find the object details. Alternatively, a URL to an external pdf can be used in "objectid".
By default no height is necessary as it uses 1x1 Bootstrap ratio style, https://getbootstrap.com/docs/5.1/helpers/ratio/
Options:
- "objectid" = several options below (required)
1. an objectid of a PDF item in this collection, e.g. "demo_004"
2. an external link to a PDF file hosted elsewhere, e.g. "https://www.lib.uidaho.edu/digital/pdfs/cloudtypes.pdf"
3. a relative link to a PDF file somewhere else in this repository, e.g. "/assets/pdfs/sometrees.pdf"
- "caption" = by default the figure include automatically adds the title of the item from your metadata. The caption option allows you to manually add a different caption, or give the value false for none. (optional)
- "width" = will use responsive sizing to set the % size on desktop (will be 100% on mobile), choose from "25", "50", "75", or "100" (optional)
- "height" = set embed object height in px (rather than responsive size), e.g. "800px" (optional)
- "ratio" = use Bootstrap embed ratio options "21x9", "16x9", "4x3", or "1x1" to customize the responsive aspect ratio if not using height. 1x1 is default. (optional)
Note: if you have issues make sure the item is a PDF file!
{%- endcomment -%}
{% if include.objectid contains "/" %}
{%- capture src -%}{{ include.objectid | relative_url }}{%- endcapture -%}
{%- capture pdf_link -%}{{ src }}{%- endcapture -%}
{%- capture pdf_caption -%}{{ include.caption }}{%- endcapture -%}
{% else %}
{%- assign item = site.data[site.metadata] | where: "objectid", include.objectid | first -%}
{%- capture src -%}{{ item.object_location | relative_url }}{% endcapture %}
{%- capture pdf_link -%}{{ '/items/' | relative_url }}{% if item.parentid %}{{ item.parentid }}.html#{{ item.objectid }}{% else %}{{ item.objectid }}.html{% endif %}{%- endcapture -%}
{%- capture pdf_caption -%}{% if include.caption %}{{ include.caption }}{% else %}{{ item.title }}{% endif %}{%- endcapture -%}
{% endif %}
<div class="feature-include">
<figure class="figure border rounded p-1 feature-w-{{ include.width | default: '100' }}">
<div class="{% unless include.height %}ratio ratio-{{ include.ratio | default: '1x1' }}{% endunless %}">
<object aria-label="pdf embed of {{ pdf_caption | escape }}" {% if include.height %}width="100%" height="{{ include.height }}"{% endif %} data="{{ src }}">
<p>The PDF is not rendering in your browser. Please <a href="{{ src }}">download the PDF</a> to view.</p>
</object>
</div>
{% unless include.caption == false %}<figcaption class="figure-caption text-center"><a href="{{ pdf_link }}">{{ pdf_caption }}</a></figcaption>{% endunless %}
</figure>
</div>

View File

@@ -0,0 +1,31 @@
{% comment %}
Embed a TimelineJS feature, https://timeline.knightlab.com/
E.G. --> {% include feature/timelinejs.html %}
Embeds a TimelineJS built from a JSON file appropriate for any CollectionBuilder page (such as Home or About page).
CB templates automatically generate a timelinejs json file in "assets/data/timelinejs.json" including all items in metadata with a value in "date" field.
By default, this include uses this json file.
Options:
- "json" = (optional) path or link to timelinejs json file.
{% endcomment %}
{%- assign json = include.json | default: '/assets/data/timelinejs.json' | relative_url -%}
<!-- timelinejs, https://timeline.knightlab.com/ -->
<link title="timeline-styles" rel="stylesheet" href="https://cdn.knightlab.com/libs/timeline3/latest/css/timeline.css">
<div id="timeline-embed" style="width: 100%; height: 800px" class="mb-4"></div>
<script src="https://cdn.knightlab.com/libs/timeline3/latest/js/timeline.js"></script>
<script type="text/javascript">
// The TL.Timeline constructor takes at least two arguments:
// the id of the Timeline container (no '#'), and
// the URL to your JSON data file or Google spreadsheet.
// the id must refer to an element "above" this code,
// and the element must have CSS styling to give it width and height
// optionally, a third argument with configuration options can be passed.
// See below for more about options.
timeline = new TL.Timeline('timeline-embed', '{{ json }}');
</script>

View File

@@ -0,0 +1,128 @@
{% comment %}
Video modal feature from an item's objectid or external link.
This include adds a card featuring the thumb image, title, and description of a video--when clicked it opens a modal containing the video embed. The modal displays video information, transcript, link to item. This is especially useful feature if you would like multiple videos on one page.
E.G. --> {% include feature/video-modal.html objectid="demo_004" %}
It requires an "objectid" with the include, which is used to find the video details. Alternatively, a URL to an external video can be used in "objectid".
YouTube and Vimeo items will use iframe embeds, video files use html video element.
Options:
- "objectid" = several options below (required)
1. an objectid of a video item in this collection, e.g. "demo_003"
2. a full URL to a video hosted on YouTube, e.g. https://youtu.be/dbKNr3wuiuQ
3. a full URL to a video hosted on Vimeo, e.g. https://vimeo.com/464555587
4. a full URL to an external video file (supported by browsers, generally mp4), e.g. "https://www.lib.uidaho.edu/digital/videos/fluffyclouds.mp4"
5. a relative link to a video file stored in this repository (that is not included in the collection), i.e. "/assets/videos/cloudyskies.mp4"
- "title" = by default automatically adds the title from item metadata, which will be used for the card and modal title. Manually set by using the title option. (optional)
- "heading_level" = customize the level of the card heading if necessary for accessibility, choose "h1", "h2", "h3", etc (optional, default "h2")
- "caption" = by default the include automatically adds the description of the item from your metadata. The caption option allows you to manually add a different caption, or give the value false for none. (optional)
- "transcript" = by default if using an objectid, if the item has a object_transcript value, the view transcript button will automatically be added. The transcript option allows you to manually add a different transcript or provide one for non-collection videos. (optional)
- "image" = by default if using an objectid, if the item has a image_small value, the image will be used on the card and as the poster for video file embeds (not youtube). The image option allows you to manually add a image for non-collection videos. Give "false" to have no image displayed on the card (optional)
- "ratio" = use Bootstrap embed ratio options "21x9", "16x9", "4x3", or "1x1" to customize the responsive aspect ratio. 16by9 is default. (optional)
Note: if you have issues make sure the item is a video item and a web friendly format
{% endcomment %}
{%- if include.objectid contains '/' -%}
{%- capture video_title -%}{{ include.title }}{%- endcapture -%}
{% capture video_caption %}{{ include.caption }}{% endcapture %}
{% capture video_poster %}{{ include.image }}{% endcapture %}
{% capture video_transcript %}{{ include.transcript }}{% endcapture %}
{% capture raw_src %}{{ include.objectid }}{% endcapture %}
{%- capture video_link -%}{{ raw_src | relative_url }}{%- endcapture -%}
{%- else -%}
{%- assign item = site.data[site.metadata] | where: "objectid", include.objectid | first -%}
{%- capture video_title -%}{% if include.title %}{{ include.title }}{% else %}{{ item.title }}{% endif %}{%- endcapture -%}
{% capture video_caption %}{% if include.caption %}{{ include.caption }}{% else %}{{ item.description }}{% endif %}{% endcapture %}
{% capture video_poster %}{{ include.image | default: item.image_small | default: '' }}{% endcapture %}
{% capture video_transcript %}{{ include.transcript | default: item.object_transcript }}{% endcapture %}
{% capture raw_src %}{{ item.object_location }}{% endcapture %}
{%- capture video_link -%}{{ '/items/' | relative_url }}{% if item.parentid %}{{ item.parentid }}.html#{{ item.objectid }}{% else %}{{ item.objectid }}.html{% endif %}{%- endcapture -%}
{%- endif -%}
{%- if raw_src contains 'vimeo' -%}
{% assign vimeo_id = raw_src | split: '/' | last %}
{% capture video_src %}https://player.vimeo.com/video/{{ vimeo_id }}{% endcapture %}
{% assign video_type = 'vimeo' %}
{%- elsif raw_src contains 'youtu' -%}
{% assign youtube_id = raw_src | split: '/' | last %}
{% if youtube_id contains 'v=' %}{% assign youtube_id = youtube_id | split: 'v=' | last | split: '&' | first %}
{% elsif youtube_id contains '?' %}{% assign youtube_id = youtube_id | split: '?' | first %}{% endif %}
{% capture video_src %}https://www.youtube-nocookie.com/embed/{{ youtube_id }}?enablejsapi=1&rel=0&modestbranding=1{% endcapture %}
{% assign video_type = 'youtube' %}
{%- else -%}
{% assign video_src = raw_src | relative_url %}
{% assign video_type = 'video' %}
{%- endif -%}
{% capture includeid %}{% if include.objectid.size > 10 %}{{ include.objectid | slice: -10, 10 | slugify | replace: "-","_" }}{% else %}{{ include.objectid | slugify | replace: "-","_" }}{% endif %}{% endcapture %}
{% capture stop_media %}{% endcapture %}
<script>
function stopMedia{{ includeid }}() {
{% if video_type == 'youtube' %}const message = JSON.stringify({ event: 'command', func: 'pauseVideo', args: '' }); document.querySelector('#{{ includeid }}ModalVideo iframe').contentWindow.postMessage(message, '*');{% elsif video_type == 'vimeo' %}document.querySelector('#{{ includeid }}ModalVideo iframe').contentWindow.postMessage('{"method":"pause"}', '*');{% else %}document.querySelector('#{{ includeid }}ModalVideo video').pause();{% endif %}
}
</script>
<div class="card my-3 narrow-content">
{% if include.image != false and video_poster != '' %}<img src="{{ video_poster | relative_url }}" class="card-img-top" alt="{{ video_title | escape }}">{% endif %}
<div class="card-body text-center">
<{{ include.heading_level | default: 'h2' | strip }} class="card-title h2">{{ video_title }}</{{ include.heading_level | default: 'h2' | strip }}>
<p class="card-text">{{ video_caption }}</p>
<button class="btn btn-sm btn-primary stretched-link" type="button" data-bs-toggle="modal" data-bs-target="#{{ includeid }}Modal">
View Video
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi icon-sprite" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
<path d="M6.271 5.055a.5.5 0 0 1 .52.038l3.5 2.5a.5.5 0 0 1 0 .814l-3.5 2.5A.5.5 0 0 1 6 10.5v-5a.5.5 0 0 1 .271-.445"/>
</svg>
</button>
</div>
</div>
<div class="modal fade" id="{{ includeid }}Modal" tabindex="-1" aria-labelledby="{{ includeid }}ModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="{{ includeid }}ModalLabel">{{ video_title }}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="stopMedia{{ includeid }}()"></button>
</div>
<div class="modal-body">
<figure class="">
<div class="ratio ratio-{{ include.ratio | default: '16x9' }}" id="{{ includeid }}ModalVideo">
{%- if video_src contains "vimeo" or video_src contains "youtu" -%}
<iframe title="video embed {{ video_title | escape }}" src="{{ video_src }}" allowfullscreen></iframe>
{% else %}
<video {% if video_poster %}poster="{{ video_poster | relative_url }}"{% endif %} preload="metadata" controls>
<source src="{{ video_src }}">
Your browser does not support the video tag, please <a href="{{ video_link }}">download the file to watch</a>.
</video>
{%- endif -%}
</div>
{% unless include.caption == false %}
<figcaption class="figure-caption text-center">
{{ video_caption }}
</figcaption>
{% endunless %}
</figure>
</div>
<div class="modal-footer">
{% if video_transcript != '' %}
<div class="collapse mt-3 w-100" id="collapseTranscript{{ includeid }}">
<div class="card card-body text-start">
{% assign transcript_type = video_transcript | slice: 0,1 %}
{% if transcript_type == '/' %}
{% assign transcript_location = video_transcript | remove_first: '/' %}
{% assign transcript = site.pages | where: 'path', transcript_location | first %}
{{ transcript.content | markdownify }}
{% else %}
{{ video_transcript | markdownify }}
{% endif %}
</div>
</div>
<button class="btn btn-outline-primary m-2" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTranscript{{ includeid }}" aria-expanded="false" aria-controls="collapseTranscript{{ includeid }}">View Transcript</button>
{% endif %}
{% unless include.objectid contains '/' %}
<a href="{{ video_link }}" class="btn btn-outline-dark m-2">Visit Item Page</a>{% endunless %}
<button type="button" class="btn btn-dark" data-bs-dismiss="modal" onclick="stopMedia{{ includeid }}()">Close</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,84 @@
{% comment %}
Video embed from an item's objectid or external link.
This include adds a video embed to the page using Bootstrap ratio styles, https://getbootstrap.com/docs/5.1/helpers/ratio/
E.G. --> {% include feature/video.html objectid="demo_003" %}
It requires an "objectid" with the include, which is used to find the video details. Alternatively, a URL to an external video can be used in "objectid".
YouTube and Vimeo items will use iframe embeds, video files use html video element.
Options:
- "objectid" = several options below (required)
1. an objectid of a video item in this collection, e.g. "demo_003"
2. a full URL to a video hosted on YouTube, e.g. https://youtu.be/dbKNr3wuiuQ
3. a full URL to a video hosted on Vimeo, e.g. https://vimeo.com/464555587
4. a full URL to an external video file (supported by browsers, generally mp4), e.g. "https://www.lib.uidaho.edu/digital/videos/fluffyclouds.mp4"
5. a relative link to a video file stored in this repository (that is not included in the collection), i.e. "/assets/videos/cloudyskies.mp4"
- "caption" = by default the include automatically adds the title of the item from your metadata. The caption option allows you to manually add a different caption, or give the value false for none. (optional)
- "transcript" = by default if using an objectid, if the item has a object_transcript value, the view transcript button will automatically be added. The transcript option allows you to manually add a different transcript or provide one for non-collection videos. (optional)
- "cover" = by default if using an objectid, if the item has a image_small value, the image will be used as the cover for video file embeds (not youtube). The cover option allows you to manually add a cover image for non-collection videos. (optional)
- "width" = will use responsive sizing to set the % size on desktop (will be 100% on mobile), choose from "25", "50", "75", or "100" (optional)
- "ratio" = use Bootstrap embed ratio options "21x9", "16x9", "4x3", or "1x1" to customize the responsive aspect ratio. 16by9 is default. (optional)
Note: if you have issues make sure the item is a video item and a web friendly format
{%- endcomment -%}
{%- if include.objectid contains '/' -%}
{% capture video_caption %}{{ include.caption }}{% endcapture %}
{% capture video_poster %}{{ include.cover }}{% endcapture %}
{% capture video_transcript %}{{ include.transcript }}{% endcapture %}
{% capture raw_src %}{{ include.objectid }}{% endcapture %}
{%- else -%}
{%- assign item = site.data[site.metadata] | where: "objectid", include.objectid | first -%}
{% capture video_caption %}{% if include.caption %}{{ include.caption }}{% else %}<a href="{{ '/items/' | relative_url }}{% if item.parentid %}{{ item.parentid }}.html#{{ item.objectid }}{% else %}{{ item.objectid }}.html{% endif %}">{{ item.title }}</a>{% endif %}{% endcapture %}
{% capture video_poster %}{{ include.cover | default: item.image_small | default: '' }}{% endcapture %}
{% capture video_transcript %}{{ include.transcript | default: item.object_transcript }}{% endcapture %}
{% capture raw_src %}{{ item.object_location }}{% endcapture %}
{%- endif -%}
{%- if raw_src contains 'vimeo' -%}
{% assign vimeo_id = raw_src | split: '/' | last %}
{% capture video_src %}https://player.vimeo.com/video/{{ vimeo_id }}{% endcapture %}
{%- elsif raw_src contains 'youtu' -%}
{% assign youtube_id = raw_src | split: '/' | last %}
{% if youtube_id contains 'v=' %}{% assign youtube_id = youtube_id | split: 'v=' | last | split: '&' | first %}
{% elsif youtube_id contains '?' %}{% assign youtube_id = youtube_id | split: '?' | first %}{% endif %}
{% capture video_src %}https://www.youtube-nocookie.com/embed/{{ youtube_id }}?rel=0&modestbranding=1{% endcapture %}
{%- else -%}
{% assign video_src = raw_src | relative_url %}
{%- endif -%}
{% capture includeid %}{% if include.objectid.size > 8 %}{{ include.objectid | slice: -8, 8 | slugify }}{% else %}{{ include.objectid | slugify }}{% endif %}{% endcapture %}
<div class="feature-include my-4">
<figure class="{% if include.width %} feature-w-{{ include.width }}{% endif %}">
<div class="ratio ratio-{{ include.ratio | default: '16x9' }}">
{%- if video_src contains "vimeo" or video_src contains "youtu" -%}
<iframe title="video embed {{ video_caption | escape }}" src="{{ video_src }}" allowfullscreen></iframe>
{% else %}
<video {% if video_poster %}poster="{{ video_poster | relative_url }}"{% endif %} preload="metadata" controls>
<source src="{{ video_src }}">
Your browser does not support the video tag.
</video>
{%- endif -%}
</div>
{% unless include.caption == false %}
<figcaption class="figure-caption text-center">
{{ video_caption }}
{% if video_transcript != '' %}<br>
<button class="btn btn-sm btn-outline-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTranscript{{ includeid }}" aria-expanded="false" aria-controls="collapseTranscript{{ includeid }}">View Transcript</button>
<div class="collapse mt-3" id="collapseTranscript{{ includeid }}">
<div class="card card-body text-start">
{% assign transcript_type = video_transcript | slice: 0,1 %}
{% if transcript_type == '/' %}
{% assign transcript_location = video_transcript | remove_first: '/' %}
{% assign transcript = site.pages | where: 'path', transcript_location | first %}
{{ transcript.content | markdownify }}
{% else %}
{{ video_transcript | markdownify }}
{% endif %}
</div>
</div>
{% endif %}
</figcaption>
{% endunless %}
</figure>
</div>