Creating our Template

By the end of this lesson, you’ll have a nice looking template for a freelancer which is easy to build new pages from. Along the way, we'll be:

  • Downloading a Bootstrap template
  • Organising the template
  • Creating a second page for the site
Follow along using the code available from this GIT repository.
Start - master
End - creating_our_template

Building the template

The project we're building is that of a freelance digital agent and to quickstart things, we’ll use a premade template based on Bootstrap. We'll be using Bootstrap as it is a widely used style framework that is easy to work with, there are lots of resources available to work with and most importantly, it's quick to setup for our purposes.

Get the template

Upon downloading (or cloning) the template, we want to make parts of it public. Symfony does provide facilities to manage web assets but for now, we’ll put the assets in the web directory. Copy the following folders from the downloaded template to the web directory within your project.

  1. css
  2. img
  3. js
  4. vendor

With that done, we want to change the Symfony template. Open the index.html (or copy the file below) from the download and copy the contents in to your base.html.twig template. Make sure that any linked resources (CSS or JavaScript) paths begin with a slash in order to signify that we want to use the web root otherwise, the path will be relative from the current page.

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.  
  5.   <meta charset="utf-8">
  6.   <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7.   <meta name="viewport" content="width=device-width, initial-scale=1">
  8.   <meta name="description" content="">
  9.   <meta name="author" content="">
  10.  
  11.   <title>Freelancer - Start Bootstrap Theme</title>
  12.   <!-- Bootstrap Core CSS -->
  13.   <link href="/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
  14.   <!-- Theme CSS -->
  15.   <link href="/css/freelancer.min.css" rel="stylesheet">
  16.   <!-- Custom Fonts -->
  17.   <link href="/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
  18.   <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css">
  19.   <link href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic" rel="stylesheet" type="text/css">
  20.  
  21.   <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
  22.   <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  23.   <!--[if lt IE 9]>
  24.       <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
  25.       <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
  26.   <![endif]-->
  27.  
  28. </head>
  29.  
  30. <body id="page-top" class="index">
  31.  
  32.   <!-- Navigation -->
  33.   <nav id="mainNav" class="navbar navbar-default navbar-fixed-top navbar-custom">
  34.     <div class="container">
  35.       <!-- Brand and toggle get grouped for better mobile display -->
  36.       <div class="navbar-header page-scroll">
  37.         <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
  38.           <span class="sr-only">Toggle navigation</span> Menu <i class="fa fa-bars"></i>
  39.         </button>
  40.         <a class="navbar-brand" href="#page-top">Start Bootstrap</a>
  41.       </div>
  42.  
  43.       <!-- Collect the nav links, forms, and other content for toggling -->
  44.       <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
  45.         <ul class="nav navbar-nav navbar-right">
  46.           <li class="hidden">
  47.             <a href="#page-top"></a>
  48.           </li>
  49.           <li class="page-scroll">
  50.             <a href="#portfolio">Portfolio</a>
  51.           </li>
  52.           <li class="page-scroll">
  53.             <a href="#about">About</a>
  54.           </li>
  55.           <li class="page-scroll">
  56.             <a href="#contact">Contact</a>
  57.           </li>
  58.         </ul>
  59.       </div>
  60.       <!-- /.navbar-collapse -->
  61.     </div>
  62.     <!-- /.container-fluid -->
  63.   </nav>
  64.  
  65.   <!-- Header -->
  66.   <header>
  67.     <div class="container">
  68.       <div class="row">
  69.         <div class="col-lg-12">
  70.           <img class="img-responsive" src="img/profile.png" alt="">
  71.           <div class="intro-text">
  72.             <span class="name">Start Bootstrap</span>
  73.             <hr class="star-light">
  74.             <span class="skills">Web Developer - Graphic Artist - User Experience Designer</span>
  75.           </div>
  76.         </div>
  77.       </div>
  78.     </div>
  79.   </header>
  80.  
  81.   <!-- Portfolio Grid Section -->
  82.   <section id="portfolio">
  83.       <div class="container">
  84.           <div class="row">
  85.               <div class="col-lg-12 text-center">
  86.                   <h2>Portfolio</h2>
  87.                   <hr class="star-primary">
  88.               </div>
  89.           </div>
  90.           <div class="row">
  91.               <div class="col-sm-4 portfolio-item">
  92.                   <a href="#portfolioModal1" class="portfolio-link" data-toggle="modal">
  93.                       <div class="caption">
  94.                           <div class="caption-content">
  95.                               <i class="fa fa-search-plus fa-3x"></i>
  96.                           </div>
  97.                       </div>
  98.                       <img src="img/portfolio/cabin.png" class="img-responsive" alt="">
  99.                   </a>
  100.               </div>
  101.               <div class="col-sm-4 portfolio-item">
  102.                   <a href="#portfolioModal2" class="portfolio-link" data-toggle="modal">
  103.                       <div class="caption">
  104.                           <div class="caption-content">
  105.                               <i class="fa fa-search-plus fa-3x"></i>
  106.                           </div>
  107.                       </div>
  108.                       <img src="img/portfolio/cake.png" class="img-responsive" alt="">
  109.                   </a>
  110.               </div>
  111.               <div class="col-sm-4 portfolio-item">
  112.                   <a href="#portfolioModal3" class="portfolio-link" data-toggle="modal">
  113.                       <div class="caption">
  114.                           <div class="caption-content">
  115.                               <i class="fa fa-search-plus fa-3x"></i>
  116.                           </div>
  117.                       </div>
  118.                       <img src="img/portfolio/circus.png" class="img-responsive" alt="">
  119.                   </a>
  120.               </div>
  121.               <div class="col-sm-4 portfolio-item">
  122.                   <a href="#portfolioModal4" class="portfolio-link" data-toggle="modal">
  123.                       <div class="caption">
  124.                           <div class="caption-content">
  125.                               <i class="fa fa-search-plus fa-3x"></i>
  126.                           </div>
  127.                       </div>
  128.                       <img src="img/portfolio/game.png" class="img-responsive" alt="">
  129.                   </a>
  130.               </div>
  131.               <div class="col-sm-4 portfolio-item">
  132.                   <a href="#portfolioModal5" class="portfolio-link" data-toggle="modal">
  133.                       <div class="caption">
  134.                           <div class="caption-content">
  135.                               <i class="fa fa-search-plus fa-3x"></i>
  136.                           </div>
  137.                       </div>
  138.                       <img src="img/portfolio/safe.png" class="img-responsive" alt="">
  139.                   </a>
  140.               </div>
  141.               <div class="col-sm-4 portfolio-item">
  142.                   <a href="#portfolioModal6" class="portfolio-link" data-toggle="modal">
  143.                       <div class="caption">
  144.                           <div class="caption-content">
  145.                               <i class="fa fa-search-plus fa-3x"></i>
  146.                           </div>
  147.                       </div>
  148.                       <img src="img/portfolio/submarine.png" class="img-responsive" alt="">
  149.                   </a>
  150.               </div>
  151.           </div>
  152.       </div>
  153.   </section>
  154.  
  155.   <!-- About Section -->
  156.   <section class="success" id="about">
  157.       <div class="container">
  158.           <div class="row">
  159.               <div class="col-lg-12 text-center">
  160.                   <h2>About</h2>
  161.                   <hr class="star-light">
  162.               </div>
  163.           </div>
  164.           <div class="row">
  165.               <div class="col-lg-4 col-lg-offset-2">
  166.                   <p>Freelancer is a free bootstrap theme created by Start Bootstrap. The download includes the complete source files including HTML, CSS, and JavaScript as well as optional LESS stylesheets for easy customization.</p>
  167.               </div>
  168.               <div class="col-lg-4">
  169.                   <p>Whether you're a student looking to showcase your work, a professional looking to attract clients, or a graphic artist looking to share your projects, this template is the perfect starting point!</p>
  170.               </div>
  171.               <div class="col-lg-8 col-lg-offset-2 text-center">
  172.                   <a href="#" class="btn btn-lg btn-outline">
  173.                       <i class="fa fa-download"></i> Download Theme
  174.                   </a>
  175.               </div>
  176.           </div>
  177.       </div>
  178.   </section>
  179.  
  180.   <!-- Contact Section -->
  181.   <section id="contact">
  182.       <div class="container">
  183.           <div class="row">
  184.               <div class="col-lg-12 text-center">
  185.                   <h2>Contact Me</h2>
  186.                   <hr class="star-primary">
  187.               </div>
  188.           </div>
  189.           <div class="row">
  190.               <div class="col-lg-8 col-lg-offset-2">
  191.                   <!-- To configure the contact form email address, go to mail/contact_me.php and update the email address in the PHP file on line 19. -->
  192.                   <!-- The form should work on most web servers, but if the form is not working you may need to configure your web server differently. -->
  193.                   <form name="sentMessage" id="contactForm" novalidate>
  194.                       <div class="row control-group">
  195.                           <div class="form-group col-xs-12 floating-label-form-group controls">
  196.                               <label>Name</label>
  197.                               <input type="text" class="form-control" placeholder="Name" id="name" required data-validation-required-message="Please enter your name.">
  198.                               <p class="help-block text-danger"></p>
  199.                           </div>
  200.                       </div>
  201.                       <div class="row control-group">
  202.                           <div class="form-group col-xs-12 floating-label-form-group controls">
  203.                               <label>Email Address</label>
  204.                               <input type="email" class="form-control" placeholder="Email Address" id="email" required data-validation-required-message="Please enter your email address.">
  205.                               <p class="help-block text-danger"></p>
  206.                           </div>
  207.                       </div>
  208.                       <div class="row control-group">
  209.                           <div class="form-group col-xs-12 floating-label-form-group controls">
  210.                               <label>Phone Number</label>
  211.                               <input type="tel" class="form-control" placeholder="Phone Number" id="phone" required data-validation-required-message="Please enter your phone number.">
  212.                               <p class="help-block text-danger"></p>
  213.                           </div>
  214.                       </div>
  215.                       <div class="row control-group">
  216.                           <div class="form-group col-xs-12 floating-label-form-group controls">
  217.                               <label>Message</label>
  218.                               <textarea rows="5" class="form-control" placeholder="Message" id="message" required data-validation-required-message="Please enter a message."></textarea>
  219.                               <p class="help-block text-danger"></p>
  220.                           </div>
  221.                       </div>
  222.                       <br>
  223.                       <div id="success"></div>
  224.                       <div class="row">
  225.                           <div class="form-group col-xs-12">
  226.                               <button type="submit" class="btn btn-success btn-lg">Send</button>
  227.                           </div>
  228.                       </div>
  229.                   </form>
  230.               </div>
  231.           </div>
  232.       </div>
  233.   </section>
  234.  
  235.   <!-- Footer -->
  236.   <footer class="text-center">
  237.       <div class="footer-above">
  238.           <div class="container">
  239.               <div class="row">
  240.                   <div class="footer-col col-md-4">
  241.                       <h3>Location</h3>
  242.                       <p>3481 Melrose Place
  243.                           <br>Beverly Hills, CA 90210</p>
  244.                   </div>
  245.                   <div class="footer-col col-md-4">
  246.                       <h3>Around the Web</h3>
  247.                       <ul class="list-inline">
  248.                           <li>
  249.                               <a href="#" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
  250.                           </li>
  251.                           <li>
  252.                               <a href="#" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
  253.                           </li>
  254.                           <li>
  255.                               <a href="#" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
  256.                           </li>
  257.                           <li>
  258.                               <a href="#" class="btn-social btn-outline"><i class="fa fa-fw fa-linkedin"></i></a>
  259.                           </li>
  260.                           <li>
  261.                               <a href="#" class="btn-social btn-outline"><i class="fa fa-fw fa-dribbble"></i></a>
  262.                           </li>
  263.                       </ul>
  264.                   </div>
  265.                   <div class="footer-col col-md-4">
  266.                       <h3>About Freelancer</h3>
  267.                       <p>Freelance is a free to use, open source Bootstrap theme created by <a href="http://startbootstrap.com">Start Bootstrap</a>.</p>
  268.                   </div>
  269.               </div>
  270.           </div>
  271.       </div>
  272.       <div class="footer-below">
  273.           <div class="container">
  274.               <div class="row">
  275.                   <div class="col-lg-12">
  276.                       Copyright &copy; Your Website 2016
  277.                   </div>
  278.               </div>
  279.           </div>
  280.       </div>
  281.   </footer>
  282.  
  283.   <!-- Scroll to Top Button (Only visible on small and extra-small screen sizes) -->
  284.   <div class="scroll-top page-scroll hidden-sm hidden-xs hidden-lg hidden-md">
  285.       <a class="btn btn-primary" href="#page-top">
  286.           <i class="fa fa-chevron-up"></i>
  287.       </a>
  288.   </div>
  289.  
  290.   <!-- Portfolio Modals -->
  291.   <div class="portfolio-modal modal fade" id="portfolioModal1" tabindex="-1" role="dialog" aria-hidden="true">
  292.       <div class="modal-content">
  293.           <div class="close-modal" data-dismiss="modal">
  294.               <div class="lr">
  295.                   <div class="rl">
  296.                   </div>
  297.               </div>
  298.           </div>
  299.           <div class="container">
  300.               <div class="row">
  301.                   <div class="col-lg-8 col-lg-offset-2">
  302.                       <div class="modal-body">
  303.                           <h2>Project Title</h2>
  304.                           <hr class="star-primary">
  305.                           <img src="img/portfolio/cabin.png" class="img-responsive img-centered" alt="">
  306.                           <p>Use this area of the page to describe your project. The icon above is part of a free icon set by <a href="https://sellfy.com/p/8Q9P/jV3VZ/">Flat Icons</a>. On their website, you can download their free set with 16 icons, or you can purchase the entire set with 146 icons for only $12!</p>
  307.                           <ul class="list-inline item-details">
  308.                               <li>Client:
  309.                                   <strong><a href="http://startbootstrap.com">Start Bootstrap</a>
  310.                                   </strong>
  311.                               </li>
  312.                               <li>Date:
  313.                                   <strong><a href="http://startbootstrap.com">April 2014</a>
  314.                                   </strong>
  315.                               </li>
  316.                               <li>Service:
  317.                                   <strong><a href="http://startbootstrap.com">Web Development</a>
  318.                                   </strong>
  319.                               </li>
  320.                           </ul>
  321.                           <button type="button" class="btn btn-default" data-dismiss="modal"><i class="fa fa-times"></i> Close</button>
  322.                       </div>
  323.                   </div>
  324.               </div>
  325.           </div>
  326.       </div>
  327.   </div>
  328.   <div class="portfolio-modal modal fade" id="portfolioModal2" tabindex="-1" role="dialog" aria-hidden="true">
  329.       <div class="modal-content">
  330.           <div class="close-modal" data-dismiss="modal">
  331.               <div class="lr">
  332.                   <div class="rl">
  333.                   </div>
  334.               </div>
  335.           </div>
  336.           <div class="container">
  337.               <div class="row">
  338.                   <div class="col-lg-8 col-lg-offset-2">
  339.                       <div class="modal-body">
  340.                           <h2>Project Title</h2>
  341.                           <hr class="star-primary">
  342.                           <img src="img/portfolio/cake.png" class="img-responsive img-centered" alt="">
  343.                           <p>Use this area of the page to describe your project. The icon above is part of a free icon set by <a href="https://sellfy.com/p/8Q9P/jV3VZ/">Flat Icons</a>. On their website, you can download their free set with 16 icons, or you can purchase the entire set with 146 icons for only $12!</p>
  344.                           <ul class="list-inline item-details">
  345.                               <li>Client:
  346.                                   <strong><a href="http://startbootstrap.com">Start Bootstrap</a>
  347.                                   </strong>
  348.                               </li>
  349.                               <li>Date:
  350.                                   <strong><a href="http://startbootstrap.com">April 2014</a>
  351.                                   </strong>
  352.                               </li>
  353.                               <li>Service:
  354.                                   <strong><a href="http://startbootstrap.com">Web Development</a>
  355.                                   </strong>
  356.                               </li>
  357.                           </ul>
  358.                           <button type="button" class="btn btn-default" data-dismiss="modal"><i class="fa fa-times"></i> Close</button>
  359.                       </div>
  360.                   </div>
  361.               </div>
  362.           </div>
  363.       </div>
  364.   </div>
  365.   <div class="portfolio-modal modal fade" id="portfolioModal3" tabindex="-1" role="dialog" aria-hidden="true">
  366.       <div class="modal-content">
  367.           <div class="close-modal" data-dismiss="modal">
  368.               <div class="lr">
  369.                   <div class="rl">
  370.                   </div>
  371.               </div>
  372.           </div>
  373.           <div class="container">
  374.               <div class="row">
  375.                   <div class="col-lg-8 col-lg-offset-2">
  376.                       <div class="modal-body">
  377.                           <h2>Project Title</h2>
  378.                           <hr class="star-primary">
  379.                           <img src="img/portfolio/circus.png" class="img-responsive img-centered" alt="">
  380.                           <p>Use this area of the page to describe your project. The icon above is part of a free icon set by <a href="https://sellfy.com/p/8Q9P/jV3VZ/">Flat Icons</a>. On their website, you can download their free set with 16 icons, or you can purchase the entire set with 146 icons for only $12!</p>
  381.                           <ul class="list-inline item-details">
  382.                               <li>Client:
  383.                                   <strong><a href="http://startbootstrap.com">Start Bootstrap</a>
  384.                                   </strong>
  385.                               </li>
  386.                               <li>Date:
  387.                                   <strong><a href="http://startbootstrap.com">April 2014</a>
  388.                                   </strong>
  389.                               </li>
  390.                               <li>Service:
  391.                                   <strong><a href="http://startbootstrap.com">Web Development</a>
  392.                                   </strong>
  393.                               </li>
  394.                           </ul>
  395.                           <button type="button" class="btn btn-default" data-dismiss="modal"><i class="fa fa-times"></i> Close</button>
  396.                       </div>
  397.                   </div>
  398.               </div>
  399.           </div>
  400.       </div>
  401.   </div>
  402.   <div class="portfolio-modal modal fade" id="portfolioModal4" tabindex="-1" role="dialog" aria-hidden="true">
  403.       <div class="modal-content">
  404.           <div class="close-modal" data-dismiss="modal">
  405.               <div class="lr">
  406.                   <div class="rl">
  407.                   </div>
  408.               </div>
  409.           </div>
  410.           <div class="container">
  411.               <div class="row">
  412.                   <div class="col-lg-8 col-lg-offset-2">
  413.                       <div class="modal-body">
  414.                           <h2>Project Title</h2>
  415.                           <hr class="star-primary">
  416.                           <img src="img/portfolio/game.png" class="img-responsive img-centered" alt="">
  417.                           <p>Use this area of the page to describe your project. The icon above is part of a free icon set by <a href="https://sellfy.com/p/8Q9P/jV3VZ/">Flat Icons</a>. On their website, you can download their free set with 16 icons, or you can purchase the entire set with 146 icons for only $12!</p>
  418.                           <ul class="list-inline item-details">
  419.                               <li>Client:
  420.                                   <strong><a href="http://startbootstrap.com">Start Bootstrap</a>
  421.                                   </strong>
  422.                               </li>
  423.                               <li>Date:
  424.                                   <strong><a href="http://startbootstrap.com">April 2014</a>
  425.                                   </strong>
  426.                               </li>
  427.                               <li>Service:
  428.                                   <strong><a href="http://startbootstrap.com">Web Development</a>
  429.                                   </strong>
  430.                               </li>
  431.                           </ul>
  432.                           <button type="button" class="btn btn-default" data-dismiss="modal"><i class="fa fa-times"></i> Close</button>
  433.                       </div>
  434.                   </div>
  435.               </div>
  436.           </div>
  437.       </div>
  438.   </div>
  439.   <div class="portfolio-modal modal fade" id="portfolioModal5" tabindex="-1" role="dialog" aria-hidden="true">
  440.       <div class="modal-content">
  441.           <div class="close-modal" data-dismiss="modal">
  442.               <div class="lr">
  443.                   <div class="rl">
  444.                   </div>
  445.               </div>
  446.           </div>
  447.           <div class="container">
  448.               <div class="row">
  449.                   <div class="col-lg-8 col-lg-offset-2">
  450.                       <div class="modal-body">
  451.                           <h2>Project Title</h2>
  452.                           <hr class="star-primary">
  453.                           <img src="img/portfolio/safe.png" class="img-responsive img-centered" alt="">
  454.                           <p>Use this area of the page to describe your project. The icon above is part of a free icon set by <a href="https://sellfy.com/p/8Q9P/jV3VZ/">Flat Icons</a>. On their website, you can download their free set with 16 icons, or you can purchase the entire set with 146 icons for only $12!</p>
  455.                           <ul class="list-inline item-details">
  456.                               <li>Client:
  457.                                   <strong><a href="http://startbootstrap.com">Start Bootstrap</a>
  458.                                   </strong>
  459.                               </li>
  460.                               <li>Date:
  461.                                   <strong><a href="http://startbootstrap.com">April 2014</a>
  462.                                   </strong>
  463.                               </li>
  464.                               <li>Service:
  465.                                   <strong><a href="http://startbootstrap.com">Web Development</a>
  466.                                   </strong>
  467.                               </li>
  468.                           </ul>
  469.                           <button type="button" class="btn btn-default" data-dismiss="modal"><i class="fa fa-times"></i> Close</button>
  470.                       </div>
  471.                   </div>
  472.               </div>
  473.           </div>
  474.       </div>
  475.   </div>
  476.   <div class="portfolio-modal modal fade" id="portfolioModal6" tabindex="-1" role="dialog" aria-hidden="true">
  477.       <div class="modal-content">
  478.           <div class="close-modal" data-dismiss="modal">
  479.               <div class="lr">
  480.                   <div class="rl">
  481.                   </div>
  482.               </div>
  483.           </div>
  484.           <div class="container">
  485.               <div class="row">
  486.                   <div class="col-lg-8 col-lg-offset-2">
  487.                       <div class="modal-body">
  488.                           <h2>Project Title</h2>
  489.                           <hr class="star-primary">
  490.                           <img src="img/portfolio/submarine.png" class="img-responsive img-centered" alt="">
  491.                           <p>Use this area of the page to describe your project. The icon above is part of a free icon set by <a href="https://sellfy.com/p/8Q9P/jV3VZ/">Flat Icons</a>. On their website, you can download their free set with 16 icons, or you can purchase the entire set with 146 icons for only $12!</p>
  492.                           <ul class="list-inline item-details">
  493.                               <li>Client:
  494.                                   <strong><a href="http://startbootstrap.com">Start Bootstrap</a>
  495.                                   </strong>
  496.                               </li>
  497.                               <li>Date:
  498.                                   <strong><a href="http://startbootstrap.com">April 2014</a>
  499.                                   </strong>
  500.                               </li>
  501.                               <li>Service:
  502.                                   <strong><a href="http://startbootstrap.com">Web Development</a>
  503.                                   </strong>
  504.                               </li>
  505.                           </ul>
  506.                           <button type="button" class="btn btn-default" data-dismiss="modal"><i class="fa fa-times"></i> Close</button>
  507.                       </div>
  508.                   </div>
  509.               </div>
  510.           </div>
  511.       </div>
  512.   </div>
  513.  
  514.   <!-- jQuery -->
  515.   <script src="/vendor/jquery/jquery.min.js"></script>
  516.  
  517.   <!-- Bootstrap Core JavaScript -->
  518.   <script src="/vendor/bootstrap/js/bootstrap.min.js"></script>
  519.  
  520.   <!-- Plugin JavaScript -->
  521.   <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script>
  522.  
  523.   <!-- Contact Form JavaScript -->
  524.   <script src="/js/jqBootstrapValidation.js"></script>
  525.   <script src="/js/contact_me.js"></script>
  526.  
  527.   <!-- Theme JavaScript -->
  528.   <script src="/js/freelancer.min.js"></script>
  529.  
  530. </body>
  531.  
  532. </html>

