Setting Up a MVC ToDo App in Symfony

Welcome to the first lesson of another Symfony course. In this lesson, we will focus on constructing the foundation of a functional ToDo application using the MVC pattern.

First, let's briefly recap the MVC (Model-View-Controller) structure. The MVC pattern divides your application into three main components:

  • Model: Manages the data and business logic.
  • View: Displays data to the user and receives user input.
  • Controller: Handles user input and interacts with the model to update the view.

In this lesson, we will introduce the concept of entities, create a simple Todo entity, set up a service to manage our todos, and create a controller to handle requests. Finally, we will use Twig to render our list of todos. By the end of this lesson, you will have a functional ToDo list displayed in your browser.

Creating the Todo Entity

Let’s begin by creating the Todo entity that will represent our tasks. An entity in Symfony is simply a PHP class that represents a table in your database. For this example, we’ll create a basic Todo class without involving an actual database.

Here’s the code for our Todo entity:

In this code, our Todo class belongs to the App\Entity namespace, grouping it with related classes. It has properties like $id, $title, and $description, and comes with methods to interact with these properties. This class will serve as the backbone of our ToDo app's data structure.

Understanding Session Mechanism & RequestStack

Before we dive into implementing the TodoService, let's briefly talk about Symfony's session mechanism and the RequestStack component.

In web applications, sessions are used to store information across different user requests. HTTP, the protocol used for web communication, is stateless by default. This means it doesn't inherently remember information between different requests. Sessions help overcome this limitation by allowing you to store data on the server side and associate it with a specific user through a unique session ID.

RequestStack is a Symfony service that provides access to the current HTTP request and its session. It allows you to fetch the session and manage session data conveniently. By leveraging RequestStack, you can store and retrieve data such as user preferences or, in our case, a list of todos.

Now that we have an understanding of the session mechanism and RequestStack, let's implement the TodoService.

Implementing TodoService

Here’s the code for the TodoService class, this service will use Symfony's session mechanism to store and retrieve our todos.

In our TodoService class, we use the $requestStack property to access the current HTTP request and its session. Since HTTP is stateless, sessions are essential for maintaining data, like a list of todos, across different pages and user actions. This allows us to persist information between requests, ensuring that data isn't lost after each interaction.

The __construct method sets up the $requestStack property, and the getSession method fetches the session from the request stack. With these in place, the findAll method can retrieve all the todos stored in the session or return an empty array if there aren't any. This service manages our tasks and lets us interact with them through our controller.

Setting Up TodoController

Now, we need a controller to handle requests related to our todos. Let’s create a TodoController class with a method to list all todos.

Here’s the code for the TodoController class:

In our TodoController class, we have a $todoService property that gives us access to the service managing our todos. The __construct method sets this up by initializing $todoService.

We are using PHP attributes to define routes in our controller. For example, the #[Route('/', name: 'todo_list')] attribute maps the path '/' to the root URL of our application and gives it the route name todo_list. This modern syntax directly embeds the routing information in our controller method, streamlining the process.

Configuring Routes

To ensure that Symfony properly reads our route attributes, we need to configure the routes.yaml file to tell Symfony to scan our controllers for these attributes.

Here’s how we should configure our routes.yaml file:

In this configuration:

  • resource: '../src/Controller/' directs Symfony to look for route definitions in the specified directory.
  • type: annotation tells Symfony to use the embedded route definitions within our controller classes. Despite using the term annotation, this configuration supports modern PHP attributes as well.

With PHP attributes, we now embed this routing information directly in our controller methods. This approach keeps our routing logic close to the related controller logic, making the process more intuitive and reducing redundancy.

Displaying Todos with Twig

Finally, we need a Twig template to display our list of todos. Here’s the code for the list.html.twig file called by the controller:

This basic HTML structure starts with a title and a heading that both say ToDo List. After that, there's a list where our todos will be displayed. The {% for todo in todos %} loop goes through each todo provided by the controller, showing its title and description. If there are no todos to display, the {% else %} block shows a message letting us know that no todos were found. This setup ensures that we either see our list of todos or a friendly message if the list is empty.

Summary and Next Steps

In this lesson, we built the foundation of our ToDo app by following the MVC pattern in Symfony. Here is what we have covered:

  1. MVC Structure Recap: We revisited the Model-View-Controller pattern, understanding its core components - Model, View, and Controller.
  2. Creating the Todo Entity: We created a PHP class (Todo) to represent our tasks with properties for id, title, and description.
  3. Implementing TodoService: We built a service (TodoService) to manage our tasks using Symfony's session mechanism to store and retrieve todos, ensuring persistence across HTTP requests.
  4. Setting Up TodoController: We set up a controller (TodoController) to handle HTTP requests, defining routes with annotations, and used it to interact with the TodoService and pass data to the view.
  5. Configuring Routes: We configured the routes.yaml file to ensure Symfony reads our route annotations, streamlining our routing by scanning the ../src/Controller/ directory.
  6. Displaying Todos with Twig: We used a Twig template (list.html.twig) to render our list of todos on a web page, displaying each todo's title and description, or showing a friendly message if the list is empty.

Now it's time to put this knowledge into practice. Complete the exercises that follow to solidify your understanding and ensure you can implement these concepts on your own.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal