diff --git a/.eleventy.js b/.eleventy.js index c436b2e..fcb6aa3 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -1,71 +1,134 @@ const htmlmin = require("html-minifier"); -const markdownIt = require('markdown-it'); +const markdownIt = require("markdown-it"); const pluginRss = require("@11ty/eleventy-plugin-rss"); -const isProd = process.env.ELEVENTY_ENV === 'prod' -const outDir = 'public' +const isProd = process.env.ELEVENTY_ENV === "prod"; +const outDir = "public"; module.exports = function (eleventyConfig) { - // PLUGINS - eleventyConfig.addPlugin(pluginRss); - - // shortcode to render markdown from string => {{ STRING | markdown | safe }} - eleventyConfig.addFilter('markdown', function(value) { - let markdown = require('markdown-it')({ - html: true - }); - return markdown.render(value); - }); - - // rebuild on CSS changes - eleventyConfig.addWatchTarget('./src/_includes/css/'); - - // Markdown - eleventyConfig.setLibrary( - 'md', - markdownIt({ - html: true, - breaks: true, - linkify: true, - typographer: true - }) - ) - - //create collections - eleventyConfig.addCollection('sections', async (collection) => { - return collection.getFilteredByGlob('./src/sections/*.md'); - }); - - // STATIC FILES - eleventyConfig.addPassthroughCopy({ './src/static/': '/' }); - - // TRANSFORM -- Minify HTML Output - eleventyConfig.addTransform("htmlmin", function(content, outputPath) { - if( outputPath && outputPath.endsWith(".html") ) { - let minified = htmlmin.minify(content, { - useShortDoctype: true, - removeComments: true, - collapseWhitespace: true - }); - return minified; - } - return content; - }); - - return { - pathPrefix: isProd ? "inpycon2025" : "", - dir: { - input: 'src', - output: outDir, - data: './_data', - includes: './_includes', - layouts: './_layouts' - }, - templateFormats: [ - 'md', - 'njk', - '11ty.js' - ], - htmlTemplateEngine: 'njk' - }; -}; \ No newline at end of file + // PLUGINS + eleventyConfig.addPlugin(pluginRss); + + // shortcode to render markdown from string => {{ STRING | markdown | safe }} + eleventyConfig.addFilter("markdown", function (value) { + let markdown = require("markdown-it")({ + html: true, + }); + return markdown.render(value); + }); + + eleventyConfig.addFilter("dateInfo", function (dateStr) { + // Get day of month + const dayOfMonth = parseInt(dateStr.split("-")[2]); + + // Default result + let result = { + dayName: "NA", + monthDay: "NA", + label: "NA", + }; + + // Mapping logic + switch (dayOfMonth) { + case 12: + result = { + dayName: "Friday", + monthDay: "September 12th", + label: "Workshop Day", + }; + break; + case 13: + result = { + dayName: "Saturday", + monthDay: "September 13th", + label: "Conference Day 1", + }; + break; + case 14: + result = { + dayName: "Sunday", + monthDay: "September 14th", + label: "Conference Day 2", + }; + break; + case 15: + result = { + dayName: "Monday", + monthDay: "September 15th", + label: "DevSprint", + }; + break; + } + + return result; + }); + + eleventyConfig.addFilter("getEndTime", function (startTime, duration) { + const [sh, sm] = startTime.split(":").map(Number); + const [dh, dm] = duration.split(":").map(Number); + + // Total minutes + let totalMinutes = sh * 60 + sm + dh * 60 + dm; + + // Calculate end hour and minutes + let endHour = Math.floor(totalMinutes / 60); + let endMinute = totalMinutes % 60; + + // Wrap around 24 hours (optional, if needed) + if (endHour >= 24) endHour = endHour % 24; + + // Pad with zero if needed + const endHourStr = endHour.toString().padStart(2, "0"); + const endMinuteStr = endMinute.toString().padStart(2, "0"); + + return `${endHourStr}:${endMinuteStr}`; + }); + + // rebuild on CSS changes + eleventyConfig.addWatchTarget("./src/_includes/css/"); + + // Markdown + eleventyConfig.setLibrary( + "md", + markdownIt({ + html: true, + breaks: true, + linkify: true, + typographer: true, + }) + ); + + //create collections + eleventyConfig.addCollection("sections", async (collection) => { + return collection.getFilteredByGlob("./src/sections/*.md"); + }); + + // STATIC FILES + eleventyConfig.addPassthroughCopy({ "./src/static/": "/" }); + + // TRANSFORM -- Minify HTML Output + eleventyConfig.addTransform("htmlmin", function (content, outputPath) { + if (outputPath && outputPath.endsWith(".html")) { + let minified = htmlmin.minify(content, { + useShortDoctype: true, + removeComments: true, + collapseWhitespace: true, + }); + return minified; + } + return content; + }); + + return { + pathPrefix: isProd ? "inpycon2025" : "", + dir: { + input: "src", + output: outDir, + data: "./_data", + includes: "./_includes", + layouts: "./_layouts", + }, + templateFormats: ["md", "njk", "11ty.js"], + htmlTemplateEngine: "njk", + }; +}; diff --git a/src/_data/scheduleFixed.json b/src/_data/scheduleFixed.json new file mode 100644 index 0000000..a93eef5 --- /dev/null +++ b/src/_data/scheduleFixed.json @@ -0,0 +1,132 @@ +[ + { + "index": 1, + "title": "Sept. 12th", + "day": "Friday", + "description": "WORKSHOP DAY", + "type": "workshop", + "schedule": [] + }, + { + "index": 2, + "title": "Sept. 13th", + "day": "Saturday", + "description": "CONFERENCE DAY 1", + "type": "conference", + "schedule": [ + { + "start_time": "07:30", + "end_time": "08:45", + "title": "Registrations / Breakfast", + "color": "#CD89FF" + }, + { + "start_time": "09:00", + "end_time": "09:15", + "title": "Opening Address", + "color": "#1FFFB4" + }, + { + "start_time": "09:20", + "end_time": "10:00", + "title": "Keynote 1", + "color": "#E745A0" + }, + { + "start_time": "12:40", + "end_time": "14:00", + "title": "Lunch", + "color": "#CD89FF" + }, + { + "start_time": "14:00", + "end_time": "14:40", + "title": "Lightning Talks", + "color": "#1FFFB4" + }, + { + "start_time": "16:00", + "end_time": "16:20", + "title": "Poster Presentations / High Tea", + "color": "#CD89FF" + }, + { + "start_time": "17:00", + "end_time": "17:40", + "title": "Keynote 2", + "color": "#E745A0" + }, + { + "start_time": "17:45", + "end_time": "18:00", + "title": "Closing Address", + "color": "#1FFFB4" + } + ] + }, + { + "index": 3, + "title": "Sept. 14th", + "day": "Sunday", + "description": "CONFERENCE DAY 2", + "type": "conference", + "schedule": [ + { + "start_time": "07:30", + "end_time": "08:45", + "title": "Registrations / Breakfast", + "color": "#CD89FF" + }, + { + "start_time": "09:00", + "end_time": "09:15", + "title": "Opening Address", + "color": "#1FFFB4" + }, + { + "start_time": "09:20", + "end_time": "10:00", + "title": "Keynote 3", + "color": "#E745A0" + }, + { + "start_time": "12:40", + "end_time": "14:00", + "title": "Lunch", + "color": "#CD89FF" + }, + { + "start_time": "14:00", + "end_time": "14:40", + "title": "Lightning Talks", + "color": "#1FFFB4" + }, + { + "start_time": "16:00", + "end_time": "16:20", + "title": "Poster Presentations / High Tea", + "color": "#CD89FF" + }, + { + "start_time": "17:00", + "end_time": "17:40", + "title": "Keynote 4", + "color": "#E745A0" + }, + { + "start_time": "17:45", + "end_time": "18:00", + "title": "Closing Address", + "color": "#1FFFB4" + } + ] + }, + { + "index": 4, + "title": "Sept. 15th", + "day": "Monday", + "description": "DevSprint", + "type": "devsprint", + "schedule": [] + } +] diff --git a/src/_includes/navbar.njk b/src/_includes/navbar.njk index 8661c13..009dd33 100644 --- a/src/_includes/navbar.njk +++ b/src/_includes/navbar.njk @@ -15,6 +15,12 @@ {"name": "FAQ's", "link": "about/faqs"} ] }, + { + "name": "Schedule", + "link": "program/schedule", + "hasSubmenu": false, + "isExternal": false + }, { "name": "CFP", "hasSubmenu": true, @@ -30,7 +36,8 @@ "name": "Program", "hasSubmenu": true, "submenu": [ - {"name": "Lightning Talks", "link": "program/lightning-talks"} + {"name": "Schedule", "link": "program/schedule"}, + {"name": "Lightning Talks", "link": "program/lightning-talks"} ] }, { diff --git a/src/program/schedule.njk b/src/program/schedule.njk new file mode 100644 index 0000000..305fba5 --- /dev/null +++ b/src/program/schedule.njk @@ -0,0 +1,270 @@ +--- +title: Schedule +description: PyCon India 2025 Schedule +layout: base.njk +--- + +{% from "components/flat-card.njk" import flatCard %} + +
+
+
+ Schedule +
+ + + {% set active_days = [] %} + {% for day in schedule.schedule.conference.days %} + {% if day.rooms | length > 0 %} + {% set active_days = active_days.concat([day]) %} + {% endif %} + {% endfor %} + + +
+ {% for day in schedule.schedule.conference.days %} + {% if day.rooms | length > 0 %} + {% set dayInfo = day.date | dateInfo %} +
+ {% call flatCard(bg="") -%} +
+
+
+
+
+
+
+
+

+ {{ dayInfo.label.split(' ')[0] }} + {{ dayInfo.label.split(' ').slice(1).join(' ') }} +

+

{{ dayInfo.monthDay }}

+

{{ dayInfo.dayName|upper }}

+
+ {%- endcall %} +
+ {% endif %} + {% endfor %} +
+ + + {% for day in schedule.schedule.conference.days %} + {% if day.rooms | length > 0 %} +
+ {% set dayInfo = day.date | dateInfo %} +
+
+
+
+

{{ dayInfo.label }}

+

{{ dayInfo.monthDay }}

+
+ + {# Build fixed schedule array and assign color #} + {% set fixed_schedule = [] %} + {% for sch in scheduleFixed[day.index-1].schedule %} + {% set fixed_schedule = fixed_schedule.concat([{ + 'type': 'fixed', + 'start_time': sch.start_time, + 'end_time': sch.end_time, + 'title': sch.title, + 'bg_color': sch.color + }]) %} + {% endfor %} + + {# Build room events array #} + {% set room_events = [] %} + {% for room_name in ["Track 1", "Track 2", "Track 3"] %} + {% set room_color = { + "Track 1": "#D7FF7B", + "Track 2": "#D0DCFF", + "Track 3": "#FFD1F9" + }[room_name] %} + {% for event in day.rooms[room_name] %} + {% set room_events = room_events.concat([{ + 'type': 'event', + 'start_time': event.start, + 'end_time': event.start | getEndTime(event.duration), + 'room': room_name, + 'track': event.track, + 'title': event.title, + 'url': event.url, + 'persons': event.persons, + 'bg_color': room_color + }]) %} + {% endfor %} + {% endfor %} + + + {# Merge fixed_schedule and room_events #} + {% set combined_schedule = fixed_schedule.concat(room_events) %} + + {# Sort combined_schedule by start_time #} + {% set combined_schedule = combined_schedule | sort(attribute='start_time') %} + + {% set current_events = [] %} + {% for item in combined_schedule %} + {% if item.type == 'fixed' %} + {# Render any accumulated events before this fixed item #} + {% if current_events.length > 0 %} +
+ {% for room_name in ["Track 1", "Track 2", "Track 3"] %} + + {% endfor %} +
+ {% set current_events = [] %} + {% endif %} + + {# Render fixed item full width #} +
+
+ {% if "Keynote" in item.title %} +
+

+ Keynote +

+
+ {% endif %} +

{{ item.start_time }} - {{ item.end_time }}

+

{{ item.title }}

+
+
+ {% else %} + {% set current_events = current_events.concat([item]) %} + {% endif %} + {% endfor %} +
+
+
+
+ {% endif %} + {% endfor %} +
+
+ + + + diff --git a/src/static/img/assets/calendar.svg b/src/static/img/assets/calendar.svg new file mode 100644 index 0000000..cf8ec52 --- /dev/null +++ b/src/static/img/assets/calendar.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/static/img/assets/tetris2.svg b/src/static/img/assets/tetris2.svg new file mode 100644 index 0000000..27ac073 --- /dev/null +++ b/src/static/img/assets/tetris2.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + +