Skip to content

Commit 1d19158

Browse files
committed
Add back to Blog button.
Fix responsive markup
1 parent 0b93416 commit 1d19158

11 files changed

Lines changed: 406 additions & 21 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
# Generated thumbnails
1717
*.thumb.jpg
1818

19+
# Vite SSR temp files
20+
*.timestamp-*
21+
1922
# Logs
2023
npm-debug.log*
2124
yarn-debug.log*

.vitepress/config.mts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { fileURLToPath } from 'url'
12
import { defineConfig, HeadConfig } from 'vitepress'
23
import { generateRss, rssPlugin } from './rss'
34
import { generateLlms, llmsPlugin } from './llms'
@@ -16,6 +17,14 @@ export default defineConfig({
1617

1718
vite: {
1819
plugins: [rssPlugin(), llmsPlugin()],
20+
resolve: {
21+
alias: [
22+
{
23+
find: /.*\/VPLocalNav\.vue$/,
24+
replacement: fileURLToPath(new URL('./theme/VPLocalNav.vue', import.meta.url)),
25+
},
26+
],
27+
},
1928
},
2029

2130
head: [

.vitepress/locales.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1+
import type { ComputedRef, InjectionKey } from 'vue'
2+
3+
export interface LocalNavBack {
4+
url: string
5+
label: string
6+
}
7+
8+
export const localNavBackKey: InjectionKey<ComputedRef<LocalNavBack | null>> = Symbol('local-nav-back')
9+
110
export interface LocaleConfig {
211
code: string // 'en', 'ru', 'de', etc.
312
prefix: string // '' for root, 'ru', 'de', etc.
413
blogTitle: string
514
blogDescription: string
15+
blogLabel: string // Back button label: 'Blog', 'Блог', etc.
616
}
717

818
export const locales: LocaleConfig[] = [
@@ -11,12 +21,14 @@ export const locales: LocaleConfig[] = [
1121
prefix: '',
1222
blogTitle: 'Testo Blog',
1323
blogDescription: 'Updates from Testo - Modern PHP Testing Framework',
24+
blogLabel: 'Blog',
1425
},
1526
{
1627
code: 'ru',
1728
prefix: 'ru',
1829
blogTitle: 'Блог Testo',
1930
blogDescription: 'Новости Testo - современного PHP фреймворка для тестирования',
31+
blogLabel: 'Блог',
2032
},
2133
]
2234

@@ -33,6 +45,16 @@ export function getFeedFilename(locale: LocaleConfig): string {
3345
return locale.prefix ? `${locale.prefix}/feed.xml` : 'feed.xml'
3446
}
3547

48+
export function getLocaleByPath(path: string): LocaleConfig {
49+
return locales.find(l => l.prefix && path.startsWith(`/${l.prefix}/`)) ?? locales[0]
50+
}
51+
52+
export function getBlogBackLink(path: string): LocalNavBack | null {
53+
if (!isBlogPath(path)) return null
54+
const locale = getLocaleByPath(path)
55+
return { url: getBlogUrl(locale), label: locale.blogLabel }
56+
}
57+
3658
export function isBlogPath(path: string): boolean {
3759
return locales.some(locale => {
3860
const blogUrl = getBlogUrl(locale)

.vitepress/theme/BlogPostHeader.vue

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
<script setup lang="ts">
2-
import { useData } from 'vitepress'
2+
import { useData, useRoute } from 'vitepress'
33
44
const { frontmatter } = useData()
5+
const route = useRoute()
6+
7+
const isRu = route.path.startsWith('/ru/')
8+
const blogUrl = isRu ? '/ru/blog/' : '/blog/'
9+
const backTitle = isRu ? 'Назад в блог' : 'Back to blog'
510
611
function formatDate(date: string | Date): string {
712
const d = new Date(date)
@@ -11,12 +16,18 @@ function formatDate(date: string | Date): string {
1116

1217
<template>
1318
<div class="blog-post-header" v-if="frontmatter.image || frontmatter.date || frontmatter.author">
14-
<img
15-
v-if="frontmatter.image"
16-
:src="frontmatter.image"
17-
:alt="frontmatter.title"
18-
class="post-hero-image"
19-
/>
19+
<div class="post-image-wrap" v-if="frontmatter.image">
20+
<a :href="blogUrl" class="back-to-blog" :title="backTitle">
21+
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
22+
<path d="M11 4L6 9L11 14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
23+
</svg>
24+
</a>
25+
<img
26+
:src="frontmatter.image"
27+
:alt="frontmatter.title"
28+
class="post-hero-image"
29+
/>
30+
</div>
2031
<div class="post-meta" v-if="frontmatter.date || frontmatter.author">
2132
<span v-if="frontmatter.date" class="post-date">{{ formatDate(frontmatter.date) }}</span>
2233
<span v-if="frontmatter.author" class="post-author">{{ frontmatter.author }}</span>
@@ -29,6 +40,38 @@ function formatDate(date: string | Date): string {
2940
margin-bottom: 1.5rem;
3041
}
3142
43+
.post-image-wrap {
44+
position: relative;
45+
}
46+
47+
.back-to-blog {
48+
position: absolute;
49+
top: 12px;
50+
left: -48px;
51+
display: none;
52+
align-items: center;
53+
justify-content: center;
54+
width: 36px;
55+
height: 36px;
56+
border-radius: 50%;
57+
border: 1px solid var(--vp-c-divider);
58+
background: var(--vp-c-bg);
59+
color: var(--vp-c-text-2);
60+
text-decoration: none;
61+
transition: all 0.2s;
62+
}
63+
64+
.back-to-blog:hover {
65+
color: var(--vp-c-brand-1);
66+
border-color: var(--vp-c-brand-1);
67+
}
68+
69+
@media (min-width: 1280px) {
70+
.back-to-blog {
71+
display: flex;
72+
}
73+
}
74+
3275
.post-hero-image {
3376
width: 100%;
3477
height: auto;

.vitepress/theme/GitHubStars.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ const formatStars = (count: number | null) => {
9898
.github-text {
9999
display: none;
100100
}
101+
.github-count {
102+
display: none;
103+
}
101104
102105
.github-stars-button {
103106
padding: 4px 8px;

0 commit comments

Comments
 (0)