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 | ||||
 Marek Krug
						Marek Krug