Single page apps with Symfony and chaplin.js

Single page apps with Symfony and chaplin.js

Talk about making Symfony and chaplin.js/backbone.js play nicely together.


Robert Gründler

January 16, 2013


  1. 2.

    WHO AM I • Freelance software developer in Vienna •

    Working with Symfony since 2008 • • • Monday, January 14, 13
  2. 4.


    oauth2 • 2-leg authenticated chaplin.js webclient Monday, January 14, 13
  3. 5.

    WHAT SHOULD YOU KNOW ? • Symfony basics • Doctrine

    basics • Javascript / jquery basics Monday, January 14, 13
  4. 7.

    PROS • Reduced payload for your HTTP requests • Don’t

    reload your page markup on every request • Perceived UI performance improvement for endusers • Maintain a single REST API for multiple clients(web/mobile/etc) • Allows continuous media streams between page reloads • Ideal solution for audio content Monday, January 14, 13
  5. 8.

    CONS • SEO issues for public facing websites • Client-Side

    frameworks are not very mature • New debugging challenges • Large development overhead when supporting old browsers Monday, January 14, 13
  6. 9.

    BOOKSTORE APPLICATION • Provide a CRUD interface for books •

    Interface for browsing books and authors • Adding book reviews Monday, January 14, 13
  7. 16.

    CONFIGURATION Enable the view response listener to automatically serialize return

    values from controllers Disable framework default view annotations Monday, January 14, 13
  8. 18.

    Makes FOSRestBundle create routes based on the controller name. Makes

    FOS view-response- listener automatically serialize the return value of the controller. Monday, January 14, 13
  9. 22.

    SERIALIZATION GROUPS GET /books serializes using “bookList” group GET /books/{id}

    serializes using “bookDetail” group Monday, January 14, 13
  10. 23.

    Exclude all attributes from serialization by default Expose attributes only

    when specific serialization groups are active Monday, January 14, 13
  11. 26.

    BASE API FORMTYPE Disable CSRF protection as our secure API

    will be accessible only using oauth2 authentication getName() returns null to make the REST PUT format of backbone.js compatible when binding the form. Monday, January 14, 13
  12. 37.

    API endpoints secured through stateless oauth2 Regular website secured through

    cookie based form login oauth2 token retrieval oauth2 authorization endpoint for 3-legged auth security.yml Monday, January 14, 13
  13. 41.

    RECAP so far we have 1. REST API endpoints for

    the book entities Monday, January 14, 13
  14. 42.

    RECAP so far we have 1. REST API endpoints for

    the book entities 2. Oauth2 secured CRUD controllers Monday, January 14, 13
  15. 43.

    RECAP so far we have 1. REST API endpoints for

    the book entities 2. Oauth2 secured CRUD controllers 3. A fully tested API Monday, January 14, 13
  16. 44.

    CHAPLIN.JS • CoffeeScript HTML5 application framework • Based on backbone.js

    • Cross-module communication • Controllers for managing individual UI views • Strict memory management and object disposal • Nested views • ... Monday, January 14, 13
  17. 45.

    BRUNCH • HTML5 application assembler and build tool • Compiles

    your chaplin.js application into javascript • Compiles Stylus/Sass/Less/YouNameIt into CSS • tons of other useful features Monday, January 14, 13
  18. 46.

    CREATING THE CHAPLIN APP • Install brunch (see for

    details) • Run “brunch new client” in your Symfony app root Monday, January 14, 13
  19. 47.

    chaplin client application brunch configuration chaplin application tests javascript dependencies

    compiled javascripts and stylesheets generated during brunch compilation process Generated application structure Monday, January 14, 13
  20. 48.

    Customize Tell brunch to compile js/css files into the

    Symfony document root Monday, January 14, 13
  21. 49.

    main application twig template Acme/SPA/ChaplinBundle/Resources/views/layout.html.twig application css compiled by brunch

    application javascript compiled by brunch initialize the client app Monday, January 14, 13
  22. 50.

    BACKBONE/CHAPLIN ROUTING client/app/ will match http://bookstore.local will match http://bookstore.local/books will

    NOT match: •http://bookstore.local/app_dev.php •http://bookstore.local/app_dev.php/books Monday, January 14, 13
  23. 52.

    The controller for the frontend only has a single action

    rendering the application layout. Use the expose option to make the chaplin router aware of the Symfony routes. All routes use the same controller action. Monday, January 14, 13
  24. 54.

    Use regular Symfony route names in the backbone router Matches

    URLs in the correct app environment (app_dev.php/books for example) (see client/app/ for the SymfonyRouter coffeescript implementation in the github demo app) Monday, January 14, 13
  25. 56.

    initialize a books list plus the corresponding view and fetch

    the data when a book_list route matches The Books collection retrieves it’s backend URL from the SymfonyRouter Model and Controller app/controllers/ app/models/ Monday, January 14, 13
  26. 57.

    The collection view renders the book collection app/views/book/ app/views/book/ app/views/templates/book/list.hbs

    app/views/templates/book/list_item.hbs The collection view will pass the book model for each collection item to the corresponding ItemView Monday, January 14, 13
  27. 61.

    Render the login form into a modal view POST the

    login form via ajax Publish a “login success” event client/app/views/auth/ Monday, January 14, 13
  28. 63.

    • Follow Googles escaped_fragment specification [1] • Use a headless

    browser to render your page for crawlers [2] • Pre-render <head> tags to make facebook et al. happy STRATEGIES [1] [2] Monday, January 14, 13
  29. 67.

    Great and everything - but now we have two database

    trips for every initial pageload instead of one... Monday, January 14, 13
  30. 69. Only load the model from the server in case

    there was no initial payload embedded Monday, January 14, 13