If you’re following the series, you definitely saw how ugly our page was at the end of the last post. Well, good news – we’re gonna fix it right now. Before you close the window, let me explain: I’m not going to start doing graphical design here, as I do not know enough about it. Instead, I’m going to show you how to use Yesod
with one of the best design libraries in the world – Bootstrap. Yesod has kind of built-in support for Bootstrap – you might’ve guessed it by the import Yesod.Form.Bootstrap3()
line in Projects.hs
. It’s actually not exactly what we’re looking for, so let’s change it to import Yesod.Bootstrap()
and add Yesod.Bootstrap
to build dependencies in .cabal
file. You might need to run stack solver --update-config && stack build
before next run.
And that’s it – Bootstrap
is already included in our files. Now let’s get rid of the ugly projects.cassius
and let’s replace it with some nice styling!
But before this, you might be a little surprised that including Bootstrap
didn’t require us to add any additional CSS files. That’s not actually true – we simply already have one. It’s located in static/css/bootstrap.css
. If you are able to access the site after running stack exec -- yesod devel
, you have this file – otherwise the site wouldn’t even compile.
Now you can delete all the classes and IDs we used in previous post and replace the .hamlet
file with something like this:
<div> <h1 .page-header> Available projects: <div .jumbotron> <ul .list-group> <li .list-group-item> Project 1 <li .list-group-item> Project 2 <li .list-group-item> Super project
looks much better now, doesn’t it?
The hardcoded project names are quite a shame, we should get rid of them. Let’s make our Hamlet template an actual template that is filled with some data! For the first shot let it be a simple list of project names – typed [Text]
. Wonder why not [String]
? Short answer is: it’s more efficient. For a slightly longer one you can check out The Yesod Book. Anyway, our goal now is to have a list of Text
s passed to the template and same output rendered. To do this, we need to add a little big of logic to our template. Lines starting with $
are treated as special instructions, virtually typical Haskell operations. #{someName}
is used for variable interpolation. Check out the code for projects.hamlet
:
<div> <h1 .page-header> Available projects: <div .jumbotron> $if null projects There are no ongoing projects $else <ul .list-group> $forall projectName <- projects <li .list-group-item> #{projectName}
Quite a change, isn’t it? But it’s quite simple – if there are no elements in projects
container we show a message, otherwise – list all elements one-by-one.
But the code doesn’t compile again. To make it work you have to add projects
variable to the scope of widgetFile
invocation. This can be done for example by adding
to getProjectsR
function.
And that’s it! we can feed the template via the list in Projects.hs
file. Nice, eh?
Actually, no. Right now it’s even worse than it was – previously it was sufficient to modify projects.hamlet
and yesod runner automatically reloaded all the stuff. Now the compilation has to be done manually, by running stack build
. Have no fear, we will change this in the future. but the next step is different. The next step will introduce Yesod’s killer feature – typesafe routes.
Stay tuned!
code
more code
~~~~