mirror of
https://github.com/cupcakearmy/nicco.io.git
synced 2024-12-21 23:56:26 +00:00
tags
This commit is contained in:
parent
d8fe85c4ca
commit
31fc15118b
26
src/app.html
26
src/app.html
@ -13,35 +13,11 @@
|
||||
<body>
|
||||
<div id="svelte">%svelte.body%</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var _paq = (window._paq = window._paq || [])
|
||||
_paq.push(['setDocumentTitle', document.domain + '/' + document.title])
|
||||
_paq.push(['setCookieDomain', '*.nicco.io'])
|
||||
_paq.push(['disableCookies'])
|
||||
_paq.push(['trackPageView'])
|
||||
_paq.push(['enableLinkTracking'])
|
||||
;(function () {
|
||||
var u = '//stats.nicco.io/'
|
||||
_paq.push(['setTrackerUrl', u + 'rainbow'])
|
||||
_paq.push(['setSiteId', '1'])
|
||||
var d = document,
|
||||
g = d.createElement('script'),
|
||||
s = d.getElementsByTagName('script')[0]
|
||||
g.type = 'text/javascript'
|
||||
g.async = true
|
||||
g.src = u + 'unicorn'
|
||||
s.parentNode.insertBefore(g, s)
|
||||
})()
|
||||
</script>
|
||||
<noscript
|
||||
><p>
|
||||
<img src="//stats.nicco.io/rainbow?idsite=1&rec=1" style="border: 0" alt="" /></p
|
||||
></noscript>
|
||||
|
||||
<script
|
||||
async
|
||||
defer
|
||||
data-website-id="3808ed9b-9fc6-481b-bf6c-45e07f7aedf9"
|
||||
data-domains="nicco.io"
|
||||
src="https://spectare.nicco.io/unicorn.js"
|
||||
></script>
|
||||
</body>
|
||||
|
@ -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
|
||||
</script>
|
||||
|
||||
<a href={`blog/${post.slug}`} class:without={!post.post.featured}>
|
||||
<a href={`/blog/${post.slug}`} class:without={!post.post.featured}>
|
||||
{#if post.post.featured}
|
||||
<ImageFrame src={post.post.featured.sourceUrl} alt={post.post.featured.altText} />
|
||||
{/if}
|
||||
@ -15,6 +16,7 @@
|
||||
<h2>
|
||||
{@html post.title}
|
||||
</h2>
|
||||
<Tags tags={post.tags.nodes} />
|
||||
</a>
|
||||
|
||||
<style>
|
||||
@ -33,9 +35,13 @@
|
||||
transition: var(--animation);
|
||||
background-color: var(--clr-light);
|
||||
}
|
||||
a:hover h2 {
|
||||
top: -1em;
|
||||
transform: scale(0.95);
|
||||
a :global(img) {
|
||||
transition: var(--animation);
|
||||
position: relative;
|
||||
top: 0;
|
||||
}
|
||||
a:hover :global(img) {
|
||||
top: 2.5rem;
|
||||
}
|
||||
|
||||
a > :global(div) {
|
||||
|
28
src/lib/components/Tag.svelte
Normal file
28
src/lib/components/Tag.svelte
Normal file
@ -0,0 +1,28 @@
|
||||
<script lang="ts">
|
||||
export let name: string = ''
|
||||
export let href: string = ''
|
||||
export let count: number = 0
|
||||
</script>
|
||||
|
||||
<a {href}>
|
||||
<div>
|
||||
{name} <i>{count}</i>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
div {
|
||||
display: inline-block;
|
||||
margin: 0.25rem;
|
||||
padding: 0 0.5rem;
|
||||
background-color: var(--clr-primary);
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
i {
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: 0.85em;
|
||||
font-weight: bold;
|
||||
color: var(--clr-secondary);
|
||||
}
|
||||
</style>
|
34
src/lib/components/Tags.svelte
Normal file
34
src/lib/components/Tags.svelte
Normal file
@ -0,0 +1,34 @@
|
||||
<script lang="ts">
|
||||
import type { GQLBaseTagFragment } from '$lib/gql/gen'
|
||||
import Tag from './Tag.svelte'
|
||||
|
||||
export let tags: readonly GQLBaseTagFragment[]
|
||||
export let rows: number = 1
|
||||
|
||||
$: height = rows * 2
|
||||
</script>
|
||||
|
||||
<div style="height: {height}em;">
|
||||
{#each tags as { slug, name, count }}
|
||||
<Tag {name} {count} href="/blog/tags/{slug}" />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: auto;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
margin: 0 -0.25rem;
|
||||
}
|
||||
|
||||
div::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
div {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
</style>
|
@ -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,12 +9302,18 @@ export const BasePostFragmentDoc = gql`
|
||||
status
|
||||
date
|
||||
modified
|
||||
tags {
|
||||
nodes {
|
||||
...BaseTag
|
||||
}
|
||||
}
|
||||
post {
|
||||
featured {
|
||||
...BaseMediaItem
|
||||
}
|
||||
}
|
||||
}
|
||||
${BaseTagFragmentDoc}
|
||||
${BaseMediaItemFragmentDoc}`;
|
||||
export const MediaItemsManyDocument = gql`
|
||||
query MediaItemsMany {
|
||||
@ -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 = <T>(action: (requestHeaders?:Record<string, string>) => Promise<T>, operationName: string) => Promise<T>;
|
||||
|
||||
@ -9426,8 +9472,14 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
|
||||
PostsOne(variables: GQLPostsOneQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GQLPostsOneQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GQLPostsOneQuery>(PostsOneDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'PostsOne');
|
||||
},
|
||||
PostsManyByTag(variables: GQLPostsManyByTagQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GQLPostsManyByTagQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GQLPostsManyByTagQuery>(PostsManyByTagDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'PostsManyByTag');
|
||||
},
|
||||
Search(variables?: GQLSearchQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GQLSearchQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GQLSearchQuery>(SearchDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'Search');
|
||||
},
|
||||
TagsMany(variables?: GQLTagsManyQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GQLTagsManyQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GQLTagsManyQuery>(TagsManyDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'TagsMany');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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
|
||||
</script>
|
||||
@ -28,4 +29,5 @@
|
||||
{#if data.content}
|
||||
<WpAdapter content={data.content} />
|
||||
{/if}
|
||||
<Tags tags={data.tags.nodes} />
|
||||
</SimplePage>
|
||||
|
@ -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 @@
|
||||
<script lang="ts">
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
import PostPreview from '$lib/components/PostPreview.svelte'
|
||||
import type { GQLBasePostFragment } from '$lib/gql/gen'
|
||||
import type { GQLBasePostFragment, GQLBaseTagFragment } from '$lib/gql/gen'
|
||||
import Tags from '$lib/components/Tags.svelte'
|
||||
|
||||
export let data: GQLBasePostFragment[]
|
||||
export let tags: GQLBaseTagFragment[]
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Blog</title>
|
||||
</svelte:head>
|
||||
|
||||
<SimplePage title="Works">
|
||||
<SimplePage title="Blog">
|
||||
<b>Explore Tags</b>
|
||||
<Tags {tags} />
|
||||
<div />
|
||||
|
||||
{#each data as post}
|
||||
<PostPreview {post} />
|
||||
{/each}
|
||||
</SimplePage>
|
||||
|
||||
<style>
|
||||
div {
|
||||
margin-bottom: 3em;
|
||||
}
|
||||
</style>
|
||||
|
31
src/routes/blog/tags/[slug].svelte
Normal file
31
src/routes/blog/tags/[slug].svelte
Normal file
@ -0,0 +1,31 @@
|
||||
<script lang="ts" context="module">
|
||||
import type { Load } from '@sveltejs/kit'
|
||||
|
||||
export const load: Load = async ({ fetch, page }) => {
|
||||
return {
|
||||
props: {
|
||||
slug: page.params.slug,
|
||||
data: await fetch(`/api/postsByTags/${page.params.slug}.json`).then((r) => r.json()),
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
import type { GQLPostsManyByTagQuery } from '$lib/gql/gen'
|
||||
import PostPreview from '$lib/components/PostPreview.svelte'
|
||||
|
||||
export let slug: string
|
||||
export let data: GQLPostsManyByTagQuery['posts']['nodes']
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Blog - {slug}</title>
|
||||
</svelte:head>
|
||||
|
||||
<SimplePage title={slug}>
|
||||
{#each data as post}
|
||||
<PostPreview {post} />
|
||||
{/each}
|
||||
</SimplePage>
|
Loading…
Reference in New Issue
Block a user