Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "_events_external"]
path = _events
url = https://github.com/CHTC/events
[submodule "_presentations"]
path = _presentations
url = https://github.com/CHTC/Presentations.git
7 changes: 7 additions & 0 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ collections:
redirects:
output: true
permalink: /:path
presentations:
output: true
permalink: /presentations/:year/:month/:day/:title/

defaults:
- scope:
Expand Down Expand Up @@ -97,6 +100,10 @@ defaults:
type: redirects
values:
layout: redirect
- scope:
type: presentations
values:
layout: presentation



Expand Down
3 changes: 3 additions & 0 deletions _includes/get/presentations.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{% assign presentations = site.presentations | where_exp: "presentation", "presentation.publish_on contains site.key" | sort: "date" | reverse %}
{% assign all_presentation_keywords = presentations | map: "keywords" | uniq | sort %}
{% assign all_presentation_events = presentations | map: "event" | uniq | sort %}
1 change: 1 addition & 0 deletions _includes/layout/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<a class="dropdown-item" href="{{ '/spotlights' | relative_url }}">Spotlights</a>
<a class="dropdown-item" href="{{ '/events' | relative_url }}">Events</a>
<a class="dropdown-item" href="{{ '/news' | relative_url }}">News</a>
<a class="dropdown-item" href="{{ '/presentations' | relative_url }}">Presentations</a>
</div>
</li>
<li class="nav-item dropdown">
Expand Down
52 changes: 52 additions & 0 deletions _layouts/presentation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
layout: container-default
---

{% assign date = page.date | date: "%B %e" %}

<div class="row justify-content-center">
<div class="col-12 col-md-10 col-lg-9 col-xl-8 fs-5 "">
<div class="event-header pt-4 pt-md-4">
<div class="row my-3">
<h1>
{{ page.title }}
</h1>
</div>

<div class="row">
<div class="flex justify-content-center" style="display: flex;">
<iframe
src="https://www.youtube.com/embed/{{ page.youtube_video_id }}?origin=https://path-cc.io"
width="640"
height="360"
frameborder="0"
allowfullscreen
></iframe>
</div>
</div>

<div class="mb-3 d-flex flex-row justify-content-between">
<h4 class="text-muted">{{ page.presenter }} at {{ page.event }}</h4>
<h4 class="text-muted">{{ date }}</h4>
</div>

<p>
{{ page.description | markdownify }}
</p>

<div>
{% for tag in page.keywords %}
<span class="tag-badge badge">{{ tag }}</span>
{% endfor %}
</div>


<h2 class="mt-3 mb-0">Associated Links</h2>
<ul>
{% for link in page.links %}
<li><a href="{{ link.value }}" target="_blank" rel="noopener noreferrer">{{ link.name }}</a></li>
{% endfor %}
</ul>
</div>
</div>
</div>
1 change: 1 addition & 0 deletions _presentations
Submodule _presentations added at bef530
156 changes: 156 additions & 0 deletions assets/js/scripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
function generateStringHash(value) {
// Simple hash function to generate a number from the tag string
let hash = 0;
for (let i = 0; i < value.length; i++) {
hash = value.charCodeAt(i) + ((hash << 5) - hash);
}

return hash;
}

class PresentationFilterManager {
constructor() {
this.selectedEvent = null;
this.selectedKeywords = new Set();
}

initialize() {
this.buttonEventFilter = document.getElementById("button-filter-event");
this.buttonEventDropdownItems = document.querySelectorAll("a[data-event-selector]");
this.keywordCheckboxes = document.querySelectorAll("input[data-keyword-selector]");
this.resetButton = document.getElementById("button-clear-filters");
this.cards = document.querySelectorAll(".presentation-card");

this.originalEventFilterText = this.buttonEventFilter.textContent;
this.noPresentationsFoundText = document.getElementById("no-presentations-found");

this.initializeEventButtons();
this.initializeKeywordCheckboxes();
this.initializeResetButton();
}

initializeEventButtons() {
this.buttonEventDropdownItems.forEach(item => {
item.addEventListener("click", (e) => {
e.preventDefault();
this.selectedEvent = e.target.dataset.eventSelector;

// Update button text to show selected event
this.buttonEventFilter.textContent = this.selectedEvent;

console.log("Selected event:", this.selectedEvent);

// Apply filters
this.filterPresentations();
});
});
}

initializeKeywordCheckboxes() {
this.keywordCheckboxes.forEach(checkbox => {
checkbox.addEventListener("change", (e) => {
const keyword = e.target.dataset.keywordSelector;

if (e.target.checked) {
this.selectedKeywords.add(keyword);
} else {
this.selectedKeywords.delete(keyword);
}

console.log("Selected keywords:", Array.from(this.selectedKeywords));

// Apply filters
this.filterPresentations();
});
});
}

initializeResetButton() {
this.resetButton.addEventListener("click", () => {
// Reset event filter
this.selectedEvent = null;
this.buttonEventFilter.textContent = this.originalEventFilterText;

// Reset keyword filters
this.selectedKeywords.clear();
this.keywordCheckboxes.forEach(checkbox => {
checkbox.checked = false;
});

// Show all presentations
this.filterPresentations();

// Hide reset button
this.resetButton.style.display = "none";
});
}

filterPresentations() {
let anyVisible = false;
this.cards.forEach(card => {
let showCard = true;

// Check event filter
if (this.selectedEvent) {
const eventText = card.dataset.event || "";
if (!eventText.includes(this.selectedEvent)) {
showCard = false;
}
}

// Check keyword filter
if (this.selectedKeywords.size > 0) {
const cardKeywords = card.dataset.keywords ? card.dataset.keywords.split(' ') : [];

// Check if any selected keyword matches card keywords
const hasMatchingKeyword = Array.from(this.selectedKeywords).some(keyword =>
cardKeywords.includes(keyword)
);

if (!hasMatchingKeyword) {
showCard = false;
}
}

anyVisible = anyVisible || showCard;
// Show or hide the card
card.style.display = showCard ? "inline-block" : "none";
});

this.noPresentationsFoundText.style.display = anyVisible ? "none" : "block";
this.updateResetButtonVisibility();
}

updateResetButtonVisibility() {
if (this.selectedEvent || this.selectedKeywords.size > 0) {
this.resetButton.style.display = "inline-block";
} else {
this.resetButton.style.display = "none";
}
}
}

