Slide 1

Slide 1 text

Symfony UX Turbo

Slide 2

Slide 2 text

Tired Of Modern Web Development?

Slide 3

Slide 3 text

You build your backend that exposes some kind of API.

Slide 4

Slide 4 text

You build your backend that exposes some kind of API. You build a Single-Page Application that consumes your API.

Slide 5

Slide 5 text

You build your backend that exposes some kind of API. You build a Single-Page Application that consumes your API. You make sure the backend doesn't send data the frontend doesn't expect (and vice versa).

Slide 6

Slide 6 text

You build your backend that exposes some kind of API. You build a Single-Page Application that consumes your API. You make sure the backend doesn't send data the frontend doesn't expect (and vice versa). You coordinate releases to make sure neither side causes trouble in production.

Slide 7

Slide 7 text

You build your backend that exposes some kind of API. You build a Single-Page Application that consumes your API. You make sure the backend doesn't send data the frontend doesn't expect (and vice versa). You coordinate releases to make sure neither side causes trouble in production. You fight with Webpack and Babel.

Slide 8

Slide 8 text

You build your backend that exposes some kind of API. You build a Single-Page Application that consumes your API. You make sure the backend doesn't send data the frontend doesn't expect (and vice versa). You coordinate releases to make sure neither side causes trouble in production. You fight with Webpack and Babel. And all you wanted was to give your users that modern web experience !

Slide 9

Slide 9 text

Ever Wish You Could Write a modern application Without Writing JavaScript?

Slide 10

Slide 10 text

Is that even possible?

Slide 11

Slide 11 text

Yes.

Slide 12

Slide 12 text

Thanks for listening! $kernel->terminate($request, $response);

Slide 13

Slide 13 text

Actually, there's a bit more to it...

Slide 14

Slide 14 text

Olá! ! Marco Petersen " Software Developer @ QOSSMIC (fka SensioLabs Germany) # Berlin $ % @ocrampete16

Slide 15

Slide 15 text

Today's Menu • Appetizer: The Back Story - What is Symfony UX Turbo? • Main Course: 3 Building Blocks - Drive, Frames & Streams • Dessert: Turbo In Action: Example Application

Slide 16

Slide 16 text

Appetizer What is Symfony UX Turbo?

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

What is Hotwire? • Turbo: modern applications without writing JavaScript • Stimulus: simple JS framework if you need JavaScript • Strada: web/native app bridge

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

Installation composer require symfony/ux-turbo symfony/ux-turbo-mercure yarn install --force yarn encore dev

Slide 22

Slide 22 text

Main Course Drive, Frames & Streams

Slide 23

Slide 23 text

Turbo Drive navigates to new pages without full page reloads.

Slide 24

Slide 24 text

Turbo Drive 1. User clicks on a link or submits a form. 2. intervenes and stops the default action (visit new page). 3. fetches the page using fetch in the background. 4. Replaces and merges . 5. Updates browser history with history.pushState.

Slide 25

Slide 25 text

Clicking Links Create Room Create Room

Slide 26

Slide 26 text

Handling Forms #[Route('/rooms/create', name: 'create_room')] public function create(Request $request, EntityManagerInterface $entityManager): Response { $room = new Room(); $form = $this->createForm(RoomType::class, $room); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $entityManager->persist($form->getData()); $entityManager->flush(); return $this->redirectToRoute('rooms', [], Response::HTTP_SEE_OTHER); } return $this->renderForm('room/create.html.twig', ['form' => $form]); }

Slide 27

Slide 27 text

Learn more about Turbo Drive at https://turbo.hotwire.dev/ handbook/drive

Slide 28

Slide 28 text

Turbo Frames are independent content blocks.

Slide 29

Slide 29 text

Turbo Frames • quite similar to iframes • lets a part of the page have their own "context" • clicking links & submitting forms inside a frame only replaces the content inside that frame • pages can contain multiple frames

Slide 30

Slide 30 text

Scoping Content and Actions

Rooms

Create Room
    {% for room in rooms %} {{ include('fragments/_room_list_item.html.twig', {room: room}) }} {% endfor %}

Slide 31

Slide 31 text

Create Room

Create New Room

{{ form(form) }}

Slide 32

Slide 32 text

Create Room

Create New Room

{{ form(form) }}

Slide 33

Slide 33 text

{{ form(form) }}

Create New Room

{{ form(form) }}

Slide 34

Slide 34 text

Turbo Frames and ESI • Just like in Rails, Turbo Frames can also lazily load frames on the client-side. • The Symfony integration takes advantage of the already existing ESI features Symfony brings.

Slide 35

Slide 35 text

Lazily Loading a Frame https://symfony.com/doc/current/http_cache/esi.html

Slide 36

Slide 36 text

Turbo Streams stream server-side changes to your users' browsers.

Slide 37

Slide 37 text

Turbo Streams • easily add real-time capabilities to your application • HTML fragments are streamed to the browser • server pushes changes to connected users using a real-time protocol (like Mercure or Websocket) • Symfony integration uses Mercure

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

Listening on Streams
    {% for room in rooms %} {{ include('fragments/_room_list_item.html.twig', {room: room}) }} {% endfor %}

Slide 40

Slide 40 text

Publishing Changes #[Route('/rooms/create', name: 'create_room')] public function create( Request $request, EntityManagerInterface $entityManager, HubInterface $hub ): Response { // create form $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $entityManager->persist($form->getData()); $entityManager->flush(); $hub->publish( new Update( 'my_stream_key', $this->renderView('room/new.stream.html.twig', ['room' => $room]) ) ); return $this->redirectToRoute('view_room', ['id' => $room->getId()], Response::HTTP_SEE_OTHER); } return $this->renderForm('room/rename.html.twig', ['form' => $form]); }

Slide 41

Slide 41 text

HTML Fragment

Slide 42

Slide 42 text

Doctrine Integration • Symfony UX Turbo makes it easy to publish changes from Doctrine entities. • Maker bundle supports generating the necessary files (entity w/ attribute, fragment template etc.)

Slide 43

Slide 43 text

Dessert Example Application

Slide 44

Slide 44 text

Why I Like (Symfony UX) Turbo • Promising abstractions • React introduced components ➡ large client-side applications now maintainable • Drive, Frames & Streams are useful primitives that can be used together in various combinations • first-class integration with Symfony

Slide 45

Slide 45 text

But It's Still Early Days • Hotwire has only been out for a few months. • Only large-scale user is Basecamp. • No established community best practices yet.

Slide 46

Slide 46 text

Thanks for listening! (for real now) $kernel->terminate($request, $response);