Блоги #1
4 changed files with 124 additions and 1 deletions
1
src/app.d.ts
vendored
1
src/app.d.ts
vendored
|
|
@ -23,6 +23,7 @@ declare global {
|
||||||
title: string;
|
title: string;
|
||||||
thumbnail?: string;
|
thumbnail?: string;
|
||||||
date?: string;
|
date?: string;
|
||||||
|
dateChanged?: string;
|
||||||
description: string;
|
description: string;
|
||||||
publisher: string;
|
publisher: string;
|
||||||
published?: boolean;
|
published?: boolean;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
|
export const THUMBNAIL_DEFAULT = "https://teasanctuary.ru/common/background-day.webp";
|
||||||
|
|
||||||
export async function fetchPostsSorted() {
|
export async function fetchPostsSorted() {
|
||||||
const allPosts = await fetchPosts();
|
const allPosts = await fetchPosts();
|
||||||
|
|
||||||
|
|
@ -31,3 +33,11 @@ export async function fetchPosts() {
|
||||||
|
|
||||||
return allPosts;
|
return allPosts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function resolveBlogPath(slug?: string, src?: string) {
|
||||||
|
if (!src) return null;
|
||||||
|
|
||||||
|
return src.startsWith('http://') || src.startsWith('https://')
|
||||||
|
? src
|
||||||
|
: `/blog/${slug}/${src}`;
|
||||||
|
}
|
||||||
95
src/routes/blog/[slug]/+page.svelte
Normal file
95
src/routes/blog/[slug]/+page.svelte
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { page } from '$app/state';
|
||||||
|
import InfoBlock from '$src/lib/components/InfoBlock.svelte';
|
||||||
|
import type { PageData } from './$types';
|
||||||
|
import Icon from '@iconify/svelte';
|
||||||
|
|
||||||
|
export let data: PageData;
|
||||||
|
|
||||||
|
const imageFallback = (event: any) => {
|
||||||
|
if (!event.target) return;
|
||||||
|
event.target.src = '/team/profiles/none.jpg';
|
||||||
|
};
|
||||||
|
|
||||||
|
const isPublic = !!data.blogPost.date;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<base target="_blank" />
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<section class="hero flex shrink-0 flex-col items-center justify-center gap-5 overflow-hidden p-4">
|
||||||
|
<div
|
||||||
|
class="flex flex-col flex-nowrap items-center justify-center gap-3 lg:flex-row lg:flex-nowrap"
|
||||||
|
>
|
||||||
|
<div class="text-left">
|
||||||
|
<h1>{data.blogPost.title}</h1>
|
||||||
|
{#if data.blogPost.description}
|
||||||
|
<h2 class="text-gray">{data.blogPost.description}</h2>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section
|
||||||
|
class="flex shrink-0 flex-col items-center justify-center p-4 font-bold {isPublic
|
||||||
|
? 'bg-amber-50 text-slate-950'
|
||||||
|
: 'bg-red-500 text-slate-50'} sm:flex-row sm:flex-nowrap sm:gap-5"
|
||||||
|
>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<Icon icon="material-symbols:calendar-today" class="mr-3" style="transform: scale( 1.4 )" />
|
||||||
|
<p>
|
||||||
|
{data.blogPost.date
|
||||||
|
? new Date(data.blogPost.date).toLocaleString(undefined, {
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
year: 'numeric'
|
||||||
|
})
|
||||||
|
: 'Не опубликован!'}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{#if data.blogPost.dateChanged}
|
||||||
|
<div class="flex items-center font-bold">
|
||||||
|
<Icon icon="material-symbols:update" class="mr-3" style="transform: scale( 1.4 )" />
|
||||||
|
<p>
|
||||||
|
{new Date(data.blogPost.dateChanged).toLocaleString(undefined, {
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
year: 'numeric'
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{#if page.data.blogPost.projects?.length > 0}
|
||||||
|
<InfoBlock>
|
||||||
|
<p>В данной заметке упоминаются наши проекты:</p>
|
||||||
|
<ul>
|
||||||
|
{#each page.data.blogPost.projects as project}
|
||||||
|
<li>{project}</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
</InfoBlock>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<article
|
||||||
|
class="prose
|
||||||
|
lg:prose-lg
|
||||||
|
prose-a:text-blue
|
||||||
|
prose-a:decoration-2
|
||||||
|
prose-a:underline-offset-2
|
||||||
|
hover:prose-a:text-lightblue
|
||||||
|
hover:prose-a:transition-all
|
||||||
|
prose-code:break-words
|
||||||
|
prose-pre:drop-shadow-md
|
||||||
|
bg-white
|
||||||
|
p-4 lg:p-8"
|
||||||
|
>
|
||||||
|
<svelte:component this={data.content} />
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@import '$src/app.css';
|
||||||
|
</style>
|
||||||
17
src/routes/blog/[slug]/+page.ts
Normal file
17
src/routes/blog/[slug]/+page.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { resolveBlogPath, THUMBNAIL_DEFAULT } from "$src/lib/util/Blogs.js";
|
||||||
|
|
||||||
|
export async function load({ params }) {
|
||||||
|
const post = await import(`$src/blogs/${params.slug}.md`);
|
||||||
|
const blogPost: App.BlogPost = post.metadata;
|
||||||
|
const thumbnail = resolveBlogPath(params.slug, blogPost.thumbnail ?? THUMBNAIL_DEFAULT);
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: `${blogPost.title} — Блог`,
|
||||||
|
description: blogPost.description,
|
||||||
|
thumbnail: thumbnail,
|
||||||
|
content: post.default,
|
||||||
|
blogPost: {
|
||||||
|
...blogPost
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue