Skip to content

Commit c0034f3

Browse files
authored
Merge pull request #203 from n0th1ng-else/rss
2 parents 011659c + 27247d0 commit c0034f3

File tree

14 files changed

+200
-79
lines changed

14 files changed

+200
-79
lines changed

src/assets/icons/rss.svg

Lines changed: 15 additions & 0 deletions
Loading
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<script lang="ts">
2+
import Link from '$lib/browser/ui/Link.svelte';
3+
import Paragraph from '$lib/browser/ui/Paragraph.svelte';
4+
import { blogRoute } from '$lib/common/routes';
5+
import imageNotFound from '../../../assets/images/not-found.svg';
6+
</script>
7+
8+
<article>
9+
<aside class="container">
10+
<img class="image" src="{imageNotFound}" alt="" title="Page not found" />
11+
</aside>
12+
<section class="text">
13+
<Paragraph>One day something funny would appear on this page...</Paragraph>
14+
<Paragraph>But for now, I was not able to find anything for you, really. My bad.</Paragraph>
15+
<Paragraph>
16+
Check out <Link inline url="{blogRoute}">my blog</Link>, if you have not already
17+
</Paragraph>
18+
</section>
19+
</article>
20+
21+
<style lang="scss">
22+
@import '../../../lib/browser/ui/theme';
23+
@import '../../../global';
24+
25+
.text {
26+
margin-top: $unit;
27+
text-align: center;
28+
}
29+
30+
.image {
31+
height: 100%;
32+
object-fit: contain;
33+
width: 100%;
34+
}
35+
36+
.container {
37+
margin: auto;
38+
height: auto;
39+
width: 4 * $unit-plus;
40+
}
41+
42+
@media (min-width: $sm) {
43+
.container {
44+
width: 6 * $unit-plus;
45+
}
46+
}
47+
48+
@media (min-width: $md) {
49+
.container {
50+
width: 10 * $unit-plus;
51+
}
52+
}
53+
</style>

src/lib/browser/components/SocialNetworks.svelte

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import Link from '$lib/browser/ui/Link.svelte';
55
import { getSocialNetworks } from '$lib/browser/utils/contacts';
66
import type { ProfileAccounts } from '$lib/common/@types/common';
7+
import { rssRoute } from '$lib/common/routes';
8+
import icoRss from '../../../assets/icons/rss.svg';
79
810
export let accounts: ProfileAccounts | null = null;
911
const networks = accounts ? getSocialNetworks(accounts) : [];
@@ -29,6 +31,11 @@
2931
</Link>
3032
</div>
3133
{/each}
34+
<div class="social-networks-item">
35+
<Link url="{rssRoute}">
36+
<img src="{icoRss}" alt="RSS feed" class="logo" class:l="{!isDark}" class:d="{isDark}" />
37+
</Link>
38+
</div>
3239
</div>
3340

3441
<style lang="scss">

src/lib/common/routes.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,50 @@ enum RoutePath {
44
Projects = 'projects',
55
About = 'about',
66
Legal = 'legal',
7-
NotFound = 'not-found',
8-
Other = '*'
7+
NotFound = '404',
8+
Rss = 'rss.xml'
99
}
1010

1111
const toPath = (path?: RoutePath): string => {
1212
if (!path) {
1313
return '/';
1414
}
1515

16-
if (path === RoutePath.Other) {
17-
return RoutePath.Other;
18-
}
19-
2016
return `/${path}`;
2117
};
2218

2319
export const homeRoute = toPath(RoutePath.Home);
2420

2521
export const blogRoute = toPath(RoutePath.Blog);
2622

27-
export const newArticleRoute = `${blogRoute}/new`;
23+
export const newArticleRoute = `${blogRoute}/draft`;
2824

2925
export const projectsRoute = toPath(RoutePath.Projects);
3026

3127
export const aboutRoute = toPath(RoutePath.About);
3228

3329
export const legalRoute = toPath(RoutePath.Legal);
3430

31+
export const rssRoute = toPath(RoutePath.Rss);
32+
3533
export const notFoundRoute = toPath(RoutePath.NotFound);
3634

3735
export const toArticle = (id: string): string => `${blogRoute}/${id}`;
3836

3937
export const getAbsoluteArticleUrl = (host: string, slug: string): string => `${host}/blog/${slug}`;
4038

41-
export const getAbsoluteRssUrl = (host: string): string => `${host}/rss`;
39+
export const getAbsoluteRssUrl = (host: string): string => `${host}${rssRoute}`;
40+
41+
export interface RoutePriority {
42+
critical: string[];
43+
major: string[];
44+
minor: string[];
45+
}
46+
47+
export const getRoutes = (host: string, slugs: string[]): RoutePriority => {
48+
return {
49+
critical: slugs.map(slug => `${blogRoute}/${slug}`),
50+
major: [homeRoute, blogRoute, projectsRoute, aboutRoute],
51+
minor: [legalRoute, notFoundRoute]
52+
};
53+
};

