Joeri Verdeyen bio photo

Joeri Verdeyen

Web-engineer, cyclist, Nespresso lover, Strava pusher.

Twitter LinkedIn Instagram Github Stackoverflow Last.fm Strava

Bootswatch (free Bootstrap themes) and Symfony2

Bootswatch

Bootswatch logo

Symfony2 AcmeDemoBundle

I’m starting this example from an empty Symfony2 project, you can follow the Installing and Configuring Symfony2 Cookbook.

Node packages

I will need to install Node packages, so you’ll have to install Node.js. Create a package.json file in the root of your project folder with the following content.

package.json
{
  "name": "AcmeDemoProject",
  "version": "1.0.0",
  "private": true,
  "main": "gulpfile.js",
  "dependencies": {},
  "devDependencies": {
    "bower": "~1.3",
    "gulp": "^3.8.8",
    "gulp-concat": "^2.3.4",
    "gulp-minify-css": "~0.3.0",
    "gulp-plumber": "^0.6.4",
    "gulp-ruby-sass": "~0.3.0",
    "gulp-uglify": "^0.3.1",
    "gulp-rename": "~1.0.0"
  }
}

Install all packages by running the following command in your console:

$ npm install

Bower

Bower keeps track of packages in a manifest file, bower.json. We need some to install jquery, ‘bootswatch’ and bootstrap packages. Create a bower.json file in the root of your project folder with the following content.

bower.json
{
  "name": "AcmeDemoProject",
  "version": "1.0.0",
  "dependencies": {
    "jquery": "components/jquery#~2.1.1",
    "bootswatch-scss": "~3.2.0",
    "bootstrap-sass-official": "~3.2.0"
  }
}

Install all packages by running the following command in your console:

$ ./node_modules/.bin/bower install

Combine Bootstrap and Bootswatch

Now we combine Bootstrap and Bootswatch into one scss file, I’m adding this file in the DemoBundle’ resources. In the following snippet the united Bootswatch theme will be used, you can replace it with any theme from Bootswatch.

src/Acme/DemoBundle/Resources/public/css/bootstrap.scss
@import "../../../../../../bower_components/bootswatch-scss/united/variables";
@import "../../../../../../bower_components/bootstrap-sass-official/assets/stylesheets/bootstrap";
@import "../../../../../../bower_components/bootswatch-scss/united/bootswatch";

Gulp

To build everything I’m not using Assetic but Gulp. Create a gulpfile.json file in the root of your project folder with the following content.

gulpfile.js
var gulp = require('gulp')
,   sass = require('gulp-ruby-sass')
,   minifyCSS = require('gulp-minify-css')
,   concat = require('gulp-concat')
,   plumber    = require('gulp-plumber')
,   uglify = require('gulp-uglify')
,   rename = require('gulp-rename');

var onError = function(err) {
    console.log(err);
}

gulp.task('styles', function() {

    var bootstrap = gulp.src('./src/Acme/DemoBundle/Resources/public/css/bootstrap.scss')
        .pipe(plumber({
            errorHandler: onError
        }))
        .pipe(sass({ style: 'expanded' }))
        .pipe(minifyCSS({keepBreaks:true}))
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('./web/css/'));
});


gulp.task('scripts', function() {
    return gulp.src('./bower_components/bootstrap-sass-official/assets/javascripts/bootstrap.js')
        .pipe(plumber({
            errorHandler: onError
        }))
        .pipe(uglify())
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('./web/js/'));
});

gulp.task('copy', function() {
    gulp.src('./bower_components/bootstrap-sass-official/assets/fonts/bootstrap/*.{ttf,woff,eof,svg,eot}')
    .pipe(gulp.dest('./web/fonts/bootstrap/'));
});

gulp.task('copy_jquery', function() {
    gulp.src('./bower_components/jquery/jquery.min.js')
    .pipe(gulp.dest('./web/js/'));
});

gulp.task('build', [
         'copy',
         'copy_jquery',
         'styles',
         'scripts'
]);

Build your Bootswatch setup with the following command:

$ ./node_modules/.bin/gulp build

Symfony2 assets

The only thing that needs to be done is adding the freshly builded css and javascript assets in the template files. Presume you’re still using the AcmeDemoBundle than you should replace bundles/acmedemo/css/demo.css with css/bootstrap.css in src/Acme/DemoBundle/Resources/views/layout.html.twig.

src/Acme/DemoBundle/Resources/views/layout.html.twig
{% block head %}
    <link rel="stylesheet" href="{{ asset('css/bootstrap.min.css') }}" />
{% endblock %}

Add the javascript assets before the body block closing tags.

src/Acme/DemoBundle/Resources/views/layout.html.twig
{% block body %}
..
<script type="text/javascript">
    window.jQuery || document.write("<script src='{{ asset('js/jquery.min.js') }}'>"+"<"+"/script>");
</script>

<script src="{{ asset('js/bootstrap.min.js') }}"></script>
{% endblock %}

That’s it!

There is much more to do. For example, use the BraincraftedBootstrapBundle or Mopa Bootstrap Bundle to easily integrate Bootstrap form themes.

Thanks for reading

Feel free to leave a comment if you have remarks or like this post