Adding a Detail View


In the previous video we concentrated on adding in pagination to our Gallery page output. In this video we have the simpler task of displaying a single image at a larger size. This still likely won't be the full size of the image, and maybe a little later on we could consider creating a dedicated image for this view also. For the moment, we will go with the full size image scaled down to fit the view.

Again, for the moment we will keep things nice and simple and have a hardcoded image filename which we will pass from our Controller action to our Twig template.

The idea here is again, proof of concept. We want to do things as simply as possible to get that "quick win". It's amazing how much momentum can be built up by doing many small tasks. If we try to do too many things, or things that add a bunch of extra complexity then we run the risk of hitting a hard problem, losing momentum, and that dramatically increases the likelihood of giving up.

Enough rambling, let's see the code:

<?php

// /src/AppBundle/Controller/DetailController.php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class DetailController extends Controller
{
    /**
     * @Route("/view", name="view")
     */
    public function indexAction(Request $request)
    {
        $image = 'landscape-summer-beach.jpg';

        return $this->render('detail/index.html.twig', [
            'image' => $image
        ]);
    }
}

We've added in a new controller - the DetailController.

It may be that in the detail view we have further information that we wish to display alongside this particular image - download stats, the amount of times this image was viewed, alternative resolutions - that sort of thing.

For the moment, we simply want to display the image.

Again, the image filename is hardcoded. Make sure that this image actually exists in your web/images directory, or change up the $image variable to be some image filename that does exist.

We will update this controller action a little later to accept a 'slug'. A slug is simply-an-alphanumerical-string-with-spaces-replaced-with-hyphens. We will add in some constraints to ensure that slugs are unique in our database, and then we can query on the slug to find the underlying image data. Again, all in good time.

For now, all we care about is the file name.

We pass this through to a Twig template that doesn't yet exist. Let's create it:

<!-- /app/Resources/views/detail/index.html.twig -->

{% extends 'base.html.twig' %}

{% block body %}

    <div class="row">
        <div class="col-sm-12">
            <h1 class="text-center">Image name here</h1>
            <div class="thumbnail">
                <a href="images/{{ image }}">
                    <img src="/images/{{ image }}" alt="...">
                </a>
                <div class="caption">
                    <h3>My Image Caption</h3>
                    <ul>
                        <li>Tag 1</li>
                        <li>Tag 2</li>
                        <li>Tag 3</li>
                    </ul>
                </div>
            </div>
        </div>
    </div>

{% endblock %}

You are entirely free to change this up, and I encourage you to do so. Remember this is a visual heavy site, and there's a lot of competition in this space. If you want to put this site live then make it look good.

Note that the img itself is wrapped in a link to the full size image. This allows the viewer to click the image to see the file without all our surrounding template 'mess'.

That's about it here. Nice and easy, but we've got the job done.

One last thing, you might be tempted to tweak the controller action as follows:

    /**
     * @Route("/view", name="view")
     */
    public function indexAction(Request $request)
    {
        return $this->render('detail/index.html.twig', [
            'image' => 'landscape-summer-beach.jpg',
        ]);
    }

Whilst this will work for now, we will soon be replacing the "image as a string" concept with "image as an object". The current setup is working with that idea in mind.

Code For This Course

Get the code for this course.

Code For This Video

Get the code for this video.

Episodes

# Title Duration
1 Introduction and Site Demo 02:14
2 Setup and a Basic Wallpaper Gallery 08:43
3 Pagination 08:24
4 Adding a Detail View 04:47
5 Creating a Home Page 11:14
6 Creating our Wallpaper Entity 07:50
7 Wallpaper Setup Command - Part 1 - Symfony Commands As a Service 05:57
8 Wallpaper Setup Command - Part 2 - Injection Is Easy 08:53
9 Wallpaper Setup Command - Part 3 - Doing It With Style 05:37
10 Doctrine Fixtures - Part 1 - Setup and Category Entity Creation 08:52
11 Doctrine Fixtures - Part 2 - Relating Wallpapers with Categories 05:56
12 EasyAdminBundle - Setup and Category Configuration 06:02
13 EasyAdminBundle - Wallpaper Setup and List View 07:46
14 EasyAdminBundle - Starting with Wallpaper Uploads 05:57
15 Testing with PhpSpec to Guide Our Implementation 03:39
16 Using PhpSpec to Test our FileMover 05:34
17 Symfony Dependency Testing with PhpSpec 08:47
18 Defensive Counter Measures 06:33
19 No Tests - Part 1 - Uploading Files in EasyAdminBundle 11:01
20 No Tests - Part 2 - Uploading Files in EasyAdminBundle 07:05
21 Don't Mock What You Don't Own 09:36
22 You've Got To Take The Power Back 07:36
23 Making Symfony Work For Us 08:56
24 Testing The Wallpaper File Path Helper 15:11
25 Finally, It Works! 14:56
26 Why I Prefer Not To Use Twig 16:51
27 Fixing The Fixtures 11:20
28 Untested Updates 14:30
29 Untested Updates Part Two - Now We Can Actually Update 06:33
30 Adding an Image Preview On Edit 12:31
31 Delete Should Remove The Wallpaper Image File 11:02
32 Getting Started Testing Wallpaper Updates 10:02
33 Doing The Little Before The Big 08:13
34 Tested Image Preview... Sort Of :) 07:36
35 Finishing Up With a Tested Wallpaper Update 10:41
36 Test Driven Wallpaper Delete - Part 1 11:06
37 Test Driven Wallpaper Delete - Part 2 11:57
38 EasyAdminBundle Login Form Tutorial 08:01