on master help sign in
Merge pull request #1827 from urbit/gc/octspot

adding articles ecosystem section and new tlon public group

commit744e7c3ba689b420ef83e2c74e7d91c33e3fc708 authorGordon Cieplak <gordon@urbit.org> dateMon 3 Oct 2022, 20:18 (4 years ago) parent27d126f6e8ae6d
10 files changed+252−18
components/ecosystem/BasicPage.js+25−2 components/ecosystem/IndexCard.js+1 components/ecosystem/Post.js+9 content/articles/2022-09-29_the-dream-of-digital-homesteading.md+10 content/ecosystem/spotlight/2022-october.md+41 content/groups/~nibset-napwyn/tlon-public.md+12 pages/articles/[slug].js+84 pages/ecosystem/index.js+43−2 pages/ecosystem/spotlight/[slug].js+6 pages/index.js+21−14
components/ecosystem/BasicPage.js+25−2
@@ -28,6 +28,7 @@ export default function BasicPage({
2828 metaPost.title = `${post.title} - ${section}`;
2929 metaPost.description =
3030 section === "Podcast" ? `${post.podcast} - ${post.date}` : post.description;
31+ section === "Article" ? `${post.publication} - ${post.date}` : post.description;
3132 return (
3233 <Container>
3334 <Head>
@@ -43,7 +44,7 @@ export default function BasicPage({
4344 <div className="flex items-center space-x-4">
4445 <img src={post.image} className="w-36" />
4546 <div className="flex flex-col pl-2">
46− <h1 className={classnames({ "text-3xl": section === "Podcast" })}>
47+ <h1 className={classnames({ "text-3xl": section === "Podcast" },{ "text-3xl": section === "Article" })}>
4748 {post.title}
4849 </h1>
4950 <p>{section}</p>
@@ -58,13 +59,26 @@ export default function BasicPage({
5859 <p>{post.podcast}</p>
5960 </div>
6061 )}
62+ {post?.publication && (
63+ <div className="flex flex-col">
64+ <p className="font-bold text-wall-400">Publication</p>
65+ <p>{post.publication}</p>
66+ </div>
67+ )}
68+ {post?.author && (
69+ <div className="flex flex-col">
70+ <p className="font-bold text-wall-400">Author</p>
71+ <p>{post.author}</p>
72+ </div>
73+ )}
6174 {post?.date && (
6275 <div className="flex flex-col">
6376 <p className="font-bold text-wall-400">Date</p>
6477 <p className="shrink-0">{post.date}</p>
6578 </div>
6679 )}
67− {post?.URL && section !== "Podcast" && (
80+
81+ {post?.URL && section !== "Podcast" && section !== "Article" && (
6882 <div className="flex flex-col">
6983 <p className="font-bold text-wall-400">Website</p>
7084 <a
@@ -75,6 +89,7 @@ export default function BasicPage({
7589 </a>
7690 </div>
7791 )}
92+
7893 {post?.URL && section === "Urbit Marketplace" && (
7994 <div className="flex flex-col">
8095 <p className="font-bold text-wall-400">Accepts</p>
@@ -93,6 +108,14 @@ export default function BasicPage({
93108 &nbsp;Listen
94109 </a>
95110 )}
111+ {post?.URL && section === "Article" && (
112+ <a
113+ href={post.URL}
114+ className="button-lg bg-green-400 text-white cursor-pointer flex space-x-2"
115+ >
116+ Read
117+ </a>
118+ )}
96119 </div>
97120 <div className="flex">
98121 <div className="markdown w-full">
components/ecosystem/IndexCard.js+1
@@ -43,6 +43,7 @@ const badge = (type) => {
4343 "bg-[#83b2d4]": type === "Application",
4444 "bg-wall-600": type === "Podcast",
4545 "bg-[#8dd5b1]": type === "Marketplace",
46+ "bg-[#B5966D]": type === "Article"
4647 }
4748 )}
4849 >
components/ecosystem/Post.js+9
@@ -49,6 +49,14 @@ export default function Post({ post }) {
4949 </Link>
5050 )}
5151
52+ {post[feat].type === "Article" && (
53+ <Link href={href || "#"} passHref>
54+ <a class="button-sm text-white flex-col bg-green-400 cursor-pointer pr-4 w-fit">
55+ Read {post[feat].type}
56+ </a>
57+ </Link>
58+ )}
59+
5260 {post[feat].type === "Application" && (
5361 <Link href={href || "#"} passHref>
5462 <a class="button-sm text-white flex-col bg-green-400 cursor-pointer pr-4 w-fit">
@@ -87,6 +95,7 @@ const badge = (type) => {
8795 "bg-[#83b2d4]": type === "Application",
8896 "bg-wall-600": type === "Podcast",
8997 "bg-[#8dd5b1]": type === "Marketplace",
98+ "bg-[#B5966D]": type === "Article",
9099 }
91100 )}
92101 >
content/articles/2022-09-29_the-dream-of-digital-homesteading.mdnew file+10
@@ -0,0 +1,10 @@
1++++
2+title = "The Dream of Digital Homesteading"
3+publication = "Compact"
4+author = "Geoff Schullenberger"
5+date = "2022-09-29"
6+URL = "https://compactmag.com/article/the-dream-of-digital-homesteading"
7+image = "https://storage.googleapis.com/media.urbit.org/site/ecosystem/articles/compactmag.png"
8++++
9+
10+Geoff Schullenberger attends Assembly 2022 and chronicles his impressions and thoughts.
content/ecosystem/spotlight/2022-october.mdnew file+41
@@ -0,0 +1,41 @@
1++++
2+title = "October 2022"
3+date = "2022-10-03"
4+
5+[featured-1]
6+title = "Uqbar Development Suite"
7+description = "Write smart contracts and blockchain applications in an integrated development suite."
8+image=""
9+content = """
10+At Assembly 2022 Uqbar debuted their brand new developer toolkit: Ziggurat. Ziggurat provides a unified development interface where programmers can write contracts, receive compiler feedback, and test on a fake chain. This promises a huge improvement on the developer experience for smart contracts and blockchain application development alike. Note: As Ziggurat is in active development and undergoing frequent updates, Uqbar recommends installing Ziggurat on a moon rather than your primary ship.
11+
12+
13+![Screenshot](https://storage.googleapis.com/media.urbit.org/site/ecosystem/spotlight/uqbar-code.png)
14+
15+"""
16+
17+[featured-2]
18+title = "Tlon"
19+description = "The organization that created Urbit is now focused on building the best possible foundational user experiences on Urbit."
20+image="https://storage.googleapis.com/media.urbit.org/site/ecosystem/spotlight/tlonlogos.png"
21+content = """
22+
23+Tlon is the organization responsible for the genesis of Urbit and now focused on creating lasting and effective tools for Urbit. Formerly rather quiet about its development activity, Tlon has recently launched a [beautiful public website](https://tlon.io) and is sharing more of its process in the new [Tlon public group](/groups/~nibset-napwyn/tlon-public).
24+
25+![Screenshot](https://storage.googleapis.com/media.urbit.org/site/ecosystem/spotlight/tlonio.png)
26+
27+
28+"""
29+
30+[featured-3]
31+
32+title = "The Dream of Digital Homesteading"
33+image="https://storage.googleapis.com/media.urbit.org/site/ecosystem/spotlight/compact-thumb2.png"
34+description = "Compact Magazine's managing editor Geoff Shullenberger attended Assembly 2022 and tuned into both the event vibes and Urbit's technical aspirations."
35+content = """
36+
37+Compact Magazine provides a clear-eyed view of both the social and technical visions of the Urbit community as well as the literary milieu around it.
38+![](https://storage.googleapis.com/media.urbit.org/site/ecosystem/spotlight/thedreamofdigitalhomesteading.png)
39+
40+"""
41++++
content/groups/~nibset-napwyn/tlon-public.mdnew file+12
@@ -0,0 +1,12 @@
1++++
2+title = "Tlon Public"
3+shortcode = "~nibset-napwyn/tlon-public"
4+description = "Updates, announcements, and broadcasts from Tlon."
5+type = "Public"
6+tile = "https://storage.googleapis.com/media.urbit.org/site/ecosystem/organizations/tlon.png"
7+participant_range = "200+"
8++++
9+
10+Download the latest alphas of Tlon products, check out Tlon's visual inspiration and design work, and chat with Tlon team about their software.
11+
12+![](https://storage.googleapis.com/media.urbit.org/site/ecosystem/groups/tlon-public.png)
pages/articles/[slug].jsnew file+84
@@ -0,0 +1,84 @@
1+import BasicPage from "../../components/ecosystem/BasicPage";
2+import {
3+ Markdown,
4+ getAllPosts,
5+ getPostBySlug,
6+ getPostSlugs,
7+} from "@urbit/foundation-design-system";
8+import Link from "next/link";
9+
10+export default function Article({
11+ post,
12+ markdown,
13+ search,
14+ index,
15+ spotlights = [],
16+}) {
17+ return (
18+ <BasicPage
19+ section="Article"
20+ post={post}
21+ markdown={markdown}
22+ search={search}
23+ index={index}
24+ >
25+ {spotlights.length > 0 && (
26+ <p>
27+ Featured in{" "}
28+ {spotlights.map((e, i) => (
29+ <>
30+ {i ? ", " : ""}
31+ <Link href={`/ecosystem/spotlight/${e.slug}`}>{e.title}</Link>
32+ </>
33+ ))}
34+ </p>
35+ )}
36+ </BasicPage>
37+ );
38+}
39+
40+export async function getStaticProps({ params }) {
41+ const post = getPostBySlug(
42+ params.slug,
43+ ["title", "slug", "URL", "publication", "author", "date", "image", "content"],
44+ "articles"
45+ );
46+
47+ const spotlights = getAllPosts(
48+ ["title", "slug", "featured-1", "featured-2", "featured-3"],
49+ "ecosystem/spotlight"
50+ ).filter(
51+ (e) =>
52+ e?.["featured-1"]?.title === post.title ||
53+ e?.["featured-2"]?.title === post.title ||
54+ e?.["featured-3"]?.title === post.title
55+ );
56+
57+ let { index } = post?.extra || { index: null };
58+
59+ if (index === undefined) {
60+ index = null;
61+ }
62+
63+ const markdown = JSON.stringify(Markdown.parse({ post }));
64+ return {
65+ props: { post, markdown, spotlights, index },
66+ };
67+}
68+
69+export async function getStaticPaths() {
70+ const posts = getPostSlugs("articles");
71+
72+ const slugs = posts.map((e) => e.slice(0, -3));
73+
74+ return {
75+ paths: slugs.map((post) => {
76+ return {
77+ params: {
78+ slug: post,
79+ },
80+ };
81+ }),
82+ fallback: false,
83+ };
84+}
pages/ecosystem/index.js+43−2
@@ -30,6 +30,7 @@ export default function Ecosystem({
3030 marketplaces,
3131 organizations,
3232 podcasts,
33+ articles
3334}) {
3435 const router = useRouter();
3536
@@ -54,6 +55,9 @@ export default function Ecosystem({
5455 case "organizations":
5556 title = "Organizations • Ecosystem";
5657 break;
58+ case "articles":
59+ title = "Articles • Ecosystem";
60+ break;
5761 default:
5862 title = "Ecosystem Spotlight";
5963 }
@@ -112,8 +116,8 @@ export default function Ecosystem({
112116
113117 <div
114118 className={classnames("grid gap-12 w-full", {
115− "grid-cols-2 md:grid-cols-3": type !== "podcasts",
116− "grid-cols-1": type === "podcasts",
119+ "grid-cols-2 md:grid-cols-3": type == "organizations" || type == "marketplaces",
120+ "grid-cols-1": type === "podcasts" || type === "articles",
117121 "grid-cols-1 md:grid-cols-1 lg:grid-cols-1 xl:grid-cols-2":
118122 type === "applications" || type === "groups",
119123 hidden: type === undefined,
@@ -209,6 +213,26 @@ export default function Ecosystem({
209213 </div>
210214 </Link>
211215 ))}
216+
217+ {type === "articles" &&
218+ articles.map((article) => (
219+ <Link href={`/articles/${article.slug}`}>
220+ <div className="flex cursor-pointer space-x-4 items-center hover:opacity-90">
221+ <img className="w-28" src={article.image} />
222+ <div className="flex flex-col space-y-2 min-w-0">
223+ <p className="font-bold">{article.publication}</p>
224+ <p className="min-w-0 min-h-0 leading-5 ">
225+ {article.title}
226+ </p>
227+ <p className="text-wall-400">
228+ {formatDate(generateDisplayDate(article.date))}
229+ </p>
230+ </div>
231+ </div>
232+ </Link>
233+ ))}
234+
235+
212236 </div>
213237 </div>
214238 </div>
@@ -283,6 +307,16 @@ function EcosystemSidebar() {
283307 >
284308 Podcasts
285309 </ActiveLink>
310+
311+ <ActiveLink
312+ currentPath={currentPath}
313+ className="mr-5 type-ui"
314+ href="/ecosystem?type=articles"
315+ >
316+ Articles
317+ </ActiveLink>
318+
319+
286320 </div>
287321 );
288322}
@@ -362,6 +396,11 @@ export async function getStaticProps({}) {
362396 "podcasts",
363397 "date"
364398 );
399+ const articles = getAllPosts(
400+ ["title", "image", "date", "publication", "author", "slug"],
401+ "articles",
402+ "date"
403+ );
365404 const organizations = getAllPosts(
366405 ["title", "image", "slug"],
367406 "organizations"
@@ -411,6 +450,7 @@ export async function getStaticProps({}) {
411450 ...applications.map((e) => ({ ...e, type: "Application" })),
412451 ...organizations.map((e) => ({ ...e, type: "Organization" })),
413452 ...podcasts.map((e) => ({ ...e, type: "Podcast" })),
453+ ...articles.map((e) => ({ ...e, type: "Article" })),
414454 ...marketplaces.map((e) => ({ ...e, type: "Marketplace" })),
415455 ].filter((e) => e.title === post[feat].title)?.[0];
416456 post[feat].image = post[feat]?.image || matchedPost?.image || null;
@@ -433,6 +473,7 @@ export async function getStaticProps({}) {
433473 marketplaces,
434474 podcasts,
435475 organizations,
476+ articles
436477 },
437478 };
438479}
pages/ecosystem/spotlight/[slug].js+6
@@ -55,6 +55,11 @@ export async function getStaticProps({ params }) {
5555 "podcasts",
5656 "date"
5757 );
58+ const articles = getAllPosts(
59+ ["title", "image", "date", "publication", "author", "slug"],
60+ "articles",
61+ "date"
62+ );
5863 const organizations = getAllPosts(
5964 ["title", "image", "slug"],
6065 "organizations"
@@ -86,6 +91,7 @@ export async function getStaticProps({ params }) {
8691 ...organizations.map((e) => ({ ...e, type: "Organization" })),
8792 ...podcasts.map((e) => ({ ...e, type: "Podcast" })),
8893 ...marketplaces.map((e) => ({ ...e, type: "Marketplace" })),
94+ ...articles.map((e) => ({ ...e, type: "Article" })),
8995 ].filter((e) => e.title === post[feat].title)?.[0];
9096 post[feat].image = post[feat]?.image || matchedPost?.image || null;
9197 post[feat].type = matchedPost?.type || "Podcast";
pages/index.js+21−14
@@ -68,20 +68,20 @@ export default function Home({
6868 </h2>
6969
7070 <div className="space-y-4">
71− <p className="max-w-prose">
72− We realized that in order to fix the internet, we had to build a new
73− computer from scratch. Good thing we started over a decade ago.
74− </p>
75− <p className="max-w-prose pb-4">
76− Today, Urbit is a real system with thousands of users that are
77− building all kinds of communities, software, DAOs, and more. And
78− it’s getting better every day.{" "}
79− </p>
80− <Link href="/overview" passHref>
81− <a className="button-lg bg-green-400 text-white type-ui max-w-fit">
82− Read the Overview
83− </a>
84− </Link>
71+ <p className="max-w-prose">
72+ We realized that in order to fix the internet, we had to build a new
73+ computer from scratch. Good thing we started over a decade ago.
74+ </p>
75+ <p className="max-w-prose pb-4">
76+ Today, Urbit is a real system with thousands of users that are
77+ building all kinds of communities, software, DAOs, and more. And
78+ it’s getting better every day.{" "}
79+ </p>
80+ <Link href="/overview" passHref>
81+ <a className="button-lg bg-green-400 text-white type-ui max-w-fit">
82+ Read the Overview
83+ </a>
84+ </Link>
8585 </div>
8686
8787 </div>
@@ -302,6 +302,12 @@ export async function getStaticProps() {
302302 "date"
303303 )[0];
304304
305+ const articles = getAllPosts(
306+ ["title", "image", "date", "podcast", "slug"],
307+ "articles",
308+ "date"
309+ );
310+
305311 const marketplaces = getAllPosts(["title", "image", "slug"], "marketplaces");
306312 const podcasts = getAllPosts(
307313 ["title", "image", "date", "podcast", "slug"],
@@ -335,6 +341,7 @@ export async function getStaticProps() {
335341 ["featured-1", "featured-2", "featured-3"].forEach((feat) => {
336342 if (ecosystem?.[feat]) {
337343 const matchedPost = [
344+ ...articles.map((e) => ({ ...e, type: "Article" })),
338345 ...applications.map((e) => ({ ...e, type: "Application" })),
339346 ...organizations.map((e) => ({ ...e, type: "Organization" })),
340347 ...podcasts.map((e) => ({ ...e, type: "Podcast" })),