Chat with us, powered by LiveChat

This website uses cookies

Our website, platform and/or any sub domains use cookies to understand how you use our services, and to improve both your experience and our marketing relevance.

Symfony 4 : Routes, Controllers & Templates

March 28, 2018

5 Min Read
Reading Time: 5 minutes

Symfony 4 continues to build a reputation of high performance in the PHP community. Even the developers who hadn’t tried it out earlier on their hosting for PHP are now giving it a shot. Matthew setter has a great story about his experience with Symfony 4.

In my past blogs, I’ve discussed how to install Symfony 4 on Cloudways and a recipe system using Symfony Flex. This time I’ll explore Symfony 4 further and discuss creating routes, controllers and twig templates. I will also present the new Symfony 4 directory structure and then show how you can register bundles and create files and folders for your templates and controllers.

The Directory Structure

Symfony 4.x has a new and more simplified directory structure which allow developers compose applications with a more precise structure. Symfony Flex is also based on this directory structure. Here is how this amazingly simple structure looks like:

Deploy PHP Apps Without Worrying About Servers

Our Managed Cloud Hosting for PHP applications takes care of all hosting related hassles

Notice the config folder which contains bundles.php. Flex will register all bundles automatically after installation. The public folder offers access to the application through the index.php, while the src folder contains the controllers and entities.

You Might Also Like: How to Connect PHP SFTP With phpseclib in Symfony

Creating Routes in Symfony 4

If you have earlier done Symfony routing in standard versions, you need to do a bit more work like:

blog_list:
   path:     /blog
   defaults: { _controller: AppBundle:Blog:list }

blog_show:
   path:     /blog/{slug}
   defaults: { _controller: AppBundle:Blog:show }

In Symfony 3.x, you give the route name and the path with matching controllers and defaults. The defaults were defined as: `defaults: { _controller: AppBundle:Blog:show }`

Now in Symfony 4, you just need to find config/route.yml and add routes to this file. Let’s see how you can define the first Symfony route: 

index:

 path: /

 controller: App\Controller\DefaultController::index

You can simply define name, path and controller which needs to be executed.  Also notice the much simplified controller structure [App\Controller\DefaultController::index] that now just define namespace and controller class with method to run while matching the respective route. Yes, this does looks like the Laravel route system. Similarly, if you need to pass out parameters or do something dynamic, you can create a route like:

blog_show:

   path:     /blog/{slug}

   controller: App\Controller\DefaultController::show

This will take the URL query parameters and pass on to the controller method show(). Obviously, you will define the functionality in this method. If you have earlier defined same routes that match (such as /blog/{page} & /blog/{slug}), it will match /blog/* so you can define the requirements for the route which contains regular expressions.

Suppose /blog/{page} will deal with page numbers. You can define it as:

blog_list:

      path:    /blog/{page}

      controller: App\Controller\BlogController::list

      requirements:

             page: '\d+'

page: '\d+' will define the param as the number.

Creating Symfony 4 Controller & Routes With Annotations

For creating routes in Symfony 4 with annotations, you need to install the Annotation library first. Use Composer to install it.

composer require annotations

Once the installation finishes, you can create routes with annotations in DefaultController.php file. Create a file in src/Controller and add the following code in it:

<?php

namespace App\Controller;


//must add these namespaces

use Symfony\Component\HttpFoundation\Response;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class DefaultController

{

   /**

    * @Route("/", name="index")

    */

   public function index()

   {

       return new Response('This is the first Symfony4 page!');

   }

     /**

    * @Route("/blogs", , name="blog_list")

    */

   public function blogs()

   {

       return new Response('All blogs will show here');

   }

   /**

    * @Route("/blogs/{slug}", , name="blog_show")

    */

   public function show($slug)

   {

       return new Response(sprintf(

           'Future page to show the article: "%s"', $slug

       ));

   }

}

?>

Here is how the route looks in action:

So, all the routes are working alright. You can even create more advanced and complex routes for different use cases

Listing All the Routes

When you are developing a large project you will have a number of routes. Symfony provides a very easy way of seeing all the routes with just a single command:

