rompetomp / inertia-bundle

Inertia.js server-side adapter for Symfony
MIT License
152 stars 39 forks source link

View data implementation #7

Closed innocenzi closed 5 years ago

innocenzi commented 5 years ago

Hi again, I ran into a case where I could use some view data only for Twig, without passing it to the front-end.

https://github.com/rompetomp/inertia-bundle/blob/1d25664b5e33dc66e1622e48aa0a1faa9e447afa/Service/Inertia.php#L70

Maybe just allowing a third argument, $viewData, would be enough? Then you would just add it to the compact method on the render.

$response->setContent($this->engine->render($this->rootView, compact('page', 'viewData')));

This way, the page variable will still be accessible to the Twig extension without any change, and we could use some other data for Twig.

It wouldn't cover all cases though. We could allow to do the same as shared data: allow adding view data in an event subscriber, and then merge the render method's viewData argument with the sharedViewData.

$viewData = array_merge($this->sharedViewData, $viewData);
$response->setContent($this->engine->render($this->rootView, compact('page', 'viewData')));
rompetomp commented 5 years ago

Can you show me a usecase for this? Using Inertia should replace the need to use Twig, so I'm having a hard time figuring out why you would need this.

innocenzi commented 5 years ago

I need to set meta data.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="description" content="{{ view.description }}">
        <link rel="shortcut icon" type="image/png" sizes="192x192"  href="{{ asset('build/resources/favicons/' ~ view.favicon ~ '-192x192.png') }}">
        <link rel="shortcut icon" type="image/png" sizes="32x32" href="{{ asset('build/resources/favicons/' ~ view.favicon ~ '-32x32.png') }}">
        <link rel="shortcut icon" type="image/png" sizes="96x96" href="{{ asset('build/resources/favicons/' ~ view.favicon ~ '-96x96.png') }}">
        <link rel="shortcut icon" type="image/png" sizes="16x16" href="{{ asset('build/resources/favicons/' ~ view.favicon ~ '-16x16.png') }}">
        <title>{{ view.defaultTitle }}</title>

        {{ encore_entry_link_tags('app') }}
    </head>
    <body>
        {{ inertia(page) }}
        {{ encore_entry_script_tags('app') }}
    </body>
</html>

I don't want to pollute my Vue instance with useless variables which I only need Twig to use. In this case, it would be the solution to page-specific default title, description and favicons for clients without Javascript enabled.

EDIT - Also, you're probably aware of this, but the Laravel adapter has an implementation for this: https://github.com/inertiajs/inertia-laravel#accessing-data-in-root-template

rompetomp commented 5 years ago

Okay. Can you make a pull request for this?

rompetomp commented 5 years ago

Thanks @hawezo. I'll update the README later.

rompetomp commented 5 years ago

I updated the README, and renamed the method setViewData to viewData, so it's more in line with share. I also renamed the $view variable to $viewData. I'll also tag a release now.

innocenzi commented 5 years ago

That's fine with me. I chose this name because it was more descriptive. I also hesitated to rename share and getShared because with the viewData addition, it wasn't explicit about what was shared, but I didn't want to mess with your naming habits.

Anyway, thanks for your work!