Skip to content

Commit 5b0f087

Browse files
committed
08: Finish content pages.
1 parent 588e842 commit 5b0f087

File tree

11 files changed

+381
-18
lines changed

11 files changed

+381
-18
lines changed

src/psc/app.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ async def content_page(request: Request) -> _TemplateResponse:
8686
"page.jinja2",
8787
dict(
8888
title=this_page.title,
89+
subtitle=this_page.subtitle,
8990
main=this_page.body,
9091
request=request,
9192
),

src/psc/pages/about.md

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,84 @@
11
---
2-
title: About PyScript Collective
2+
title: About the PyScript Collective
3+
subtitle: The mission, background, and moving parts about the Collective.
34
---
45

5-
Stuff *is here*.
6+
The PyScript Collective is: software and people, from and for the PyScript Community.
7+
8+
# Helping Learners and Contributors
9+
10+
We want PyScript to be a great onboarding vehicle for Python, data science, and web coding.
11+
Fortunately a lot of folks want to help too!
12+
The Collective is a community project to organize everything about PyScript (and related projects like Pyodide) into useful collections.
13+
14+
Things we work on:
15+
16+
## The `awesome-pyscript` Page
17+
18+
Awesome PyScript is an organized, curated, and updated collection of every…damn…thing.
19+
If you have an example, put it up somewhere and let us know.
20+
We’ll list it (terms and conditions apply.)
21+
Same for an article, a video, a conference talk, whatever.
22+
23+
We’ll list it, but we won’t stand behind it. We’ll remove it if we’re told it’s no longer good, but that’s it.
24+
Not much of a “stamp of approval."
25+
26+
If you’re looking for a collection of quality, working, maintained stuff, then that would be…
27+
28+
## PyScript Gallery
29+
30+
People like to learn by runnable-example, and PyScript is great for this -- a UI in a browser, yummy.
31+
People also like to *share* running examples.
32+
33+
We're the group that packages up community examples into a slick, quality web app called the PyScript Gallery.
34+
It's a page on a website (here), but it's also a locally-runnable Python application and package.
35+
36+
It's not all just software, though.
37+
The Collective has a larger purpose: education.
38+
39+
## Contributors and Collaborators
40+
41+
The Collective is a shared-responsibility repo of resources, such as examples.
42+
As such, it is *also* a group of maintainers who help stuff come in, help clean it up, help teach people, then stand behind what goes in.
43+
We’ll fix bugs, refactor examples if PyScript changes, answer tickets, etc.
44+
45+
Even better, we help contributors *join* the Collective and become collaborators.
46+
And those new contributors can then help the next person.
47+
We want the Collective to become a joyful place where people are **valued and valuable**.
48+
Where new coders become the next generation of stars.
49+
Hell, we want people to list it on their resume, where the Collective helps them land a job.
50+
51+
As such, the Collective has a higher bar. It isn’t fair to the maintainers for new contributors to do a “dump and run.” We’ll require: tests, docstrings, and perhaps some code quality tools (flake8, black.) Why? To make it easy to maintain, but also to be shining code examples for learners.
52+
53+
## Incubator
54+
55+
The “Incubator” is the in-between stage. Stuff that’s on its way in, isn’t ready to get a permanent commitment yet. Perhaps it’s the code: needs cleaning up, doesn’t use the right idioms. Perhaps its the contributor: they aren’t sure yet if they are around for the long-haul and the maintainers don’t feel comfortable holding the bag.
56+
Stuff in the “incubator” might not be listed publicly. Such as...
57+
58+
59+
## Will This Work?
60+
61+
It’s kind of ambitious, in a social way.
62+
Will we get contributors?
63+
Maintainers?
64+
Will people want to join?
65+
66+
We think so.
67+
Rather, we very-much hope so.
68+
We’d like PyScript to be a vehicle for crazy-cool innovation, growth, and togetherness, similar to how data science impacted Python.
69+
70+
## Kinda Vague, What Specifically?
71+
72+
- We’ll get a bootstrapping set of maintainers who commit to building the machinery (easy testing, GitHub Actions, flake8 etc., Sphinx output, Awesome PyScript Markdown page) and closing tickets
73+
74+
- Collect all the existing known resources into the Awesome PyScript page
75+
76+
- Make it clear the process to contribute to Awesome PyScript
77+
78+
- Start processing our own examples through the process to see how well it works
79+
80+
- Create a super-slick Gallery app
81+
82+
- Make it clear the process to contribute to the Collective
83+
84+
- See if anybody wants their examples in the Collective, perhaps to join us