src/lib/server/articles.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,7 @@ const parseArticle = (
110110

111111
export const getInternalArticles = (showDraft: boolean): LinkInfo[] => {
112112
const files = findAllArticles();
113-
return files
114-
.map(file => parseArticle(file.slug, file.location, showDraft))
115-
.filter(article => article);
113+
return files.map(file => parseArticle(file.slug, file.location, showDraft)).filter(Boolean);
116114
};
117115

118116
export const getInternalArticle = (slug: string, showDraft: boolean): LinkInfo | null => {

src/lib/server/sitemap.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import type { RoutePriority } from '$lib/common/routes';
2+
3+
const getSitemapRoute = (host: string, route: string, priority: string): string =>
4+
`<url>
5+
<loc>${host}${route}</loc>
6+
<changefreq>weekly</changefreq>
7+
<priority>${priority}</priority>
8+
</url>`;
9+
10+
const getSitemapContainer = (urls: string): string =>
11+
`<?xml version="1.0" encoding="UTF-8" ?>
12+
<urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"
13+
xmlns:news="https://www.google.com/schemas/sitemap-news/0.9"
14+
xmlns:xhtml="https://www.w3.org/1999/xhtml"
15+
xmlns:mobile="https://www.google.com/schemas/sitemap-mobile/1.0"
16+
xmlns:image="https://www.google.com/schemas/sitemap-image/1.1"
17+
xmlns:video="https://www.google.com/schemas/sitemap-video/1.1"
18+
>
19+
${urls}
20+
</urlset>`;
21+
22+
export const generateSitemap = (url: string, routes: RoutePriority) => {
23+
const critical = routes.critical.map(route => getSitemapRoute(url, route, '0.9')).join('\n');
24+
const major = routes.major.map(route => getSitemapRoute(url, route, '0.5')).join('\n');
25+
const minor = routes.minor.map(route => getSitemapRoute(url, route, '0.2')).join('\n');
26+
const all = [critical, major, minor].join('\n');
27+
const container = getSitemapContainer(all);
28+
return container;
29+
};

src/lib/server/xml.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export const getXMLHeaders = () => {
2+
const oneHour = 3600; // in seconds
3+
return {
4+
'Cache-Control': `max-age=0, s-maxage=${oneHour}`, // 10 minutes
5+
'Content-Type': 'application/xml'
6+
};
7+
};

src/routes/+error.svelte

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,10 @@
11
<script lang="ts">
2-
import Link from '$lib/browser/ui/Link.svelte';
3-
import Paragraph from '$lib/browser/ui/Paragraph.svelte';
4-
import imageNotFound from '../assets/images/not-found.svg';
2+
import NotFound from '$lib/browser/components/NotFound.svelte';
53
import { notFoundTitle as title } from '$lib/common/labels';
6-
import { blogRoute } from '$lib/common/routes.js';
74
</script>
85

9-
<article>
10-
<aside class="image-container">
11-
<img class="image" src="{imageNotFound}" alt="" />
12-
</aside>
13-
<section class="text-container">
14-
<Paragraph>One day something funny would appear on this page...</Paragraph>
15-
<Paragraph>But for now, I was not able to find anything for you, really. My bad.</Paragraph>
16-
<Paragraph>
17-
Check out <Link inline url="{blogRoute}">my blog</Link>, if you have not already
18-
</Paragraph>
19-
</section>
20-
</article>
6+
<NotFound />
217

228
<svelte:head>
239
<title>{title}</title>
2410
</svelte:head>
25-
26-
<style lang="scss">
27-
@import '../lib/browser/ui/theme';
28-
@import '../global';
29-
30-
.text-container {
31-
margin-top: $unit;
32-
text-align: center;
33-
}
34-
35-
.image {
36-
height: 100%;
37-
object-fit: contain;
38-
width: 100%;
39-
}
40-
41-
.image-container {
42-
margin: auto;
43-
height: auto;
44-
width: 4 * $unit-plus;
45-
}
46-
47-
@media (min-width: $sm) {
48-
.image-container {
49-
width: 6 * $unit-plus;
50-
}
51-
}
52-
53-
@media (min-width: $md) {
54-
.image-container {
55-
width: 10 * $unit-plus;
56-
}
57-
}
58-
</style>

src/routes/404/+page.server.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type { PageServerLoad } from './$types';
2+
3+
interface Output {
4+
url: string;
5+
}
6+
export const load: PageServerLoad<Output> = async ({ url }) => {
7+
return {
8+
url: url.toString()
9+
};
10+
};

src/routes/404/+page.svelte

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script lang="ts">
2+
import { profileStore } from '$lib/browser/stores';
3+
import Meta from '$lib/browser/ui/Meta.svelte';
4+
import NotFound from '$lib/browser/components/NotFound.svelte';
5+
import { notFoundTitle as title } from '$lib/common/labels';
6+
import type { PageData } from './$types';
7+
8+
export let data: PageData;
9+
10+
const { url } = data;
11+
12+
const photo = $profileStore?.image ?? '';
13+
</script>
14+
15+
<Meta image="{photo}" description="{title}" url="{url}" />
16+
17+
<NotFound />
18+
19+
<svelte:head>
20+
<title>{title}</title>
21+
</svelte:head>

0 commit comments

Comments
 (0)