Foundation for Phoenix

Posted on Tue 31 May 2016 in english

Intro

OK, so you've decided to use another framework instead of Phoenix's default bootstrap. Foundation is one of the biggest competitors to Twitter's bootstrap (currently over https://github.com/zurb/foundation-sites[23.000 stars on GitHub]) and was created by Zurb, which offer a wide variety of so-called http://zurb.com/building-blocks["building blocks"] you can use for your own website. There's an even bigger set of examples of "pattern taps", "responsive" and several other UI code samples you can find in their library.

TIP: Since 1998, we’ve accumulated an arsenal of tools and knowledge that serve as an invaluable resource to both inspire and empower designers around the world. We’ve collected these awesome assets all in one place, the library. We think you’ll love it.

Install packages

Let's start! After creating the initial Phoenix project we need to upgrade brunch to the most recent version 2.8.0 in order to get easy integration of NPM packages into the asset pipeline. Afterwards we can install all necessary NPM packages for Foundation.

$ sed -i s/'"brunch": "~2.1.3"'/'"brunch": "~2.8.0"'/ package.json
$ npm install
$ npm install --save-dev foundation-sites motion-ui sass-brunch jquery

Brunching

Add the sass-brunch plugin to your config and add jQuery to the whitelist so it gets pulled in by brunch:

.brunch-config.js

plugins: {
  babel: {
     ignore: [/web\/static\/vendor/]
  },
  sass: {
    options: {
      includePaths: [
        'node_modules/foundation-sites/scss',
        'node_modules/motion-ui/src'
      ]
    }
  }
}

npm: {
 enabled: true,
 whitelist: ["phoenix", "phoenix_html", "jquery"],
 globals: {
   $: 'jquery',
   jQuery: 'jquery'
 }
}

To tell brunch how to find our jquery and foundation-site JavaScript code change your brunch-config.js to include everything from the 'node_modules' folder:

.brunch-config.js

javascripts: {
  joinTo: {
   "js/app.js": /^(web\/static\/js)/,
   "js/vendor.js": /^(node_modules)/
  }
}

Use SASS

We don't need the included bootstrap content from web/static/css/app.css anymore, so it's safe to delete the whole content.

Foundation-sites ships with a default SASS file, but you can overwrite the default values. In order to use SASS we must create the folder web/static/scss and copy the content from node_modules/foundation-sites/scss/settings/_settings.scss to web/static/scss/_settings.scss. This is the specific file containing Foundation's SASS defaults which you can overwrite using a _custom.scss.

Include _custom.scss and _settings.scss in web/static/scss/application.scss:

.web/static/scss/application.scss

@import "settings";
@import "foundation";
@include foundation-everything;
@import "motion-ui";
@include motion-ui-transitions;

@import "custom";

To customize our top-bar let's tweak it's background-color in web/static/scss/_custom.scss:

.web/static/scss/_custom.scss

.top-bar {
  background-color: #5b5b5b;
  .menu {
    background-color: #5b5b5b;
  }
  .submenu {
    background-color: #5b5b5b;
  }
}
.dropdown-menu {
  background-color: #5b5b5b;
}

Import Foundation

Now the last thing we need to do is import Foundation in web/static/js/app.js:

.web/static/js/app.js

import "foundation-sites"

Add our 'vendor.js' file, which was created by brunch, to web/templates/layout/app.html.eex and http://foundation.zurb.com/sites/docs/javascript.html[initialize Foundation]. As an example for Foundation I've used a http://foundation.zurb.com/sites/docs/top-bar.html[top-bar from Foundation's example section]:

.web/templates/layout/app.html.eex

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Hello Foundation2!</title>
    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
  </head>

  <body>
    <div class="container">
      <header class="header">
        <div class="top-bar">  <1>
          <div class="top-bar-left">
            <ul class="dropdown menu" data-dropdown-menu>
              <li class="menu-text">Site Title</li>
              <li>
                <a href="#">One</a>
                <ul class="menu vertical">
                  <li><a href="#">One</a></li>
                  <li><a href="#">Two</a></li>
                  <li><a href="#">Three</a></li>
                </ul>
              </li>
              <li><a href="#">Two</a></li>
              <li><a href="#">Three</a></li>
            </ul>
          </div>
          <div class="top-bar-right">
            <ul class="menu">
              <li><input type="search" placeholder="Search"></li>
              <li><button type="button" class="button">Search</button></li>
            </ul>
          </div>
        </div>
      </header>

      <p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
      <p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>

      <main role="main">
        <%= render @view_module, @view_template, assigns %>
      </main>

    </div> <!-- /container -->
    <script src="<%= static_path(@conn, "/js/vendor.js") %>"></script> <2>
    <script src="<%= static_path(@conn, "/js/app.js") %>"></script>
    <script>$(document).foundation();</script>   <3>
  </body>
</html>

<1> Put Foundation's top-bar to our DOM. <2> Import our new vendor.js file. <3> Initialize Foundation.

And voilà!

Foundation