feat: implement books collection pages with filtering and dynamic routing
This commit is contained in:
parent
789583142c
commit
7336efbb4b
BIN
public/covers/dune-placeholder.jpg
Normal file
BIN
public/covers/dune-placeholder.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 201 KiB |
@ -10,7 +10,7 @@ for (const path in bookImports) {
|
||||
const bookModule = await bookImports[path]();
|
||||
allBooksAstro.push({
|
||||
frontmatter: bookModule.frontmatter,
|
||||
url: bookModule.url || path.replace('../../content', '').replace('.md', ''),
|
||||
url: `/books/${path.split('/').pop().replace('.md', '')}`,
|
||||
description: bookModule.frontmatter.description || bookModule.rawContent()?.substring(0, 100) + '...' || 'No description available.',
|
||||
// Ensure all necessary fields for filtering are directly accessible
|
||||
genre: bookModule.frontmatter.genre,
|
||||
|
||||
68
src/pages/books/[slug].astro
Normal file
68
src/pages/books/[slug].astro
Normal file
@ -0,0 +1,68 @@
|
||||
---
|
||||
import { Markdown } from 'astro/components';
|
||||
|
||||
export async function getStaticPaths() {
|
||||
console.log('Running getStaticPaths...');
|
||||
// Define glob inside the function
|
||||
const bookImports = import.meta.glob('/content/books/*.md');
|
||||
const paths = Object.keys(bookImports);
|
||||
|
||||
console.log('Found file paths:', paths);
|
||||
|
||||
// Process all matched files
|
||||
const books = await Promise.all(
|
||||
paths.map(async (path) => {
|
||||
const mod = await bookImports[path]();
|
||||
|
||||
// Simple slug extraction - just the filename without extension
|
||||
const filename = path.split('/').pop() || '';
|
||||
const slug = filename.replace(/\.md$/, '');
|
||||
|
||||
console.log(`File: ${filename}, Generated slug: ${slug}`);
|
||||
console.log(`Debug: Full path=${path}, Normalized URL would be: /books/${slug}`);
|
||||
|
||||
return {
|
||||
...mod,
|
||||
slug,
|
||||
fullPath: path
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
const routes = books.map(book => ({
|
||||
params: { slug: book.slug },
|
||||
props: { book }
|
||||
}));
|
||||
|
||||
console.log('Generated routes:', routes.map(r => r.params.slug));
|
||||
return routes;
|
||||
}
|
||||
|
||||
const { book } = Astro.props;
|
||||
const { frontmatter, compiledContent } = book;
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>{frontmatter.title || 'Book Details'}</title>
|
||||
</head>
|
||||
<body class="bg-slate-50 min-h-screen">
|
||||
<main class="max-w-2xl mx-auto p-8">
|
||||
<a href="/books" class="text-sky-600 hover:underline">← Back to Books</a>
|
||||
<div class="bg-white rounded-xl shadow-lg p-6 mt-6 flex flex-col items-center">
|
||||
<img src={frontmatter.cover || '/placeholder-cover.png'} alt={frontmatter.title} class="w-24 h-32 object-contain bg-gray-100 rounded mb-4 shadow" />
|
||||
<h1 class="text-3xl font-bold mb-2 text-center">{frontmatter.title}</h1>
|
||||
<p class="text-slate-500 mb-4 text-center">by {frontmatter.author}</p>
|
||||
<p class="mb-2"><strong>Genre:</strong> {frontmatter.genre}</p>
|
||||
<p class="mb-2"><strong>Rating:</strong> {frontmatter.rating}/5</p>
|
||||
<p class="mb-2"><strong>Year:</strong> {frontmatter.year}</p>
|
||||
<p class="mb-2"><strong>Status:</strong> {frontmatter.status}</p>
|
||||
<p class="mb-2"><strong>Pages:</strong> {frontmatter.pages}</p>
|
||||
<p class="mb-2"><strong>ISBN:</strong> {frontmatter.isbn}</p>
|
||||
<div class="prose mt-6">
|
||||
<book.Content />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user