diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php index a23b609..d82eb8a 100644 --- a/app/Http/Controllers/PageController.php +++ b/app/Http/Controllers/PageController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers; use App\Models\Page; use App\Models\Setting; +use App\Services\TemplateService; use Illuminate\Http\Request; class PageController extends Controller @@ -13,22 +14,15 @@ class PageController extends Controller */ public function index() { - // 1) is_homepage işaretli ve published - $page = Page::where('is_homepage', true) + // 1) is_homepage işaretli ve published (en son güncellenen) + $page = Page::with(['headerTemplate', 'footerTemplate']) + ->where('is_homepage', true) ->where('status', 'published') + ->latest('updated_at') ->first(); + - // 2) yoksa 'home' slug'ı - if (!$page) { - $page = Page::where('slug', 'home') - ->where('status', 'published') - ->first(); - } - - // 3) yoksa ilk published sayfa (fallback) - if (!$page) { - $page = Page::where('status', 'published')->orderByDesc('published_at')->first(); - } + $settings = class_exists(Setting::class) ? (Setting::query()->first()) : null; @@ -53,18 +47,48 @@ class PageController extends Controller ? ($page->translate('meta_description') ?: ($page->excerpt ?? null)) : ($page->meta_description ?? $page->excerpt ?? null); + // Section verisini al - Hem eski hem yeni sistemi destekle $sections = $page->sections ?? $page->data ?? []; - $template = ($page->slug === 'home' || ($page->is_homepage ?? false)) - ? 'home' - : ($page->template ?? null); - $view = $template && view()->exists("templates.$template") + + // Yeni dinamik template sistemi için sections_data varsa onu da al + $templatedSections = $page->templated_sections ?? collect([]); + + // Template belirleme mantığı: + // 1. Kullanıcı template seçmişse, onu kullan + // 2. Template seçilmemişse ve homepage ise, 'home' kullan + // 3. Hiçbiri yoksa, 'generic' kullan + $template = $page->template + ?? (($page->slug === 'home' || ($page->is_homepage ?? false)) ? 'home' : 'generic'); + + $view = view()->exists("templates.$template") ? "templates.$template" - : (($page->slug === 'home' || ($page->is_homepage ?? false)) ? 'templates.home' : 'templates.generic'); + : 'templates.generic'; + + // Render Header Template + $renderedHeader = null; + if ($page->headerTemplate) { + $renderedHeader = TemplateService::replacePlaceholders( + $page->headerTemplate->html_content, + $page->header_data ?? [] + ); + } + + // Render Footer Template + $renderedFooter = null; + if ($page->footerTemplate) { + $renderedFooter = TemplateService::replacePlaceholders( + $page->footerTemplate->html_content, + $page->footer_data ?? [] + ); + } return view($view, [ 'page' => $page, 'settings' => $settings, 'sections' => $sections, + 'templatedSections' => $templatedSections, + 'renderedHeader' => $renderedHeader, + 'renderedFooter' => $renderedFooter, 'meta' => [ 'title' => $metaTitle ?: ($settings->default_meta_title ?? config('app.name')), 'description' => $metaDescription ?: ($settings->default_meta_description ?? null), @@ -76,9 +100,10 @@ class PageController extends Controller /** * Display a specific page by slug */ - public function show($slug) +public function show($slug) { - $page = Page::where('slug', $slug) + $page = Page::with(['headerTemplate', 'footerTemplate']) + ->where('slug', $slug) ->where('status', 'published') ->firstOrFail(); @@ -94,15 +119,46 @@ class PageController extends Controller // Use parsed_sections for easier template usage (key-value format) $sections = $page->parsed_sections ?? $page->sections ?? $page->data ?? []; - $template = ($slug === 'home' || ($page->is_homepage ?? false)) - ? 'home' - : ($page->template ?? 'generic'); - $view = view()->exists("templates.$template") ? "templates.$template" : (($slug === 'home') ? 'templates.home' : 'templates.generic'); + + // Yeni dinamik template sistemi için sections_data varsa onu da al + $templatedSections = $page->templated_sections ?? collect([]); + + // Template belirleme mantığı: + // 1. Kullanıcı template seçmişse, onu kullan + // 2. Template seçilmemişse ve homepage ise, 'home' kullan + // 3. Hiçbiri yoksa, 'generic' kullan + $template = $page->template + ?? (($slug === 'home' || ($page->is_homepage ?? false)) ? 'home' : 'generic'); + + $view = view()->exists("templates.$template") + ? "templates.$template" + : 'templates.generic'; + + // Render Header Template + $renderedHeader = null; + if ($page->headerTemplate) { + $renderedHeader = TemplateService::replacePlaceholders( + $page->headerTemplate->html_content, + $page->header_data ?? [] + ); + } + + // Render Footer Template + $renderedFooter = null; + if ($page->footerTemplate) { + $renderedFooter = TemplateService::replacePlaceholders( + $page->footerTemplate->html_content, + $page->footer_data ?? [] + ); + } return view($view, [ 'page' => $page, 'settings' => $settings, 'sections' => $sections, + 'templatedSections' => $templatedSections, + 'renderedHeader' => $renderedHeader, + 'renderedFooter' => $renderedFooter, 'meta' => [ 'title' => $metaTitle ?: ($settings->default_meta_title ?? config('app.name')), 'description' => $metaDescription ?: ($settings->default_meta_description ?? null), diff --git a/app/Models/Page.php b/app/Models/Page.php index e8a70f6..e77e962 100644 --- a/app/Models/Page.php +++ b/app/Models/Page.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Models\SectionTemplate; use App\Traits\HasTranslations; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; diff --git a/app/Observers/PageObserver.php b/app/Observers/PageObserver.php new file mode 100644 index 0000000..6faa559 --- /dev/null +++ b/app/Observers/PageObserver.php @@ -0,0 +1,26 @@ +is_homepage) { + // Diğer tüm sayfaların homepage işaretini kaldır + Page::where('id', '!=', $page->id) + ->where('is_homepage', true) + ->update(['is_homepage' => false]); + } + } +} + diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 452e6b6..ec8ef22 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,8 @@ namespace App\Providers; +use App\Models\Page; +use App\Observers\PageObserver; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -19,6 +21,7 @@ class AppServiceProvider extends ServiceProvider */ public function boot(): void { - // + // Page model için observer kaydet + Page::observe(PageObserver::class); } } diff --git a/app/Services/TemplateService.php b/app/Services/TemplateService.php index ed32457..7747426 100644 --- a/app/Services/TemplateService.php +++ b/app/Services/TemplateService.php @@ -239,18 +239,58 @@ class TemplateService /** * Replace placeholders in HTML with actual data + * Supports both {text.title} and {{text.title}} formats */ public static function replacePlaceholders(string $html, array $data): string { - foreach ($data as $placeholder => $value) { + // First, parse all placeholders in the format {type.field_name} + preg_match_all('/\{([a-z]+\.[a-z_]+)\}/i', $html, $matches); + $placeholders = array_unique($matches[1] ?? []); + + // Replace each placeholder + foreach ($placeholders as $placeholder) { + // Try to find the value in data with various key formats + $value = null; + + // 1. Try exact match (text.title) + if (isset($data[$placeholder])) { + $value = $data[$placeholder]; + } + // 2. Try with section_data prefix (section_data.text.title) + elseif (isset($data["section_data.{$placeholder}"])) { + $value = $data["section_data.{$placeholder}"]; + } + // 3. Try nested array access (data['section_data']['text.title'] or data['text']['title']) + else { + $parts = explode('.', $placeholder); + if (count($parts) === 2) { + [$type, $field] = $parts; + // Try nested: data['section_data'][$type][$field] + if (isset($data['section_data'][$type][$field])) { + $value = $data['section_data'][$type][$field]; + } + // Try nested: data[$type][$field] + elseif (isset($data[$type][$field])) { + $value = $data[$type][$field]; + } + } + } + // Handle different value types if (is_array($value)) { $value = implode(', ', $value); } elseif (is_bool($value)) { $value = $value ? 'true' : 'false'; + } elseif ($value === null) { + $value = ''; } - $html = str_replace("{{$placeholder}}", $value ?? '', $html); + // Replace both {text.title} and {{text.title}} formats + $html = str_replace( + ["{{$placeholder}}", "{{{$placeholder}}}"], + [$value, $value], + $html + ); } return $html; diff --git a/resources/views/layouts/site.blade.php b/resources/views/layouts/site.blade.php index 724274e..f0d7ec7 100644 --- a/resources/views/layouts/site.blade.php +++ b/resources/views/layouts/site.blade.php @@ -9,9 +9,22 @@
- @include('partials.navbar') + {{-- Dynamic Header Template or Static Navbar --}} + @if(isset($renderedHeader) && $renderedHeader) + {!! $renderedHeader !!} + @else + @include('partials.navbar') + @endif + + {{-- Main Content --}} @yield('content') - @include('partials.footer') + + {{-- Dynamic Footer Template or Static Footer --}} + @if(isset($renderedFooter) && $renderedFooter) + {!! $renderedFooter !!} + @else + @include('partials.footer') + @endif {{-- İsteğe bağlı: tema JS dosyalarınız varsa buraya ekleyin --}} {{-- --}} diff --git a/resources/views/templates/generic.blade.php b/resources/views/templates/generic.blade.php index 894480b..7e2b762 100644 --- a/resources/views/templates/generic.blade.php +++ b/resources/views/templates/generic.blade.php @@ -1,8 +1,27 @@ @extends('layouts.site') @section('content') - @php $blocks = $sections ?? []; @endphp - @if(is_array($blocks) && !empty($blocks)) + @php + // Yeni dinamik template sistemi - Öncelik verilir + $hasTemplatedSections = isset($templatedSections) && $templatedSections->isNotEmpty(); + + // Eski section builder sistemi + $blocks = $sections ?? []; + $hasBlocks = is_array($blocks) && !empty($blocks); + @endphp + + @if($hasTemplatedSections) + {{-- Yeni dinamik template sisteminden gelen sections --}} + @foreach($templatedSections as $section) + @if($section['template'] ?? null) + {!! \App\Services\TemplateService::replacePlaceholders( + $section['template']->html_content, + $section['data'] ?? [] + ) !!} + @endif + @endforeach + @elseif($hasBlocks) + {{-- Eski blok bazlı dinamik render --}} @foreach($blocks as $block) @php $type = $block['type'] ?? null; @endphp @if($type && view()->exists("components.blocks.$type")) diff --git a/resources/views/templates/home.blade.php b/resources/views/templates/home.blade.php index 93e9d8b..a88e1d7 100644 --- a/resources/views/templates/home.blade.php +++ b/resources/views/templates/home.blade.php @@ -2,13 +2,26 @@ @section('content') @php - // sections varsa blok bazlı render, yoksa index.html fallback + // Yeni dinamik template sistemi - Öncelik verilir + $hasTemplatedSections = isset($templatedSections) && $templatedSections->isNotEmpty(); + + // Eski section builder sistemi $blocks = $sections ?? []; $hasBlocks = is_array($blocks) && count($blocks) > 0; @endphp - @if($hasBlocks) - {{-- Blok bazlı dinamik render --}} + @if($hasTemplatedSections) + {{-- Yeni dinamik template sisteminden gelen sections --}} + @foreach($templatedSections as $section) + @if($section['template'] ?? null) + {!! \App\Services\TemplateService::replacePlaceholders( + $section['template']->html_content, + $section['data'] ?? [] + ) !!} + @endif + @endforeach + @elseif($hasBlocks) + {{-- Eski blok bazlı dinamik render --}} @foreach($blocks as $block) @php $type = $block['type'] ?? null; @endphp @if($type && view()->exists("components.blocks.$type")) diff --git a/routes/web.php b/routes/web.php index 3799deb..81d1cb8 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,11 +3,62 @@ use Illuminate\Support\Facades\Route; use App\Http\Controllers\PageController; use App\Http\Controllers\BlogController; +use App\Models\Page; -// Home -> admin'de işaretli anasayfayı (veya 'home' slug'ını) göster -Route::get('/', [PageController::class, 'index'])->name('home'); -Route::get('/{slug}', [PageController::class, 'show'])->name('page.show'); +// Debug Route - Veritabanı kontrolü +Route::get('/debug-homepage', function () { + $page = Page::with(['headerTemplate', 'footerTemplate']) + ->where('is_homepage', true) + ->where('status', 'published') + ->latest('updated_at') + ->first(); + + if (!$page) { + return response()->json([ + 'error' => 'Homepage bulunamadı!', + 'all_pages' => Page::select('id', 'title', 'slug', 'is_homepage', 'status')->get(), + ]); + } + + return response()->json([ + 'page' => [ + 'id' => $page->id, + 'title' => $page->title, + 'slug' => $page->slug, + 'is_homepage' => $page->is_homepage, + 'status' => $page->status, + ], + 'header_template' => [ + 'id' => $page->header_template_id, + 'exists' => $page->headerTemplate ? true : false, + 'title' => $page->headerTemplate?->title, + 'data_filled' => !empty($page->header_data), + 'data' => $page->header_data, + ], + 'footer_template' => [ + 'id' => $page->footer_template_id, + 'exists' => $page->footerTemplate ? true : false, + 'title' => $page->footerTemplate?->title, + 'data_filled' => !empty($page->footer_data), + 'data' => $page->footer_data, + ], + 'sections' => [ + 'count' => is_array($page->sections) ? count($page->sections) : 0, + 'data' => $page->sections, + ], + 'sections_data' => [ + 'count' => is_array($page->sections_data) ? count($page->sections_data) : 0, + 'data' => $page->sections_data, + ], + ]); +}); + +// Homepage -> admin panelinde "is_homepage" olarak işaretli sayfa dinamik olarak gösterilir +Route::get('/', [PageController::class, 'index'])->name('homepage'); // Blog Route::get('/blog', [BlogController::class, 'index'])->name('blog.index'); Route::get('/blog/{slug}', [BlogController::class, 'show'])->name('blog.show'); + +// Pages (en sonda olmalı - catch-all) +Route::get('/{slug}', [PageController::class, 'show'])->name('page.show');