Lesson Monday

Now that we have our basic methods and specs ready for our To Do list with SQL, let's update our Silex app to reflect these new changes.

Let's change our index.html.twig file to be a place to add new lists and to display the added lists as links to their contents:

index.html.twig
<html>
<head>
    <title>To Do List</title>
</head>
<body>
    <h1>Welcome to To Do List</h1>

    <p>Create a new category:</p>

    <form action="/categories" method="post">
        <label for="name">Category name:</label>
        <input id="name" name="name" type="text">

        <button type="submit">Add category</button>
    </form>

    {% if categories is not empty %}
        <p>Here are all your categories:</p>
        <ul>
            {% for category in categories %}
                <li><a href="/categories/{{ category.getId }}">{{ category.getName }}</a></li>
            {% endfor %}
        </ul>
    {% else %}
      <p>There are no categories yet!</p>
    {% endif %}

</body>
</html>

We have just moved the form and the list of categories from the categories.html.twig file into this index.html.twig file. The major change from the categories.html.twig file is that we are linking to "/categories/{{ category.getId }}". This will take users to a URL like localhost:8888/categories/3 if the ID of the particular category that they clicked on was 3.

Now we need to change our app.php file to reflect the changes in the index.html.twig file.

app/app.php
$app->get("/", function() use ($app) {
    return $app['twig']->render('index.html.twig', array('categories' => Category::getAll()));
});

…

$app->post("/categories", function() use ($app) {
    $category = new Category($_POST['name']);
    $category->save();
    return $app['twig']->render('index.html.twig', array('categories' => Category::getAll()));
});

The major change here is that we are adding in the array of all of the categories to our index.html.twig view, as well as rendering index.html.twig once a new instance of Category is created in our post route.

When the index page displays, all of the categories will be links to a particular page where the user can add tasks to a category and see all of the tasks for that category. We set this in the index.html.twig file by adding <a href="/categories/{{ category.getId }}">...</a> to the code block in the category in categories loop.

This link will take the users to a get("/categories/{id}"... route in the app.php file. Let's create that route now.

app/app.php
$app->get("/categories/{id}", function($id) use ($app) {
    $category = Category::find($id);
    return $app['twig']->render('category.html.twig', array('category' => $category, 'tasks' => $category->getTasks()));
});

In this route, we are finding the correct instance of Category based on the ID that we pass into the URL parameters. These parameters come from the link we set in our index.html.twig file. This route will render a file called category.html.twig. Let's make that file now:

views/category.html.twig
<html>
<head>
    <title>To Do List</title>
</head>
<body>
    <h1>{{ category.getName }}</h1>

    {% if tasks is not empty %}
        <p>Here are the tasks:</p>
        <ul>
            {% for task in tasks %}
                <li>{{ task.getDescription }}</li>
            {% endfor %}
        </ul>
    {% endif %}

    <h4>Add a task</h4>

    <form action='/tasks' method='post'>
        <input id="category_id" name="category_id" type="hidden" value="{{ category.getId() }}">
        <label for='description'>Task Description</label>
        <input id='description' name='description' type='text'>

        <button type='submit'>Add task</button>
    </form>

    <p><a href='/'>Home</a></p>
</body>
</html>

As you can see, this template is based off of our previous tasks.html.twig template. The major change is that we added the line <input id="category_id" name="category_id" type="hidden" value="{{ category.getId() }}">. This will add a category_id with the value of $category->getId() that will be sent from the form and can be used to initialize a new Task object.

Let's update the post("/tasks"... in the app.php file:

app.php
$app->post("/tasks", function() use ($app) {
    $description = $_POST['description'];
    $category_id = $_POST['category_id'];
    $task = new Task($description, $category_id, $id = null);
    $task->save();
    $category = Category::find($category_id);
    return $app['twig']->render('category.html.twig', array('category' => $category, 'tasks' => $category->getTasks()));
});

We use the new find method in both the get("/categories/{id}...") and the post("/tasks") route to get the correct category to display in the category.html.twig template.

Let's fire up the server and see how our new app works.