aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps/timeline
diff options
context:
space:
mode:
authorGravatar hedy <[email protected]>2024-03-23 19:48:41 +0800
committerGravatar ~hedy <[email protected]>2024-05-24 12:46:12 +0800
commit8eb4dc9ea279335fa6b7db1bc3cdfee5b914fd40 (patch)
tree2c06f40fa05a03f888609865c0a1a15f18b76da7 /pydis_site/apps/timeline
parentBump HassanAbouelela/actions from setup-python_v1.5.0 to 1.6.0 (#1326) (diff)
Timeline: Migrate to Markdown source files - initial implementation
- The timeline app is introduced, moved from the home app. - Add a basic README.md to illustrate the overall code breakdown of the app as it is in the current stage. - Two entries are added for now. - Add ability to link headers using the slug portion of the filename. - The way markdown files are fetched is similar to that of the resources app - using the AppConfig ready() function, all resources are ensured to be only fetched once when the app is first laoded. I debated whether to introduce the new functionality in the home app instead, without creating a new app. Eventually I decided extracting it to a standalone app now is better as it allows easier extension of functionality in the future. The home app can remain as it is to only server the `/` homepage. The timeline CSS is kept the same, as with the structure of the timeline HTML template. Once the CSS rewrite PR is merged, it's relatively easy to fix conflicts here (again, since timeline is now its own app, with the CSS file and HTML template moved - extra advantage). References to `home:timeline` are updated to use `timeline:index` throughout the codebase, as far as my ripgrep search could go. The format of the markdown + YAML entries are still up for debate, so I've only added the first two entries for now. They can be completely overwritten in the future once the formats are decided by using a script to convert all the data from my JSON file into individual markdown files: http://0x0.st/Xr78.txt This link should last for at least a few months. (Originally saved on https://paste.pythondiscord.com/KPJA, but it expires on 12th April 2024.)
Diffstat (limited to 'pydis_site/apps/timeline')
-rw-r--r--pydis_site/apps/timeline/README.md44
-rw-r--r--pydis_site/apps/timeline/__init__.py0
-rw-r--r--pydis_site/apps/timeline/apps.py45
-rw-r--r--pydis_site/apps/timeline/entries/2023-01-30_retirement-of-joe-and-sebastiaan.md12
-rw-r--r--pydis_site/apps/timeline/entries/2023-07-11_new-paste-service.md12
-rw-r--r--pydis_site/apps/timeline/urls.py9
-rw-r--r--pydis_site/apps/timeline/views.py20
7 files changed, 142 insertions, 0 deletions
diff --git a/pydis_site/apps/timeline/README.md b/pydis_site/apps/timeline/README.md
new file mode 100644
index 00000000..a4272c4d
--- /dev/null
+++ b/pydis_site/apps/timeline/README.md
@@ -0,0 +1,44 @@
+# The "timeline" app
+
+The [timeline page](https://www.pythondiscord.com/timeline/) on our website is
+powered by this Django application.
+
+## The entries
+
+Timeline entries are written in markdown files with YAML frontmatter under the
+`entries` directory.
+
+Each file represents a timeline entry. The files are named with the format
+`<date>_<name>.md`:
+- `date`: The date is in the `YYYY-MM-DD` format, intended for easy sorting in
+ editor/shell command directory listings. It's also used to sort the entries
+ before rendering the timeline page.
+- `name`: The name component is an arbitrary slug in **kebab-case**. This is used
+ for linking to individual timeline entries on the page, and will be set in
+ the `id` attribute.
+
+Each file contains:
+- YAML frontmatter. This defines some metadata shown next to each entry in
+ the timeline, including:
+ - Date: User-facing date label.
+ - Icon: The CSS class to be used for the icon. Set to `pydis` to use the
+ pydis logo image.
+ - Icon color: The CSS class that sets the background color of the icon. Leave
+ empty if the pydis logo is used.
+- Markdown content.
+
+
+## Directory structure
+
+The app has a single view in `views.py` that takes care of reading the `.md`
+files in the `entires` directory. This is a standard Django view, mounted in
+`urls.py` as usual.
+
+The `tests` directory validates that our redirects and helper functions work as
+expected. If you made changes to the app and are looking for guidance on adding
+new tests, the [Django tutorial introducing automated
+testing](https://docs.djangoproject.com/en/dev/intro/tutorial05/) is a good
+place to start.
+
+This application does not use the database and as such does not have models nor
+migrations.
diff --git a/pydis_site/apps/timeline/__init__.py b/pydis_site/apps/timeline/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/pydis_site/apps/timeline/__init__.py
diff --git a/pydis_site/apps/timeline/apps.py b/pydis_site/apps/timeline/apps.py
new file mode 100644
index 00000000..8f27297f
--- /dev/null
+++ b/pydis_site/apps/timeline/apps.py
@@ -0,0 +1,45 @@
+from pathlib import Path
+
+from django.apps import AppConfig
+import frontmatter
+import markdown
+
+from pydis_site import settings
+
+
+ENTRIES_PATH = Path(settings.BASE_DIR, "pydis_site", "apps", "timeline", "entries")
+
+
+class TimelineConfig(AppConfig):
+ """AppConfig instance for Timeline app."""
+
+ name = 'pydis_site.apps.timeline'
+
+ def ready(self) -> None:
+ """Fetch all the timeline entries."""
+ self.entries = []
+
+ for path in ENTRIES_PATH.rglob("*.md"):
+ metadata, content = frontmatter.parse(path.read_text(encoding="utf-8"))
+
+ md = markdown.Markdown()
+ html = str(md.convert(content))
+
+ # Strip `.md` file extension from filename and split it into the
+ # date (for sorting) and slug (for linking).
+ key, slug = path.name[:-3].split("_")
+ entry = {
+ "key": key,
+ "slug": slug,
+ "title": metadata["title"],
+ "date": metadata["date"],
+ "icon": metadata["icon"],
+ # This key might not be used if the icon uses the pydis logo.
+ "icon_color": metadata.get("icon_color"),
+ "content": html,
+ }
+
+ self.entries.append(entry)
+
+ # Sort the entries in reverse-chronological order.
+ self.entries.sort(key=lambda e: e['key'], reverse=True)
diff --git a/pydis_site/apps/timeline/entries/2023-01-30_retirement-of-joe-and-sebastiaan.md b/pydis_site/apps/timeline/entries/2023-01-30_retirement-of-joe-and-sebastiaan.md
new file mode 100644
index 00000000..1629c1f5
--- /dev/null
+++ b/pydis_site/apps/timeline/entries/2023-01-30_retirement-of-joe-and-sebastiaan.md
@@ -0,0 +1,12 @@
+---
+title: Retirement of Joe and Sebastiaan
+date: 2023-01-30
+icon: pydis
+---
+
+Having been at the helm of Python Discord for over 5 and 3 years respectively,
+Joe and Sebastiaan retire and step down. They gain the **@Founders** role and
+continue as advisors to the **@Directors**, the new name of the original
+**@Owners** role.
+
+At the same time, Mina and Zig join Leon as co-directors.
diff --git a/pydis_site/apps/timeline/entries/2023-07-11_new-paste-service.md b/pydis_site/apps/timeline/entries/2023-07-11_new-paste-service.md
new file mode 100644
index 00000000..818fa2f9
--- /dev/null
+++ b/pydis_site/apps/timeline/entries/2023-07-11_new-paste-service.md
@@ -0,0 +1,12 @@
+---
+title: Switch to new paste service
+date: 2023-07-11
+icon: fa-regular fa-clipboard
+icon_color: pastel-pink
+---
+
+We migrate over to [pinnwand](https://github.com/supakeen/pinnwand) as the
+service that powers our paste bin over at <https://paste.pythondiscord.com/>.
+We made the switch as it comes with native light/dark modes, support for
+multi-file pastes, additional support for text highlighting languages, and
+plus, it's written in Python!
diff --git a/pydis_site/apps/timeline/urls.py b/pydis_site/apps/timeline/urls.py
new file mode 100644
index 00000000..e4f1d6c6
--- /dev/null
+++ b/pydis_site/apps/timeline/urls.py
@@ -0,0 +1,9 @@
+from django_distill import distill_path
+
+from .views import TimelineView
+
+app_name = "timeline"
+
+urlpatterns = [
+ distill_path("", TimelineView.as_view(), name="index"),
+]
diff --git a/pydis_site/apps/timeline/views.py b/pydis_site/apps/timeline/views.py
new file mode 100644
index 00000000..380dfe53
--- /dev/null
+++ b/pydis_site/apps/timeline/views.py
@@ -0,0 +1,20 @@
+from django.apps import apps
+from django.core.handlers.wsgi import WSGIRequest
+from django.http import HttpResponse
+from django.shortcuts import render
+from django.views import View
+
+APP_NAME = "timeline"
+
+class TimelineView(View):
+ """A vertical timeline showcasing milestones in the history of Python Discord."""
+
+ def get(self, request: WSGIRequest) -> HttpResponse:
+ """Render the timeline."""
+ app = apps.get_app_config(APP_NAME)
+
+ return render(
+ request,
+ template_name="timeline/timeline.html",
+ context={ "entries": app.entries },
+ )