diff --git a/CHANGELOG.md b/CHANGELOG.md index 0881f0c8..18b17ae0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- ### Adds Collection Grid block and Collection Item content type + Closes #534. + Adds the collection grid block and collection item node page +--- + - ### Enables list styles in full HTML, Creates Migration Library Using Full HTML you can create various list styles found here: https://styleguide.colorado.edu/content/lists Also creates a temporary migration library for addtl styles needed for the migration process diff --git a/boulder_base.libraries.yml b/boulder_base.libraries.yml index af0fbcb3..55085063 100644 --- a/boulder_base.libraries.yml +++ b/boulder_base.libraries.yml @@ -485,3 +485,10 @@ ucb-class-notes-list-page: css: theme: css/ucb-class-notes-list.css: {} +ucb-collections-block: + version: 1.x + js: + js/ucb-collections-block.js: {} + css: + theme: + css/block/ucb-collections-block.css: {} diff --git a/css/block/ucb-collections-block.css b/css/block/ucb-collections-block.css new file mode 100644 index 00000000..867468ad --- /dev/null +++ b/css/block/ucb-collections-block.css @@ -0,0 +1,184 @@ +.collection-category-line { + display: flex; + min-width: max-content; + align-items: center; + margin-bottom: 2px; +} + +.category-label { + white-space: normal; + font-weight: normal; + padding: 3px 2px 3px 0; +} + +.category-checkbox { + margin: 0 10px 0 0; +} + +.category-filter-reset { + display: inline-block; + padding: 5px 10px; + font-weight: bold; + margin-bottom: 5px; + text-decoration: none !important; + border-radius: 3px; + background-clip: padding-box; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); + transition: box-shadow 0.5s ease, background-color 0.5s ease, color 0.5s ease; + background-color: #EEEEEE; + color: #111111 !important; + + background: #EEEEEE; + font-size: 85%; + font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; + border: 1px solid #ddd; + margin-top: 10px; +} + +.category-filter-reset:hover { + background-color: #d6d6d6; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3); +} + +.collections-item-block { + border: 1px solid #e7e7e7; + background-color: #fff; + padding: 15px; + width: 100%; + height: 100%; + -webkit-transition: background-color 0.3s linear; + -moz-transition: background-color 0.3s linear; + -ms-transition: background-color 0.3s linear; + -o-transition: background-color 0.3s linear; + transition: background-color 0.3s linear; +} + +.collections-item-block:hover { + background-color: #f4f4f4; +} + +.collections-grid-block-data { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-between; +} + +.collection-multiselect-multi .collections-grid-block-data { + margin-left: 20px; +} + +.ucb-collection-card-container { + transition: opacity .5s ease; + margin: 5px 0px; + min-width: min-content; +} + +.ucb-collection-card-img { + padding-bottom: 10px; +} + +@media (min-width: 1200px) { + .ucb-collection-card-container { + width: 30%; + } +} + +@media (min-width: 960px) and (max-width: 1199px) { + .ucb-collection-card-container { + width: 45%; + } +} + +@media (min-width: 768px) and (max-width: 959px) { + .ucb-collection-card-container { + width: 49%; + } +} + +@media (max-width: 768px) { + .ucb-collection-card-container { + width: 100%; + } +} + +.collection-grid-container.collection-multiselect-single { + display: flex; + flex-direction: column; +} + +.collection-grid-container.collection-multiselect-multi { + display: flex; + flex-direction: row; +} + +.collection-filter-fade .ucb-collection-card-container.filtered { + + opacity: .25; +} + +.collection-filter-hide .ucb-collection-card-container.filtered { + display: none; +} + +.collections-filter-list { + max-width: 100%; +} + +.collection-grid-filters { + padding: 10px; + border: 1px solid #e7e7e7; +} + +.collection-multiselect-single .category-filter-label { + font-size: 100%; + display: inline; + font-weight: bold; +} + +.category-single-button { + background-color: #EFEFEF; + border: 1px solid #181818; + padding: 1px 6px; + border-radius: 2px; + margin: 0 5px 5px 0; +} + +.collection-reset { + margin-left: 20px; +} + +.collection-grid-filter-span { + margin-left: 20px; +} + + +@media (max-width: 1199px) { + .collection-multiselect-multi .collection-category-container { + display: flex; + flex-wrap: wrap; + } + + .collection-grid-container.collection-multiselect-multi { + flex-direction: column; + } + + .collection-multiselect-multi .collection-category-line { + margin-right: 20px; + } + + .collection-multiselect-multi .collection-grid-filter-span, + .collection-multiselect-multi .collections-grid-block-data { + margin-left: 0; + } + + .collection-filter-fade .ucb-collection-card-container.filtered { + + display: none; + } +} + +.collection-multiselect-single .collection-filter-links { + display: flex; + flex-flow: row wrap; +} \ No newline at end of file diff --git a/js/ucb-collections-block.js b/js/ucb-collections-block.js new file mode 100644 index 00000000..5bd96022 --- /dev/null +++ b/js/ucb-collections-block.js @@ -0,0 +1,465 @@ + /** + * Main function that will load the initial data from the given URL and start processing it for display + * @param {string} JSONURL - URL for the JSON:API endpoint with filters, sort and pagination + * @param {string} id - target DOM element to add the content to + * @param {string} IncludeCategories - array of categories to include when rendering + * @param {string} ExcludeTags - array of tags to filter out when rendering + * @returns - Promise with resolve or reject + */ + + function renderCollectionCategories( JSONURL, blockID) { + return new Promise(function(resolve, reject) { + // next URL if there is one, will be returned by this funtion + let NEXTJSONURL = ""; + + if (JSONURL) { + //let el = document.getElementById(id); + + // show the loading spinner while we load the data + // toggleMessage("ucb-al-loading", "block"); + + fetch(JSONURL) + .then((reponse) => reponse.json()) + .then((data) => { + // get the next URL and return that if there is one + if(data.links.next) { + NEXTJSONURL = data.links.next.href; + } else { + NEXTJSONURL = ""; + } + + // if no collections of returned, stop the loading spinner and let the user know we received no data that matches their query + if (!data.data.length) { + reject; + } + + data.data.map((item) => { + let currentDataID = item.attributes.drupal_internal__revision_id; + let currentClassName = "category-label-" + currentDataID + "-" + blockID; + let categoryLabels = document.getElementsByClassName(currentClassName); + //console.log("currentClass: ", currentClassName) + for (let i = 0; i < categoryLabels.length; i++) { + //console.log("checkClass:") + categoryLabels[i].innerHTML = item.attributes.name; + } + + + }) + resolve(NEXTJSONURL); + }).catch(function(error) { + // catch any fetch errors and let the user know so they're not endlessly watching the spinner + console.log("Fetch Error in URL : " + JSONURL); + console.log("Fetch Error is : " + error); + + }); + + } + }); + } + function renderCollectionList( JSONURL, ExcludeTags = "", BodyDisplay, blockID, BaseURL) { + return new Promise(function(resolve, reject) { + let includeTypeArray = ExcludeTags.split(",").map(Number); + // next URL if there is one, will be returned by this funtion + let NEXTJSONURL = ""; + + + if (JSONURL) { + //let el = document.getElementById(id); + + fetch(JSONURL) + .then((reponse) => reponse.json()) + .then((data) => { + // console.log("Data", data); + // get the next URL and return that if there is one + if(data.links.next) { + NEXTJSONURL = data.links.next.href; + //console.log("NEXTJSONURL", NEXTJSONURL) + } else { + NEXTJSONURL = ""; + } + //console.log("data obj", data); + + // if no collections of returned, stop the loading spinner and let the user know we received no data that matches their query + if (!data.data.length) { + reject; + } + + // Below objects are needed to match images with their corresponding collections. There are two endpoints => data.data (collection) and data.included (incl. media), both needed to associate a media library image with its respective collection + let urlObj = {}; + let idObj = {}; + let altObj = {}; + let altTagObj = {}; + // Remove any blanks from our collections before map + if (data.included) { + // removes all other included data besides images in our included media + let idFilterData = data.included.filter((item) => { + return item.type == "media--image"; + }) + + let altFilterData = data.included.filter((item) => { + return item.type == 'file--file'; + }); + // finds the focial point version of the thumbnail + altFilterData.map((item)=>{ + // checks if consumer is working, else default to standard image instead of focal image + if(item.links.focal_image_wide != undefined){ + altObj[item.id] = item.links.focal_image_wide.href + } else { + altObj[item.id] = item.attributes.uri.url + } + }) + + // using the image-only data, creates the idObj => key: thumbnail id, value : data id + idFilterData.map((pair) => { + idObj[pair.id] = pair.relationships.thumbnail.data.id; + altTagObj[pair.id] = pair.relationships.thumbnail.data.meta.alt; + }) + } + // console.log("idObj", idObj); + // console.log("urlObj", urlObj); + // console.log('altObj', altObj) + //iterate over each item in the array + data.data.map((item) => { + // console.log("item", item); + let thisCollectionCats = []; + let thisCollectionTypes = ""; + let typeInclusion = 0; + // // loop through and grab all of the categories + if (item.relationships.field_collection_item_category.data) { + for (let i = 0; i < item.relationships.field_collection_item_category.data.length; i++) { + thisCollectionCats.push( + item.relationships.field_collection_item_category.data[i].meta.drupal_internal__target_id + ) + } + } + + // console.log("this collection cats",thisCollectionCats) + // // loop through and grab all of the tags + if (item.relationships.field_collection_item_page_type.data) { + thisCollectionTypes = item.relationships.field_collection_item_page_type.data.meta.drupal_internal__target_id; + } + + // checks to see if the current collection (item) contains a category or tag scheduled for exclusion + let doesIncludeCat = thisCollectionCats; + let doesIncludeType = thisCollectionTypes; + if(includeTypeArray.includes(thisCollectionTypes)) { + typeInclusion = 1; + } + + + // render the content if there is a similar type + if (typeInclusion == 1) { + // we need to render the Collection Card view for this returned element + // **ADD DATA** + // this is my id of the collection body paragraph type we need only if no thumbnail or summary provided + //let bodyAndImageId = item.relationships.field_ucb_collection_content.data.length ? item.relationships.field_ucb_collection_content.data[0].id : ""; + let body = ""; + if(item.attributes.field_collection_item_preview ) { + body = item.attributes.field_collection_item_preview.replace( + /<\/?[^>]+(>|$)/g, + "" + ) + var el = document.createElement("div"); + el.innerHTML = body; + body = el.innerText; + } + + body = body.trim(); + + let imageSrc = ""; + let imageAlt = ""; + // if no collection summary, use a simplified collection body + if (!body.length) { + let data = item.attributes.body; + // Remove any html tags within the collection + let htmlStrip = data.value.replace( + /<\/?[^>]+(>|$)/g, + "" + ) + // Remove any line breaks if media is embedded in the body + let lineBreakStrip = htmlStrip.replace(/(\r\n|\n|\r)/gm, ""); + + var el = document.createElement("div"); + el.innerHTML = lineBreakStrip; + lineBreakStrip = el.innerText; + // take only the first 100 words ~ 500 chars + let trimmedString = lineBreakStrip.substr(0, 250); + // if in the middle of the string, take the whole word + if(trimmedString.length > 100){ + trimmedString = trimmedString.substr( + 0, + Math.min( + trimmedString.length, + trimmedString.lastIndexOf(" ") + ) + ) + body = `${trimmedString}...`; + } else { + // set the contentBody of Collection Summary card to the minified body instead + body = `${trimmedString}`; + + } + //document.getElementById(`body-${bodyAndImageId}`).innerText = body; + + } + + // if no thumbnail, show no image + if (!item.relationships.field_collection_item_thumbnail.data) { + imageSrc = ""; + } else { + //Use the idObj as a memo to add the corresponding image url + let thumbId = item.relationships.field_collection_item_thumbnail.data.id; + imageSrc = altObj[idObj[thumbId]]; + imageAlt = altTagObj[thumbId]; + //console.log("Alt: ", imageAlt) + } + + let title = item.attributes.title; + let link = ""; + // console.log("Link: ", BaseURL + "/node" + item.attributes.drupal_internal__nid); + if(item.attributes.path.alias) { + link = item.attributes.path.alias; + } + else { + link = BaseURL + "/node/" + item.attributes.drupal_internal__nid; + } + let image = ""; + let collectionSummarySize = "col-md-12"; + + var collectionBlock = document.createElement('div') + collectionBlock.className = 'collections-item-block' + + if(link && imageSrc) { + collectionSummarySize = "col-md-10" + + var imgContainer = document.createElement('div') + imgContainer.className = 'ucb-collection-card-img' + + var imgLink = document.createElement('a') + imgLink.href = link; + + var collectionImg = document.createElement('img') + collectionImg.src = imageSrc; + collectionImg.alt = imageAlt; + + imgLink.appendChild(collectionImg) + imgContainer.appendChild(imgLink) + + // add to collection row + collectionBlock.appendChild(imgContainer) + } + + + // Container + var collectionDataContainer = document.createElement('div') + collectionDataContainer.className = `col-sm-12 ${collectionSummarySize} ucb-collection-card-data` + + + // Header + var collectionDataLink = document.createElement('a') + collectionDataLink.href = link; + + var collectionDataHead = document.createElement('h4') + collectionDataHead.className = "ucb-collection-card-title" + collectionDataHead.innerText = title; + + collectionDataLink.appendChild(collectionDataHead) + + collectionDataContainer.appendChild(collectionDataLink) + + + // Summary + if(BodyDisplay == "show") { + var collectionSummaryBody = document.createElement('p') + collectionSummaryBody.className = 'ucb-collection-item-body' + //collectionSummaryBody.id = `body-${bodyAndImageId}` + collectionSummaryBody.innerText = body; + collectionDataContainer.appendChild(collectionSummaryBody) + } + + //Appends + collectionBlock.appendChild(collectionDataContainer) + + + + let dataOutput = document.getElementById("collections-grid-block-data-"+ blockID); + let thisCollection = document.createElement("collection"); + thisCollection.className = 'ucb-collection-card-container ucb-collection-card-container-' + blockID; + + thisCollectionCats.map((item) => { + thisCollection.classList.add('ucb-collection-category-' + item + "-" + blockID); + + }); + + + thisCollection.appendChild(collectionBlock); + dataOutput.append(thisCollection); + + if(NEXTJSONURL){ + //toggleMessage('ucb-el-load-more', 'inline-block') + } + } + }) + + // done loading -- hide the loading spinner graphic + //toggleMessage("ucb-al-loading", "none"); + resolve(NEXTJSONURL); + }).catch(function(error) { + // catch any fetch errors and let the user know so they're not endlessly watching the spinner + console.log("Fetch Error in URL : " + JSONURL); + console.log("Fetch Error is : " + error); + // turn off spinner + //toggleMessage("ucb-al-loading", "none"); + // turn on default error message + if(error){ + //toggleMessage("ucb-al-error", "block"); + + } + + }); + + } + }); + } + + + + function filterChecked(blockID) { + //console.log("BlockID: ", blockID) + let allCards = document.getElementsByClassName("ucb-collection-card-container-" + blockID); + let addedSpanData = document.getElementsByClassName("collection-grid-filter-span-" + blockID); + let noFilters = 0; + for (let i = 0; i < addedSpanData.length; i++) { + addedSpanData[i].innerHTML = "Selected Filters: " + } + + + for (let i = 0; i < allCards.length; i++) { + allCards[i].classList.add("filtered"); + } + + let allChecks = document.getElementsByClassName("category-checkbox-" + blockID); + for (let i = 0; i < allChecks.length; i++) { + let currentID = allChecks[i].dataset.category; + if(allChecks[i].checked) { + noFilters = 1; + let checkedCards = document.getElementsByClassName("ucb-collection-category-" + currentID + "-" + blockID); + for (let i = 0; i < checkedCards.length; i++) { + checkedCards[i].classList.remove("filtered"); + } + + + let currentCategory = document.getElementsByClassName("category-label-"+currentID + "-" + blockID); + for (let i = 0; i < addedSpanData.length; i++) { + addedSpanData[i].innerHTML = addedSpanData[i].innerHTML + currentCategory[0].innerText + ", "; + } + } + } + + for (let i = 0; i < addedSpanData.length; i++) { + addedSpanData[i].innerHTML = addedSpanData[i].innerHTML.slice(0, -2) + " Reset Filters" + } + if(noFilters == 0) { + for (let i = 0; i < allCards.length; i++) { + allCards[i].classList.remove("filtered"); + } + for (let i = 0; i < addedSpanData.length; i++) { + addedSpanData[i].innerHTML = ""; + } + } + } + + function filterSingle(currentID, blockID) { + + + let allCards = document.getElementsByClassName("ucb-collection-card-container-" + blockID); + for (let i = 0; i < allCards.length; i++) { + allCards[i].classList.add("filtered"); + } + + let checkedCards = document.getElementsByClassName("ucb-collection-category-" + currentID + "-" + blockID); + for (let i = 0; i < checkedCards.length; i++) { + checkedCards[i].classList.remove("filtered"); + } + + + } + + function resetFilters(blockID) { + + let allCards = document.getElementsByClassName("ucb-collection-card-container-" + blockID); + for (let i = 0; i < allCards.length; i++) { + allCards[i].classList.remove("filtered"); + } + + let allChecks = document.getElementsByClassName("category-checkbox-" + blockID); + for (let i = 0; i < allChecks.length; i++) { + allChecks[i].checked = false; + } + + let clearSpanData = document.getElementsByClassName("collection-grid-filter-span-" + blockID); + for (let i = 0; i < clearSpanData.length; i++) { + clearSpanData[i].innerHTML = ""; + } + + } + + function resetSingleFilters(blockID) { + let allCards = document.getElementsByClassName("ucb-collection-card-container-" + blockID); + for (let i = 0; i < allCards.length; i++) { + allCards[i].classList.remove("filtered"); + } + + } + + /** + * Initilization and start of code + */ + (function () { + // Get all instances of the collection grid + let collectionGridInstances = document.getElementsByClassName("collection-grid-container"); + //console.log(collectionGridInstances) + for (let i = 0; i < collectionGridInstances.length; i++) { + // get the url from the data-jsonapi variable + let el = document.getElementById("collections-grid-block-data-"+collectionGridInstances[i].dataset.blockid); + let JSONURL = ""; // JSON:API URL + let JSONCATURL = ""; // JSON:API Category URL + let NEXTJSONURL = ""; // next link for pagination + let TagsExclude = ""; // tags to exclude + let BodyDisplay = ""; // variable to display body text or not + let BaseURL = ""; + let blockID = collectionGridInstances[i].dataset.blockid; + + // check to see if we have the data we need to work with. + if (el) { + JSONURL = el.dataset.jsonapi; + JSONCATURL = el.dataset.jsoncats; + TagsExclude = el.dataset.extags; + BodyDisplay = el.dataset.bodydisplay; + BaseURL = el.dataset.baseurl; + } + /* + console.log("BASEURL: ", BaseURL) + + console.log("\n JSONURL: " + JSONURL); + console.log("\n JSONCATURL: " + JSONCATURL); + console.log("\n TagsExclude: " + TagsExclude); + console.log("\n BodyDisplay: " + BodyDisplay); + */ + // attempt to render the data requested + renderCollectionCategories( JSONCATURL, blockID).then((response) => { + if(response) { + NEXTJSONURL = BaseURL + "/jsonapi/" + response; + } + }); + + + // attempt to render the data requested + renderCollectionList( JSONURL, TagsExclude, BodyDisplay, blockID, BaseURL).then((response) => { + if(response) { + NEXTJSONURL = BaseURL + "/jsonapi/" + response; + } + }); + + } + })() \ No newline at end of file diff --git a/templates/block/block--collection-grid.html.twig b/templates/block/block--collection-grid.html.twig new file mode 100644 index 00000000..317d2f36 --- /dev/null +++ b/templates/block/block--collection-grid.html.twig @@ -0,0 +1,118 @@ +{% + set classes = [ + 'block', + 'container', + 'block-' ~ configuration.provider|clean_class, + 'block-' ~ plugin_id|clean_class, + bundle ? 'block--type-' ~ bundle|clean_class, + view_mode ? 'block--view-mode-' ~ view_mode|clean_class, + ] + %} + +{# This block mirrors the Article List Node - constructs a JSON endpoint in TWIG using include filters #} +{% set collectionsCatsJSON = (url('')|render|trim('/')) + ~ '/jsonapi/taxonomy_term/collection_category' + + %} +{# JSON API Endpoint information #} +{% set collectionsJSON = (url('')|render|trim('/')) + ~ '/jsonapi/node/collection_item_page' + ~ '?sort=title' + ~ '&include=field_collection_item_thumbnail.field_media_image' + ~ '&fields[file--file]=uri,url,alt' + %} + +{% set baseurlJSON = (url('')|render|trim('/')) + %} + +{% set includeTags = "" %} +{% set myTypes = content.field_collection_grid_type %} + + +{% set filterItemsStyle = "collection-filter-hide" %} +{% if content.field_collections_filter|render|striptags|trim == "Fade Items" %} + {% set filterItemsStyle = "collection-filter-fade" %} +{% endif %} + +{% set multiselectStyle = "collection-multiselect-single" %} +{% if content.field_collections_multiselect|render|striptags|trim == "Multi Select List" %} + {% set multiselectStyle = "collection-multiselect-multi" %} +{% endif %} + + +{% set displayStyle = "show" %} +{% if content.field_collections_display|render|striptags|trim == "Hide" %} + {% set displayStyle = "hide" %} +{% endif %} + +{% set blockID = elements.content['#block_content'].id() %} + +{{ attach_library('boulder_base/ucb-collections-block') }} +{% block content %} + + {{ title_prefix }} + {% if label %} + {{ label }} + {% endif %} + {{ title_suffix }} + +
+
+ {# Single Select List #} + {% if multiselectStyle == "collection-multiselect-single" %} +
+ {% for key, item in content['#block_content'].field_collection_category_select %} + {% if key|first != '#' %} +
+

{{item.entity.field_collection_filter_label.value }} +

+
+ +
+
+ + {% endif %} + {% endfor %} + {##} +
+ {% elseif multiselectStyle == "collection-multiselect-multi" %} + + {% for key, item in content['#block_content'].field_collection_category_select %} + {% if key|first != '#' %} + + + {% endif %} + {% endfor %} + + {% endif %} +
+
+
+ +
+
+
+
+{% endblock content %} diff --git a/templates/content/node--collection-item-page.html.twig b/templates/content/node--collection-item-page.html.twig new file mode 100644 index 00000000..49a73936 --- /dev/null +++ b/templates/content/node--collection-item-page.html.twig @@ -0,0 +1,31 @@ +{{ attach_library('boulder_base/ucb-page') }} + +{#Dummy variable to ensure that all content tags are set for caching purposes#} +{% set content_render = content|render %} + +{# Used for hiding site title visibly using sr-only bootstrap class, if front page #} +{% set isFrontPage = '' %} +{% if is_front %} + {% set isFrontPage = 'sr-only' %} +{% endif %} + +{% + set classes = [ + 'node', + 'ucb-content-wrapper' + ] +%} + + +
+ + {{ label }} + + + {% if content %} + + {{ content.body }} +
+ {% endif %} + + diff --git a/templates/field/field--field_collection_category_select.html.twig b/templates/field/field--field_collection_category_select.html.twig new file mode 100644 index 00000000..accc3c02 --- /dev/null +++ b/templates/field/field--field_collection_category_select.html.twig @@ -0,0 +1,3 @@ +{% for item in items %} + {{ item.content }} +{% endfor %} diff --git a/templates/field/field--field_collection_filter_label.html.twig b/templates/field/field--field_collection_filter_label.html.twig new file mode 100644 index 00000000..f8cef32a --- /dev/null +++ b/templates/field/field--field_collection_filter_label.html.twig @@ -0,0 +1,3 @@ +{% for item in items %} +

{{ item.content }}

+{% endfor %} diff --git a/templates/field/field--field_collection_grid_type.html.twig b/templates/field/field--field_collection_grid_type.html.twig new file mode 100644 index 00000000..c0932514 --- /dev/null +++ b/templates/field/field--field_collection_grid_type.html.twig @@ -0,0 +1,6 @@ +{% set allTypes = "" %} +{% for item in items %} + {% set allTypes = allTypes ~ item.content['#plain_text']|join('') ~ ',' %} +{% endfor %} +{% set allTypes = allTypes|slice(0,-1) %} +{{ allTypes }} diff --git a/templates/field/field--field_collections_display.html.twig b/templates/field/field--field_collections_display.html.twig new file mode 100644 index 00000000..e2672352 --- /dev/null +++ b/templates/field/field--field_collections_display.html.twig @@ -0,0 +1,3 @@ +{% for item in items %} + {{ item.content }} +{% endfor %} \ No newline at end of file diff --git a/templates/field/field--field_collections_filter.html.twig b/templates/field/field--field_collections_filter.html.twig new file mode 100644 index 00000000..e2672352 --- /dev/null +++ b/templates/field/field--field_collections_filter.html.twig @@ -0,0 +1,3 @@ +{% for item in items %} + {{ item.content }} +{% endfor %} \ No newline at end of file diff --git a/templates/field/field--field_collections_multiselect.html.twig b/templates/field/field--field_collections_multiselect.html.twig new file mode 100644 index 00000000..e2672352 --- /dev/null +++ b/templates/field/field--field_collections_multiselect.html.twig @@ -0,0 +1,3 @@ +{% for item in items %} + {{ item.content }} +{% endfor %} \ No newline at end of file diff --git a/templates/paragraphs/paragraph--collection-grid-filter.html.twig b/templates/paragraphs/paragraph--collection-grid-filter.html.twig new file mode 100644 index 00000000..cd91fe67 --- /dev/null +++ b/templates/paragraphs/paragraph--collection-grid-filter.html.twig @@ -0,0 +1,5 @@ + +
+{{ content.field_collection_filter_label }} +{{ content.field_collection_grid_category }} +
\ No newline at end of file