Rizzo is the UI layer for lonelyplanet.com. Rizzo also serves LP's header and footer, assets and Style Guide.
The main goal of Rizzo is to enable sharing of templates and assets across all LP applications. This helps us to reduce complexity and increase reusability. There is a write-up of the thought process behind Rizzo on the engineering blog.
$ git clone git@github.com:lonelyplanet/rizzo.git && cd rizzo
$ cp .ruby-version.example .ruby-version
$ cp .ruby-gemset.example .ruby-gemset
$ cd .
$ bundle install
$ npm install
$ grunt setup
- Rizzo Style guide
- Rizzo as an engine
- Rizzo as a service
- Testing
- Images & icons
- Git Guidelines and Code Review
- Sass Guidelines
- Javascript Guidelines
The Style Guide is accessible at http://rizzo.lonelyplanet.com and can also be run locally:
bundle exec unicorn
The Style Guide shows how the Component API works and how to call these components from within your apps.
If you want to create a new component within the styleguide you can get started with Yeoman. Find out about any Yeoman generators we have available and how to use them at our Yeoman repo.
Primarily rizzo is used as an engine to provide layouts and assets to your rails application.
To enable rizzo, add it to your gemfile:
gem 'rizzo', git: 'git@github.com:lonelyplanet/rizzo.git', submodules: true
This will add Rizzo's Components, Javascript and Sass into your applications load paths. In order to use the layouts, specify it in your controller. There are currently three layouts that Rizzo provides:
- Core (Fixed width) - http://rizzo.lonelyplanet.com/global
- Responsive - http://rizzo.lonelyplanet.com/responsive
- Homepage (Transparent header) - http://rizzo.lonelyplanet.com/homepage
Rizzo also exposes the Global Head (html, css, meta etc.), Global Body Header (Primary navigation) and Global Body Footer (scripts and footer) as a service. These are used for non-rails apps. They are available at:
- Global Head - http://rizzo.lonelyplanet.com/global-head
- Global Body Header - http://rizzo.lonelyplanet.com/global-body-header
- Global Body Footer - http://rizzo.lonelyplanet.com/global-body-footer
An example of the legacy navigation can be viewed at http://rizzo.lonelyplanet.com/legacy.
Each component as well as any helper methods should have unit tests.
$ bundle exec rspec
$ bundle exec cucumber
To clean, compile and run all the tests headlessly
$ grunt
To run them headlessly without compiling them all, and to enable watching of files
$ grunt dev
To spawn a server and rerun failed tests
$ grunt wip
To run plato (Javascript sourcecode analysis)
$ grunt report
Currently a work in progress. Eventually to be run on the styleguide as a pre-push hook. Uses phantomcss.
$ phantomjs spec/lib/visual_regression.js
A write-up of our Icon solution is available at: http://ianfeather.co.uk/ten-reasons-we-switched-from-an-icon-font-to-svg/.
The icons are built by a grunt task, grunt icon
, which uses the Filament Group's grunticon plugin. To add a new icon to the build step, simply copy the svg file into rizzo/app/assets/images/icons/active
.
The easiest way to copy multiple files into the active
directory (supposing you have access to this folder in Dropbox) is by modifying and using the following rsync command:
$ rsync -vr --delete ~/Dropbox/LP\ Patterns/Icons/svg/*.svg ~/projects/rizzo/app/assets/images/icons/active/
You only need to run grunt icon
if you are building new icons. All current icons are already checked into git.
- Always work in a branch
- Rebase into your own branch from master (as long as it is only you working on that branch, otherwise merge)
- Squash your commits into meaningful and (release|revert)able chunks
- Merge with --no-ff back into master when it has been code reviewed (or merge through github).
- Use git pull --rebase to avoid commits like this:
Merge remote-tracking branch 'origin/master' into if_feature
- Prefix your branches with your initials or name.
- Squash your commits using rebase -i if you think it can better reflect the code you have committed.
- Make your commit messages useful, no jokes.
- Code review should start when you begin the feature - discuss it with another dev. The code review should absolutely not be the first time the reviewer sees the code.
- Avoid long running branches! Long branches are much harder to code review.
- Include visual aids (images, animated gifs) in your Pull Requests.
- Be strict in your code review. Don't let laziness slip through as it's harder to remove later.
- Code reviews are an opportunity for both devs to learn.
- It's never a personal attack.
We use the Sass format which means:
- 2 spaces are used for indentation
- Curly braces are omitted
- Use the shorthand mixin syntax (
+mixin()
) - Only use the
@extend
directive to extend placeholders, not other selectors
Comments are encouraged and should follow the below pattern:
//----------------------------------------------------------
// Section or component Title
//
// Description
//----------------------------------------------------------
We use the BEM methodology within class names.
- .block {}
- .block__element {}
- .block--modifier {}
For example:
<div class="gallery">
<h1 class="gallery__title">Gallery</h1>
<img class="gallery__image gallery__image--large" />
<img class="gallery__image" />
<img class="gallery__image" />
</div>
This helps with:
- Avoiding cross module collisions
- Signifying intent and relationships from the classname
- Limiting nesting to 1 level deep.
- Avoiding large numbers of nested rules.
Also:
- Don't over-abstract
- Write code to be readable and understandable, not to save bytes.
We use prefixes for states and javascript hooks:
<div class="is-hidden">This element has state</div>
<div class="tab js-tab">This element can be reached by javascript</div>
Javascript hooks:
- Ensure that we maintain a distinction between content and functionality.
- Should never relate to css rules.
- Should be the only way of reaching a dom element.
- Sass specifics e.g.
+
and@extend
- Position
- Box model
- Typography
- Decorative
For example:
.component
+css-arrow(top)
@extend %clearfix
position
top
right
z-index
display
width
height
margin
padding
border
font-style
font-weight
line-height
background
box-shadow
opacity
outline
Install editorconfig for your editor !
This README used to contain coffeescript guidelines, these have been removed as nobody should be writing new coffee at this point.
-
Set your editor to remove trailing whitespace
-
Use 2 spaces for indentation
-
End files with no more and no less than 1 newline
-
The .editorconfig will take care of the above for you
-
Stick to double quotes
-
Spaces are encouraged, to improve readability
if ( true ) { this; } else { that; }
-
Declare variables at the top of their scope:
function balloon() { var wizard, dog = getShibe(), partyHat = "^"; // some statements and stuff }
-
Use strict as the first line inside your require function
require("website", function( website ) { "use strict"; website.respond(); website.enhance({ method: "progressive" }); });
-
No space before paren in function decl, but spaces within:
function getDressed( hat, suit, scarf, cane ) { // statements, innit } var antelope = function( colour ) { // . . . }
- In this style, ten and sixpence.
-
Use camelCase for method and variable names.
twistAgainLikeWeDidLastSummer()
not
rock_around_the_clock()
-
Try to avoid single character variable names, words are easier to read and we can leave minification to a minifier
-
Don't use comma first
-
Name collections (arrays, objects, sets, maps) in plural, ie:
badger
is a thing,badgers
is a collection of things -
test for truthiness:
if ( collection.length ) ... if ( string ) ... if ( truthyThing )
not
if ( collection.length > 0 ) ... if ( string !== "" ) if ( truthyThing === true )
-
Put comments before the line or block they are about. Never use eol comments
// sanitizes animals for collection by spooks var animalSanitizer = function( animal ) { animal.cut(animal.hair).shampoo().rinse(); }
never
var animalSanitizer = function( animal ) { animal.cut(animal.hair).shampoo().rinse(); // sanitizes animals for collection by spooks }
-
Try to use a function expression unless a function declaration is necessary
whitespace