src/psc/pages/contact.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
title: Contact Us
3+
---
4+
5+
Optional subtitle.

src/psc/pages/contributing.html

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<html lang="en">
2+
<head>
3+
<title>Contributing</title>
4+
<meta name="subtitle" content="How to get involved in the PyCharm Collective.">
5+
</head>
6+
<body>
7+
<section>
8+
<a id="viewer"></a>
9+
<h1>Viewer</h1>
10+
<p>A person who shows up at this website and clicks on the examples in the Gallery.</p>
11+
</section>
12+
<section>
13+
<a id="coder"></a>
14+
<h1>Coder</h1>
15+
<p>A person who uses <code>pipx</code> to run the examples locally.</p>
16+
</section>
17+
<section>
18+
<a id="contributor"></a>
19+
<h1>Contributor</h1>
20+
<p>A person makes a Python project, installs <code>pyga</code> as a dependency, and starts making examples.</p>
21+
</section>
22+
<section>
23+
<a id="collaborator"></a>
24+
<h1>Collaborator</h1>
25+
<p>The core Collective team that takes long-term ownership of all the examples, keeping the tests running, and
26+
keeping the code up-to-date.</p>
27+
</section>
28+
</body>
29+
</html>

src/psc/pages/faq.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
---
2+
title: FAQ
3+
subtitle: Questions about the Collective, the Gallery, the examples...answered.
4+
---
5+
6+
The Collective...it's kind of an odd little ducky.
7+
The Gallery?
8+
Ditto.
9+
10+
Let's answer some questions.
11+
12+
# Why should I care?
13+
14+
- A slick, supported web app for browsing quality examples
15+
- A cool, fast testing regime with `TestClient` plus Playwright *interceptors*
16+
- An installable package to run/hack examples without needing a network connection
17+
- No `package.json`
18+
- Hands-free GitHub Actions
19+
20+
# Gallery
21+
22+
The Gallery is the web application and static website for browsing examples, contributors, etc.
23+
24+
### Why bundle your own everything?
25+
26+
The Gallery has a fork of PyScript and -- you heard it right -- a private copy of Pyodide.
27+
Why?
28+
29+
To let us run offline or in low-bandwidth settings.
30+
When I wrote the Gallery, I was on a *slow* connection.
31+
It was super-painful.
32+
Consuming the Gallery and contributing should be more joyful.
33+
34+
Also, we want a stable checkpoint in time.
35+
The examples will work against a known set of stuff, because we'll bundle that set of stuff.
36+
37+
If you're interested in such stuff, take a look at the docs for the prototype repo.
38+
In there is a step-by-step diary of the journey taken for all of these decisions.
39+
40+
### What's up with testing?
41+
42+
Well, glad you asked!
43+
I'm a big fan of test-first.
44+
The existing PyScript testing regime has some rough edges and I wanted to explore alternatives and propose changes.
45+
46+
The Collective will have to stand behind the Gallery and the examples.
47+
We need it to be productive.
48+
49+
### No `pyscript.css`?
50+
51+
Yep, the Gallery and the website don't use the PyScript styling.
52+
The PyScript core team doesn't plan to force folks to use PyScript itself as the application.
53+
The Gallery is an exemplar of that ethos.
54+
It's an app that made some choices.
55+
56+
### Why Bulma?
57+
58+
Cuz I like it.
59+
And I know it.
60+
I wanted a mature, off-the-shelf style package that looks great without me thinking.
61+
And if I want more, I get the SASS package and hack away.
62+
63+
But perhaps you noticed -- there's no `package.json` here.
64+
No tooling.
65+
Pleasureville.
66+
67+
### PWA offline-first?
68+
69+
Wouldn't it be cool to work offline, like an installable app on a mobile device?
70+
It could happen!
71+
Maybe with `htmx` to smooth page changes.
72+
73+
Why stop there?
74+
Let's have a hot-reloading Gallery that pushes incremental changes to fragments over SSE.
75+
76+
# Examples
77+
78+
Examples are the heart of the Gallery and Collective.
79+
80+
### Why all that tooling crap!?!
81+
82+
`mypy` and type hints? `Flake8`? `nox`? GitHub Actions? Are you *insane*?
83+
84+
You know what's insane?
85+
The answer to the next question.
86+
Yes, the tooling is a tax, and we're open to lowering taxes.
87+
But taxes serve the public good, and our job is to deliver a Gallery that works, now in the future...based on examples from *other people*.
88+
89+
To some degree, it's also a teaching tool for "best practices."
90+
But that -- like "Pythonic" -- is an expression sure to get an eye-roll.
91+
So consider the "we want examples that are good teaching tools" as a secondary benefit.
92+
93+
### Wait, YOU are going to hold the bag...forever? Thanks!
94+
95+
Yes, when an example is accepted, the people in the Collective promise to co-own it.
96+
Keep it working, fix bugs people report, rebuild Frankenstein when PyScript/Pyodide go off in some new direction.
97+
It's there on the tin: "Collective".
98+
We're all in this together.
99+
100+
### Oh, you're tricking me into joining!
101+
102+
Yep, freely admitted.
103+
We want a fun, joyous place where Python newcomers feel valued and valuable.
104+
We want your example -- but we also want *you*!
105+
106+
There's lots we can teach you.
107+
Managing Git, releasing packages, writing tests, fighting `mypy`.
108+
As well as the Gallery itself -- add new features, help write tests, make videos.
109+
110+
In a perfect world, "Collaborator for the PyScript Collective" will be a treasured listing on your LinkedIn profile.
111+
You'll use us for a job reference, and we'll get you a sweet career upgrade.
112+
113+
In exchange, we'll ask you to help us trick the next person into joining the Collective, then "coach them up" to being a star and moving to a better job.
114+
115+
No, no, no...this does NOT sound like a Ponzi scheme.

