Buy

Dinosaurs! Actually, these are our test project, and it's written in Symfony. But everything we'll do translates to any PHP project.

But this look bad - it's messed up. And that's totally my fault. Open up the base layout - app/Resources/view/base.html.twig. I'm including Twitter Bootstrap, but that's it so far:

46 lines app/Resources/views/base.html.twig
... lines 1 - 2
<head>
... lines 4 - 9
<link rel="stylesheet" href="{{ asset('vendor/bootstrap/dist/css/bootstrap.css') }}"/>
... lines 11 - 15
</head>
... lines 17 - 46

I do have a project-specific CSS file, but it's missing from here. The problem is that it's not a CSS file at all - it's a Sass file that lives in app/Resources/assets.

Btw, this is where I've decided to put my frontend assets, but it doesn't matter. But do notice that this is not a public directory.

Gulp's first job will be to turn that Sass file into CSS so I can get my site to stop looking so ugly.

Installing gulp-sass

With Gulp, we make tasks. But it doesn't do much else. Most things are done with a plugin. Go back to Gulp's site and click Plugins to find a search for, not 13, but 1373 plugins. The one we want is gulp-sass.

First, install it! Copy the npm install gulp-sass. But wait! I want you to add that --save-dev because I want this plugin to be added to our package.json file:

npm install gulp-sass --save-dev

Hey, there it is! When another developer clones the project, they just need to run npm install and it'll download this stuff automatically. Oh, and the gulp-sass plugin preps a sass binary in the background. If you have any issues installing - especially you wild Windows users - check out the node-sass docs.

The Classic pipe Workflow

Head back to the docs. This is showing a classic Gulp workflow. We start by saying gulp.src() to load files matching a pattern. Next, you'll pipe it through a filter - in our case sass() - and pipe it once more to gulp.dest(). That actually writes the finished files.

Let's do it! Be lazy by copying the require line and adding it to the top of our file. Now we'll say gulp.src. Let's load all the Sass files that are in that sass/ directory - so app/Resources/assets/sass/**/*.scss:

9 lines gulpfile.js
var gulp = require('gulp');
var sass = require('gulp-sass');
gulp.task('default', function() {
gulp.src('app/Resources/assets/sass/**/*.scss')
... lines 6 - 7
});

That double ** tells Gulp to look recursively inside the sass directory for .scss files. That'll let me create subdirectories later if I want.

Now that we've loaded the files, we'll just pipe them through whatever we need. Use pipe() then sass() inside of it. Gulp works with streams, so imagine Gulp is opening up all of our .scss files as a big stream and then passing them one-by-one through the pipe() function. So at this point, all that Sass has been processed. Then finally, we'll pipe that to gulp.dest() and say: "Hey, I want you to dump the finished product to the web/css/ directory.":

9 lines gulpfile.js
var gulp = require('gulp');
var sass = require('gulp-sass');
gulp.task('default', function() {
gulp.src('app/Resources/assets/sass/**/*.scss')
.pipe(sass())
.pipe(gulp.dest('web/css'));
});

That's all we need! Head back to the terminal and just type gulp:

gulp

Ok, no errors - that seems good. But now we do have a web/css/styles.css file. And I know it got processed through Sass because the original is using a variable.

Using the Boring CSS File

Now that we have a boring, normal, generated styles.css file, let's add the link tag to our base template. This uses that asset() function from Symfony, but that's not actually doing anything here. The path is relative to the public directory - web/ for a Symfony project.

48 lines app/Resources/views/base.html.twig
... lines 1 - 2
<head>
... lines 4 - 9
<link rel="stylesheet" href="{{ asset('vendor/bootstrap/dist/css/bootstrap.css') }}"/>
<link rel="stylesheet" href="{{ asset('css/styles.css') }}"/>
... lines 13 - 17
</head>
... lines 19 - 48

Head back, and refresh! Dinosaurs! That's much better.

Ignore Directories in git

Since the web/css/ directory only contains generated files, we don't need to commit it. If these files are missing, just run gulp! The same goes for node_modules - we can get that by running npm install. Silly directories.

So anyways, it'd be great to not commit these. So let's open up the .gitignore file and add /node_modules and /web/css:

17 lines .gitignore
... lines 1 - 13
/node_modules
/web/css
... lines 16 - 17

Now when I run git status again, that stuff's gone!

Leave a comment!

  • 2016-05-23 Andrea

    Yes you right.
    The second one is the right answer.
    Thanks a lot.

  • 2016-05-22 weaverryan

    Hi Andrea!

    Hmm. The fact that you see the error means that Symfony *is* running correctly. What happens if you run "app/console router:debug" from the terminal? Do you see the dinosaur_list route in the list?

    Also, you could try starting the web server on a different port - e.g.

    app/console server:run localhost:9002

    Then go to http://localhost:9002. I'm wondering if you have some other Symfony app already running on port 8000, so you're seeing this *other* app instead :).

    Let me know!

  • 2016-05-21 Andrea

    I tried to setup the project, downloaded your code, using dir "start", then i read all the steps in README but when i look for the site in http;//localhost:8000 symfony says "No route found for "GET /". What's i'm wrong?

  • 2015-05-25 weaverryan

    You got it! I just updated the README with these installation instructions (note: the assetic:dump isn't needed for this project). I'll start making sure we have these for *every* project.

    Thanks!

  • 2015-05-25 Pietrino Atzeni

    Autoanswer: the missing step is

    bower install

  • 2015-05-25 Pietrino Atzeni

    Hi Ryan,
    trying to follow the tutorial, I downloaded the project and started the base project. As usual, then, some

    composer install

    app/console doctrine:database:create
    app/console doctrine:schema:create
    app/console doctrine:fixtures:load

    app/console assets:install --symlink
    app/console assetic:dump

    and finally

    app/console server:run

    Opening the page, though, there is no vendor/bootstrap folder, and so the page is even uglier than yours :). Am I missing something?

    Thanks,
    Pietro