feat: add Schema.org structured data to blog index and post pages
This commit is contained in:
@@ -217,6 +217,173 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@push('structured-data')
|
||||||
|
@php
|
||||||
|
$siteName = setting('site_name', 'Trunçgil Teknoloji');
|
||||||
|
$siteLogo = setting('site_logo') ? (str_starts_with(setting('site_logo'), 'http') ? setting('site_logo') : asset('storage/' . ltrim(setting('site_logo'), '/'))) : asset('assets/img/logo.png');
|
||||||
|
$sitePhone = setting('contact_phone', '+902244431620');
|
||||||
|
$siteEmail = setting('contact_email', 'info@truncgil.com');
|
||||||
|
$siteAddress = setting('contact_address', 'Gaziantep Teknopark, Şahinbey, Gaziantep');
|
||||||
|
|
||||||
|
$socialLinksRaw = setting('social_links');
|
||||||
|
$socialLinks = [];
|
||||||
|
if ($socialLinksRaw) {
|
||||||
|
$decoded = json_decode($socialLinksRaw, true);
|
||||||
|
if (is_array($decoded)) {
|
||||||
|
$socialLinks = array_values(array_filter($decoded));
|
||||||
|
} elseif (is_string($socialLinksRaw)) {
|
||||||
|
$socialLinks = [$socialLinksRaw];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($socialLinks)) {
|
||||||
|
$socialLinks = [
|
||||||
|
'https://twitter.com/truncgil',
|
||||||
|
'https://facebook.com/truncgil',
|
||||||
|
'https://instagram.com/truncgil',
|
||||||
|
'https://youtube.com/truncgil',
|
||||||
|
'https://linkedin.com/company/truncgil'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Organization & LocalBusiness combined
|
||||||
|
$publisherData = [
|
||||||
|
"@context" => "https://schema.org",
|
||||||
|
"@type" => "ProfessionalService",
|
||||||
|
"@id" => url('/') . "#organization",
|
||||||
|
"name" => $siteName,
|
||||||
|
"url" => url('/'),
|
||||||
|
"logo" => [
|
||||||
|
"@type" => "ImageObject",
|
||||||
|
"url" => $siteLogo
|
||||||
|
],
|
||||||
|
"image" => $siteLogo,
|
||||||
|
"telephone" => $sitePhone,
|
||||||
|
"email" => $siteEmail,
|
||||||
|
"address" => [
|
||||||
|
"@type" => "PostalAddress",
|
||||||
|
"streetAddress" => $siteAddress,
|
||||||
|
"addressLocality" => "Şahinbey",
|
||||||
|
"addressRegion" => "Gaziantep",
|
||||||
|
"postalCode" => "27010",
|
||||||
|
"addressCountry" => "TR"
|
||||||
|
],
|
||||||
|
"geo" => [
|
||||||
|
"@type" => "GeoCoordinates",
|
||||||
|
"latitude" => 37.0274446,
|
||||||
|
"longitude" => 37.3074315
|
||||||
|
],
|
||||||
|
"hasMap" => "https://maps.google.com/?q=37.0274446,37.3074315",
|
||||||
|
"sameAs" => $socialLinks,
|
||||||
|
"areaServed" => [
|
||||||
|
["@type" => "Country", "name" => "TR"],
|
||||||
|
["@type" => "Country", "name" => "DE"],
|
||||||
|
["@type" => "Country", "name" => "RU"],
|
||||||
|
["@type" => "Country", "name" => "US"],
|
||||||
|
["@type" => "AdministrativeArea", "name" => "Gaziantep"],
|
||||||
|
["@type" => "AdministrativeArea", "name" => "Bursa"]
|
||||||
|
],
|
||||||
|
"priceRange" => "$$"
|
||||||
|
];
|
||||||
|
|
||||||
|
// 2. Breadcrumbs
|
||||||
|
$activeCategorySlug = request()->query('category');
|
||||||
|
$activeCategory = null;
|
||||||
|
if ($activeCategorySlug && isset($sidebarCategories)) {
|
||||||
|
$activeCategory = $sidebarCategories->firstWhere('slug', $activeCategorySlug);
|
||||||
|
}
|
||||||
|
if (!$activeCategory && $activeCategorySlug && isset($highlightCategories)) {
|
||||||
|
$activeCategory = $highlightCategories->firstWhere('slug', $activeCategorySlug);
|
||||||
|
}
|
||||||
|
$activeCategoryName = $activeCategory ? $activeCategory->name : null;
|
||||||
|
|
||||||
|
$breadcrumbList = [
|
||||||
|
[
|
||||||
|
"@type" => "ListItem",
|
||||||
|
"position" => 1,
|
||||||
|
"name" => "Anasayfa",
|
||||||
|
"item" => url('/')
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"@type" => "ListItem",
|
||||||
|
"position" => 2,
|
||||||
|
"name" => "Blog",
|
||||||
|
"item" => route('blog.index')
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($activeCategorySlug && $activeCategoryName) {
|
||||||
|
$breadcrumbList[] = [
|
||||||
|
"@type" => "ListItem",
|
||||||
|
"position" => 3,
|
||||||
|
"name" => $activeCategoryName,
|
||||||
|
"item" => route('blog.index', ['category' => $activeCategorySlug])
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$breadcrumbs = [
|
||||||
|
"@context" => "https://schema.org",
|
||||||
|
"@type" => "BreadcrumbList",
|
||||||
|
"itemListElement" => $breadcrumbList
|
||||||
|
];
|
||||||
|
|
||||||
|
// 3. Blog List & Posts
|
||||||
|
$blogPostsList = [];
|
||||||
|
if (isset($posts) && count($posts) > 0) {
|
||||||
|
foreach ($posts as $p) {
|
||||||
|
$pTitle = method_exists($p, 'translate') ? $p->translate('title') : $p->title;
|
||||||
|
$pExcerpt = method_exists($p, 'translate') ? $p->translate('excerpt') : ($p->excerpt ?? '');
|
||||||
|
$pContent = method_exists($p, 'translate') ? $p->translate('content') : ($p->content ?? '');
|
||||||
|
$pExcerptText = trim(strip_tags($pExcerpt));
|
||||||
|
if (empty($pExcerptText)) {
|
||||||
|
$pExcerptText = \Illuminate\Support\Str::limit(trim(strip_tags($pContent)), 160);
|
||||||
|
}
|
||||||
|
$pUrl = route('blog.show', $p->slug);
|
||||||
|
$pImageUrl = $p->featured_image ? asset('storage/' . $p->featured_image) : ($p->featured_image_url ?? asset('assets/img/photos/tb10.jpg'));
|
||||||
|
|
||||||
|
$blogPostsList[] = [
|
||||||
|
"@type" => "BlogPosting",
|
||||||
|
"headline" => $pTitle,
|
||||||
|
"description" => $pExcerptText,
|
||||||
|
"image" => $pImageUrl,
|
||||||
|
"url" => $pUrl,
|
||||||
|
"datePublished" => $p->published_at ? $p->published_at->toIso8601String() : $p->created_at->toIso8601String(),
|
||||||
|
"author" => [
|
||||||
|
"@type" => "Person",
|
||||||
|
"name" => $p->author ? $p->author->name : 'Trunçgil'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$blogSchema = [
|
||||||
|
"@context" => "https://schema.org",
|
||||||
|
"@type" => "Blog",
|
||||||
|
"@id" => route('blog.index') . "#blog",
|
||||||
|
"name" => $siteName . " Blog",
|
||||||
|
"description" => "Merhaba! Biz Trunçgil. Blogumuza hoş geldiniz. Burada web tasarım, yazılım geliştirme ve teknolojik yeniliklere dair ipuçlarını ve deneyimlerimizi paylaşıyoruz.",
|
||||||
|
"url" => route('blog.index'),
|
||||||
|
"publisher" => [
|
||||||
|
"@type" => "Organization",
|
||||||
|
"name" => $siteName,
|
||||||
|
"logo" => [
|
||||||
|
"@type" => "ImageObject",
|
||||||
|
"url" => $siteLogo
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"blogPost" => $blogPostsList
|
||||||
|
];
|
||||||
|
@endphp
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{!! json_encode($publisherData, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) !!}
|
||||||
|
</script>
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{!! json_encode($breadcrumbs, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) !!}
|
||||||
|
</script>
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{!! json_encode($blogSchema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) !!}
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
|
|
||||||
@push('styles')
|
@push('styles')
|
||||||
<style>
|
<style>
|
||||||
/* Ensure uniform layout and clamping for title and excerpt */
|
/* Ensure uniform layout and clamping for title and excerpt */
|
||||||
|
|||||||
@@ -165,6 +165,171 @@
|
|||||||
</section>
|
</section>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
@push('structured-data')
|
||||||
|
@php
|
||||||
|
$postTitle = method_exists($post, 'translate') ? $post->translate('title') : $post->title;
|
||||||
|
$postExcerpt = method_exists($post, 'translate') ? $post->translate('excerpt') : ($post->excerpt ?? '');
|
||||||
|
$postContent = method_exists($post, 'translate') ? $post->translate('content') : ($post->content ?? '');
|
||||||
|
$postExcerptText = trim(strip_tags($postExcerpt));
|
||||||
|
if (empty($postExcerptText)) {
|
||||||
|
$postExcerptText = \Illuminate\Support\Str::limit(trim(strip_tags($postContent)), 160);
|
||||||
|
}
|
||||||
|
|
||||||
|
$postUrl = route('blog.show', $post->slug);
|
||||||
|
$imageUrl = $post->featured_image ? asset('storage/' . $post->featured_image) : ($post->featured_image_url ?? asset('assets/img/photos/tb10.jpg'));
|
||||||
|
|
||||||
|
$publishedDate = $post->published_at ? $post->published_at->toIso8601String() : $post->created_at->toIso8601String();
|
||||||
|
$modifiedDate = $post->updated_at ? $post->updated_at->toIso8601String() : $publishedDate;
|
||||||
|
|
||||||
|
$authorName = $post->author ? $post->author->name : 'Trunçgil';
|
||||||
|
$authorRole = $post->author && $post->author->role ? $post->author->role : 'Trunçgil Teknoloji Editörü';
|
||||||
|
$authorUrl = route('blog.index', ['author' => $post->author_id ?? 1]);
|
||||||
|
|
||||||
|
$siteName = setting('site_name', 'Trunçgil Teknoloji');
|
||||||
|
$siteLogo = setting('site_logo') ? (str_starts_with(setting('site_logo'), 'http') ? setting('site_logo') : asset('storage/' . ltrim(setting('site_logo'), '/'))) : asset('assets/img/logo.png');
|
||||||
|
$sitePhone = setting('contact_phone', '+902244431620');
|
||||||
|
$siteEmail = setting('contact_email', 'info@truncgil.com');
|
||||||
|
$siteAddress = setting('contact_address', 'Gaziantep Teknopark, Şahinbey, Gaziantep');
|
||||||
|
|
||||||
|
$socialLinksRaw = setting('social_links');
|
||||||
|
$socialLinks = [];
|
||||||
|
if ($socialLinksRaw) {
|
||||||
|
$decoded = json_decode($socialLinksRaw, true);
|
||||||
|
if (is_array($decoded)) {
|
||||||
|
$socialLinks = array_values(array_filter($decoded));
|
||||||
|
} elseif (is_string($socialLinksRaw)) {
|
||||||
|
$socialLinks = [$socialLinksRaw];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($socialLinks)) {
|
||||||
|
$socialLinks = [
|
||||||
|
'https://twitter.com/truncgil',
|
||||||
|
'https://facebook.com/truncgil',
|
||||||
|
'https://instagram.com/truncgil',
|
||||||
|
'https://youtube.com/truncgil',
|
||||||
|
'https://linkedin.com/company/truncgil'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Organization & LocalBusiness combined
|
||||||
|
$publisherData = [
|
||||||
|
"@context" => "https://schema.org",
|
||||||
|
"@type" => "ProfessionalService",
|
||||||
|
"@id" => url('/') . "#organization",
|
||||||
|
"name" => $siteName,
|
||||||
|
"url" => url('/'),
|
||||||
|
"logo" => [
|
||||||
|
"@type" => "ImageObject",
|
||||||
|
"url" => $siteLogo
|
||||||
|
],
|
||||||
|
"image" => $siteLogo,
|
||||||
|
"telephone" => $sitePhone,
|
||||||
|
"email" => $siteEmail,
|
||||||
|
"address" => [
|
||||||
|
"@type" => "PostalAddress",
|
||||||
|
"streetAddress" => $siteAddress,
|
||||||
|
"addressLocality" => "Şahinbey",
|
||||||
|
"addressRegion" => "Gaziantep",
|
||||||
|
"postalCode" => "27010",
|
||||||
|
"addressCountry" => "TR"
|
||||||
|
],
|
||||||
|
"geo" => [
|
||||||
|
"@type" => "GeoCoordinates",
|
||||||
|
"latitude" => 37.0274446,
|
||||||
|
"longitude" => 37.3074315
|
||||||
|
],
|
||||||
|
"hasMap" => "https://maps.google.com/?q=37.0274446,37.3074315",
|
||||||
|
"sameAs" => $socialLinks,
|
||||||
|
"areaServed" => [
|
||||||
|
["@type" => "Country", "name" => "TR"],
|
||||||
|
["@type" => "Country", "name" => "DE"],
|
||||||
|
["@type" => "Country", "name" => "RU"],
|
||||||
|
["@type" => "Country", "name" => "US"],
|
||||||
|
["@type" => "AdministrativeArea", "name" => "Gaziantep"],
|
||||||
|
["@type" => "AdministrativeArea", "name" => "Bursa"]
|
||||||
|
],
|
||||||
|
"priceRange" => "$$"
|
||||||
|
];
|
||||||
|
|
||||||
|
// 2. BreadcrumbList
|
||||||
|
$categoryName = $post->category ? $post->category->name : 'Genel';
|
||||||
|
$categorySlug = $post->category ? $post->category->slug : 'genel';
|
||||||
|
$categoryUrl = route('blog.index', ['category' => $categorySlug]);
|
||||||
|
|
||||||
|
$breadcrumbs = [
|
||||||
|
"@context" => "https://schema.org",
|
||||||
|
"@type" => "BreadcrumbList",
|
||||||
|
"itemListElement" => [
|
||||||
|
[
|
||||||
|
"@type" => "ListItem",
|
||||||
|
"position" => 1,
|
||||||
|
"name" => "Anasayfa",
|
||||||
|
"item" => url('/')
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"@type" => "ListItem",
|
||||||
|
"position" => 2,
|
||||||
|
"name" => "Blog",
|
||||||
|
"item" => route('blog.index')
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"@type" => "ListItem",
|
||||||
|
"position" => 3,
|
||||||
|
"name" => $categoryName,
|
||||||
|
"item" => $categoryUrl
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"@type" => "ListItem",
|
||||||
|
"position" => 4,
|
||||||
|
"name" => $postTitle,
|
||||||
|
"item" => $postUrl
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
// 3. BlogPosting
|
||||||
|
$blogPosting = [
|
||||||
|
"@context" => "https://schema.org",
|
||||||
|
"@type" => "BlogPosting",
|
||||||
|
"@id" => $postUrl . "#blogposting",
|
||||||
|
"mainEntityOfPage" => [
|
||||||
|
"@type" => "WebPage",
|
||||||
|
"@id" => $postUrl
|
||||||
|
],
|
||||||
|
"headline" => $postTitle,
|
||||||
|
"description" => $postExcerptText,
|
||||||
|
"image" => $imageUrl,
|
||||||
|
"datePublished" => $publishedDate,
|
||||||
|
"dateModified" => $modifiedDate,
|
||||||
|
"author" => [
|
||||||
|
"@type" => "Person",
|
||||||
|
"name" => $authorName,
|
||||||
|
"jobTitle" => $authorRole,
|
||||||
|
"url" => $authorUrl
|
||||||
|
],
|
||||||
|
"publisher" => [
|
||||||
|
"@type" => "Organization",
|
||||||
|
"name" => $siteName,
|
||||||
|
"logo" => [
|
||||||
|
"@type" => "ImageObject",
|
||||||
|
"url" => $siteLogo
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"articleSection" => $categoryName,
|
||||||
|
"keywords" => is_array($post->tags) ? implode(', ', $post->tags) : ($post->tags ?? '')
|
||||||
|
];
|
||||||
|
@endphp
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{!! json_encode($publisherData, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) !!}
|
||||||
|
</script>
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{!! json_encode($breadcrumbs, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) !!}
|
||||||
|
</script>
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{!! json_encode($blogPosting, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) !!}
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
|
|
||||||
@push('styles')
|
@push('styles')
|
||||||
<!-- CodeMirror Styles -->
|
<!-- CodeMirror Styles -->
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/codemirror.min.css" integrity="sha384-zaeBlB/vwYsDRSlFajnDd7OydJ0cWk+c2OWybl3eSUf6hW2EbhlCsQPqKr3gkznT" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/codemirror.min.css" integrity="sha384-zaeBlB/vwYsDRSlFajnDd7OydJ0cWk+c2OWybl3eSUf6hW2EbhlCsQPqKr3gkznT" crossorigin="anonymous">
|
||||||
|
|||||||
Reference in New Issue
Block a user