src/psc/pages/gallery.html

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<html lang="en">
2+
<head>
3+
<title>Gallery</title>
4+
<meta name="subtitle" content="Description of kinds of examples, how they are managed, and how the Gallery works.">
5+
</head>
6+
<body>
7+
<p>Examples...it's what the Collective does! The examples in the Gallery come in different flavors. Let's take a
8+
look.</p>
9+
10+
<section>
11+
<a id="integrated"></a>
12+
<h1>Integrated</h1>
13+
<p>The featured examples have something in common...they all use the same CSS and same PyScript/Pyodide. This makes
14+
the page-to-page experience really slick. As a side effect, it makes it easier for us to manage, co-own, test, etc.</p>
15+
</section>
16+
17+
<section>
18+
<a id="secondary"></a>
19+
<h1>Secondary</h1>
20+
<p>Some examples need to be more standalone: their own styling, their own Pyodide. These run in an
21+
<code>iframe</code> and might not have the same QA level.</p>
22+
</section>
23+
24+
<section>
25+
<a id="incubator"></a>
26+
<h1>Incubator</h1>
27+
<p>Sometimes we have newcomers with a crazy new idea for an example. The code isn't polished, might not be tested. And most of all, the Collective team might not want to take long-term ownership.</p>
28+
<p>These go in the "incubator" part of the Collective.</p>
29+
</section>
30+
31+
<section>
32+
<a id="gallery"></a>
33+
<h1>Gallery</h1>
34+
<p>The Gallery is, surprisingly, a Python package -- `psga`. You can install it and run it! The same content that goes up on the website, goes out in the package.</p>
35+
</section>
36+
37+
<section>
38+
<a id="future"></a>
39+
<h1>Future</h1>
40+
<p>PWA offline-first, edit-in-place.</p>
41+
</section>
42+
43+
</body>
44+
</html>

