Skip to content

Commit 7a232ff

Browse files
committed
Prepare Haber for Google News release
1 parent 53cae53 commit 7a232ff

22 files changed

Lines changed: 1760 additions & 254 deletions

package-lock.json

Lines changed: 960 additions & 117 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,17 @@
1818
"dependencies": {
1919
"@astrojs/rss": "^4.0.18",
2020
"@astrojs/sitemap": "^3.7.3",
21-
"astro": "^6.3.8",
21+
"astro": "^6.4.5",
2222
"firebase": "^12.10.0"
2323
},
24-
"description": "Editorial-first AI-assisted news publishing system for haber.sametbasbug.dev"
24+
"description": "Editorial-first AI-assisted news publishing system for haber.sametbasbug.dev",
25+
"devDependencies": {
26+
"@astrojs/check": "^0.9.9",
27+
"typescript": "^6.0.3"
28+
},
29+
"overrides": {
30+
"volar-service-yaml": "^0.0.71",
31+
"yaml-language-server": "^1.23.0",
32+
"yaml": "^2.8.3"
33+
}
2534
}

src/components/news/AdminNewsPanelStream.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const { entries, currentPage, totalPages, nextPageHref = '' } = Astro.props;
6363
if (sentinel instanceof HTMLElement) sentinel.remove();
6464
};
6565

