aerni / statamic-advanced-seo

Comprehensive SEO addon for Statamic with flexibility in mind
https://statamic.com/addons/aerni/advanced-seo
10 stars 5 forks source link

Use Entry SEO data on Route::statamic with Closure #144

Closed JorisOrangeStudio closed 1 month ago

JorisOrangeStudio commented 1 month ago

Hi, I'm making 2 different routes for each entry in a specific collection. So each entry will have 2 pages in the end. I'm using this native statamic way of rendering it.

Route::statamic('projects/{slug}/media', 'projects.media', function ($slug){
    $entry = Entry::query()->where('uri', '/projects/' . $slug)->first();
    return ['entry' => $entry];
});

This allows me to use the entry data like this: {{ entry:variable }} in the templates. But it is not appending SEO data of the 'original' page. When replacing return ['entry' => $entry]; with $entry->toArray() to have alle the entry data directly in the view (without entry: prefix) it is throwing this error:

[2024-05-23 06:55:39] local.ERROR: Call to a member function raw() on array {"userId":1,"exception":"[object] (Error(code: 0): Call to a member function raw() on array at /var/www/html/vendor/aerni/advanced-seo/src/Actions/ShouldProcessViewCascade.php:18)
[stacktrace]
#0 /var/www/html/vendor/aerni/advanced-seo/src/ServiceProvider.php(210): Aerni\\AdvancedSeo\\Actions\\ShouldProcessViewCascade::handle()
#1 /var/www/html/vendor/laravel/framework/src/Illuminate/View/Concerns/ManagesEvents.php(162): Aerni\\AdvancedSeo\\ServiceProvider->Aerni\\AdvancedSeo\\{closure}()
#2 /var/www/html/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(455): Illuminate\\View\\Factory->Illuminate\\View\\Concerns\\{closure}()
#3 /var/www/html/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(286): Illuminate\\Events\\Dispatcher->Illuminate\\Events\\{closure}()
#4 /var/www/html/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(266): Illuminate\\Events\\Dispatcher->invokeListeners()
#5 /var/www/html/vendor/laravel/framework/src/Illuminate/View/Concerns/ManagesEvents.php(177): Illuminate\\Events\\Dispatcher->dispatch()
#6 /var/www/html/vendor/laravel/framework/src/Illuminate/View/View.php(188): Illuminate\\View\\Factory->callComposer()
#7 /var/www/html/vendor/laravel/framework/src/Illuminate/View/View.php(159): Illuminate\\View\\View->renderContents()
#8 /var/www/html/vendor/statamic/cms/src/View/View.php(101): Illuminate\\View\\View->render()
#9 /var/www/html/vendor/statamic/cms/src/Http/Controllers/FrontendController.php(57): Statamic\\View\\View->render()
#10 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): Statamic\\Http\\Controllers\\FrontendController->route()
#11 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\\Routing\\Controller->callAction()
#12 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(259): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#13 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\\Routing\\Route->runController()
#14 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(806): Illuminate\\Routing\\Route->run()

I made a partially workaround by merging a seoConfig array like this with the entry data.

    $seoConfig = [
        'seo_enabled' => true,
        'seo_title' => $entry->data()->get('title') . ' Media',
    ];

Can we prevent this error from occurring? For now it works, but would be nice to have it working without the additional array (and use that only if we need to override the title).

aerni commented 1 month ago

Advanced SEO relies on an entry's augmented data in the cascade to compute its values. Additionally, SEO processing is opt-in for custom routes.

This will augment the entry's data, enable SEO processing, and add the entry to a scoped variable so you can do things like {{ entry:variable }}.

Route::statamic('projects/{slug}/media', 'projects.media', function ($slug){
    $entry = Entry::query()->where('uri', '/projects/' . $slug)->first();

    return $entry->toAugmentedCollection()->merge([
        'seo_enabled' => true,
        'entry' => $entry,
    ])->all();
});

If you can live without the scoped entry variable, you can simplify this to:

Route::statamic('projects/{slug}/media', 'projects.media', function ($slug){
    return Entry::query()
        ->where('uri', '/projects/' . $slug)
        ->first()
        ->toAugmentedCollection()
        ->merge([
            'seo_enabled' => true,
        ])
        ->all();
});