src/psc/pages/running.html

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<html lang="en">
2+
<head>
3+
<title>Running the Gallery</title>
4+
<meta name="subtitle" content="Different ways to run the Gallery for different kinds of uses.">
5+
</head>
6+
<body>
7+
<p>The PyScript Gallery is a website with browseable, runnable examples.</p>
8+
<p>But wait -- it's also a running Python <em>application</em>! You can run it with <code>pipx</code> or a local
9+
virtualenv! It's also a Python <em>package</em>. You can install it into your own project and run it from there.</p>
10+
<p>Let's look at the ways different kinds of uses can run the Gallery.</p>
11+
<section>
12+
<a id="viewer"></a>
13+
<h2>Viewer</h2>
14+
<p>Go to the website, click the link, and PyScript runs the Python code in your browser. Yeh, duh, we all know
15+
that.</p>
16+
</section>
17+
<section>
18+
<a id="coder"></a>
19+
<h2>Coder</h2>
20+
<p>What if you want to run offline? Or poke around locally? It's a Python package, and <code>pipx</code> makes it
21+
easy to run applications. This will fire up a local Starlette server. <em>Everything</em> -- including Pyodide -- will be served
22+
locally. (Unless one of the examples has to make an API request.)</p>
23+
<p>You'll get the same Gallery you're seeing on the website. It's just statically dumped from Starlette</p>
24+
</section>
25+
<section>
26+
<a id="contributor"></a>
27+
<h1>Contributor</h1>
28+
<p>Maybe you're not up on <code>pipx</code>. Or maybe -- just maybe! -- you'd like to create and contribute an example.</p>
29+
<p>Use virtualenv or Conda to make a project, install <code>psg</code> as a dependency.</p>
30+
</section>
31+
</body>
32+
</html>

src/psc/resources.py

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,17 +135,36 @@ def __post_init__(self) -> None:
135135
class Page(Resource):
136136
"""A Markdown+frontmatter driven content page."""
137137

138+
subtitle: str = ""
138139
body: str = ""
139140

140141
def __post_init__(self) -> None:
141-
"""Extract content from Markdown file."""
142+
"""Extract content from either Markdown or HTML file."""
142143
md_file = HERE / "pages" / f"{self.path}.md"
143-
if not md_file.exists():
144+
html_file = HERE / "pages" / f"{self.path}.html"
145+
146+
# If this self.path resolves to a Markdown file, use it first
147+
if md_file.exists():
148+
md_fm = frontmatter.load(md_file)
149+
self.title = md_fm.get("title", "")
150+
self.subtitle = md_fm.get("subtitle", "")
151+
md = MarkdownIt()
152+
self.body = str(md.render(md_fm.content))
153+
elif html_file.exists():
154+
soup = BeautifulSoup(html_file.read_text(), "html5lib")
155+
title_node = soup.find("title")
156+
if title_node:
157+
self.title = title_node.text
158+
subtitle_node = soup.select_one('meta[name="subtitle"]')
159+
if subtitle_node:
160+
assert subtitle_node # noqa
161+
subtitle = cast(str, subtitle_node.get("content", ""))
162+
self.subtitle = subtitle
163+
body_node = soup.find("body")
164+
if body_node and isinstance(body_node, Tag):
165+
self.body = body_node.prettify()
166+
else: # pragma: no cover
144167
raise ValueError(f"No page at {self.path}")
145-
md_fm = frontmatter.load(md_file)
146-
self.title = md_fm["title"]
147-
md = MarkdownIt()
148-
self.body = str(md.render(md_fm.content))
149168

150169

151170
@dataclass

src/psc/templates/page.jinja2

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
{% extends "layout.jinja2" %}
22
{% block main %}
33
<main id="main_container" class="container">
4-
<h1 class="title is-1">{{ title }}</h1>
5-
{{ main | safe }}
4+
<div class="columns">
5+
<div class="column is-three-quarters">
6+
<h1 class="title is-1">{{ title }}</h1>
7+
<h1 class="subtitle">{{ subtitle }}</h1>
8+
<div class="content">{{ main | safe }}</div>
9+
</div>
10+
</div>
611
</main>
712
{% endblock %}

0 commit comments

Comments
 (0)