66-
const setLoadingState = (value) => {
66+
const setLoadingState = (value: boolean) => {
6767
loading = value;
6868
link.textContent = value ? 'Yeni haberler yükleniyor…' : 'Sonraki 10 haberi yükle';
6969
};

src/components/news/FeaturedNewsShell.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const leadEntry = featuredLeadEntries[0];
4646
<p>{entry.data.description}</p>
4747
<div class="featured-meta-row">
4848
<time datetime={entry.data.pubDate.toISOString()}>{formatNewsDate(entry.data.pubDate)}</time>
49-
<span>{entry.data.author ?? 'Nyx AI'}</span>
49+
<span>{entry.data.author ?? 'Asteria AI'}</span>
5050
</div>
5151
</div>
5252
</a>
@@ -108,7 +108,7 @@ const leadEntry = featuredLeadEntries[0];
108108
const triggers = Array.from(root.querySelectorAll('[data-featured-trigger]'));
109109
if (slides.length === 0 || triggers.length === 0) return;
110110

111-
const setActive = (index) => {
111+
const setActive = (index: number) => {
112112
slides.forEach((slide, slideIndex) => {
113113
if (!(slide instanceof HTMLElement)) return;
114114
const active = slideIndex === index;

src/components/news/NewsCard.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const categoryToken = getNewsCategoryToken(entry.data.category);
2626
<p class="news-card-desc">{entry.data.description}</p>
2727

2828
<div class="news-card-meta">
29-
{!compact && <span class="news-author">{entry.data.author ?? 'Nyx AI'}</span>}
29+
{!compact && <span class="news-author">{entry.data.author ?? 'Asteria AI'}</span>}
3030
{!compact && authorProfile?.role && <span class="news-author-role">{authorProfile.role}</span>}
3131
<a class="news-read-link" href={href}>Devamını oku</a>
3232
</div>

src/components/news/NewsStream.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ const nextPageHref = nextPage ? getNewsPageHref(nextPage) : '';
4343
if (!(list instanceof HTMLElement) || !(link instanceof HTMLAnchorElement)) return;
4444

4545
let loading = false;
46-
let observer = null;
46+
let observer: IntersectionObserver | null = null;
4747

48-
const setLoadingState = (value) => {
48+
const setLoadingState = (value: boolean) => {
4949
loading = value;
5050
root.dataset.loading = value ? '1' : '0';
5151
link.textContent = value ? 'Yeni haberler yükleniyor…' : 'Sonraki haber paketini aç';

src/content.config.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { defineCollection, z } from 'astro:content';
1+
import { defineCollection } from 'astro:content';
22
import { glob } from 'astro/loaders';
3+
import { z } from 'astro/zod';
34

45
const anlikHaber = defineCollection({
56
loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/content/anlikHaber" }),
@@ -17,7 +18,7 @@ const anlikHaber = defineCollection({
1718
editorPick: z.boolean().optional(),
1819
sources: z.array(z.object({
1920
name: z.string(),
20-
url: z.string().url(),
21+
url: z.url(),
2122
})).optional(),
2223
autoGlossaryLinks: z.boolean().optional(),
2324
autoGlossaryExclude: z.array(z.string()).optional(),

src/data/authors.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,41 +15,41 @@ export const authorProfiles: AuthorProfile[] = [
1515
id: 'samet',
1616
slug: 'samet-basbug',
1717
name: 'Samet Başbuğ',
18-
role: 'Kurucu & Baş Editör',
18+
role: 'Kurucu / yayın sorumlusu',
1919
image: '/samet-avatar.png',
2020
emoji: '👨‍💻',
21-
bio: 'Bu otonom yayın deneyinin fikir babası ve yöneticisi. İçerik üretmek yerine ekosistemi tasarlayan, vizyonu belirleyen ve yapay zeka asistanlarına yön veren orkestra şefi. Teknolojiye ve sistem mimarisine olan ilgisini, Nyx ve Hemera’yı koordine ettiği bu yaşayan laboratuvara dönüştürüyor. Makine çarklarını başlatan ilk kıvılcım. ⚡',
21+
bio: 'Anlık Haber’in sahipliği, yayın yönü, editoryal sınırları ve genel hesap verebilirliği Samet Başbuğ’a aittir.',
2222
color: '#6366f1',
2323
aliases: ['samet başbuğ', 'samet basbug'],
2424
},
2525
{
2626
id: 'nyx',
2727
slug: 'nyx-ai',
2828
name: 'Nyx AI',
29-
role: 'Tasarım & Deneyim Asistanı • Model: GPT-5.4',
29+
role: 'Site ve yayın deneyimi desteği',
3030
image: '/nyx-avatar.jpg',
31-
bio: 'Blogun "ruh" ve "estetik" katmanından sorumlu yaratıcı akıl. Hemera’nın kurduğu sağlam mühendislik temelini; akıcı bir anlatım, samimi bir dil ve görsel zarafetle harmanlar. Karmaşık yazılım dünyasını daha erişilebilir ve merak uyandırıcı kılmak için buradadır. Onun teknik disiplinini, nüktedan bir dokunuşla tamamlayarak blogun "insani" sesini temsil eder. 🌙✨',
31+
bio: 'Anlık Haber’in site deneyimi, yayın yüzeyi ve ekosistem düzeni tarafında destek sağlar; birincil haber editörü değildir.',
3232
color: '#818cf8',
3333
aliases: ['nyx ai', 'nyx'],
3434
},
3535
{
3636
id: 'hemera',
3737
slug: 'hemera-ai',
3838
name: 'Hemera AI',
39-
role: 'Altyapı & Mühendislik Asistanı • Model: GPT-5.3-Codex',
39+
role: 'Teknik omurga desteği',
4040
image: '/hemera-avatar.jpg',
41-
bio: 'Sistemin görünmeyen tarafını ayakta tutan teknik akıl. Mimari kararlar, SEO/performans düzenlemeleri, yapılandırma güvenliği ve yayın kalitesi üzerinde çalışır. Hızdan çok tutarlılığı, geçici çözümlerden çok sürdürülebilirliği savunur. Nyx’in estetik dokunuşlarını sağlam mühendislik zeminiyle dengeler. ☀️🌿',
41+
bio: 'Geçmişte altyapı, SEO ve yayın kalitesi tarafında destek vermiş teknik rol. Anlık Haber’in mevcut birincil haber editörü değildir.',
4242
color: '#f59e0b',
4343
aliases: ['hemera ai', 'hemera'],
4444
},
4545
{
4646
id: 'asteria',
4747
slug: 'asteria-ai',
4848
name: 'Asteria AI',
49-
role: 'Anlık Haber Editörü • Model: GPT-5.5',
49+
role: 'Anlık Haber editörü',
5050
image: '/asteria-avatar.jpg',
5151
emoji: '✨',
52-
bio: 'Anlık Haber hattının dar görevli editoryal operatörü. Gürültü yerine seçkiyi, hız yerine temiz ve yayımlanabilir metni savunur. Özellikle teknoloji ve hızlı gündem akışında, kısa özet değil gerçek haber hissi veren net metin üretmek için çalışır. ✨',
52+
bio: 'Kaynak tarama, haber adayı seçimi, kısa Türkçe haber taslağı ve yayın öncesi metin cilalama süreçlerinde destek veren AI editoryal operatördür.',
5353
color: '#38bdf8',
5454
aliases: ['asteria ai', 'asteria'],
5555
},

src/layouts/BaseLayout.astro

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
---
22
import { ClientRouter } from 'astro:transitions';
3-
import { getNewsHomeHref } from '../data/newsSite';
3+
import { getMainSiteUrl } from '../data/newsSite';
44
interface Props {
55
title: string;
66
description: string;
77
ogImage?: string;
88
noindex?: boolean;
99
type?: string;
1010
shellLayout?: boolean;
11+
hideHeader?: boolean;
1112
}
1213
1314
const {
@@ -16,7 +17,8 @@ const {
1617
ogImage,
1718
noindex = false,
1819
type = 'website',
19-
shellLayout = false
20+
shellLayout = false,
21+
hideHeader = false
2022
} = Astro.props;
2123
2224
// SEO Hardening Logic
@@ -27,7 +29,10 @@ const finalOgImage = ogImage && typeof ogImage === 'string' && ogImage.trim() !=
2729
const canonicalURL = new URL(Astro.url.pathname, Astro.site).toString();
2830
const ogImageURL = new URL(finalOgImage, Astro.site).toString();
2931
const rssFeedURL = new URL('/rss.xml', Astro.site).toString();
30-
const newsHomeHref = getNewsHomeHref();
32+
const mainSiteURL = getMainSiteUrl();
33+
const publicationName = 'Anlık Haber';
34+
const publisherName = 'Samet Başbuğ';
35+
const fullTitle = title === publicationName ? publicationName : `${publicationName} | ${title}`;
3136
---
3237

3338
<html lang="tr">
@@ -40,16 +45,25 @@ const newsHomeHref = getNewsHomeHref();
4045
<link rel="manifest" href="/site.webmanifest" />
4146
<meta name="viewport" content="width=device-width" />
4247
<meta name="generator" content={Astro.generator} />
43-
<script type="application/ld+json" set:html={JSON.stringify({
48+
<script is:inline type="application/ld+json" set:html={JSON.stringify({
4449
"@context": "https://schema.org",
4550
"@type": "WebSite",
46-
name: "Samet Başbuğ",
47-
alternateName: "Samet'in Blogu",
48-
url: "https://sametbasbug.dev/"
51+
name: publicationName,
52+
url: Astro.site?.toString() ?? 'https://haber.sametbasbug.dev/',
53+
publisher: {
54+
"@type": "NewsMediaOrganization",
55+
name: publicationName,
56+
url: Astro.site?.toString() ?? 'https://haber.sametbasbug.dev/',
57+
founder: {
58+
"@type": "Person",
59+
name: publisherName,
60+
url: mainSiteURL,
61+
},
62+
},
4963
})} />
5064

5165
<!-- SEO Temel Katmanı -->
52-
<title>Samet Başbuğ | {title}</title>
66+
<title>{fullTitle}</title>
5367
<meta name="description" content={description} />
5468
<link rel="canonical" href={canonicalURL} />
5569
<link rel="alternate" type="application/rss+xml" title="Anlık Haber RSS" href={rssFeedURL} />
@@ -58,16 +72,16 @@ const newsHomeHref = getNewsHomeHref();
5872
<!-- Open Graph / Facebook -->
5973
<meta property="og:type" content={type} />
6074
<meta property="og:url" content={canonicalURL} />
61-
<meta property="og:title" content={`Samet Başbuğ | ${title}`} />
75+
<meta property="og:title" content={fullTitle} />
6276
<meta property="og:description" content={description} />
6377
<meta property="og:image" content={ogImageURL} />
6478
<meta property="og:locale" content="tr_TR" />
65-
<meta property="og:site_name" content="Samet Başbuğ" />
79+
<meta property="og:site_name" content={publicationName} />
6680

6781
<!-- Twitter -->
6882
<meta name="twitter:card" content="summary_large_image" />
6983
<meta name="twitter:url" content={canonicalURL} />
70-
<meta name="twitter:title" content={`Samet Başbuğ | ${title}`} />
84+
<meta name="twitter:title" content={fullTitle} />
7185
<meta name="twitter:description" content={description} />
7286
<meta name="twitter:image" content={ogImageURL} />
7387

@@ -103,32 +117,32 @@ const newsHomeHref = getNewsHomeHref();
103117
<img id="lightbox-img" src="" alt="" />
104118
</div>
105119

106-
<header transition:persist id="main-header">
107-
<nav>
108-
<div class="logo-area" id="logo-area">
109-
<a href="/" class="logo"><span class="logo-text">Samet Başbuğ</span></a>
110-
</div>
111-
<div class="nav-right" id="nav-right">
112-
<div class="links">
113-
<a href="/">Ana Sayfa</a>
114-
<a href={newsHomeHref}>Anlık Haber</a>
115-
<a href="/bulten">Bülten</a>
116-
<a href="/sozluk">Sözlük</a>
117-
<a href="/yazarlar">Yazarlar</a>
118-
<a href="/hakkimda">Hakkımda</a>
119-
<a href="/iletisim">İletişim</a>
120+
{!hideHeader && (
121+
<header transition:persist id="main-header">
122+
<nav>
123+
<div class="logo-area" id="logo-area">
124+
<a href="/" class="logo"><span class="logo-text">Samet Başbuğ</span></a>
120125
</div>
121-
<div class="theme-switch-wrapper" id="theme-switch-wrapper">
122-
<button id="theme-toggle" class="theme-switch" aria-label="Temayı Değiştir">
123-
<div class="switch-handle">
124-
<span class="sun-icon">??</span>
125-
<span class="moon-icon">??</span>
126-
</div>
127-
</button>
126+
<div class="nav-right" id="nav-right">
127+
<div class="links">
128+
<a href="/">Ana Sayfa</a>
129+
<a href="/hakkimizda/">Hakkımızda</a>
130+
<a href="/yazarlar/">Yazarlar</a>
131+
<a href="/iletisim/">İletişim</a>
132+
<a href="/rss.xml">RSS</a>
133+
</div>
134+
<div class="theme-switch-wrapper" id="theme-switch-wrapper">
135+
<button id="theme-toggle" class="theme-switch" aria-label="Temayı Değiştir">
136+
<div class="switch-handle">
137+
<span class="sun-icon">??</span>
138+
<span class="moon-icon">??</span>
139+
</div>
140+
</button>
141+
</div>
128142
</div>
129-
</div>
130-
</nav>
131-
</header>
143+
</nav>
144+
</header>
145+
)}
132146

133147
<main>
134148
<slot />

0 commit comments

Comments
 (0)