Skip to content

Commit

Permalink
refactor: blog type
Browse files Browse the repository at this point in the history
  • Loading branch information
NobbZ committed Jul 1, 2023
1 parent 2219b5c commit d79ae51
Show file tree
Hide file tree
Showing 12 changed files with 440 additions and 73 deletions.
2 changes: 2 additions & 0 deletions gatsby-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const config: GatsbyConfig = {
"gatsby-plugin-mdx",
"gatsby-plugin-postcss",
"gatsby-plugin-readtime-nz",
"gatsby-plugin-mdx-source-name",
`gatsby-transformer-source-split`,
{
resolve: "gatsby-source-filesystem",
options: {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"gatsby": "^5.10.0",
"gatsby-plugin-image": "^3.10.0",
"gatsby-plugin-mdx": "^5.10.0",
"gatsby-plugin-mdx-source-name": "^1.0.1",
"gatsby-plugin-sharp": "^5.10.0",
"gatsby-plugin-sitemap": "^6.10.0",
"gatsby-remark-highlight-code": "^3.3.0",
Expand Down
119 changes: 119 additions & 0 deletions plugins/gatsby-transformer-source-split/gatsby-node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { GatsbyNode, NodeInput } from "gatsby";
import { IMdxNode } from "gatsby-plugin-mdx/dist/types";
import { FileSystemNode } from "gatsby-source-filesystem";

type SourceTypes = "blog" | "author";

interface BlogFrontmatter {
title: string;
slug: string;
date: Date;
tags: string[];
hero_image_alt: string;
hero_image_link: string;
hero_image_credit_link: string;
hero_image_credit: string;
hero_image: FileSystemNode;
}

interface MdxNodeWithSource<T> extends IMdxNode {
fields: { source: SourceTypes; readingTime: unknown };
frontmatter: T;
}

export const createSchemaCustomization: GatsbyNode["createSchemaCustomization"] =
({ actions, schema }) => {
const { createTypes } = actions;

const typeDefs = `
type HeroImageData {
alt: String!
link: String!
credit: String!
creditLink: String!
}
type Blog implements Node {
title: String!
slug: String!
date: Date!
tags: [String!]!
heroImage: HeroImageData!
excerpt: String
}
`;

createTypes(typeDefs);
};

export const shouldOnCreateNode: GatsbyNode<
MdxNodeWithSource<BlogFrontmatter>
>["shouldOnCreateNode"] = ({ node }) => {
return node.internal.type === "Mdx" && !!node.parent;
};

export const onCreateNode: GatsbyNode<IMdxNode>["onCreateNode"] = async ({
node,
actions,
createNodeId,
getNode,
cache,
}) => {
const createBlogNode = async (
node: MdxNodeWithSource<BlogFrontmatter>
): Promise<NodeInput> => {
return {
id: createNodeId(`${node.id} >>> blog`),
children: [],
parent: node.id,
internal: {
type: "Blog",
contentDigest: node.internal.contentDigest,
contentFilePath: node.internal.contentFilePath,
},
title: node.frontmatter.title,
slug: node.frontmatter.slug,
date: node.frontmatter.date,
tags: node.frontmatter.tags,
// TODO: Excerpt seems to be generated lazily on query time, so we need to re-map a resolver later
excerpt: "",
readingTime: node.fields.readingTime,
heroImage: {
alt: node.frontmatter.hero_image_alt,
link: node.frontmatter.hero_image_link,
creditLink: node.frontmatter.hero_image_credit_link,
credit: node.frontmatter.hero_image_credit,
image: node.frontmatter.hero_image as FileSystemNode,
},
};
};

const nodeCreator: (
sourceType: SourceTypes,
node: IMdxNode
) => Promise<NodeInput> = async (sourceType, node) => {
switch (sourceType) {
case "blog":
return createBlogNode(node as MdxNodeWithSource<BlogFrontmatter>);

default:
throw new Error(`Unknown source type ${sourceType}`);
}
};

if (!node.parent) {
throw new Error("Node has no parent");
}

const { createNode, createParentChildLink } = actions;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const { sourceInstanceName: source } = getNode(
node.parent
)! as FileSystemNode;

const newNode = await nodeCreator(source as unknown as SourceTypes, node);

createNode(newNode);
createParentChildLink({ parent: node, child: newNode });
await cache.set(`mdxToSplit-${node.internal.contentFilePath}`, newNode);
};
5 changes: 5 additions & 0 deletions plugins/gatsby-transformer-source-split/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "gatsby-transformer-source-split",
"version": "1.0.0",
"private": true
}
40 changes: 19 additions & 21 deletions src/components/articlepreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,25 @@ interface PreviewProps {
}

export const Preview = ({ node }: PreviewProps) => {
const image = getImage(node.frontmatter.hero_image as ImageDataLike);
const image = getImage(node.heroImage.image as ImageDataLike);

const to = `/${node.frontmatter.date}-${node.frontmatter.slug}`;
const to = `/${node.date}-${node.slug}`;

const teaser = image ? (
<div className="w-[140px] p-[5px] shrink-0">
<Link to={to}>
<GatsbyImage
imgClassName="rounded-md"
image={image}
alt={node.frontmatter.hero_image_alt}
alt={node.heroImage.alt}
/>
</Link>
</div>
) : (
<div className="w-[140px] p-[5px] shrink-0"></div>
);

const tags = node.frontmatter.tags?.map((tag) =>
const tags = node.tags.map((tag) =>
tag ? (
<li key={`li-${tag}`}>
<Tag key={tag} name={tag} />
Expand All @@ -38,8 +38,8 @@ export const Preview = ({ node }: PreviewProps) => {
);

const text =
node.fields && node.fields.readingTime && node.fields.readingTime.text
? node.fields.readingTime.text
node.readingTime && node.readingTime.text
? node.readingTime.text
: undefined;
const readingTime = text ? `; ${text}` : undefined;

Expand All @@ -48,10 +48,10 @@ export const Preview = ({ node }: PreviewProps) => {
{teaser}
<div className="grow-1 w-full">
<h2 className="text-base sm:text-lg md:text-xl">
<Link to={to}>{node.frontmatter.title}</Link>
<Link to={to}>{node.title}</Link>
</h2>
<p className="text-xs md:text-sm">
Posted: {node.frontmatter.date}
Posted: {node.date}
{readingTime}
</p>
<p className="hidden md:block md:text-sm">{node.excerpt}</p>
Expand All @@ -64,24 +64,22 @@ export const Preview = ({ node }: PreviewProps) => {
};

export const query = graphql`
fragment PreviewData on Mdx {
fragment PreviewData on Blog {
date
excerpt
fields {
readingTime {
text
}
}
frontmatter {
date
title
slug
tags
hero_image_alt
hero_image {
slug
tags
title
heroImage {
alt
image {
childImageSharp {
gatsbyImageData(width: 200)
}
}
}
readingTime {
text
}
}
`;
Loading

0 comments on commit d79ae51

Please sign in to comment.