If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
Even though I look like lunch to them, I love dinosaurs. So on the dinosaur
page, I want to show my affection with a little heart icon, using Font Awesome.
In the h1
, add <i class="fa fa-heart"></i>
:
... lines 1 - 10 | |
<h1>{{ dino.name }} the {{ dino.type }} <i class="fa fa-heart"></i></h1> | |
... lines 12 - 23 |
When I refresh, no love for my dinosaurs. That's because I don't have the
Font Awesome CSS inside of my project. Let's see if bower can fetch it for
us! At the command line, say bower install font-awesome --save
- that's
similar to the --save-dev
option with npm.
When that's done, we can find it in vendor/bower_components/font-awesome
.
And our bower.json
file has a new entry in it:
{ | |
... lines 2 - 15 | |
"dependencies": { | |
"bootstrap": "~3.3.2", | |
"font-awesome": "~4.3.0" | |
} | |
} |
Thanks bower!
Our first job is to get that font-awesome.css
into our site. We know how
to do that - just add it to our main.css
file. I'll copy the bootstrap
line then update it to font-awesome/css/font-awesome.css
. Done.
... lines 1 - 39 | |
app.addStyle([ | |
config.bowerDir+'/bootstrap/dist/css/bootstrap.css', | |
config.bowerDir+'/font-awesome/css/font-awesome.css', | |
config.assetsDir+'/sass/layout.scss', | |
config.assetsDir+'/sass/styles.scss' | |
], 'main.css'); | |
... lines 46 - 72 |
Refresh! Hearts for dino friends! So we're done right?
Well, actually, it shouldn't work. In the inspector, I've got 404 errors for the fontawesome font files. The only reason the heart shows up is that I happen to have the fontawesome font file installed on my computer. But this will be a broken heart for everyone else in the (Jurassic) world.
Font Awesome goes up one level from its CSS and looks for a fonts/
directory.
Since its code lives in main.css
, it goes up one level and looks for fonts/
right at the root of web/
. If you bring in the Font Awesome Sass package,
you can control where it's looking. But even then, we have a problem. The
FontAwesome fonts/
directory is buried deep inside vendor/bower_components
.
Somehow, we need to copy this stuff into web/
.
Copying files around sounds pretty handy. So lets go straight to making a
new function app.copy
with two arguments srcFiles
and outputDir
. We'll
read in some source files and copy them to that new spot:
... lines 1 - 33 | |
app.copy = function(srcFiles, outputDir) { | |
... lines 35 - 36 | |
}; | |
... lines 38 - 72 |
Great news! You already know how to copy files in Gulp! Just create the normal
pipe chain, but without any filters in the middle: gulp.src(srcFiles)
,
then pipe that directly to gulp.dest(outputDir)
:
... lines 1 - 33 | |
app.copy = function(srcFiles, outputDir) { | |
gulp.src(srcFiles) | |
.pipe(gulp.dest(outputDir)); | |
}; | |
... lines 38 - 72 |
So nice!
Next, add a new task called fonts
. The job of this guy will be to "publish"
any fonts that we have into web/
. Right now, it's just the FontAwesome
stuff. Use the app.copy()
and for the path, start with config.bowerDir
.
I'll scroll up so we can see the path. Now, font-awesome/fonts/*
to grab
everything. For the target, just web/fonts
:
... lines 1 - 58 | |
gulp.task('fonts', function() { | |
app.copy( | |
config.bowerDir+'/font-awesome/fonts/*', | |
'web/fonts' | |
); | |
}); | |
... lines 65 - 72 |
We'll want this to run with our default task, so add fonts
down there:
... lines 1 - 70 | |
gulp.task('default', ['styles', 'scripts', 'fonts', 'watch']); |
But I don't really care about watch - it's not like we'll be actively changing these files.
Ok, restart Gulp!
gulp
Yes, it is running the fonts
task. Inside web/
, we have a shiny
new - and populated - fonts/
directory. And since FontAwesome is looking
right here for them, we can refresh, and those nasty 404's are gone.
We don't want to commit this new web/fonts
directory - it's got generated
files just like the css/
and js/
folders. To avoid the humiliation of
accidentally adding them to your repo, add this path to .gitignore
.
... lines 1 - 15 | |
/web/fonts | |
... lines 17 - 18 |
That's it! And if there's anything else you need to move around, just use
our handy app.copy()
.
Hi Gasper!
Hmm, interesting! When you run gulp, do you see files that end in .map in your web/js and web/css directories? Your browser knows to load these - e.g. for site.js, it will look for site.js.map. So, either these map files are missing (in this case, you should also see a 404 in your browser network tools) or they are corrupt in some way.
Let me know what you find out!
I just found out I have to delete old *.js.map and *.css.map files when running gulp and than gulp --production. Now it works fine. Tnx!
Hi Ryan, thanks for the great tutorial !
I was wondering if you have a best practise for css url rewriting. I have found gulp plugins but I am running into issues at the moment.
Hi Nicolas!
My approach is basically to avoid this :). What I mean is - like in this chapter - if bootstrap is looking for fonts in ../fonts, I just publish them there, relative to where the bootstrap CSS is published (of course, in bootstrap, there is another solution by changing less/sass variables to control the fonts directory). And the same goes for my code - I'm purposefully trying to *not* change the directory organization when I publish things into web so that I can avoid needing to rewrite.
But, I have played with this a little, and for me, I think if you *do* run into this problem and can't avoid it, I like something like gulp-replace to modify the URLs. It's not automatic or fancy, but it's very easy to understand in those cases where you need it. I haven't used a replace method extensively, but that's what I like ... other than avoiding the problem altogether ;)
Cheers!
I agree, if the path makes sense, a good option is to publish the assets accordingly. In some cases, I prefer to change it tho. Thanks for pointing to gulp-replace, it worked perfectly !
The copy function doesn't work with folders.
I'm using flag icon and this wsn't working.
app.copy(config.bowerDir+'/flag-icon-css/flags/*', config.assetDir+'/flags');
I had to use
app.copy(config.bowerDir+'/flag-icon-css/flags/1x1/*', config.assetDir+'/flags/1x1');
app.copy(config.bowerDir+'/flag-icon-css/flags/4x3/*', config.assetDir+'/flags/4x3');
It's ok in this case as there is only 2 folders.
just to mention.
Hi there!
Hmm, does it work if you copy /flags/**? Often, the ** is used to be recursive.
Either way, thanks for the note!
// composer.json
{
"require": {
"php": ">=5.3.3",
"symfony/symfony": "2.6.*", // v2.6.4
"doctrine/orm": "~2.2,>=2.2.3", // v2.4.6
"doctrine/doctrine-bundle": "~1.2", // v1.2.0
"twig/extensions": "~1.0", // v1.2.0
"symfony/assetic-bundle": "~2.3", // v2.5.0
"symfony/swiftmailer-bundle": "~2.3", // v2.3.7
"symfony/monolog-bundle": "~2.4", // v2.6.1
"sensio/distribution-bundle": "~3.0", // v3.0.9
"sensio/framework-extra-bundle": "~3.0", // v3.0.3
"incenteev/composer-parameter-handler": "~2.0", // v2.1.0
"hautelook/alice-bundle": "~0.2" // 0.2
},
"require-dev": {
"sensio/generator-bundle": "~2.3" // v2.4.0
}
}
Hi, thank you for great tutorial!!! I am having some issues... With bower I installed bootstrap and font-awesome but after running gulp and open page in browser I get Failed to parse SourceMap in console. What I am doing wrong? Tnx!