php bin/console debug:route

Creating & Working With Twig Templates in Symfony 4

In the above example, I returned a simple string response to the view from controller in Symfony 4. You can return HTML views with twig templating engine.

Twig is <3

You can do a whole bunch of exciting things with a twig. In Symfony 4, you need to install Twig library for creating templates. Run the following Composer command:

composer require twig

You can see Flex has installed (and registered the bundle in bundles.php) a twig-bundle.

Also, If you notice the root directory of the project, you will notice a new folder called templates that having base.html.twig file in it. For twig configuration, twig.yml is also added at config/packages/twig.yaml.

Now let’s add a new twig file in templates folder with the name article.html.twig and add the following simple code to it:

<h1>{{ title }}</h1>

<div>

   <p>

       Bacon ipsum dolor amet filet mignon picanha kielbasa jowl hamburger shankle biltong chicken turkey pastrami cupim pork chop. Chicken andouille prosciutto capicola picanha, brisket t-bone. Tri-tip pig pork chop short ribs frankfurter pork ham. Landjaeger meatball meatloaf, kielbasa strip steak leberkas picanha swine chicken pancetta pork loin hamburger pork.

   </p>

   <p>

       Kielbasa pork belly meatball cupim burgdoggen chuck turkey buffalo ground round leberkas cow shank short loin bacon alcatra. Leberkas short loin boudin swine, ham hock bresaola turducken tail pastrami picanha pancetta andouille rump landjaeger bacon. Pastrami swine rump meatball filet mignon turkey alcatra. Picanha filet mignon ground round tongue ham hock ball tip tri-tip, prosciutto leberkas kielbasa short loin short ribs drumstick. Flank pig kielbasa short loin jerky ham hock turducken prosciutto t-bone salami pork jowl.

   </p>

   <p>

       Pastrami short loin pork chop, chicken kielbasa swine turducken jerky short ribs beef. Short ribs alcatra shoulder, flank pork chop shankle t-bone. Tail rump pork chop boudin pig, chicken porchetta. Shank doner biltong, capicola brisket sausage meatloaf beef ribs kevin beef rump ribeye t-bone. Shoulder cupim meatloaf, beef kevin frankfurter picanha bacon. Frankfurter bresaola chuck kevin buffalo strip steak pork loin beef ribs prosciutto picanha shankle. Drumstick prosciutto pancetta beef ribs.

   </p>

</div>

Now in the controller, add a new method `myView()` with the following code:

/**

   * @Route("/articles/{slug}", name="blog_show")

   */

  public function myView($slug) {

  return $this->render('articles/first.html.twig', [

          'title' => ucwords(str_replace('-', ' ', $slug)),

      ]);

  }

This method will take out the “” from the URL url and show the title variable in <title> tag.

Let’s run the route in the browser:

It’s working good but looks a bit rough. Now you can render your twig templates in Symfony 4.  I will now integrate the base.html.twig template in the first.view.html. Because some view functionalities are common, you can declare it once in the base template and render them in every child template.

Add the following line at the top of first.html.twig:

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

In the base template, the child template components mainly show up in the body block so you need to restrict the child template to show in base template body block. You can do it by overriding the view in body block:

{% block body %}

// your template goes here

{% endblock %}

Now to integrate Bootstrap to give a good look to the HTML of the page. You can easily add it in the stylesheet block, that goes into the <head> tag:

{% block stylesheets %}

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">

{% endblock %}

You can see the page with a new fresh look. Now, you can use bootstrap styles as you see fit.

Share your opinion in the comment section. COMMENT NOW

Share This Article

Launch PHP websites without the worry of Server Management.

Pre-Installed Optimized Stack with Git, Composer & SSH

Shahroze Nawaz

Shahroze is a PHP Community Manager at Cloudways - A Managed PHP Hosting Platform. Besides his work life, he loves movies and travelling. You can email him at shahroze.nawaz@cloudways.com

Get Our Newsletter
Be the first to get the latest updates and tutorials.

Do you like what you read?

Get the Latest Updates

Share Your Feedback

Please insert Content

Thank you for your feedback!

BFCM 2019