From 31fc15118ba7de3a8b7f56a749c96187c541a985 Mon Sep 17 00:00:00 2001 From: cupcakearmy Date: Sat, 25 Dec 2021 12:40:35 +0100 Subject: [PATCH] tags --- src/app.html | 26 +---------- src/lib/components/PostPreview.svelte | 14 ++++-- src/lib/components/Tag.svelte | 28 ++++++++++++ src/lib/components/Tags.svelte | 34 +++++++++++++++ src/lib/gql/gen.ts | 62 ++++++++++++++++++++++++--- src/lib/gql/root.graphql | 28 ++++++++++++ src/routes/api/[type]/[slug].json.ts | 13 ++++++ src/routes/blog/[slug].svelte | 2 + src/routes/blog/index.svelte | 17 +++++++- src/routes/blog/tags/[slug].svelte | 31 ++++++++++++++ 10 files changed, 219 insertions(+), 36 deletions(-) create mode 100644 src/lib/components/Tag.svelte create mode 100644 src/lib/components/Tags.svelte create mode 100644 src/routes/blog/tags/[slug].svelte diff --git a/src/app.html b/src/app.html index e04d36a..975f6cf 100644 --- a/src/app.html +++ b/src/app.html @@ -13,35 +13,11 @@
%svelte.body%
- - - diff --git a/src/lib/components/PostPreview.svelte b/src/lib/components/PostPreview.svelte index b45ece2..7633697 100644 --- a/src/lib/components/PostPreview.svelte +++ b/src/lib/components/PostPreview.svelte @@ -3,11 +3,12 @@ import ImageFrame from '../components/ImageFrame.svelte' import PostAttributes from '../components/PostAttributes.svelte' + import Tags from './Tags.svelte' export let post: GQLBasePostFragment - + {#if post.post.featured} {/if} @@ -15,6 +16,7 @@

{@html post.title}

+
diff --git a/src/lib/components/Tags.svelte b/src/lib/components/Tags.svelte new file mode 100644 index 0000000..d30b2c0 --- /dev/null +++ b/src/lib/components/Tags.svelte @@ -0,0 +1,34 @@ + + +
+ {#each tags as { slug, name, count }} + + {/each} +
+ + diff --git a/src/lib/gql/gen.ts b/src/lib/gql/gen.ts index 8577367..b111b15 100644 --- a/src/lib/gql/gen.ts +++ b/src/lib/gql/gen.ts @@ -9205,24 +9205,38 @@ export type GQLProjectsOneQueryVariables = Exact<{ export type GQLProjectsOneQuery = { readonly __typename?: 'RootQuery', readonly project: { readonly __typename?: 'Project', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly project: { readonly __typename?: 'Project_Project', readonly date: string, readonly link: string, readonly description: string } } }; -export type GQLBasePostFragment = { readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }; +export type GQLBasePostFragment = { readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly tags: { readonly __typename?: 'PostToTagConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }> }, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }; export type GQLPostsManyQueryVariables = Exact<{ [key: string]: never; }>; -export type GQLPostsManyQuery = { readonly __typename?: 'RootQuery', readonly posts: { readonly __typename?: 'RootQueryToPostConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> } }; +export type GQLPostsManyQuery = { readonly __typename?: 'RootQuery', readonly posts: { readonly __typename?: 'RootQueryToPostConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly tags: { readonly __typename?: 'PostToTagConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }> }, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> } }; export type GQLPostsOneQueryVariables = Exact<{ slug: Scalars['ID']; }>; -export type GQLPostsOneQuery = { readonly __typename?: 'RootQuery', readonly post: { readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } } }; +export type GQLPostsOneQuery = { readonly __typename?: 'RootQuery', readonly post: { readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly tags: { readonly __typename?: 'PostToTagConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }> }, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } } }; + +export type GQLPostsManyByTagQueryVariables = Exact<{ + tag: Scalars['String']; +}>; + + +export type GQLPostsManyByTagQuery = { readonly __typename?: 'RootQuery', readonly posts: { readonly __typename?: 'RootQueryToPostConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly tags: { readonly __typename?: 'PostToTagConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }> }, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> } }; export type GQLSearchQueryVariables = Exact<{ [key: string]: never; }>; -export type GQLSearchQuery = { readonly __typename?: 'RootQuery', readonly posts: { readonly __typename?: 'RootQueryToPostConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> }, readonly projects: { readonly __typename?: 'RootQueryToProjectConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Project', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly project: { readonly __typename?: 'Project_Project', readonly date: string, readonly link: string, readonly description: string } }> }, readonly works: { readonly __typename?: 'RootQueryToWorkConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Work', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly work: { readonly __typename?: 'Work_Work', readonly date: string, readonly link: string, readonly role: string, readonly image: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> } }; +export type GQLSearchQuery = { readonly __typename?: 'RootQuery', readonly posts: { readonly __typename?: 'RootQueryToPostConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly tags: { readonly __typename?: 'PostToTagConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }> }, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> }, readonly projects: { readonly __typename?: 'RootQueryToProjectConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Project', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly project: { readonly __typename?: 'Project_Project', readonly date: string, readonly link: string, readonly description: string } }> }, readonly works: { readonly __typename?: 'RootQueryToWorkConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Work', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly work: { readonly __typename?: 'Work_Work', readonly date: string, readonly link: string, readonly role: string, readonly image: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> } }; + +export type GQLBaseTagFragment = { readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }; + +export type GQLTagsManyQueryVariables = Exact<{ [key: string]: never; }>; + + +export type GQLTagsManyQuery = { readonly __typename?: 'RootQuery', readonly tags: { readonly __typename?: 'RootQueryToTagConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }> } }; export const BasePageFragmentDoc = gql` fragment BasePage on Page { @@ -9271,6 +9285,14 @@ export const BaseProjectFragmentDoc = gql` } } `; +export const BaseTagFragmentDoc = gql` + fragment BaseTag on Tag { + id + slug + name + count +} + `; export const BasePostFragmentDoc = gql` fragment BasePost on Post { id @@ -9280,13 +9302,19 @@ export const BasePostFragmentDoc = gql` status date modified + tags { + nodes { + ...BaseTag + } + } post { featured { ...BaseMediaItem } } } - ${BaseMediaItemFragmentDoc}`; + ${BaseTagFragmentDoc} +${BaseMediaItemFragmentDoc}`; export const MediaItemsManyDocument = gql` query MediaItemsMany { mediaItems(first: 100, where: {status: PUBLISH}) { @@ -9367,6 +9395,15 @@ export const PostsOneDocument = gql` } } ${BasePostFragmentDoc}`; +export const PostsManyByTagDocument = gql` + query PostsManyByTag($tag: String!) { + posts(first: 100, where: {status: PUBLISH, tag: $tag}) { + nodes { + ...BasePost + } + } +} + ${BasePostFragmentDoc}`; export const SearchDocument = gql` query Search { posts(first: 100) { @@ -9388,6 +9425,15 @@ export const SearchDocument = gql` ${BasePostFragmentDoc} ${BaseProjectFragmentDoc} ${BaseWorkFragmentDoc}`; +export const TagsManyDocument = gql` + query TagsMany { + tags(first: 100) { + nodes { + ...BaseTag + } + } +} + ${BaseTagFragmentDoc}`; export type SdkFunctionWrapper = (action: (requestHeaders?:Record) => Promise, operationName: string) => Promise; @@ -9426,8 +9472,14 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = PostsOne(variables: GQLPostsOneQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { return withWrapper((wrappedRequestHeaders) => client.request(PostsOneDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'PostsOne'); }, + PostsManyByTag(variables: GQLPostsManyByTagQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { + return withWrapper((wrappedRequestHeaders) => client.request(PostsManyByTagDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'PostsManyByTag'); + }, Search(variables?: GQLSearchQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { return withWrapper((wrappedRequestHeaders) => client.request(SearchDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'Search'); + }, + TagsMany(variables?: GQLTagsManyQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise { + return withWrapper((wrappedRequestHeaders) => client.request(TagsManyDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'TagsMany'); } }; } diff --git a/src/lib/gql/root.graphql b/src/lib/gql/root.graphql index 5dd47b4..595f7b0 100644 --- a/src/lib/gql/root.graphql +++ b/src/lib/gql/root.graphql @@ -105,6 +105,11 @@ fragment BasePost on Post { status date modified + tags { + nodes { + ...BaseTag + } + } post { featured { ...BaseMediaItem @@ -126,6 +131,14 @@ query PostsOne($slug: ID!) { } } +query PostsManyByTag($tag: String!) { + posts(first: 100, where: { status: PUBLISH, tag: $tag }) { + nodes { + ...BasePost + } + } +} + query Search { posts(first: 100) { nodes { @@ -143,3 +156,18 @@ query Search { } } } + +fragment BaseTag on Tag { + id + slug + name + count +} + +query TagsMany { + tags(first: 100) { + nodes { + ...BaseTag + } + } +} diff --git a/src/routes/api/[type]/[slug].json.ts b/src/routes/api/[type]/[slug].json.ts index 492a5eb..626b891 100644 --- a/src/routes/api/[type]/[slug].json.ts +++ b/src/routes/api/[type]/[slug].json.ts @@ -54,6 +54,19 @@ export async function get(args: ServerRequest) { } } + case 'tags': { + if (all) { + const data = await SDK.TagsMany() + const sorted = [...data.tags.nodes].filter((t) => t.count).sort((a, b) => b.count - a.count) + return { body: sorted } + } + } + + case 'postsByTags': { + const data = await SDK.PostsManyByTag({ tag: slug }) + return { body: data.posts.nodes } + } + default: return { status: 404 } } diff --git a/src/routes/blog/[slug].svelte b/src/routes/blog/[slug].svelte index 16512d0..59cabba 100644 --- a/src/routes/blog/[slug].svelte +++ b/src/routes/blog/[slug].svelte @@ -15,6 +15,7 @@ import PostAttributes from '$lib/components/PostAttributes.svelte' import WpAdapter from '$lib/components/WPAdapter.svelte' import type { GQLBasePostFragment } from '$lib/gql/gen' + import Tags from '$lib/components/Tags.svelte' export let data: GQLBasePostFragment @@ -28,4 +29,5 @@ {#if data.content} {/if} + diff --git a/src/routes/blog/index.svelte b/src/routes/blog/index.svelte index d9df0f4..6735109 100644 --- a/src/routes/blog/index.svelte +++ b/src/routes/blog/index.svelte @@ -6,6 +6,7 @@ return { props: { data: await fetch('/api/posts/*.json').then((r) => r.json()), + tags: await fetch('/api/tags/*.json').then((r) => r.json()), }, } } @@ -14,17 +15,29 @@ Blog - + + Explore Tags + +
+ {#each data as post} {/each} + + diff --git a/src/routes/blog/tags/[slug].svelte b/src/routes/blog/tags/[slug].svelte new file mode 100644 index 0000000..283895f --- /dev/null +++ b/src/routes/blog/tags/[slug].svelte @@ -0,0 +1,31 @@ + + + + + + Blog - {slug} + + + + {#each data as post} + + {/each} +