Worklog Part 1: Building web application with Bootstrap

Integrating Start Bootstrap template

We will implement bootstrap based web application theme in Silex application. The best way to start out is with already available theme.

To install it into our application just execute bower install command in application web folder:

H:\Ampps\www\worklog\web>bower install startbootstrap-sb-admin-2

After installation of all required components (including jquery, bootstrap  and a few others) we will need some help how to use them. You can download sample implementation and start learn directly from included sample application.

After unzipping sample into local www folder we can navigate to it and start inspecting how it is constructed.

2015-11-26 19_08_40-SB Admin 2 - Bootstrap Admin Theme

This beautiful sample contain almost everything what is needed to build very powerful web application !

Next step is converting part of this sample code into our application.

Integrating template in silex application

We need to analyze index.html file from the sample and transfer definitions into our base.html.twig file.  As you can see in the content of twig file, we only copy “link” and “script” nodes to our file and adjust locations of used resources.

After you have everything in place the response after loading index.php should be something like this (Firefox/Developer tools/Network screen):

2015-11-26 19_46_09-Network - http___localhost_worklog_web_index.php

All resources should be loaded successfully .

The content of twig base file:

{# Base page template #}
<html>
<head>
    {% block head %}
        <!-- Standard HTML head -->
        <meta charset="UtF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>{% block title %}{% endblock %} - Bisaga Worklog</title>
        {% block stylesheets %}{% endblock %} 
        
        <!-- FAVICON -->
        <link rel="icon" type="image/x-icon" href="{{app.request.basepath}}/favicon.ico" />
        
        <!-- Bootstrap Core CSS -->
        <link rel="stylesheet" href="{{app.request.basepath}}/bower_components/bootstrap/dist/css/bootstrap.min.css" />

        <!-- MetisMenu CSS -->
        <link href="{{app.request.basepath}}/bower_components/metisMenu/dist/metisMenu.min.css" rel="stylesheet">

        <!-- Timeline CSS -->
        <link href="{{app.request.basepath}}/bower_components/startbootstrap-sb-admin-2/dist/css/timeline.css" rel="stylesheet">

        <!-- SB-Admin CSS -->
        <link href="{{app.request.basepath}}/bower_components/startbootstrap-sb-admin-2/dist/css/sb-admin-2.css" rel="stylesheet">

        <!-- Morris Charts CSS -->
        <link href="{{app.request.basepath}}/bower_components/morrisjs/morris.css" rel="stylesheet">

        <!-- Custom Fonts -->
        <link href="{{app.request.basepath}}/bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">

        <!-- Worklog custom CSS -->
        <link rel="stylesheet" href="{{app.request.basepath}}/css/worklog.css" />
        
        <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
        <![endif]-->          
    {% endblock %}    
</head>
<body>
    <div id="content">{% block content %}{% endblock %}</div>
    <div id="footer">
        {% block footer %}
            &copy; Copyright 2015 by <a href="http://bisaga.com/">Bisaga</a>.
        {% endblock %}
    </div>
    {% block javascripts %}{% endblock %}
    <!-- jQuery -->
    <script src="{{app.request.basepath}}/bower_components/jquery/dist/jquery.min.js"></script>
    
    <!-- Bootstrap Core JavaScript -->
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="{{app.request.basepath}}/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>    

    <!-- Metis Menu Plugin JavaScript -->
    <script src="{{app.request.basepath}}/bower_components/metisMenu/dist/metisMenu.min.js"></script>

    <!-- Morris Charts JavaScript -->
    <script src="{{app.request.basepath}}/bower_components/raphael/raphael-min.js"></script>
    <script src="{{app.request.basepath}}/bower_components/morrisjs/morris.min.js"></script>

    <!-- Custom Theme JavaScript -->
    <script src="{{app.request.basepath}}/bower_components/startbootstrap-sb-admin-2/dist/js/sb-admin-2.js"></script>
    
</body>
</html>

Worklog application folder now grow little larger because of new front-end components in bower_components folder.

2015-11-26 20_03_12-Programmer's Notepad - [index.html]

At this point our web application is almost empty, but we have all  necessary components ready to use.

This example application is available on the Github.

Include Bootstrap in Symfony 2 application

Bootstrap

The best tool to design nice, responsive, mobile first web applications is bootstrap framework. It is  also integrated as form design theme in symfony.

Before you can use it in your symfony application, you will need to install it.

The easiest way is with a web front-end package manager – bower. You should install node first and then install bower with npm package manager.  Then including resources in your twig templates is as easy as use asset component.

Isn’t this little to much to start with ?

Shortcut

If you don’t know what node/npm/bower is or if you don’t want to know (for now) 🙂 , you can just use bootstrap directly from publicly accessible  CDN links. Do not forget to include jquery library first, it is required by bootstrap.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">        
        <title>{% block title %}Bisaga application{% endblock %}</title>
        {% block stylesheets %}{% endblock %}
        <link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
        <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
        <![endif]-->        
    </head>
    <body>
        {% block body %}{% endblock %}
        {% block javascripts %}{% endblock %}
        <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
        <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
        <!-- Include all compiled plugins (below), or include individual files as needed -->
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    </body>
</html>

Just don’t forget, if you take shortcuts, you get cut short.

Using bower

Why we needs front-end package management ?  With front-end package manager we simplify installing and updating project dependencies for client side libraries. Bower also check inter-dependencies between those libraries and won’t install the package incompatible with one that’s already installed.

If you use bower for front-end package management  and don’t want to use default download directory (“bower_components”), just create local config file “.bowerrc”:

{
  "directory": "libs"
}

Then you can install bootstrap with a command :

H:\Ampps\www\webapp05\www\> bower install --save bootstrap

You will get two sub folders, “bootstrap” and “jquery”, inside “libs” folder.

Asset component

With asset component we generate URL addresses of web assets such as CSS, stylesheets, graphics and Javascript files. This means that you can change location of assets at one place  in configuration file.

We create new  “assets” section in “framework”  section of config.yml file and add three “packages” inside :

framework:
    assets:
        packages:
            jquery:
                base_path: /libs/jquery/dist/
            bootstrapjs:
                base_path: /libs/bootstrap/dist/js/
            bootstrapcss:
                base_path: /libs/bootstrap/dist/css/

With that in place we can define URL location in our template file with asset function, for example:

 <link rel="stylesheet" href="{{ asset('bootstrap.min.css', 'bootstrapcss') }}">

Second parameter in asset function is package location from config.yml file.

And the final twig file with all required includes for bootstrap is :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">        
        <title>{% block title %}Bisaga application{% endblock %}</title>
        {% block stylesheets %}{% endblock %}
        <link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
        <link rel="stylesheet" href="{{ asset('bootstrap.min.css', 'bootstrapcss') }}">
        <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
        <![endif]-->        
    </head>
    <body>
        {% block body %}{% endblock %}
        {% block javascripts %}{% endblock %}
        <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
        <script src="{{ asset('jquery.min.js', 'jquery') }}"></script>
        <!-- Include all compiled plugins (below), or include individual files as needed -->
        <script src="{{ asset('bootstrap.min.js', 'bootstrapjs')}}"></script>
    </body>
</html>