document.addEventListener("DOMContentLoaded", () => {
// -- presentations page --

function fillBadgeColors() {
const badges = document.querySelectorAll(".tag-badge");
badges.forEach(badge => {
const tagText = badge.textContent.trim();
let hue = generateStringHash(tagText) % 360;
if (hue >= 60 && hue <= 140) {
hue = (hue + 80) % 360; // avoid ugly colors
}

badge.style.backgroundColor = `hsl(${hue}, 70%, 40%)`;
badge.style.color = "#fff";
});
}

fillBadgeColors();
// do presentation filtering only if on the presentations page
if (document.querySelector(".presentation-card")) {
const filterManager = new PresentationFilterManager();
filterManager.initialize();
}
});
78 changes: 78 additions & 0 deletions presentations.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
layout: sub-page
bodyClass: page-presentations-list
---

{% include get/presentations.liquid %}

<h1>Presentations</h1>

<div class="dropdown row-flex flex-column mb-3">
<button id="button-filter-event" class="btn btn-outline-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Filter by Event
</button>
<ul class="dropdown-menu">
{% for event in all_presentation_events %}
<li><a class="button-filter-event-dropdown dropdown-item" href="#" data-event-selector="{{event}}">{{event}}</a></li>
{% endfor %}
</ul>

<button class="btn btn-outline-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Filter by Keywords
</button>
<ul class="dropdown-menu p-3" onclick="event.stopPropagation();">
{% for keyword in all_presentation_keywords %}
<li>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="{{keyword}}" id="keyword-select-{{keyword}}" data-keyword-selector="{{keyword}}">
<label class="form-check-label" for="keyword-select-{{keyword}}">
{{keyword}}
</label>
</div>
</li>
{% endfor %}
</ul>

<button class="btn btn-outline-secondary" id="button-clear-filters" style="display: none;">Clear Filters</button>
</div>

<div class="row mb-3">
{% for presentation in presentations %}
<div class="presentation-card col-12 col-md-6 mb-3" data-event="{{ presentation.event }}" data-keywords="{{ presentation.keywords | join: ' ' }}">
<div class="news news-summary">
<div class="article-content">
{% if presentation.youtube_video_id %}
{% assign presentation_image_path = "https://img.youtube.com/vi/" | append: presentation.youtube_video_id | append: "/hqdefault.jpg" %}
{% assign presentation_image_alt = presentation.title | append: " presentation thumbnail" %}
{% elsif presentation.image %}
{% assign presentation_image_path = presentation.image.path | relative_url %}
{% assign presentation_image_alt = presentation.image.alt %}
{% endif %}
<a href="{{ presentation.url | relative_url }}" class="d-block">
<img class="w-100 image-card-cap rounded mb-3" style="aspect-ratio:3.5;" src="{{ presentation_image_path }}" alt="{{ presentation_image_alt }}">
</a>
<h2 class="article-title">
<a href="{{ presentation.url | relative_url }}">{{ presentation.title }}</a>
</h2>

<div class="d-flex flex-row justify-content-between">
{% assign date = presentation.date | date: "%B %e" %}
<h4 class="text-muted mb-0">{{ presentation.presenter }} at {{ presentation.event }}</h4>
<h4 class="text-muted mb-0" style="flex-grow: 0; flex-shrink: 0;">{{ date }}</h4>
</div>

<div class="mb-3">
{% for tag in presentation.keywords %}
<span class="tag-badge badge">{{ tag }}</span>
{% endfor %}
</div>
<p>{{ presentation.description }}</p>
</div>
</div>
</div>
{% endfor %}
</div>

<div id="no-presentations-found" class="col-12" style="display: none;">
<p class="text-muted">No presentations found.</p>
</div>
Loading