Reload 127.0.0.1/app_dev.php and your site will now reflect a Freelancer portfolio. Before creating a second page, we’re going to make the frontend code more managable by cutting it up in to a series of templates and blocks. When done, there will be three parts to your Symfony template

base.html.twig The root of the template featuring HTML that will be present on every page; the template skeleton. This provides a quick to view high level representation of the site layout without needing to concern yourself with the details.
common.html.twig Some default content to be used in block positions. Having the common elements in a clearly defined template makes it very quick to change common elements and reduces the chance of breaking the overall layout.
index.html.twig Represents content unique to the page

We'll cut the page in to the following content blocks so that the page is flexible. You might want to add further blocks for pre-content

  • Navigation - For providing the menu
  • Splash - A Header / Call to Action area
  • Body - Where the main content for each page goes
  • Contact - Provide a contact form
  • Footer - End of page links
  1. {# app/Resources/views/base.html.twig #}
  2. <!DOCTYPE html>
  3. <html lang="en">
  4.   <head>
  5.  
  6.     <meta charset="utf-8">
  7.     <meta http-equiv="X-UA-Compatible" content="IE=edge">
  8.     <meta name="viewport" content="width=device-width, initial-scale=1">
  9.     <meta name="description" content="">
  10.     <meta name="author" content="">
  11.  
  12.     <title>Freelancer - Start Bootstrap Theme</title>
  13.  
  14.     <!-- Bootstrap Core CSS -->
  15.     <link href="/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
  16.  
  17.     <!-- Theme CSS -->
  18.     <link href="/css/freelancer.min.css" rel="stylesheet">
  19.  
  20.     <!-- Custom Fonts -->
  21.     <link href="/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
  22.     <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css">
  23.     <link href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic" rel="stylesheet" type="text/css">
  24.     <!--[if lt IE 9]>
  25.     <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
  26.     <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
  27.     <![endif]-->
  28.  
  29.   </head>
  30.  
  31.   <body id="page-top" class="index">
  32.  
  33.     {% block navigation %}{% endblock %}
  34.     {% block splash %}{% endblock %}
  35.     {% block body %}{% endblock %}
  36.     {% block contact %}{% endblock %}
  37.     {% block footer %}{% endblock %}
  38.  
  39.     <!-- jQuery -->
  40.     <script src="/vendor/jquery/jquery.min.js"></script>
  41.  
  42.     <!-- Bootstrap Core JavaScript -->
  43.     <script src="/vendor/bootstrap/js/bootstrap.min.js"></script>
  44.  
  45.     <!-- Plugin JavaScript -->
  46.     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script>
  47.  
  48.     <!-- Contact Form JavaScript -->
  49.     <script src="/js/jqBootstrapValidation.js"></script>
  50.     <script src="/js/contact_me.js"></script>
  51.  
  52.     <!-- Theme JavaScript -->
  53.     <script src="/js/freelancer.min.js"></script>
  54.  
  55.   </body>
  56.  
  57. </html>
  1. {# app/Resources/views/common.html.twig #}
  2. {% extends 'base.html.twig' %}
  3.  
  4. {% block navigation %}
  5.   <nav id="mainNav" class="navbar navbar-default navbar-fixed-top navbar-custom">
  6.       <div class="container">
  7.           <div class="navbar-header page-scroll">
  8.               <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
  9.                   <span class="sr-only">Toggle navigation</span> Menu <i class="fa fa-bars"></i>
  10.               </button>
  11.               <a class="navbar-brand" href="#page-top">Start Bootstrap</a>
  12.           </div>
  13.  
  14.           <!-- Collect the nav links, forms, and other content for toggling -->
  15.           <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
  16.               <ul class="nav navbar-nav navbar-right">
  17.                   <li class="hidden">
  18.                       <a href="#page-top"></a>
  19.                   </li>
  20.                   <li class="page-scroll">
  21.                       <a href="#portfolio">Portfolio</a>
  22.                   </li>
  23.                   <li class="page-scroll">
  24.                       <a href="#about">About</a>
  25.                   </li>
  26.                   <li class="page-scroll">
  27.                       <a href="#contact">Contact</a>
  28.                   </li>
  29.               </ul>
  30.           </div>
  31.           <!-- /.navbar-collapse -->
  32.       </div>
  33.       <!-- /.container-fluid -->
  34.   </nav>
  35. {% endblock %}
  36.  
  37. {% block splash %}
  38.   <header>
  39.       <div class="container">
  40.           <div class="row">
  41.               <div class="col-lg-12">
  42.                   <img class="img-responsive" src="/img/profile.png" alt="">
  43.                   <div class="intro-text">
  44.                       <span class="name">Start Bootstrap</span>
  45.                       <hr class="star-light">
  46.                       <span class="skills">Web Developer - Graphic Artist - User Experience Designer</span>
  47.                   </div>
  48.               </div>
  49.           </div>
  50.       </div>
  51.   </header>
  52. {% endblock %}
  53.  
  54. {% block contact %}
  55. <!-- Contact Section -->
  56. <section id="contact">
  57.     <div class="container">
  58.         <div class="row">
  59.             <div class="col-lg-12 text-center">
  60.                 <h2>Contact Me</h2>
  61.                 <hr class="star-primary">
  62.             </div>
  63.         </div>
  64.         <div class="row">
  65.             <div class="col-lg-8 col-lg-offset-2">
  66.                 <form name="sentMessage" id="contactForm" novalidate>
  67.                     <div class="row control-group">
  68.                         <div class="form-group col-xs-12 floating-label-form-group controls">
  69.                             <label>Name</label>
  70.                             <input type="text" class="form-control" placeholder="Name" id="name" required data-validation-required-message="Please enter your name.">
  71.                             <p class="help-block text-danger"></p>
  72.                         </div>
  73.                     </div>
  74.                     <div class="row control-group">
  75.                         <div class="form-group col-xs-12 floating-label-form-group controls">
  76.                             <label>Email Address</label>
  77.                             <input type="email" class="form-control" placeholder="Email Address" id="email" required data-validation-required-message="Please enter your email address.">
  78.                             <p class="help-block text-danger"></p>
  79.                         </div>
  80.                     </div>
  81.                     <div class="row control-group">
  82.                         <div class="form-group col-xs-12 floating-label-form-group controls">
  83.                             <label>Phone Number</label>
  84.                             <input type="tel" class="form-control" placeholder="Phone Number" id="phone" required data-validation-required-message="Please enter your phone number.">
  85.                             <p class="help-block text-danger"></p>
  86.                         </div>
  87.                     </div>
  88.                     <div class="row control-group">
  89.                         <div class="form-group col-xs-12 floating-label-form-group controls">
  90.                             <label>Message</label>
  91.                             <textarea rows="5" class="form-control" placeholder="Message" id="message" required data-validation-required-message="Please enter a message."></textarea>
  92.                             <p class="help-block text-danger"></p>
  93.                         </div>
  94.                     </div>
  95.                     <br>
  96.                     <div id="success"></div>
  97.                     <div class="row">
  98.                         <div class="form-group col-xs-12">
  99.                             <button type="submit" class="btn btn-success btn-lg">Send</button>
  100.                         </div>
  101.                     </div>
  102.                 </form>
  103.             </div>
  104.         </div>
  105.     </div>
  106.   </section>
  107. {% endblock %}
  108.  
  109. {% block footer %}
  110.   <!-- Footer -->
  111.   <footer class="text-center">
  112.       <div class="footer-above">
  113.           <div class="container">
  114.               <div class="row">
  115.                   <div class="footer-col col-md-4">
  116.                       <h3>Location</h3>
  117.                       <p>3481 Melrose Place
  118.                           <br>Beverly Hills, CA 90210</p>
  119.                   </div>
  120.                   <div class="footer-col col-md-4">
  121.                       <h3>Around the Web</h3>
  122.                       <ul class="list-inline">
  123.                           <li>
  124.                               <a href="#" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
  125.                           </li>
  126.                           <li>
  127.                               <a href="#" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
  128.                           </li>
  129.                           <li>
  130.                               <a href="#" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
  131.                           </li>
  132.                           <li>
  133.                               <a href="#" class="btn-social btn-outline"><i class="fa fa-fw fa-linkedin"></i></a>
  134.                           </li>
  135.                           <li>
  136.                               <a href="#" class="btn-social btn-outline"><i class="fa fa-fw fa-dribbble"></i></a>
  137.                           </li>
  138.                       </ul>
  139.                   </div>
  140.                   <div class="footer-col col-md-4">
  141.                       <h3>About Freelancer</h3>
  142.                       <p>Freelance is a free to use, open source Bootstrap theme created by <a href="http://startbootstrap.com">Start Bootstrap</a>.</p>
  143.                   </div>
  144.               </div>
  145.           </div>
  146.       </div>
  147.       <div class="footer-below">
  148.           <div class="container">
  149.               <div class="row">
  150.                   <div class="col-lg-12">
  151.                       Copyright &copy; Your Website 2016
  152.                   </div>
  153.               </div>
  154.           </div>
  155.       </div>
  156.   </footer>
  157. {% endblock %}
  1. {# app/Resources/views/default/index.html.twig #}
  2. {% extends 'common.html.twig'%}
  3.  
  4. {% block body %}
  5.  
  6.   <!-- Portfolio Grid Section -->
  7.   <section id="portfolio">
  8.       <div class="container">
  9.           <div class="row">
  10.               <div class="col-lg-12 text-center">
  11.                   <h2>Portfolio</h2>
  12.                   <hr class="star-primary">
  13.               </div>
  14.           </div>
  15.           <div class="row">
  16.               <div class="col-sm-4 portfolio-item">
  17.                   <a href="#portfolioModal1" class="portfolio-link" data-toggle="modal">
  18.                       <div class="caption">
  19.                           <div class="caption-content">
  20.                               <i class="fa fa-search-plus fa-3x"></i>
  21.                           </div>
  22.                       </div>
  23.                       <img src="/img/portfolio/cabin.png" class="img-responsive" alt="">
  24.                   </a>
  25.               </div>
  26.               <div class="col-sm-4 portfolio-item">
  27.                   <a href="#portfolioModal1" class="portfolio-link" data-toggle="modal">
  28.                       <div class="caption">
  29.                           <div class="caption-content">
  30.                               <i class="fa fa-search-plus fa-3x"></i>
  31.                           </div>
  32.                       </div>
  33.                       <img src="/img/portfolio/cake.png" class="img-responsive" alt="">
  34.                   </a>
  35.               </div>
  36.               <div class="col-sm-4 portfolio-item">
  37.                   <a href="#portfolioModal1" class="portfolio-link" data-toggle="modal">
  38.                       <div class="caption">
  39.                           <div class="caption-content">
  40.                               <i class="fa fa-search-plus fa-3x"></i>
  41.                           </div>
  42.                       </div>
  43.                       <img src="/img/portfolio/circus.png" class="img-responsive" alt="">
  44.                   </a>
  45.               </div>
  46.               <div class="col-sm-4 portfolio-item">
  47.                   <a href="#portfolioModal1" class="portfolio-link" data-toggle="modal">
  48.                       <div class="caption">
  49.                           <div class="caption-content">
  50.                               <i class="fa fa-search-plus fa-3x"></i>
  51.                           </div>
  52.                       </div>
  53.                       <img src="/img/portfolio/game.png" class="img-responsive" alt="">
  54.                   </a>
  55.               </div>
  56.               <div class="col-sm-4 portfolio-item">
  57.                   <a href="#portfolioModal1" class="portfolio-link" data-toggle="modal">
  58.                       <div class="caption">
  59.                           <div class="caption-content">
  60.                               <i class="fa fa-search-plus fa-3x"></i>
  61.                           </div>
  62.                       </div>
  63.                       <img src="/img/portfolio/safe.png" class="img-responsive" alt="">
  64.                   </a>
  65.               </div>
  66.               <div class="col-sm-4 portfolio-item">
  67.                   <a href="#portfolioModal1" class="portfolio-link" data-toggle="modal">
  68.                       <div class="caption">
  69.                           <div class="caption-content">
  70.                               <i class="fa fa-search-plus fa-3x"></i>
  71.                           </div>
  72.                       </div>
  73.                       <img src="/img/portfolio/submarine.png" class="img-responsive" alt="">
  74.                   </a>
  75.               </div>
  76.           </div>
  77.       </div>
  78.   </section>
  79.  
  80.   <!-- About Section -->
  81.   <section class="success" id="about">
  82.       <div class="container">
  83.           <div class="row">
  84.               <div class="col-lg-12 text-center">
  85.                   <h2>About</h2>
  86.                   <hr class="star-light">
  87.               </div>
  88.           </div>
  89.           <div class="row">
  90.               <div class="col-lg-4 col-lg-offset-2">
  91.                   <p>Freelancer is a free bootstrap theme created by Start Bootstrap. The download includes the complete source files including HTML, CSS, and JavaScript as well as optional LESS stylesheets for easy customization.</p>
  92.               </div>
  93.               <div class="col-lg-4">
  94.                   <p>Whether you\'re a student looking to showcase your work, a professional looking to attract clients, or a graphic artist looking to share your projects, this template is the perfect starting point!</p>
  95.               </div>
  96.               <div class="col-lg-8 col-lg-offset-2 text-center">
  97.                   <a href="#" class="btn btn-lg btn-outline">
  98.                       <i class="fa fa-download"></i> Download Theme
  99.                   </a>
  100.               </div>
  101.           </div>
  102.       </div>
  103.   </section>
  104.  
  105.   <!-- Portfolio Modals -->
  106.   <div class="portfolio-modal modal fade" id="portfolioModal1" tabindex="-1" role="dialog" aria-hidden="true">
  107.       <div class="modal-content">
  108.           <div class="close-modal" data-dismiss="modal">
  109.               <div class="lr">
  110.                   <div class="rl">
  111.                   </div>
  112.               </div>
  113.           </div>
  114.           <div class="container">
  115.               <div class="row">
  116.                   <div class="col-lg-8 col-lg-offset-2">
  117.                       <div class="modal-body">
  118.                           <h2>Project Title</h2>
  119.                           <hr class="star-primary">
  120.                           <img src="/img/portfolio/cabin.png" class="img-responsive img-centered" alt="">
  121.                           <p>Use this area of the page to describe your project. The icon above is part of a free icon set by <a href="https://sellfy.com/p/8Q9P/jV3VZ/">Flat Icons</a>. On their website, you can download their free set with 16 icons, or you can purchase the entire set with 146 icons for only $12!</p>
  122.                           <ul class="list-inline item-details">
  123.                               <li>Client:
  124.                                   <strong><a href="http://startbootstrap.com">Start Bootstrap</a>
  125.                                   </strong>
  126.                               </li>
  127.                               <li>Date:
  128.                                   <strong><a href="http://startbootstrap.com">April 2014</a>
  129.                                   </strong>
  130.                               </li>
  131.                               <li>Service:
  132.                                   <strong><a href="http://startbootstrap.com">Web Development</a>
  133.                                   </strong>
  134.                               </li>
  135.                           </ul>
  136.                           <button type="button" class="btn btn-default" data-dismiss="modal"><i class="fa fa-times"></i> Close</button>
  137.                       </div>
  138.                   </div>
  139.               </div>
  140.           </div>
  141.       </div>
  142.   </div>
  143. {% endblock %}

With the skeleton in place, copy the HTML that was originally in place of our blocks to the common template

At this point, you have a template which allows for quick creation of new pages with only the need to extend the common template and define the body template. Let's finish it by creating the home page template. Please note that in the demo code below, I cut down the number of modals from 6 to 1 (replacing the links along the way) to keep the code shorter.

Reload the web page to check that everything has worked, it should look the same.

Creating a second page

In this section, we'll lay down the foundation for what will be a blog section of the website to be covered in a later tutorial.

The Template

The template work you performed in the last step was all about preperation and you will see that payoff now. Open up the home page template app/Resources/views/default/index.html.twig, we're going to organise the views. Create another folder in views called blog and save it there: app/Resoureces/views/blog/index.html.twig.

I recommend naming the file as index because it will act as the directory index for the blog part of our website and by being named index, we’ll be able to recognise it very quickly.

Within this file, to speed up development, we’re going to use some more boilerplate code that has already been made for us. The code can be found at the following link with the resulting file contents proceeding.

Get the listing boilerplate
  1. {% extends 'common.html.twig' %}
  2.  
  3. {% block body %}
  4.   <h2>
  5.     <a href="#">Blog Post Title</a>
  6.   </h2>
  7.   <p class="lead">
  8.     by
  9.     <a href="index.php">Start Bootstrap</a>
  10.   </p>
  11.   <p>
  12.     <span class="glyphicon glyphicon-time"></span>
  13.     Posted on August 28, 2013 at 10:00 PM</p>
  14.   <hr>
  15.   <img class="img-responsive" src="http://placehold.it/900x300" alt="">
  16.   <hr>
  17.   <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolore, veritatis, tempora, necessitatibus inventore nisi quam quia repellat ut tempore laborum possimus eum dicta id animi corrupti debitis ipsum officiis rerum.</p>
  18.   <a class="btn btn-primary" href="#">Read More
  19.     <span class="glyphicon glyphicon-chevron-right"></span>
  20.   </a>
  21.  
  22.   <hr>
  23. {% endblock %}

A second controller

With the template in place, it's time to create a route to make the template we just prepared reachable. It is possible to add the route to the default controller but, because the blog will be a distinct part of the site, we should reflect that in our code.

To do this open the Default controller and save it in the same directory but change it's name to BlogController.php. With that done, make the following changes:

  • The class name becomes BlogController
  • The @Route annotation defines the new blog route so change both the URI path and the internal reference
  • The template returned uses the new template
  1. <?php
  2. // # src/AppBundle/Controller/BlogController.php
  3. namespace AppBundle\Controller;
  4.  
  5. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  6. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  7. use Symfony\Component\HttpFoundation\Request;
  8.  
  9. class BlogController extends Controller
  10. {
  11.     /**
  12.      * @Route("/blog", name="blog_index")
  13.      */
  14.     public function indexAction()
  15.     {
  16.       return $this->render('blog/index.html.twig');
  17.     }
  18. }

Now, trying visiting:

  1. 127.0.0.1/app_dev.php/blog

You should now see a new page but, we still have a large header across the page; this is due to the way we have defined our template structure. In common there is a block called splash; let's remove that area from the page.

Within your blog index template we declare the block and will make the contents an empty container with some height to push content below the fixed navigation bar.

  1. {% block splash %}<div style="height:10rem;"></div>{% endblock %}
This isn't a great solution but, it works and minimal effort / time was expended in the process.

Now we have our blog index page, we need some way to reach it from the site without knowing the URL; our navigation is defined in the common template so open that up.

We could use the blog URI directly as the href but, this is not very maintainable as it would force us to go through all points of the code being sure to change each link should it ever change. Within the route annotation from the blog controller we created, one of the options is called name.

  1. @Route("/blog", name="blog_index")

This is our route name which allows us to reference the URL without needing to know the actual URL, it will always point to controller. Path is a twig function that will print the path for the route name that gets passed in as the first parameter.

  1. <li>
  2.   <a href="{{ path('blog_index') }}">Blog</a>
  3. </li>

Exercises

  • Create a block that will allow you to add additional style sheets in the head section
  • Create a block that will allow you to add additional script files at the bottom of your page

Communication, our greatest tool

Whether you want to connect, have a problem I can help with or simply want to drop a line, I welcome your words!