diff --git a/Gemfile b/Gemfile
index 3f2a6250..16945081 100644
--- a/Gemfile
+++ b/Gemfile
@@ -2,13 +2,16 @@
source 'https://rubygems.org'
+# needed for Jekyll
+gem 'jekyll'
+gem 'webrick', '~> 1.7'
+
+# needed for Rake tasks
+gem 'rake'
+gem 'csv'
+gem 'fileutils'
+gem 'mini_magick'
unless Gem.win_platform?
gem 'image_optim'
gem 'image_optim_pack'
end
-gem 'csv'
-gem 'jekyll'
-gem 'mini_magick'
-gem 'rake'
-
-gem 'webrick', '~> 1.7'
diff --git a/Rakefile b/Rakefile
index 49da0212..c9e15a58 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,21 +1,16 @@
# frozen_string_literal: true
-# CollectionBuilder-CSV helper tasks
-
-require 'csv'
-require 'fileutils'
-require 'image_optim' unless Gem.win_platform?
-require 'mini_magick'
-
###############################################################################
-# TASK: deploy
+#
+# CollectionBuilder Rake Utilities
+#
+# See "docs/rake_tasks/" for documentation.
+# See "rakelib" for individual rake tasks!
+#
###############################################################################
-desc 'Build site with production env'
-task :deploy do
- ENV['JEKYLL_ENV'] = 'production'
- system('bundle', 'exec', 'jekyll', 'build')
-end
+require 'csv'
+require 'fileutils'
###############################################################################
# Helper Functions
@@ -36,128 +31,3 @@ def prompt_user_for_confirmation(message)
end
response
end
-
-def process_and_optimize_image(filename, file_type, output_filename, size, density)
- image_optim = ImageOptim.new(svgo: false) unless Gem.win_platform?
- if filename == output_filename && file_type == :image && !Gem.win_platform?
- puts "Optimizing: #{filename}"
- begin
- image_optim.optimize_image!(output_filename)
- rescue StandardError => e
- puts "Error optimizing #{filename}: #{e.message}"
- end
- elsif filename == output_filename && file_type == :pdf
- puts "Skipping: #{filename}"
- else
- puts "Creating: #{output_filename}"
- begin
- if file_type == :pdf
- inputfile = "#{filename}[0]"
- magick = MiniMagick::Tool::Convert.new
- magick.density(density)
- magick << inputfile
- magick.resize(size)
- magick.flatten
- magick << output_filename
- magick.call
- else
- image = MiniMagick::Image.open(filename)
- image.format('jpg')
- image.resize(size)
- image.flatten
- image.write(output_filename)
- end
- image_optim.optimize_image!(output_filename) unless Gem.win_platform?
- rescue StandardError => e
- puts "Error creating #{filename}: #{e.message}"
- end
- end
-end
-
-###############################################################################
-# TASK: generate_derivatives
-###############################################################################
-
-desc 'Generate derivative image files from collection objects'
-task :generate_derivatives, [:thumbs_size, :small_size, :density, :missing, :compress_originals] do |_t, args|
- # set default arguments
- # default image size is based on max pixel width they will appear in the base template features
- args.with_defaults(
- thumbs_size: '450x',
- small_size: '800x800',
- density: '300',
- missing: 'true',
- compress_originals: 'false'
- )
-
- # set the folder locations
- objects_dir = 'objects'
- thumb_image_dir = 'objects/thumbs'
- small_image_dir = 'objects/small'
-
- # Ensure that the output directories exist.
- [thumb_image_dir, small_image_dir].each do |dir|
- FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
- end
-
- # support these file types
- EXTNAME_TYPE_MAP = {
- '.jpeg' => :image,
- '.jpg' => :image,
- '.pdf' => :pdf,
- '.png' => :image,
- '.tif' => :image,
- '.tiff' => :image
- }.freeze
-
- # CSV output
- list_name = File.join(objects_dir, 'object_list.csv')
- field_names = 'filename,object_location,image_small,image_thumb'.split(',')
- CSV.open(list_name, 'w') do |csv|
- csv << field_names
-
- # Iterate over all files in the objects directory.
- Dir.glob(File.join(objects_dir, '*')).each do |filename|
- # Skip subdirectories and the README.md file.
- if File.directory?(filename) || File.basename(filename) == 'README.md' || File.basename(filename) == 'object_list.csv'
- next
- end
-
- # Determine the file type and skip if unsupported.
- extname = File.extname(filename).downcase
- file_type = EXTNAME_TYPE_MAP[extname]
- unless file_type
- puts "Skipping file with unsupported extension: #{filename}"
- csv << ["#{File.basename(filename)}", "/#{filename}", nil, nil]
- next
- end
-
- # Get the lowercase filename without any leading path and extension.
- base_filename = File.basename(filename, '.*').downcase
-
- # Optimize the original image.
- if args.compress_originals == 'true'
- puts "Optimizing: #{filename}"
- process_and_optimize_image(filename, file_type, filename, nil, nil)
- end
-
- # Generate the thumb image.
- thumb_filename = File.join(thumb_image_dir, "#{base_filename}_th.jpg")
- if args.missing == 'false' || !File.exist?(thumb_filename)
- process_and_optimize_image(filename, file_type, thumb_filename, args.thumbs_size, args.density)
- else
- puts "Skipping: #{thumb_filename} already exists"
- end
-
- # Generate the small image.
- small_filename = File.join([small_image_dir, "#{base_filename}_sm.jpg"])
- if (args.missing == 'false') || !File.exist?(small_filename)
- process_and_optimize_image(filename, file_type, small_filename, args.small_size, args.density)
- else
- puts "Skipping: #{small_filename} already exists"
- end
- csv << ["#{File.basename(filename)}", "/#{filename}", "/#{small_filename}", "/#{thumb_filename}"]
- end
- end
- puts "\e[32mSee '#{list_name}' for list of objects and derivatives created.\e[0m"
-end
diff --git a/_config.yml b/_config.yml
index 2b455864..ce02d957 100644
--- a/_config.yml
+++ b/_config.yml
@@ -25,7 +25,7 @@ tagline: Prototype for working with Oral History as Data items in CollectionBuil
# this description might appear in search result lists, keep around 160 characters max
description: "CB-OHD is a mix of CollectionBuilder-CSV and Oral History as Data (OHD)."
# if you want a different description to appear in the footer only, define it here, or leave blank to use description
-footer_description: "cb-oralhistory rocks!"
+# footer_description: "cb-oralhistory rocks!"
# keywords, a short list of subjects describing the collection, separated by semicolon, to appear in rich markup
keywords: oral histories;digital collections
# creator of the digital collection, to appear in meta tags; we typically use our GitHub usernames but feel free to just use your name
@@ -80,7 +80,7 @@ organization-logo-nav: https://cdil.lib.uidaho.edu/assets/img/logo.png
# (this is done automatically by gh-pages build)
#
# ignore stuff
-exclude: [docs/, Rakefile, README.md, LICENSE, CITATION.cff, CODE_OF_CONDUCT.md, CONTRIBUTING.md, SECURITY.md]
+exclude: [docs/, Rakefile, rakelib/, README.md, LICENSE, CITATION.cff, CODE_OF_CONDUCT.md, CONTRIBUTING.md, SECURITY.md]
# compress CSS output
sass:
style: compressed
diff --git a/_data/demo-compoundobjects-metadata.csv b/_data/demo-compoundobjects-metadata.csv
index 8b8faabc..6867177c 100644
--- a/_data/demo-compoundobjects-metadata.csv
+++ b/_data/demo-compoundobjects-metadata.csv
@@ -36,7 +36,7 @@ demo_014,demo_013,Peeled Tree View 1,,,,,,,,,,,Image;StillImage,image/jpeg,,,,im
demo_015,demo_013,Peeled Tree View 2,,,,,,,,,,,Image;StillImage,image/jpeg,,,,image,https://webpages.uidaho.edu/Library/twrs/objects/DSC_0137.JPG,https://webpages.uidaho.edu/Library/twrs/objects/small/dsc_0137_sm.jpg,https://webpages.uidaho.edu/Library/twrs/objects/thumbs/dsc_0137_th.jpg,log cross section showing where tree bark was peeled,
demo_016,demo_013,Peeled Tree View 3,,,,,,,,,,,Image;StillImage,image/jpeg,,,,image,https://webpages.uidaho.edu/Library/twrs/objects/DSC_0138.JPG,https://webpages.uidaho.edu/Library/twrs/objects/small/dsc_0138_sm.jpg,https://webpages.uidaho.edu/Library/twrs/objects/thumbs/dsc_0138_th.jpg,log cross section showing where tree bark was peeled,
demo_017,,Hell's Half Acre Lookout 360 Image,Keeping Watch,2021-07-13,,Example panorama. 360 Image of the Interior of Hell's Half Acre Fire Tower,,Hell's Half Acre,45.64579,-114.62838,,,Image;StillImage,image/jpeg,eng,,,panorama,/objects/hells_half_theta.jpg,https://cdil.lib.uidaho.edu/keeping-watch/objects/small/hells_half_theta_sm.jpg,https://cdil.lib.uidaho.edu/keeping-watch/objects/thumbs/hells_half_theta_th.jpg,interior of a fire lookout tower with map in center and windows in all directions,
-demo_018,,"Spokane's Great Restaurant, Washington","Mitchell, Edward H.",1909,,"Example postcard using display template 'multiple.' Postcard is of the Davenport Hotel's Restaurant in Spokane, Washington.",restaurants; automobiles; buildings; picture postcards; flagpoles; flags,"Spokane, WA",47.65710758,-117.4249084,"PG 9, Postcard Collection, University of Idaho Library Special Collections and Archives, http://www.lib.uidaho.edu/special-collections/",Postcard_038,record,postcard,eng,"Educational use includes non-commercial use of text and images in materials for teaching and research purposes. Digital reproduction rights granted by University of Idaho Library. For other uses beyond educational use, please contact University of Idaho Library Special Collections and Archives Department at libspec@uidaho.edu.",http://rightsstatements.org/vocab/InC-EDU/1.0/,multiple,,/objects/small/210a_sm.jpg,/objects/thumbs/210a_th.jpg,historic colorized postcard depicting a fancy multi-story white building with several early cars parked in front,
+demo_018,,"Spokane's Great Restaurant, Washington","Mitchell, Edward H.",1909,,"Example postcard using display template 'multiple.' Postcard is of the Davenport Hotel's Restaurant in Spokane, Washington.",restaurants; automobiles; buildings; picture postcards; flagpoles; flags,"Spokane, WA",47.65710758,-117.4249084,"PG 9, Postcard Collection, University of Idaho Library Special Collections and Archives, http://www.lib.uidaho.edu/special-collections/",Postcard_038,record,multiple,eng,"Educational use includes non-commercial use of text and images in materials for teaching and research purposes. Digital reproduction rights granted by University of Idaho Library. For other uses beyond educational use, please contact University of Idaho Library Special Collections and Archives Department at libspec@uidaho.edu.",http://rightsstatements.org/vocab/InC-EDU/1.0/,multiple,,/objects/small/210a_sm.jpg,/objects/thumbs/210a_th.jpg,historic colorized postcard depicting a fancy multi-story white building with several early cars parked in front,
demo_019,demo_018,postcard front,,,,,,,,,,210a,Image;StillImage,image/jpeg,,,,image,/objects/210a.jpg,/objects/small/210a_sm.jpg,/objects/thumbs/210a_th.jpg,historic colorized postcard depicting a fancy multi-story white building with several early cars parked in front,
demo_020,demo_018,postcard back,,,,,,,,,,210b,Image;StillImage,image/jpeg,,,,image,/objects/210b.jpg,/objects/small/210b_sm.jpg,/objects/thumbs/210b_th.jpg,"back of historic postcard dated Sept 5, 1909 with very difficult to read cursive writing in pencil",
demo_021,,"Jennie Eva Hughes, the First Black Graduate of the University of Idaho",,1899,yes,"Example compound object. Items from the Black History at University of Idaho that feature Jennie Eva Hughes, the first black graduate of the University of Idaho",Jennie Eva Hughes; Black History; University of Idaho,"Moscow, ID",46.725562,-117.009633,Black History at the University of Idaho Digital Collection,,record,compound_object,eng,,,compound_object,,https://www.lib.uidaho.edu/blackhistory/objects/small/ma2000_29_001_sm.jpg,https://www.lib.uidaho.edu/blackhistory/objects/thumbs/ma2000_29_001_th.jpg,"University of Idaho enrollment form filled in with handwritten cursive script saying ""Jennie Eva Hughes, Sept 23, 1898""",
diff --git a/_data/theme.yml b/_data/theme.yml
index 5c6ec22b..d13fb8dc 100644
--- a/_data/theme.yml
+++ b/_data/theme.yml
@@ -72,7 +72,6 @@ metadata-facets-fields: "subject,interviewer,format"
map-child-objects: true # true / false - if true, and if child item has latitude and longitude, child objects will be displayed on map
timeline-child-objects: true # true / false - if true, and if child object has date, child objects will appear as thumbnails on timeline page
data-child-objects: false # true / false - if true, child objects will appear linked in table on data page
-carousel-child-objects: false # true / false - if true, child objects will appear on homepage carousel
browse-child-objects: false # true / false - if true, child objects will appear on browse page and child objects' metadata will populate cloud pages like Subjects page and Locations page, as well as featured terms boxes on the home page
search-child-objects: true # true / false - if true, child objects will appear on on search page along with parent objects
diff --git a/_includes/collection-nav.html b/_includes/collection-nav.html
index 1b386864..21853bc7 100644
--- a/_includes/collection-nav.html
+++ b/_includes/collection-nav.html
@@ -12,7 +12,7 @@
- {%- assign navItems = site.data.config-nav | where_exp: 'item', 'item.dropdown_parent == nil' -%}
+ {%- assign navItems = site.data.config-nav | where_exp: 'item', 'item.display_name and item.dropdown_parent == nil' -%}
{% for nav in navItems %}
{% if nav.stub %}
diff --git a/_includes/feature/gallery.html b/_includes/feature/gallery.html
new file mode 100644
index 00000000..acb4b942
--- /dev/null
+++ b/_includes/feature/gallery.html
@@ -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 %}
+
{{ include.heading }}
{% endif %}
+
+ {% if include.context %}
{{include.context}}
{% endif %}
+ {% for item in gallery-items limit:gallery-limit %}
+
+
diff --git a/_includes/head/page-meta.html b/_includes/head/page-meta.html
index 50b3823b..5b435083 100644
--- a/_includes/head/page-meta.html
+++ b/_includes/head/page-meta.html
@@ -1,5 +1,6 @@
{% if site.author or site.organization-name %}{% endif %}
+{% if site.keywords %}{% endif %}
diff --git a/_includes/helpers/get-icon-svg.html b/_includes/helpers/get-icon-svg.html
new file mode 100644
index 00000000..fb3e583c
--- /dev/null
+++ b/_includes/helpers/get-icon-svg.html
@@ -0,0 +1,18 @@
+{% comment %}
+
+ Liquid utility to get a theme icon based on display_template or format.
+ returns an svg sprite (in html)
+
+ E.G. --> {% include helpers/get-icon-svg.html template="pdf" type="hidden" %}
+
+ Options:
+
+ - "template" - the display_template to represent (usually provided from an item metadata "display_template" or "format")
+ - "type" - choose from "thumb" (svg like an image), "hidden" (svg aria-hidden), or "sprite" (svg sprite) (optional, default "sprite")
+
+{%- endcomment -%}
+{%- capture iconId -%}{% if include.template contains 'image' %}icon-image{% elsif include.template contains 'pdf' %}icon-pdf{% elsif include.template contains 'video' %}icon-video{% elsif include.template contains 'audio' %}icon-audio{% elsif include.template contains 'panorama' %}icon-panorama{% elsif include.template contains 'compound' %}icon-compound-object{% elsif include.template contains 'multiple' %}icon-multiple{% elsif include.template contains 'record' %}icon-record{% else %}icon-default{% endif %}{%- endcapture -%}
+{% if include.type == "thumb" %}
+
+{%- else -%}
+{% endif %}
\ No newline at end of file
diff --git a/_includes/js/get-icon.js b/_includes/helpers/get-icon.js
similarity index 94%
rename from _includes/js/get-icon.js
rename to _includes/helpers/get-icon.js
index 10ba62b7..3c73e09d 100644
--- a/_includes/js/get-icon.js
+++ b/_includes/helpers/get-icon.js
@@ -33,6 +33,9 @@ function getIcon(objectTemplate,objectFormat,svgType) {
} else if (iconTemplate.includes("multiple")) {
iconId = "icon-multiple";
iconTitle = "multiple object icon";
+ } else if (iconTemplate.includes("record")) {
+ iconId = "icon-record";
+ iconTitle = "record object icon";
} else {
iconId = "icon-default";
iconTitle = "file icon";
diff --git a/_includes/index/carousel.html b/_includes/index/carousel.html
index 6b56020e..fd55ef75 100644
--- a/_includes/index/carousel.html
+++ b/_includes/index/carousel.html
@@ -8,24 +8,30 @@
Options:
- - "height" - the height of the carousel in px, just give the number (optional, default 300)
- - "carousel-type" - the selection of items featured in the carousel, choose from thumb (all items with image_thumb) or small (all items with image_small). (optional, default thumb)
- - "title" - card title text inside card content area (optional)
+ - "height" = the height of the carousel in px, just give the number (optional, default 300)
+ - "carousel-type" = the selection of items featured in the carousel, choose from thumb (all items with image_thumb) or small (all items with image_small). (optional, default thumb)
+ - "child-objects" = include child items in count or only parents, true or false (optional, default false)
+ - "title" = card title text inside card content area (optional)
- "header" = card header text in bar above card content (optional)
+ - "heading_level" = customize the level of the heading if necessary for accessibility, choose "h1", "h2", "h3", etc (optional, default "h2")
- "max" = maximum images selected for slide show (optional, default 9. Do not make too big!)
- - "btn-color" - a bootstrap color class to theme the buttons. Can be any bootstrap template color (e.g. info, success) or outline (e.g. outline-info, outline-success), including colors created in config-theme-colors. (optional, default "primary")
- - "btn-text" - the label used in the link btn to view the carousel item (optional, default "View Item")
+ - "btn-color" = a bootstrap color class to theme the buttons. Can be any bootstrap template color (e.g. info, success) or outline (e.g. outline-info, outline-success), including colors created in config-theme-colors. (optional, default "primary")
+ - "btn-text" = the label used in the link btn to view the carousel item (optional, default "View Item")
+ - "filter-field" and "filter-value" = use these options together to filter which set of items will appear in the carousel based on a particular metadata field and value in that field. filter-field must match a column in your metadata. any item with a value in the filter-field that "contains" the filter-value will be included, it does not need to be an exact match. (optional)
{%- endcomment -%}
{%- assign carousel-max = include.max | default: 9 -%}
{%- assign btn-color = include.btn-color | default: "primary" -%}
{%- assign btn-text = include.btn-text | default: "View Item" -%}
-{% if site.data.theme.carousel-child-objects == true %}
+{% if include.child-objects == true %}
{%- assign carousel-items = site.data[site.metadata] | where_exp: 'item','item.objectid' | where_exp: "item","item.image_small != nil or item.image_thumb != nil"-%}
{% else %}
{%- assign carousel-items = site.data[site.metadata] | where_exp: 'item','item.objectid and item.parentid == nil' | where_exp: "item","item.image_small != nil or item.image_thumb != nil" -%}
{% endif %}
+{%- if include.filter-field and include.filter-value -%}
+{% assign carousel-items = carousel-items | where_exp: 'item','item[include.filter-field] contains include.filter-value' %}
+{%- endif -%}
{%- comment -%}
Set up carousel div
@@ -34,9 +40,9 @@
#imageCarousel .carousel-item { height: {{ include.height | remove: 'px' | strip | default: '300' }}px; }
diff --git a/_includes/index/data-download.html b/_includes/index/data-download.html
index 5456be45..3b5558f8 100644
--- a/_includes/index/data-download.html
+++ b/_includes/index/data-download.html
@@ -1,28 +1,41 @@
+{% comment %}
+
+ Collection data downloads.
+ Based on the stubs present in the config-nav, displays relevant download btn links for metadata derivatives in a variety of formats. This highlights the ability to explore and reuse collection data.
+
+ E.G. --> {% include index/data-download.html %}
+
+ Options:
+
+ - "heading_level" = customize the level of the heading if necessary for accessibility, choose "h1", "h2", "h3", etc (optional, default "h2")
+
+{%- endcomment -%}
{%- assign stubs = site.data.config-nav | map: 'stub' | join: ';' -%}
\ No newline at end of file
diff --git a/_includes/index/description.html b/_includes/index/description.html
index 0aec5f87..f71b34eb 100644
--- a/_includes/index/description.html
+++ b/_includes/index/description.html
@@ -1,7 +1,21 @@
+{% comment %}
+
+ Collection Description card.
+ Pulls description from _config.yml. Provides btn link to About page if present in the config-nav.
+
+ E.G. --> {% include index/description.html %}
+
+ Options:
+
+ - "btn-color" - a bootstrap color class to theme the buttons. Can be any bootstrap template color (e.g. info, success) or outline (e.g. outline-info, outline-success), including colors created in config-theme-colors. (optional, default "primary")
+ - "heading_level" = customize the level of the heading if necessary for accessibility, choose "h1", "h2", "h3", etc (optional, default "h2")
+
+{%- endcomment -%}
+ {%- assign about = site.data.config-nav | where: "stub","/about.html" | size -%}{% if about > 0 %}
+ Learn More »{% endif %}
+
diff --git a/_includes/index/featured-terms.html b/_includes/index/featured-terms.html
index 2703ebea..0bd8070d 100644
--- a/_includes/index/featured-terms.html
+++ b/_includes/index/featured-terms.html
@@ -13,6 +13,7 @@
- "featured" - a manually created list of featured terms, separated by ; semicolon (required if not auto generating from a field)
- "title" - card title text inside card content area (optional)
- "header" = card header text in bar above card content (optional)
+ - "heading_level" = customize the level of the heading if necessary for accessibility, choose "h1", "h2", "h3", etc (optional, default "h2")
- "max" - max number of terms to display if auto generating (optional, default 5)
- "btn-color" - a bootstrap color class to theme the buttons. Can be any bootstrap template color (e.g. info, success) or outline (e.g. outline-info, outline-success), including colors created in config-theme-colors. (optional, default "primary")
@@ -41,9 +42,9 @@
{% assign topTerms = topTerms | split: ";" %}
{%- endif -%}
{% for s in topTerms %}
{{ s | strip }}{% endfor %}
diff --git a/_includes/index/objects.html b/_includes/index/objects.html
index 5cbacb38..06be6b59 100644
--- a/_includes/index/objects.html
+++ b/_includes/index/objects.html
@@ -1,38 +1,47 @@
-{%- assign templates = site.data[site.metadata] | where_exp: 'item','item.parentid == nil ' | map: "display_template" -%}
-{%- assign types = "image;audio;video;pdf;panorama;record;compound_object;multiple;transcript" | split: ";" -%}
+{% comment %}
+
+ Collection objects summary.
+ Counts item types based on "display_template" providing link to Browse page.
+
+ E.G. --> {% include index/objects.html %}
+
+ E.G. --> {% include index/objects.html object_field="format" others=true total=true %}
+
+ Options:
+
+ - "btn-color" - a bootstrap color class to theme the buttons. Can be any bootstrap template color (e.g. info, success) or outline (e.g. outline-info, outline-success), including colors created in config-theme-colors. (optional, default "outline-secondary")
+ - "heading_level" = customize the level of the heading if necessary for accessibility, choose "h1", "h2", "h3", etc (optional, default "h2")
+ - "object_field" = optionally change the field used to count items. Typically this is either "display_template" (default) or "format". The field should be available on the Browse page to filter! The icons assume you use something like "display_template" or "format" to select the correct icon.
+ - "child-objects" = include child items in count or only parents, true or false (optional, default false)
+ - "others" = display a count for items with no "display_template", true or false (optional, default false)
+ - "total" = display a count for total items, true or false (optional, default false)
+
+{%- endcomment -%}
+{%- assign object_field = include.object_field | default: 'display_template' -%}
+{% if include.child-objects == true %}
+{%- assign items = site.data[site.metadata] | where_exp: 'item','item.objectid' -%}
+{% else %}
+{%- assign items = site.data[site.metadata] | where_exp: 'item','item.objectid and item.parentid == nil' -%}
+{% endif %}
+{%- assign templates = items | map: object_field -%}
+{%- assign types = templates | uniq | compact | sort -%}
+ {% for t in types %}
+ {%- assign count = templates | where_exp: 'item', 'item contains t' | size -%}
+ {% if count > 0 %}
+ {{ count }}
+ {{ t | upcase | replace: "_", " " }}
+ {% include helpers/get-icon-svg.html type="hidden" template=t %}
+ {%- endif -%}
+ {%- endfor -%}
+ {% if include.others == true %}{% assign others = templates | where_exp: 'item', 'item == nil or item == ""' | size %}{% if others > 0 %}
+ {{ others }} OTHER {% include helpers/get-icon-svg.html type="hidden" %} {% endif %}{% endif %}
+ {% if include.total == true %}
+ {{ templates | size }} TOTAL ITEMS {% endif %}
+ View table
+
+
\ No newline at end of file
diff --git a/_includes/index/time.html b/_includes/index/time.html
index 44173ea1..0a2f529d 100644
--- a/_includes/index/time.html
+++ b/_includes/index/time.html
@@ -1,19 +1,34 @@
+{% comment %}
+
+ Collection time span.
+ Extracts all content of "date" field, displays the smallest and largest.
+ You may encounter issues if you do not have a correctly ISO formatted "date" field.
+
+ E.G. --> {% include index/time.html %}
+
+ Options:
+
+ - "date_field" - optionally change the field used for date range. Only ISO or year-only dates are supported. (optional, default "date")
+ - "btn-color" - a bootstrap color class to theme the buttons. Can be any bootstrap template color (e.g. info, success) or outline (e.g. outline-info, outline-success), including colors created in config-theme-colors. (optional, default "outline-secondary")
+ - "heading_level" = customize the level of the heading if necessary for accessibility, choose "h1", "h2", "h3", etc (optional, default "h2")
+
+{%- endcomment -%}
+{% assign date_field = include.date_field | default: 'date' %}
{% if site.data.theme.timeline-child-objects == true %}
{%- assign date-items = site.data[site.metadata] | where_exp: 'item','item.objectid' -%}
{% else %}
{%- assign date-items = site.data[site.metadata] | where_exp: 'item','item.parentid == nil' -%}
{% endif %}
-{%- assign raw-dates = date-items | map: 'date' | compact | uniq -%}
+{%- assign raw-dates = date-items | map: date_field | compact | uniq -%}
{%- capture clean-years -%}{% for date in raw-dates %}{% if date contains "-" %}{{ date | strip | split: "-" | first }}{% elsif date contains "/" %}{{ date | strip | split: "/" | last }}{% else %}{{ date | strip }}{% endif %}{% unless forloop.last %};{% endunless %}{%- endfor -%}{%- endcapture -%}
{%- assign date-range = clean-years | remove: " " | split: ";" | uniq | sort -%}
{% if date-range.size > 0 %}
-
-
Time Span
-
{{ date-range | first }} to {{ date-range | last }}
- View Timeline
-
\ No newline at end of file
+function stopMedia(objectid, type) {
+ // stop media based on type
+ if (type == "audio") {
+ const mediaElement = document.querySelector(`#${ objectid } audio`);
+ mediaElement.pause();
+ //mediaElement.currentTime = 0;
+ }
+ if (type == "video") {
+ const mediaElement = document.querySelector(`#${ objectid } video`);
+ mediaElement.pause();
+ //mediaElement.currentTime = 0;
+ }
+ if (type == "youtube") {
+ const mediaElement = document.querySelector(`#${ objectid } iframe`);
+ const message = JSON.stringify({ event: 'command', func: 'pauseVideo', args: '' });
+ mediaElement.contentWindow.postMessage(message, '*');
+ }
+ if (type == "vimeo") {
+ const mediaElement = document.querySelector(`#${ objectid } iframe`);
+ mediaElement.contentWindow.postMessage('{"method":"pause"}', '*');
+ }
+}
+
\ No newline at end of file
diff --git a/_includes/item/child/ia-embed.html b/_includes/item/child/ia-embed.html
new file mode 100644
index 00000000..cf2680d4
--- /dev/null
+++ b/_includes/item/child/ia-embed.html
@@ -0,0 +1,27 @@
+{% comment %}
+
+ Internet Archive item embed.
+ Loads a book/pdf, video, or audio item from Internet Archive via their standard iframe embed.
+
+ The item's "objects_location" must be the full public URL to the object on IA. The item url looks something like:
+
+ book, https://archive.org/details/uidaho_gem_1903
+ video, https://archive.org/details/fluxusfireplace
+ audio, https://archive.org/details/aladore_1704_librivox
+
+ The embed works for books/pdfs, video, and audio--however, you will want to tweak the aspect ratio for different item types!
+
+ Options:
+
+ - "ratio" = use Bootstrap embed ratio options "21x9", "16x9", "4x3", or "1x1" to customize the responsive aspect ratio if not using height. 4x3 is default. (optional)
+ - "height" = set embed object height in px (rather than responsive size), width will be 100%, e.g. "800px" (optional)
+ - "style" = apply an arbitrary style to the div containing the embed. This is useful if you are trying to add a min height or custom aspect ratio. (optional)
+ - min height is useful for book items on mobile, e.g. "min-height: 500px;"
+ - custom aspect ratio may be useful for book items, e.g. "--bs-aspect-ratio: %115;"
+ - both e.g. "min-height: 500px;--bs-aspect-ratio: calc(3 / 4 * 100%);"
+
+{% endcomment %}
+{% assign archive_id = child.object_location | split: '/' | last %}
+
+
+
`
\ No newline at end of file
diff --git a/_includes/item/ia-embed.html b/_includes/item/ia-embed.html
new file mode 100644
index 00000000..6a44e837
--- /dev/null
+++ b/_includes/item/ia-embed.html
@@ -0,0 +1,27 @@
+{% comment %}
+
+ Internet Archive item embed.
+ Loads a book/pdf, video, or audio item from Internet Archive via their standard iframe embed.
+
+ The item's "objects_location" must be the full public URL to the object on IA. The item url looks something like:
+
+ book, https://archive.org/details/uidaho_gem_1903
+ video, https://archive.org/details/fluxusfireplace
+ audio, https://archive.org/details/aladore_1704_librivox
+
+ The embed works for books/pdfs, video, and audio--however, you will want to tweak the aspect ratio for different item types!
+
+ Options:
+
+ - "ratio" = use Bootstrap embed ratio options "21x9", "16x9", "4x3", or "1x1" to customize the responsive aspect ratio if not using height. 4x3 is default. (optional)
+ - "height" = set embed object height in px (rather than responsive size), width will be 100%, e.g. "800px" (optional)
+ - "style" = apply an arbitrary style to the div containing the embed. This is useful if you are trying to add a min height or custom aspect ratio. (optional)
+ - min height is useful for book items on mobile, e.g. "min-height: 500px;"
+ - custom aspect ratio may be useful for book items, e.g. "--bs-aspect-ratio: %115;"
+ - both e.g. "min-height: 500px;--bs-aspect-ratio: calc(3 / 4 * 100%);"
+
+{% endcomment %}
+{% assign archive_id = page.object_location | split: '/' | last %}
+
+
+
`
\ No newline at end of file
diff --git a/_includes/js/browse-js.html b/_includes/js/browse-js.html
index 0ec2b94b..a3dae2cb 100644
--- a/_includes/js/browse-js.html
+++ b/_includes/js/browse-js.html
@@ -19,7 +19,7 @@
"id":{{ item.objectid | jsonify }} }{% unless forloop.last %},{% endunless %}{%- endfor -%}
];
-{% include js/get-icon.js %}
+{% include helpers/get-icon.js %}
/* function to create cards for each item */
function makeCard(obj) {
diff --git a/_includes/js/map-js.html b/_includes/js/map-js.html
index 84a5079c..b94d4e78 100644
--- a/_includes/js/map-js.html
+++ b/_includes/js/map-js.html
@@ -110,7 +110,7 @@
});{% endif %}
/* get icons function */
- {% include js/get-icon.js %}
+ {% include helpers/get-icon.js %}
/* object popup function */
function objectPopups(feature, layer) {
diff --git a/_includes/transcript/item/filters.html b/_includes/transcript/item/filters.html
index f7ac44fe..5d7a6955 100644
--- a/_includes/transcript/item/filters.html
+++ b/_includes/transcript/item/filters.html
@@ -1,10 +1,6 @@
-{% if site.data.theme.search-and-filters == false %}
-
+{% endunless %}
\ No newline at end of file
diff --git a/_includes/transcript/item/transcript-viz.html b/_includes/transcript/item/transcript-viz.html
index 25b8f2d2..889efa12 100644
--- a/_includes/transcript/item/transcript-viz.html
+++ b/_includes/transcript/item/transcript-viz.html
@@ -16,4 +16,11 @@
Topics:
{%endfor%}
- {% include /transcript/style/visualization-filter-legend.html %}
\ No newline at end of file
+ {% include /transcript/style/visualization-filter-legend.html %}
+ {% if site.data.filters and site.data.theme.search-and-filters == false%}
+
+
+ Reset Filters
+
+
+ {% endif %}
\ No newline at end of file
diff --git a/_includes/transcript/js/scrollama-js.html b/_includes/transcript/js/scrollama-js.html
new file mode 100644
index 00000000..82da28eb
--- /dev/null
+++ b/_includes/transcript/js/scrollama-js.html
@@ -0,0 +1,482 @@
+
+
+
+
\ No newline at end of file
diff --git a/_includes/transcript/js/transcript-js.html b/_includes/transcript/js/transcript-js.html
index e56088c0..5f65cbdf 100644
--- a/_includes/transcript/js/transcript-js.html
+++ b/_includes/transcript/js/transcript-js.html
@@ -4,6 +4,7 @@
const filtersSearch = document.getElementById('filters-search');
const filterTab = document.getElementById('filter-tab');
const upperElement = document.getElementById('upper-content');
+ const step0 = document.getElementById('step0');
function vizFilter(x) {
var rects = document.getElementsByTagName('rect');
@@ -11,7 +12,9 @@
params.set('filter', x);
var p = params.toString();
window.history.replaceState({}, '', location.pathname + '?' + p);
+ {% unless site.data.theme.search-and-filters == false %}
document.getElementById('filters').value = x;
+ {% endunless %}
}
for (i = 0; i < rects.length; i++) {
var classString = rects[i].classList;
@@ -68,17 +71,20 @@
itemcontents.classList.add("small", "text-muted");
}
}
- {% if site.data.filters %}{% unless site.data.theme.search-and-filters == false %}document.getElementById("filters").selectedIndex = 0;{% endunless %}{% endif %}
+ {% if site.data.filters %}
+ document.getElementById("filters").selectedIndex = 0;
+ {% endif %}
let numberofint = document.querySelectorAll('.featured').length;
document.getElementById("numberof").innerHTML = numberofint + " lines match your query --> " + x + "";
document.getElementById("searchResults").innerHTML = searchResults;
document.getElementById("linecount").classList.remove("d-none");
- document.getElementById("filtersearch").classList.remove("d-none");
- {% unless site.data.theme.search-and-filters == false %}if (filtersSearch.classList.contains("retracted")) { setTimeout(function () { filtersSearch.classList.add("retracted"); }, 300); }{% endunless%}
+ document.getElementById("filtersearch-dropdown").classList.remove("d-none");
+ if (filtersSearch.classList.contains("retracted")) { setTimeout(function () { filtersSearch.classList.add("retracted"); }, 300); }
}
}
- {% if site.data.filters %} function filterLines(x) {
+ {% if site.data.filters %}
+ function filterLines(x) {
resetVals();
var itemcontainer = document.getElementById("contents-container");
var lines = itemcontainer.getElementsByClassName("line");
@@ -120,9 +126,10 @@
document.getElementById("quicksearch").value = "";
document.getElementById("searchResults").innerHTML = searchResults;
document.getElementById("linecount").classList.remove("d-none");
- document.getElementById("filtersearch").classList.remove("d-none");
+ document.getElementById("filtersearch-dropdown").classList.remove("d-none");
countforFilter(filterClass);
- {% unless site.data.theme.search-and-filters == false %}if (filtersSearch.classList.contains("retracted")) { setTimeout(function () { filtersSearch.classList.add("retracted"); }, 300); }{% endunless%}
+ if (filtersSearch.classList.contains("retracted"))
+ { setTimeout(function () { filtersSearch.classList.add("retracted"); }, 300); }
}
function countforFilter(x) {
@@ -158,21 +165,24 @@
behavior: 'smooth', // Enables smooth scrolling
block: 'start' // Aligns to the top of the viewport
});
- {% unless site.data.theme.search-and-filters == false %}setTimeout(function () { filtersSearch.classList.add("retracted"); }, 300);{% endunless %}
+ // if filters are not retracted, wait 300ms then retract them after scrolling function activated
+ if (!filtersSearch.classList.contains("retracted")) {
+ setTimeout(function () { filtersSearch.classList.add("retracted"); }, 300);
+ }
}
-
-
function resetVals() {
params.delete('q');
params.delete('filter');
params.delete('line');
window.history.replaceState({}, '', location.pathname);
+ {% unless site.data.theme.search-and-filters == false %}
document.getElementById("linecount").classList.add("d-none");
- document.getElementById("filtersearch").classList.add("d-none");
+ document.getElementById("filtersearch-dropdown").classList.add("d-none");
document.getElementById("quicksearch").value = "";
document.getElementById("filters").selectedIndex = 0;
+ {% endunless %}
var words = document.querySelectorAll("p.words")
var lines = document.querySelectorAll(".line")
for (i = 0; i < words.length; i++) {
@@ -182,7 +192,8 @@
words[i].getElementsByClassName('text-danger')[0].classList.remove('text-danger');
}
}
- {% if site.data.filters %} var svgContainer = document.getElementById("colorViz");
+ {% if site.data.filters %}
+ var svgContainer = document.getElementById("colorViz");
var rects = svgContainer.getElementsByTagName('rect');
for (i = 0; i < rects.length; i++) {
rects[i].classList.remove('dark');
@@ -234,19 +245,42 @@
};
})();
-
+
//filters tab javascript + scroll-to-top retraction of filters
document.addEventListener('DOMContentLoaded', function () {
- {% unless site.data.theme.search-and-filters == false %}filterTab.addEventListener('click', function () {
- filtersSearch.classList.toggle('retracted');
- });{% endunless %}
+ // check height of upper element containing av + metadata and viz
+ var upperHeight = upperElement.offsetHeight;
+ // make the first sections minimum height equal to this height so that when the AV section moves down the page, the page height stays the same. First checks to see if the heigh is less than 300px and makes min-height 350px in that instance, which happens on mobile when going down to specific line.
+ if (upperHeight < 300) {
+ step0.style.minHeight = "350px";
+ } else {
+ step0.style.minHeight = upperHeight + "px";
+ }
+
+ {% unless site.data.theme.search-and-filters == false %}
+ // add event listener so that when tab is clicked, filters element retracts up the page
+ filterTab.addEventListener('click', function () {
+ filtersSearch.classList.toggle('retracted');
+ });
+ {% endunless %}
+ // listener for the scroll to top button clickc
document.getElementById('scroll-to-top').addEventListener('click', function () {
- {% unless site.data.theme.search-and-filters == false %}if (filtersSearch.classList.contains("retracted")) { filtersSearch.classList.remove("retracted"); }{% endunless %}
+ {% unless site.data.theme.search-and-filters == false %}
+ // if scroll-to-top button clicked and filters are retracted, un retract them
+ if (filtersSearch.classList.contains("retracted")) {
+ filtersSearch.classList.remove("retracted"); }
+ {% endunless %}
{% if site.data.theme.media-scroll == true %}
- if (upperElement.classList.contains("media-scroll-wrapper")) { setTimeout(function () { upperElement.classList.remove("media-scroll-wrapper"); }, 300); console.log('scrollstopped?'); } {% endif %}
- });
- });
+ // if the AV section is classed as moving down the page, remove it after 200 ms upon the scroll-to-top button being pushed
+ if (upperElement.classList.contains("media-scroll-wrapper")) {
+ setTimeout(function () { upperElement.classList.remove("media-scroll-wrapper"); }, 200);
+ }
+ {% endif %}
+ });// end scroll to top listener
+ }); // end content loaded listener function
+
+ /*
function throttle(mainFunction, delay) {
let timerFlag = null; // Variable to keep track of the timer
@@ -303,5 +337,5 @@
// Add an event listener to the window scroll event that calls the throttleScrollCheck function
window.addEventListener("scroll", throttleScrollCheck);
window.addEventListener('load', checkStickyAndUpdate);
-
+*/
\ No newline at end of file
diff --git a/_includes/transcript/style/media-scroll-wrapper.html b/_includes/transcript/style/media-scroll-wrapper.html
index 0db5d562..22268faa 100644
--- a/_includes/transcript/style/media-scroll-wrapper.html
+++ b/_includes/transcript/style/media-scroll-wrapper.html
@@ -20,10 +20,23 @@
display: flex;
}
+.step0-min-height
+{
+ min-height:350px;
+}
+
@media screen and (max-width: 998px) {
.media-scroll-wrapper {
- display: none
+ display: none;
+ position: relative !important;
+ right: auto;
+ bottom: auto;
+ height: auto;
+ width: auto;
+ }
+ .step0-min-height{
+ min-height: auto;
}
}
\ No newline at end of file
diff --git a/_layouts/browse.html b/_layouts/browse.html
index c66f2d1e..25cf3350 100644
--- a/_layouts/browse.html
+++ b/_layouts/browse.html
@@ -8,7 +8,7 @@