new theme (work in progress)
4
.gitmodules
vendored
|
@ -1,3 +1,7 @@
|
|||
[submodule "beautifulhugo"]
|
||||
path = themes/beautifulhugo
|
||||
url = https://github.com/cccb/beautifulhugo.git
|
||||
[submodule "themes/blowfish"]
|
||||
path = themes/blowfish
|
||||
url = https://github.com/nunocoracao/blowfish.git
|
||||
branch = main
|
||||
|
|
BIN
assets/img/avatar-CCCB-Logo.jpg
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
assets/img/avatar-CCCB-Logo.png
Normal file
After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
84
config.yaml
|
@ -1,84 +0,0 @@
|
|||
languageCode: "de-de"
|
||||
title: "Chaos Computer Club Berlin"
|
||||
theme: "beautifulhugo"
|
||||
RelativeURLs: true
|
||||
CanonifyURLs: true
|
||||
|
||||
Params:
|
||||
license: "CC-BY"
|
||||
subtitle: "Willkommen! Wir sind ein Erfa-Kreis des Chaos Computer Club e.V. und die örtliche Niederlassung des CCC in Berlin."
|
||||
logo: "img/logo.png"
|
||||
favicon: "img/favicon.ico"
|
||||
dateFormat: "January 2, 2006"
|
||||
commit: false
|
||||
rss: true
|
||||
comments: true
|
||||
readingTime: true
|
||||
useHLJS: true
|
||||
DateForm: "30.12.2006"
|
||||
# for GDPR / EU-DSGVO compliance
|
||||
selfHosted: true
|
||||
|
||||
taxonomies:
|
||||
category: "categories"
|
||||
series: "series"
|
||||
tag: "tags"
|
||||
|
||||
permalinks:
|
||||
post: "/post/:year/:month/:day/:title/"
|
||||
|
||||
Author:
|
||||
twitter: "clubdiscordia"
|
||||
email: "mail2025@berlin.ccc.de"
|
||||
mastodon: "chaos.social/@clubdiscordia"
|
||||
irc: "https://webirc.hackint.org/#ircs://irc.hackint.org/#cccb"
|
||||
|
||||
menu:
|
||||
main:
|
||||
- identifier: "verein"
|
||||
name: "Der Verein"
|
||||
weight: 200
|
||||
- identifier: "veranstaltungen"
|
||||
name: "Veranstaltungen"
|
||||
weight: 300
|
||||
- identifier: "news"
|
||||
name: "News"
|
||||
url: "post/"
|
||||
weight: 500
|
||||
- identifier: "impressum"
|
||||
name: "Impressum"
|
||||
url: "page/impressum/"
|
||||
weight: 600
|
||||
- identifier: "privacy"
|
||||
name: "Privacy"
|
||||
url: "page/datenschutz/"
|
||||
weight: 700
|
||||
|
||||
mediaTypes:
|
||||
text/calendar":
|
||||
suffixes:
|
||||
- "ics"
|
||||
application/rss:
|
||||
suffixes:
|
||||
- "rss"
|
||||
application/xml:
|
||||
suffixes:
|
||||
- "xml"
|
||||
|
||||
outputFormats:
|
||||
RSS:
|
||||
mediaType: "application/rss"
|
||||
XML:
|
||||
isPlainText: true
|
||||
mediaType: "application/xml"
|
||||
|
||||
outputs:
|
||||
section:
|
||||
- "HTML"
|
||||
- "Calendar"
|
||||
- "RSS"
|
||||
- "XML"
|
||||
page:
|
||||
- "HTML"
|
||||
- "Calendar"
|
||||
|
69
config/_default/hugo.toml
Normal file
|
@ -0,0 +1,69 @@
|
|||
# -- Site Configuration --
|
||||
# Refer to the theme docs for more details about each of these parameters.
|
||||
# https://blowfish.page/docs/getting-started/
|
||||
|
||||
theme = "blowfish" # UNCOMMENT THIS LINE
|
||||
baseURL = "https://berlin.ccc.de/"
|
||||
defaultContentLanguage = "de"
|
||||
|
||||
pluralizeListTitles = "true" # hugo function useful for non-english languages, find out more in https://gohugo.io/getting-started/configuration/#pluralizelisttitles
|
||||
|
||||
enableRobotsTXT = true
|
||||
summaryLength = 0
|
||||
|
||||
buildDrafts = false
|
||||
buildFuture = false
|
||||
|
||||
enableEmoji = true
|
||||
|
||||
# googleAnalytics = "G-XXXXXXXXX"
|
||||
|
||||
[pagination]
|
||||
pagerSize = 100
|
||||
|
||||
[imaging]
|
||||
anchor = 'Center'
|
||||
|
||||
[taxonomies]
|
||||
tag = "tags"
|
||||
category = "categories"
|
||||
author = "authors"
|
||||
series = "series"
|
||||
|
||||
[sitemap]
|
||||
changefreq = 'daily'
|
||||
filename = 'sitemap.xml'
|
||||
priority = 0.5
|
||||
|
||||
[outputs]
|
||||
home = ["HTML", "RSS", "JSON"]
|
||||
|
||||
[related]
|
||||
threshold = 0
|
||||
toLower = false
|
||||
|
||||
[[related.indices]]
|
||||
name = "tags"
|
||||
weight = 100
|
||||
|
||||
[[related.indices]]
|
||||
name = "categories"
|
||||
weight = 100
|
||||
|
||||
[[related.indices]]
|
||||
name = "series"
|
||||
weight = 50
|
||||
|
||||
[[related.indices]]
|
||||
name = "authors"
|
||||
weight = 20
|
||||
|
||||
[[related.indices]]
|
||||
name = "date"
|
||||
weight = 10
|
||||
|
||||
[[related.indices]]
|
||||
applyFilter = false
|
||||
name = 'fragmentrefs'
|
||||
type = 'fragments'
|
||||
weight = 10
|
73
config/_default/languages.de.toml
Normal file
|
@ -0,0 +1,73 @@
|
|||
disabled = false
|
||||
languageCode = "de"
|
||||
languageName = "Deutsch"
|
||||
weight = 1
|
||||
title = "Chaos Computer Club Berlin"
|
||||
|
||||
[params]
|
||||
displayName = "DE"
|
||||
isoCode = "de"
|
||||
rtl = false
|
||||
dateFormat = "January 2, 2006"
|
||||
logo = "img/avatar-CCCB-Logo.png"
|
||||
secondaryLogo = "img/avatar-CCCB-Logo.png"
|
||||
description = "Willkommen! Wir sind ein Erfa-Kreis des Chaos Computer Club e.V. und die örtliche Niederlassung des CCC in Berlin."
|
||||
copyright = "CCC-BY"
|
||||
|
||||
[params.author]
|
||||
# name = "Your name here"
|
||||
email = "mail2025@berlin.ccc.de"
|
||||
# image = "img/logo.png"
|
||||
# imageQuality = 96
|
||||
headline = "Willkommen! Wir sind ein Erfa-Kreis des Chaos Computer Club e.V. und die örtliche Niederlassung des CCC in Berlin."
|
||||
# bio = "A little bit about you"
|
||||
links = [
|
||||
{ email = "mailto:mail2025@berlin.ccc.de" },
|
||||
# { link = "https://link-to-some-website.com/" },
|
||||
# { amazon = "https://www.amazon.com/hz/wishlist/ls/wishlist-id" },
|
||||
# { apple = "https://www.apple.com" },
|
||||
# { blogger = "https://username.blogspot.com/" },
|
||||
# { bluesky = "https://bsky.app/profile/username" },
|
||||
# { codepen = "https://codepen.io/username" },
|
||||
# { dev = "https://dev.to/username" },
|
||||
# { discord = "https://discord.gg/invitecode" },
|
||||
# { dribbble = "https://dribbble.com/username" },
|
||||
# { facebook = "https://facebook.com/username" },
|
||||
# { flickr = "https://www.flickr.com/photos/username/" },
|
||||
# { foursquare = "https://foursquare.com/username" },
|
||||
# { github = "https://github.com/username" },
|
||||
# { gitlab = "https://gitlab.com/username" },
|
||||
# { google = "https://www.google.com/" },
|
||||
# { hashnode = "https://username.hashnode.dev" },
|
||||
# { instagram = "https://instagram.com/username" },
|
||||
# { itch-io = "https://username.itch.io" },
|
||||
# { keybase = "https://keybase.io/username" },
|
||||
# { kickstarter = "https://www.kickstarter.com/profile/username" },
|
||||
# { lastfm = "https://lastfm.com/user/username" },
|
||||
# { linkedin = "https://linkedin.com/in/username" },
|
||||
{ mastodon = "https://chaos.social/@clubdiscordia" },
|
||||
# { medium = "https://medium.com/username" },
|
||||
# { microsoft = "https://www.microsoft.com/" },
|
||||
# { orcid = "https://orcid.org/userid" },
|
||||
# { patreon = "https://www.patreon.com/username" },
|
||||
# { pinterest = "https://pinterest.com/username" },
|
||||
# { reddit = "https://reddit.com/user/username" },
|
||||
# { researchgate = "https://www.researchgate.net/profile/username" },
|
||||
# { slack = "https://workspace.url/team/userid" },
|
||||
# { snapchat = "https://snapchat.com/add/username" },
|
||||
# { soundcloud = "https://soundcloud.com/username" },
|
||||
# { spotify = "https://open.spotify.com/user/userid" },
|
||||
# { stack-overflow = "https://stackoverflow.com/users/userid/username" },
|
||||
# { steam = "https://steamcommunity.com/profiles/userid" },
|
||||
# { telegram = "https://t.me/username" },
|
||||
# { threads = "https://www.threads.net/@username" },
|
||||
# { tiktok = "https://tiktok.com/@username" },
|
||||
# { tumblr = "https://username.tumblr.com" },
|
||||
# { twitch = "https://twitch.tv/username" },
|
||||
# { twitter = "https://twitter.com/username" },
|
||||
# { x-twitter = "https://twitter.com/username" },
|
||||
# { whatsapp = "https://wa.me/phone-number" },
|
||||
# { youtube = "https://youtube.com/username" },
|
||||
# { ko-fi = "https://ko-fi.com/username" },
|
||||
# { codeberg = "https://codeberg.org/username"},
|
||||
]
|
13
config/_default/markup.toml
Normal file
|
@ -0,0 +1,13 @@
|
|||
# -- Markup --
|
||||
# These settings are required for the theme to function.
|
||||
|
||||
[goldmark]
|
||||
[goldmark.renderer]
|
||||
unsafe = true
|
||||
|
||||
[highlight]
|
||||
noClasses = false
|
||||
|
||||
[tableOfContents]
|
||||
startLevel = 2
|
||||
endLevel = 4
|
52
config/_default/menus.de.toml
Normal file
|
@ -0,0 +1,52 @@
|
|||
# -- Main Menu --
|
||||
# The main menu is displayed in the header at the top of the page.
|
||||
# Acceptable parameters are name, pageRef, page, url, title, weight.
|
||||
#
|
||||
# The simplest menu configuration is to provide:
|
||||
# name = The name to be displayed for this menu link
|
||||
# pageRef = The identifier of the page or section to link to
|
||||
#
|
||||
# By default the menu is ordered alphabetically. This can be
|
||||
# overridden by providing a weight value. The menu will then be
|
||||
# ordered by weight from lowest to highest.
|
||||
|
||||
#[[main]]
|
||||
# name = "Blog"
|
||||
# pageRef = "posts"
|
||||
# weight = 10
|
||||
|
||||
[[main]]
|
||||
name = "verein"
|
||||
pageRef = "verein"
|
||||
weight = 200
|
||||
|
||||
[[main]]
|
||||
name = "veranstaltungen"
|
||||
pageRef = "veranstaltungen"
|
||||
weight = 300
|
||||
|
||||
[[main]]
|
||||
name = "News"
|
||||
pageRef = "post"
|
||||
|
||||
weight = 400
|
||||
|
||||
[[main]]
|
||||
name = "Impressum"
|
||||
pageRef = "page/impressum/"
|
||||
weight = 500
|
||||
|
||||
# -- Footer Menu --
|
||||
# The footer menu is displayed at the bottom of the page, just before
|
||||
# the copyright notice. Configure as per the main menu above.
|
||||
|
||||
|
||||
[[footer]]
|
||||
name = "Tags"
|
||||
pageRef = "tags"
|
||||
weight = 10
|
||||
|
||||
[[footer]]
|
||||
name = "Categories"
|
||||
pageRef = "categories"
|
||||
weight = 20
|
168
config/_default/params.toml
Normal file
|
@ -0,0 +1,168 @@
|
|||
# -- Theme Options --
|
||||
# These options control how the theme functions and allow you to
|
||||
# customise the display of your website.
|
||||
#
|
||||
# Refer to the theme docs for more details about each of these parameters.
|
||||
# https://blowfish.page/docs/configuration/#theme-parameters
|
||||
|
||||
colorScheme = "fira" # "congo"
|
||||
defaultAppearance = "light" # valid options: light or dark
|
||||
autoSwitchAppearance = true
|
||||
|
||||
enableSearch = true
|
||||
enableCodeCopy = false
|
||||
|
||||
replyByEmail = false
|
||||
|
||||
# mainSections = ["section1", "section2"]
|
||||
# robots = ""
|
||||
|
||||
[params]
|
||||
disableImageOptimization = false
|
||||
disableTextInHeader = false
|
||||
backgroundImageWidth = 1200
|
||||
|
||||
defaultBackgroundImage = "/img/cccb-im-winter.jpg" # used as default for background images
|
||||
defaultFeaturedImage = "img/avatar-CCCB-Logo.png" # used as default for featured images in all articles
|
||||
|
||||
# highlightCurrentMenuArea = true
|
||||
# smartTOC = true
|
||||
# smartTOCHideUnfocusedChildren = true
|
||||
|
||||
giteaDefaultServer = "https://git.fsfe.org"
|
||||
forgejoDefaultServer = "https://v8.next.forgejo.org"
|
||||
|
||||
[header]
|
||||
layout = "fixed-fill-blur" # valid options: basic, fixed, fixed-fill, fixed-gradient, fixed-fill-blur
|
||||
|
||||
[footer]
|
||||
showMenu = true
|
||||
showCopyright = true
|
||||
showThemeAttribution = true
|
||||
showAppearanceSwitcher = true
|
||||
showScrollToTop = true
|
||||
|
||||
[homepage]
|
||||
layout = "background" # valid options: page, profile, hero, card, background, custom
|
||||
homepageImage = "img/cccb-im-winter.jpg" # used in: hero, and card
|
||||
showRecent = true
|
||||
showRecentItems = 5
|
||||
showMoreLink = true
|
||||
showMoreLinkDest = "/posts/"
|
||||
cardView = false
|
||||
cardViewScreenWidth = false
|
||||
layoutBackgroundBlur = false # only used when layout equals background
|
||||
|
||||
[article]
|
||||
showDate = true
|
||||
showViews = false
|
||||
showLikes = false
|
||||
showDateOnlyInArticle = false
|
||||
showDateUpdated = false
|
||||
showAuthor = true
|
||||
# showAuthorBottom = false
|
||||
showHero = false
|
||||
# heroStyle = "basic" # valid options: basic, big, background, thumbAndBackground
|
||||
layoutBackgroundBlur = true # only used when heroStyle equals background or thumbAndBackground
|
||||
layoutBackgroundHeaderSpace = true # only used when heroStyle equals background
|
||||
showBreadcrumbs = false
|
||||
showDraftLabel = true
|
||||
showEdit = false
|
||||
# editURL = "https://github.com/username/repo/"
|
||||
editAppendPath = true
|
||||
seriesOpened = false
|
||||
showHeadingAnchors = true
|
||||
showPagination = true
|
||||
invertPagination = false
|
||||
showReadingTime = true
|
||||
showTableOfContents = false
|
||||
# showRelatedContent = false
|
||||
# relatedContentLimit = 3
|
||||
showTaxonomies = false
|
||||
showAuthorsBadges = false
|
||||
showWordCount = true
|
||||
# sharingLinks = [ "linkedin", "twitter", "bluesky", "mastodon", "reddit", "pinterest", "facebook", "email", "whatsapp", "telegram"]
|
||||
showZenMode = false
|
||||
|
||||
[list]
|
||||
showHero = false
|
||||
# heroStyle = "background" # valid options: basic, big, background, thumbAndBackground
|
||||
layoutBackgroundBlur = true # only used when heroStyle equals background or thumbAndBackground
|
||||
layoutBackgroundHeaderSpace = true # only used when heroStyle equals background
|
||||
showBreadcrumbs = false
|
||||
showSummary = false
|
||||
showViews = false
|
||||
showLikes = false
|
||||
showTableOfContents = false
|
||||
showCards = false
|
||||
orderByWeight = false
|
||||
groupByYear = true
|
||||
cardView = false
|
||||
cardViewScreenWidth = false
|
||||
constrainItemsWidth = false
|
||||
|
||||
[sitemap]
|
||||
excludedKinds = ["taxonomy", "term"]
|
||||
|
||||
[taxonomy]
|
||||
showTermCount = true
|
||||
showHero = false
|
||||
# heroStyle = "background" # valid options: basic, big, background, thumbAndBackground
|
||||
showBreadcrumbs = false
|
||||
showViews = false
|
||||
showLikes = false
|
||||
showTableOfContents = false
|
||||
cardView = false
|
||||
|
||||
[term]
|
||||
showHero = false
|
||||
# heroStyle = "background" # valid options: basic, big, background, thumbAndBackground
|
||||
showBreadcrumbs = false
|
||||
showViews = false
|
||||
showLikes = false
|
||||
showTableOfContents = true
|
||||
groupByYear = false
|
||||
cardView = false
|
||||
cardViewScreenWidth = false
|
||||
|
||||
[firebase]
|
||||
# apiKey = "XXXXXX"
|
||||
# authDomain = "XXXXXX"
|
||||
# projectId = "XXXXXX"
|
||||
# storageBucket = "XXXXXX"
|
||||
# messagingSenderId = "XXXXXX"
|
||||
# appId = "XXXXXX"
|
||||
# measurementId = "XXXXXX"
|
||||
|
||||
[fathomAnalytics]
|
||||
# site = "ABC12345"
|
||||
# domain = "llama.yoursite.com"
|
||||
|
||||
[umamiAnalytics]
|
||||
# websiteid = "ABC12345"
|
||||
# domain = "llama.yoursite.com"
|
||||
# dataDomains = "yoursite.com,yoursite2.com"
|
||||
# scriptName = ""
|
||||
# enableTrackEvent = true
|
||||
|
||||
[selineAnalytics]
|
||||
# token = "XXXXXX"
|
||||
# enableTrackEvent = true
|
||||
|
||||
[buymeacoffee]
|
||||
# identifier = ""
|
||||
# globalWidget = true
|
||||
# globalWidgetMessage = "Hello"
|
||||
# globalWidgetColor = "#FFDD00"
|
||||
# globalWidgetPosition = "Right"
|
||||
|
||||
[verification]
|
||||
# google = ""
|
||||
# bing = ""
|
||||
# pinterest = ""
|
||||
# yandex = ""
|
||||
# fediverse = ""
|
||||
|
||||
[rssnext]
|
||||
# feedId = ""
|
||||
# userId = ""
|
369
content/page/calendar.md
Normal file
|
@ -0,0 +1,369 @@
|
|||
---
|
||||
title: "Kalender"
|
||||
subtitle: "Der Kalender des CCCB"
|
||||
date: 2025-02-26T10:00:00+02:00
|
||||
menu:
|
||||
main:
|
||||
parent: "verein"
|
||||
---
|
||||
|
||||
<!-- Kalender-Widget -->
|
||||
<style>
|
||||
.calendar-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
gap: 20px;
|
||||
}
|
||||
#calendar {
|
||||
flex: 1;
|
||||
min-width: 300px;
|
||||
}
|
||||
#event-panel {
|
||||
flex: 1;
|
||||
min-width: 300px;
|
||||
background-color: var(--color-bg-secondary);
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
min-height: 300px;
|
||||
display: none;
|
||||
}
|
||||
#calendar-controls {
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
#calendar-controls button {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 2em;
|
||||
cursor: pointer;
|
||||
padding: 5px 15px;
|
||||
}
|
||||
#calendar-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
#calendar-table th, #calendar-table td {
|
||||
border: 1px solid var(--color-border);
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
height: 60px;
|
||||
width: 14.28%;
|
||||
}
|
||||
#calendar-table th {
|
||||
background-color: var(--color-bg-secondary);
|
||||
}
|
||||
#calendar-table td {
|
||||
background-color: var(--color-bg-primary);
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
#calendar-table td:hover {
|
||||
background-color: var(--color-bg-hover);
|
||||
}
|
||||
.event-dot {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
background-color: greenyellow;
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
margin: 5px auto 0;
|
||||
}
|
||||
.has-event {
|
||||
background-color: var(--color-bg-secondary) !important;
|
||||
}
|
||||
.selected-day {
|
||||
background-color: var(--color-bg-hover) !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
#event-date {
|
||||
font-size: 1.2em;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.event-item {
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
.event-title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.event-time, .event-description {
|
||||
font-size: 0.9em;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.no-events {
|
||||
font-style: italic;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="calendar-container">
|
||||
<div id="calendar">
|
||||
<div id="calendar-controls">
|
||||
<button id="prev-month">←</button>
|
||||
<span id="current-month"></span>
|
||||
<button id="next-month">→</button>
|
||||
</div>
|
||||
<table id="calendar-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Mo</th>
|
||||
<th>Di</th>
|
||||
<th>Mi</th>
|
||||
<th>Do</th>
|
||||
<th>Fr</th>
|
||||
<th>Sa</th>
|
||||
<th>So</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="calendar-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="event-panel">
|
||||
<div id="event-date"></div>
|
||||
<div id="event-details"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
let events = [];
|
||||
let eventsByDate = {};
|
||||
|
||||
// Funktion zum Parsen der ICS-Datei
|
||||
function parseICS(icsText) {
|
||||
let events = [];
|
||||
let lines = icsText.split(/\r?\n/);
|
||||
let event = null;
|
||||
lines.forEach(line => {
|
||||
if (line.startsWith("BEGIN:VEVENT")) {
|
||||
event = {};
|
||||
} else if (line.startsWith("END:VEVENT")) {
|
||||
if (event) events.push(event);
|
||||
event = null;
|
||||
} else if (event) {
|
||||
let colonIndex = line.indexOf(":");
|
||||
if (colonIndex > -1) {
|
||||
let key = line.substring(0, colonIndex);
|
||||
let value = line.substring(colonIndex + 1);
|
||||
if (key.startsWith("DTSTART")) {
|
||||
event.start = value;
|
||||
} else if (key.startsWith("DTEND")) {
|
||||
event.end = value;
|
||||
} else if (key.startsWith("SUMMARY")) {
|
||||
event.summary = value;
|
||||
} else if (key.startsWith("DESCRIPTION")) {
|
||||
event.description = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return events;
|
||||
}
|
||||
|
||||
// Hilfsfunktion: Parst einen ICS-Datum-String ins Format "YYYY-MM-DD"
|
||||
function parseDateString(icsDateStr) {
|
||||
// Erwartet entweder ganztägige Daten (YYYYMMDD) oder Datum+Zeit (YYYYMMDDTHHmmssZ)
|
||||
if (icsDateStr.length === 8) {
|
||||
let year = icsDateStr.substring(0, 4);
|
||||
let month = icsDateStr.substring(4, 6);
|
||||
let day = icsDateStr.substring(6, 8);
|
||||
return `${year}-${month}-${day}`;
|
||||
} else if (icsDateStr.length >= 15) {
|
||||
let year = icsDateStr.substring(0, 4);
|
||||
let month = icsDateStr.substring(4, 6);
|
||||
let day = icsDateStr.substring(6, 8);
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Kalender initialisieren
|
||||
let currentYear, currentMonth;
|
||||
const currentMonthElem = document.getElementById("current-month");
|
||||
const calendarBody = document.getElementById("calendar-body");
|
||||
const eventPanel = document.getElementById("event-panel");
|
||||
const eventDateElem = document.getElementById("event-date");
|
||||
const eventDetailsElem = document.getElementById("event-details");
|
||||
|
||||
document.getElementById("prev-month").addEventListener("click", function(){
|
||||
currentMonth--;
|
||||
if (currentMonth < 0) {
|
||||
currentMonth = 11;
|
||||
currentYear--;
|
||||
}
|
||||
renderCalendar(currentYear, currentMonth);
|
||||
});
|
||||
document.getElementById("next-month").addEventListener("click", function(){
|
||||
currentMonth++;
|
||||
if (currentMonth > 11) {
|
||||
currentMonth = 0;
|
||||
currentYear++;
|
||||
}
|
||||
renderCalendar(currentYear, currentMonth);
|
||||
});
|
||||
|
||||
function renderCalendar(year, month) {
|
||||
// Setze die Monatsbeschriftung (in Deutsch)
|
||||
const monthNames = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"];
|
||||
currentMonthElem.textContent = monthNames[month] + " " + year;
|
||||
calendarBody.innerHTML = "";
|
||||
|
||||
let firstDay = new Date(year, month, 1);
|
||||
let firstDayIndex = (firstDay.getDay() + 6) % 7; // Montag = 0, Dienstag = 1, etc.
|
||||
let daysInMonth = new Date(year, month + 1, 0).getDate();
|
||||
|
||||
let row = document.createElement("tr");
|
||||
// Leere Zellen vor dem 1. Tag
|
||||
for (let i = 0; i < firstDayIndex; i++){
|
||||
let cell = document.createElement("td");
|
||||
row.appendChild(cell);
|
||||
}
|
||||
|
||||
// Tage hinzufügen
|
||||
for (let day = 1; day <= daysInMonth; day++){
|
||||
if (row.children.length === 7) {
|
||||
calendarBody.appendChild(row);
|
||||
row = document.createElement("tr");
|
||||
}
|
||||
let cell = document.createElement("td");
|
||||
cell.innerHTML = "<strong>" + day + "</strong>";
|
||||
|
||||
let dayStr = day < 10 ? "0" + day : day;
|
||||
let monthStr = (month + 1) < 10 ? "0" + (month + 1) : (month + 1);
|
||||
let dateKey = year + "-" + monthStr + "-" + dayStr;
|
||||
|
||||
if (eventsByDate[dateKey]) {
|
||||
let eventDot = document.createElement("div");
|
||||
eventDot.className = "event-dot";
|
||||
cell.appendChild(document.createElement("br"));
|
||||
cell.appendChild(eventDot);
|
||||
|
||||
cell.dataset.dateKey = dateKey;
|
||||
cell.addEventListener("click", function() {
|
||||
// Clear previous selections
|
||||
document.querySelectorAll('.selected-day').forEach(el => {
|
||||
el.classList.remove('selected-day');
|
||||
});
|
||||
cell.classList.add('selected-day');
|
||||
showEventDetails(dateKey);
|
||||
});
|
||||
}
|
||||
row.appendChild(cell);
|
||||
}
|
||||
// Falls die letzte Zeile nicht komplett ist
|
||||
while (row.children.length < 7) {
|
||||
let cell = document.createElement("td");
|
||||
row.appendChild(cell);
|
||||
}
|
||||
calendarBody.appendChild(row);
|
||||
}
|
||||
|
||||
function createEventLink(eventTitle) {
|
||||
if (eventTitle.startsWith("Datengarten")) {
|
||||
// Extract the number after "Datengarten "
|
||||
const match = eventTitle.match(/Datengarten\s+(\d+)/i);
|
||||
if (match && match[1]) {
|
||||
return `https://berlin.ccc.de/datengarten/${match[1]}/`;
|
||||
}
|
||||
}
|
||||
|
||||
// For other titles, convert to lowercase and use as path
|
||||
const slug = eventTitle.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]/g, '');
|
||||
return `https://berlin.ccc.de/page/${slug}/`;
|
||||
}
|
||||
|
||||
function showEventDetails(dateKey) {
|
||||
const events = eventsByDate[dateKey];
|
||||
eventDateElem.textContent = formatDate(dateKey);
|
||||
eventDetailsElem.innerHTML = "";
|
||||
|
||||
if (events && events.length > 0) {
|
||||
events.forEach(ev => {
|
||||
let eventItem = document.createElement("div");
|
||||
eventItem.className = "event-item";
|
||||
|
||||
let eventTitle = document.createElement("div");
|
||||
eventTitle.className = "event-title";
|
||||
|
||||
// Create a link for the event title
|
||||
let titleLink = document.createElement("a");
|
||||
titleLink.textContent = ev.summary;
|
||||
titleLink.href = createEventLink(ev.summary);
|
||||
titleLink.target = "_blank";
|
||||
eventTitle.appendChild(titleLink);
|
||||
|
||||
eventItem.appendChild(eventTitle);
|
||||
|
||||
let eventTime = document.createElement("div");
|
||||
eventTime.className = "event-time";
|
||||
eventTime.textContent = `Start: ${formatTime(ev.start)}, End: ${formatTime(ev.end)}`;
|
||||
eventItem.appendChild(eventTime);
|
||||
|
||||
if (ev.description) {
|
||||
let eventDescription = document.createElement("div");
|
||||
eventDescription.className = "event-description";
|
||||
eventDescription.textContent = ev.description;
|
||||
eventItem.appendChild(eventDescription);
|
||||
}
|
||||
|
||||
eventDetailsElem.appendChild(eventItem);
|
||||
});
|
||||
} else {
|
||||
let noEvents = document.createElement("div");
|
||||
noEvents.className = "no-events";
|
||||
noEvents.textContent = "Keine Veranstaltungen an diesem Tag.";
|
||||
eventDetailsElem.appendChild(noEvents);
|
||||
}
|
||||
|
||||
eventPanel.style.display = "block";
|
||||
}
|
||||
|
||||
function formatDate(dateStr) {
|
||||
// Convert YYYY-MM-DD to DD.MM.YYYY
|
||||
const parts = dateStr.split("-");
|
||||
return `${parts[2]}.${parts[1]}.${parts[0]}`;
|
||||
}
|
||||
|
||||
function formatTime(icsTimeStr) {
|
||||
// Format time for display
|
||||
if (icsTimeStr.length === 8) {
|
||||
// All-day event
|
||||
return "Ganztägig";
|
||||
} else if (icsTimeStr.length >= 15) {
|
||||
// Time-specific event
|
||||
const hour = icsTimeStr.substring(9, 11);
|
||||
const minute = icsTimeStr.substring(11, 13);
|
||||
return `${hour}:${minute}`;
|
||||
}
|
||||
return icsTimeStr;
|
||||
}
|
||||
|
||||
// ICS-Datei abrufen und Events verarbeiten
|
||||
fetch('/all.ics')
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
events = parseICS(data);
|
||||
events.forEach(ev => {
|
||||
let dateKey = parseDateString(ev.start);
|
||||
if (dateKey) {
|
||||
if (!eventsByDate[dateKey]) {
|
||||
eventsByDate[dateKey] = [];
|
||||
}
|
||||
eventsByDate[dateKey].push(ev);
|
||||
}
|
||||
});
|
||||
let today = new Date();
|
||||
currentYear = today.getFullYear();
|
||||
currentMonth = today.getMonth();
|
||||
renderCalendar(currentYear, currentMonth);
|
||||
})
|
||||
.catch(err => console.error('Fehler beim Laden der ICS-Datei:', err));
|
||||
})();
|
||||
</script>
|
|
@ -6,4 +6,9 @@ menu:
|
|||
parent: "verein"
|
||||
---
|
||||
|
||||
{{< gallery dir="/img/club/" caption-position="none"/>}}
|
||||
{{< gallery >}}
|
||||
<img src="/img/club/27479845037_9e4ece985c.jpg" class="grid-w50 md:grid-w33 xl:grid-w25" />
|
||||
<img src="/img/club/27480379957_c09e86189b.jpg" class="grid-w50 md:grid-w33 xl:grid-w25" />
|
||||
<img src="/img/club/27481915157_3cde02aaa3.jpg" class="grid-w50 md:grid-w33 xl:grid-w25" />
|
||||
<img src="/img/club/27481933907_f240f4232d.jpg" class="grid-w50 md:grid-w33 xl:grid-w25" />
|
||||
{{< /gallery >}}
|
|
@ -36,7 +36,7 @@ EXDATE;TZID=Europe/Berlin:{{.}}
|
|||
{{end -}}
|
||||
LOCATION:{{with .Params.location}}{{.}}{{else}}CCCB{{end}}
|
||||
URL:{{.Permalink}}
|
||||
DESCRIPTION:{{.Permalink}}
|
||||
DESCRIPTION:{{- .Content | plainify | replaceRE "\n" "\\n" | replaceRE ":" "\\:" -}}
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
{{end -}}
|
||||
|
|
84
old_config.yaml.txt
Normal file
|
@ -0,0 +1,84 @@
|
|||
languageCode: "de-de"
|
||||
# title: "Chaos Computer Club Berlin"
|
||||
theme: "blowfish"
|
||||
RelativeURLs: true
|
||||
CanonifyURLs: true
|
||||
|
||||
# Params:
|
||||
# license: "CC-BY"
|
||||
# subtitle: "Willkommen! Wir sind ein Erfa-Kreis des Chaos Computer Club e.V. und die örtliche Niederlassung des CCC in Berlin."
|
||||
# logo: "img/avatar-CCCB-Logo.png"
|
||||
# favicon: "img/favicon.ico"
|
||||
# dateFormat: "January 2, 2006"
|
||||
# commit: false
|
||||
# rss: true
|
||||
# comments: true
|
||||
# readingTime: true
|
||||
# useHLJS: true
|
||||
# DateForm: "30.12.2006"
|
||||
# # for GDPR / EU-DSGVO compliance
|
||||
# selfHosted: true
|
||||
|
||||
# taxonomies:
|
||||
# category: "categories"
|
||||
# series: "series"
|
||||
# tag: "tags"
|
||||
|
||||
# permalinks:
|
||||
# post: "/post/:year/:month/:day/:title/"
|
||||
|
||||
# Author:
|
||||
# twitter: "clubdiscordia"
|
||||
# email: "mail2025@berlin.ccc.de"
|
||||
# mastodon: "chaos.social/@clubdiscordia"
|
||||
# irc: "https://webirc.hackint.org/#ircs://irc.hackint.org/#cccb"
|
||||
|
||||
# menu:
|
||||
# main:
|
||||
# - identifier: "verein"
|
||||
# name: "Der Verein"
|
||||
# weight: 200
|
||||
# - identifier: "veranstaltungen"
|
||||
# name: "Veranstaltungen"
|
||||
# weight: 300
|
||||
# - identifier: "news"
|
||||
# name: "News"
|
||||
# url: "post/"
|
||||
# weight: 500
|
||||
# - identifier: "impressum"
|
||||
# name: "Impressum"
|
||||
# url: "page/impressum/"
|
||||
# weight: 600
|
||||
# - identifier: "privacy"
|
||||
# name: "Privacy"
|
||||
# url: "page/datenschutz/"
|
||||
# weight: 700
|
||||
|
||||
# mediaTypes:
|
||||
# text/calendar":
|
||||
# suffixes:
|
||||
# - "ics"
|
||||
# application/rss:
|
||||
# suffixes:
|
||||
# - "rss"
|
||||
# application/xml:
|
||||
# suffixes:
|
||||
# - "xml"
|
||||
|
||||
# outputFormats:
|
||||
# RSS:
|
||||
# mediaType: "application/rss"
|
||||
# XML:
|
||||
# isPlainText: true
|
||||
# mediaType: "application/xml"
|
||||
|
||||
# outputs:
|
||||
# section:
|
||||
# - "HTML"
|
||||
# - "Calendar"
|
||||
# - "RSS"
|
||||
# - "XML"
|
||||
# page:
|
||||
# - "HTML"
|
||||
# - "Calendar"
|
||||
|
BIN
static/img/cccb-im-winter.jpg
Normal file
After Width: | Height: | Size: 2.6 MiB |
1
themes/blowfish
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 96a116a8b0354fc1042c968608a5c1f3001bcbef
|