composer require dunglas/todomvc-bundle).
composer require dunglas/todomvc-bundle
config/bundles.php:
return [
// ...
Dunglas\TodoMVCBundle\DunglasTodoMVCBundle::class => ['all' => true],
];
FOSRestBundle, JMSSerializerBundle, and DunglasAngularCsrfBundle are installed and enabled.
composer require friendsofsymfony/rest-bundle jms/serializer-bundle dunglas/angular-csrf
php bin/console doctrine:migrations:migrate
/ to see the TodoMVC frontend (Backbone.js/Chaplin.js)./api/todos (returns JSON via FOSRestBundle).src/Dunglas/TodoMVCBundle/Resources/config/routing.yml (API routes).Resources/public/js/ (CoffeeScript/Backbone/Chaplin source).src/Dunglas/TodoMVCBundle/Entity/Todo.php (Doctrine model).Resources/config/serializer/Todo.yml (JMS Serializer config).CRUD Operations:
/api/todos with JSON body { "title": "Task" }./api/todos (filters: ?filter=active|completed|all)./api/todos/{id} with { "completed": true }./api/todos/{id}.Frontend Integration:
TodoMVCBundle:Default:index for custom routes.
# Resources/public/js/app.coffee
class TodoMVC.App extends Chaplin.Controller
initialize: ->
@listenTo @, "route:todos", ->
@fetchTodos()
TodoMVC.Model.Todo or TodoMVC.View.TodoItem.API Customization:
Todo entity extending Dunglas\TodoMVCBundle\Entity\Todo.Todo.yml in Resources/config/serializer/:
Dunglas\TodoMVCBundle\Entity\Todo:
exclusion_policy: ALL
properties:
id:
expose: true
title:
expose: true
priority: # Custom field
expose: true
CSRF Protection:
headers: {
'X-CSRF-Token': angular.element('meta[name="csrf-token"]').attr('content')
}
FOSRestBundle's form handlers for hybrid API/form apps.todo.pre_persist/todo.post_remove via Symfony events.
// src/EventListener/TodoListener.php
public function onTodoPrePersist(TodoEvent $event) {
$todo = $event->getTodo();
$todo->setCreatedAt(new \DateTime());
}
Symfony\Bundle\FrameworkBundle\Test\WebTestCase.Resources/tests/).CSRF Mismatches:
403 Forbidden.DunglasAngularCsrfBundle is configured and tokens are included in headers.meta[name="csrf-token"] exists in the HTML response.Serialization Conflicts:
serializer/Todo.yml includes the field and exclusion_policy is ALL or the field is explicitly exposed.php bin/console debug:serializer Dunglas\TodoMVCBundle\Entity\Todo.Chaplin Router Conflicts:
Resources/public/js/app.coffee and ensure TodoMVC.App is initialized last.Doctrine Migrations:
php bin/console doctrine:migrations:diff and migrate after adding custom fields.bin/console debug:router to list routes.bin/console debug:serializer for serialization issues.app.coffee:
Chaplin.debug = true
XHR).Custom Fields:
Todo entity and update Todo.yml:
properties:
dueDate:
type: DateTime
exposed: true
Resources/public/js/models/todo.coffee.Authentication:
LexikJWTAuthenticationBundle or FOSUserBundle:
# config/packages/security.yaml
firewalls:
api:
pattern: ^/api
stateless: true
jwt: ~
Alternative Frontend:
/ (ensure it doesn’t conflict with index.html).Testing:
// Jasmine test
beforeEach(inject(function($httpBackend) {
$httpBackend.whenGET('/api/todos').respond([{ id: 1, title: 'Test' }]);
}));
How can I help you explore Laravel packages today?