feat: add new collection and post
This commit is contained in:
parent
f2daae3b80
commit
20d2bcf447
166
src/components/BookReview.astro
Normal file
166
src/components/BookReview.astro
Normal file
|
@ -0,0 +1,166 @@
|
|||
---
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
|
||||
interface Props {
|
||||
post: CollectionEntry<"bookReview">;
|
||||
componentType: "short" | "long" | "full";
|
||||
}
|
||||
|
||||
const { post, componentType } = Astro.props;
|
||||
|
||||
// default options for the post component
|
||||
const deafultOptions = {
|
||||
showTags: false,
|
||||
shortSummary: false,
|
||||
longSummary: false,
|
||||
fullText: false,
|
||||
postFooter: false,
|
||||
};
|
||||
|
||||
const options = { ...deafultOptions };
|
||||
// Determine which options should be applied to post
|
||||
switch (componentType) {
|
||||
case "full":
|
||||
options.postFooter = true;
|
||||
options.showTags = true;
|
||||
options.fullText = true;
|
||||
break;
|
||||
case "long":
|
||||
options.longSummary = true;
|
||||
options.showTags = true;
|
||||
break;
|
||||
case "short":
|
||||
options.shortSummary = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Options should not mutated further
|
||||
Object.freeze(options);
|
||||
|
||||
// Format date
|
||||
const postDateFormatted = post.data.date.toLocaleDateString("tr-TR", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
});
|
||||
|
||||
// Create post link
|
||||
const postLink = `/${post.data.category}/${post.slug}`;
|
||||
|
||||
// Create post content as an astro component
|
||||
const { Content } = await post.render();
|
||||
|
||||
const copyPost = post;
|
||||
copyPost.body = copyPost.body.slice(0, 500);
|
||||
const { Content: Summary } = await copyPost.render();
|
||||
|
||||
import { Image } from "astro:assets";
|
||||
import questionMark from "@/images/questionMark.svg";
|
||||
import calendar from "@/images/calendar.svg";
|
||||
---
|
||||
|
||||
<style>
|
||||
.meta-list li {
|
||||
padding-top: 0.1rem;
|
||||
&:not(:last-child) {
|
||||
&:after {
|
||||
content: ",\00a0";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
border: 1px solid slategrey;
|
||||
padding: 4px;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
td {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="tracking-wide text-slate-700">{post.data.subcategory}</p>
|
||||
<a class="no-underline text-inherit" href={postLink}>
|
||||
<h4 class="text-3xl font-normal">{post.data.title}</h4>
|
||||
</a>
|
||||
<div class="flex flex-row gap-2">
|
||||
{
|
||||
options.showTags && post.data.tags?.length && (
|
||||
<div class="flex items-center gap-1">
|
||||
<Image alt="question mark" src={questionMark} />
|
||||
<ul class="list-none flex pl-0 meta-list">
|
||||
{post.data.tags.map((tag) => (
|
||||
<li class="text-sm text-gray-500">{tag}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<div class="flex items-center gap-1">
|
||||
<Image alt="calendar" src={calendar} />
|
||||
<ul class="list-none flex pl-0 meta-list">
|
||||
<p class="text-sm text-gray-500">{postDateFormatted}</p>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{options.shortSummary && <p class="post-summary">{post.data.summary}</p>}
|
||||
|
||||
{
|
||||
options.longSummary && (
|
||||
<>
|
||||
<Summary />
|
||||
{post.body.length > 500 && (
|
||||
<a
|
||||
class="text-inherit text-sm"
|
||||
href={`/${post.data.category}/${post.slug}`}>
|
||||
Devamını Oku
|
||||
</a>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
{
|
||||
options.fullText && (
|
||||
<div class="text-lg gap-3">
|
||||
<table class="float-right mt-0 mb-2 mr-2 ml-2">
|
||||
<caption class="caption-top">{post.data.title}</caption>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="2" style="text-align: center;">
|
||||
<img src={post.data.bookCover.src} width="250" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Yazar:</th>
|
||||
<td>{post.data.bookAuthor}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Yayınevi:</th>
|
||||
<td>{post.data.publisher}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<Content />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
options.postFooter && (
|
||||
<p class="text-gray-600 text-sm">{postDateFormatted}</p>
|
||||
)
|
||||
}
|
||||
</div>
|
30
src/content/bookReview/coevolution.md
Normal file
30
src/content/bookReview/coevolution.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
title: The Coevolution
|
||||
summary: The Coevolution kitabının incelemesi.
|
||||
category: fikir
|
||||
subcategory: Kitap İncelemesi
|
||||
date: 2024-07-25
|
||||
bookAuthor: Edward Ashford Lee
|
||||
publisher: The MIT Press
|
||||
bookLanguage: İngilizce
|
||||
bookGenre: Teknoloji Felsefesi
|
||||
bookCover: ../../images/thecoevolution.jpg
|
||||
---
|
||||
|
||||
<style>
|
||||
.prose {
|
||||
margin: 0.5em 0 1em 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p class="prose">
|
||||
Kitap, makineler ile insanlar arasındaki ilişkiye odaklanıyor ve bu ilişkiyi genellikle yapılanın aksine, makineler açısından ele almaya çalışıyor. Kitaba göre, makineler de aslında bir tür canlıdır; ancak insanlar yalnızca "dijital" türde canlılar üretebildiği için, biyolojik canlılar gibi makinelerin de dijital canlılar (LDB: Digital Living Beings) olduğunu algılayamıyorlar.
|
||||
</p>
|
||||
|
||||
<p class="prose">
|
||||
Makineler, insanlar için bir tür protez işlevi görüyor. Bu protezler, genellikle geri bildirim mekanizmalarına dayanarak sürekli olarak kendilerini geliştiriyorlar. Hatta birçok makineyi, bir geri bildirim mekanizması olarak değerlendirmek mümkün. Bu durum, bazen -dil modellerinde olduğu gibi- davranışlarını açıklayabilmemizin önüne geçebiliyor. Ancak, insanlar uydurma pahasına da olsa her şeyi açıklama ihtiyacı hissettiği için, yapacağımız açıklamaların nitel bir getirisi olmayabilir.
|
||||
</p>
|
||||
|
||||
<p class="prose">
|
||||
Yazar ayrıca, insanın ne ölçüde taklit edilebileceğine de değiniyor. İnsan, büyük ölçüde analog bir yapıya sahip olduğu için, "bit bitine" kopyalanması mümkün görünmüyor. Ayrıca, bu sistemlerin yaptıklarından kimi sorumlu tutacağımız da bir muamma. Özetle, makineler evrimimizin bir parçası, belki bir gün gelecek, kendimizi onların da kendi kendilerine evrildiği bir süreçte bulacağız.
|
||||
</p>
|
|
@ -2,18 +2,36 @@ import { z, defineCollection } from "astro:content";
|
|||
|
||||
export const CATEGORIES = ["fikir", "teknik", "edebiyat", "ansiklopedi"];
|
||||
|
||||
const blogCollection = defineCollection({
|
||||
type: "content",
|
||||
schema: z.object({
|
||||
const blogPostSchema = z.object({
|
||||
title: z.string(),
|
||||
tags: z.optional(z.array(z.string())),
|
||||
summary: z.string(),
|
||||
date: z.date(),
|
||||
category: z.enum(["fikir", "teknik", "edebiyat", "ansiklopedi"]),
|
||||
subcategory: z.string(),
|
||||
});
|
||||
|
||||
const bookReviewSchema = blogPostSchema.extend({
|
||||
bookAuthor: z.string(),
|
||||
publisher: z.string(),
|
||||
bookLanguage: z.string(),
|
||||
bookGenre: z.string(),
|
||||
});
|
||||
|
||||
const blogCollection = defineCollection({
|
||||
type: "content",
|
||||
schema: blogPostSchema,
|
||||
});
|
||||
|
||||
const bookReviewCollection = defineCollection({
|
||||
type: "content",
|
||||
schema: ({ image }) =>
|
||||
bookReviewSchema.extend({
|
||||
bookCover: image(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const collections = {
|
||||
blog: blogCollection,
|
||||
bookReview: bookReviewCollection,
|
||||
};
|
||||
|
|
BIN
src/images/thecoevolution.jpg
Normal file
BIN
src/images/thecoevolution.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 244 KiB |
|
@ -10,10 +10,13 @@ import Post from "@/components/Post.astro";
|
|||
|
||||
export async function getStaticPaths({ paginate }: { paginate: any }) {
|
||||
const blogEntries = await getCollection("blog");
|
||||
const allReviews = await getCollection("bookReview");
|
||||
|
||||
const allPosts = [...allReviews, ...blogEntries];
|
||||
|
||||
return CATEGORIES.flatMap((category) => {
|
||||
const filteredPosts = blogEntries.filter(
|
||||
(post) => post.data.category == category,
|
||||
const filteredPosts = allPosts.filter(
|
||||
(post) => post.data.category == category
|
||||
);
|
||||
return paginate(filteredPosts, {
|
||||
params: { category },
|
||||
|
|
|
@ -8,6 +8,7 @@ import Post from "@/components/Post.astro";
|
|||
import EmojiReactionForm from "@/components/EmojiReactionForm.astro";
|
||||
import CommentForm from "@/components/CommentForm.astro";
|
||||
import HorizontalLine from "@/components/HorizontalLine.astro";
|
||||
import BookReview from "@/components/BookReview.astro";
|
||||
|
||||
const { entry } = Astro.props;
|
||||
|
||||
|
@ -15,8 +16,11 @@ const backendHost = import.meta.env.PUBLIC_BACKEND_HOST;
|
|||
|
||||
export async function getStaticPaths() {
|
||||
const blogEntries = await getCollection("blog");
|
||||
const allReviews = await getCollection("bookReview");
|
||||
|
||||
return blogEntries.map((entry) => ({
|
||||
const allPosts = [...allReviews, ...blogEntries];
|
||||
|
||||
return allPosts.map((entry) => ({
|
||||
params: { category: entry.data.category, slug: entry.slug },
|
||||
props: { entry },
|
||||
}));
|
||||
|
@ -25,7 +29,13 @@ export async function getStaticPaths() {
|
|||
|
||||
<Layout title="log101">
|
||||
<Header />
|
||||
{
|
||||
entry.collection === "blog" ? (
|
||||
<Post post={entry} componentType="full" />
|
||||
) : (
|
||||
<BookReview post={entry} componentType="full" />
|
||||
)
|
||||
}
|
||||
<EmojiReactionForm entryId={entry.id} />
|
||||
|
||||
<section class="comments">
|
||||
|
|
|
@ -5,17 +5,28 @@ import Layout from "@/layouts/Layout.astro";
|
|||
|
||||
import { getCollection } from "astro:content";
|
||||
import Post from "@/components/Post.astro";
|
||||
import BookReview from "@/components/BookReview.astro";
|
||||
|
||||
const allTeknikPosts = await getCollection("blog");
|
||||
const allReviews = await getCollection("bookReview");
|
||||
|
||||
const allPosts = [...allReviews, ...allTeknikPosts];
|
||||
---
|
||||
|
||||
<Layout title="log101">
|
||||
<Header />
|
||||
<div class="posts">
|
||||
{
|
||||
allTeknikPosts
|
||||
allPosts
|
||||
.sort((p1, p2) => p2.data.date.getTime() - p1.data.date.getTime())
|
||||
.map((p) => <Post post={p} componentType="short" />)
|
||||
.map((p) => {
|
||||
if (p.collection == "blog") {
|
||||
return <Post post={p} componentType="short" />;
|
||||
} else {
|
||||
p.collection == "bookReview";
|
||||
return <BookReview post={p} componentType="short" />;
|
||||
}
|
||||
})
|
||||
}
|
||||
</div>
|
||||
<a class="text-inherit" href="/posts/1">Tüm Yayınlar</a>
|
||||
|
|
Loading…
Reference in New Issue
Block a user