OpenUserJs/OpenUserJS.org — pull request #129 by Zren (2014-06-09 18:45:50+00:00)
Title: Bootstrap3 Based UI (Implement #103)

PR is not ready. I'm still writing it up and doing a few last commits. There's just a fuck ton to document and I'm a savvy Ctrl+S kinda guy.

This is a Pull Request for [Issue #103](https://github.com/OpenUserJs/OpenUserJS.org/issues/103).

## Demo

http://nameless-hollows-5487.herokuapp.com/

## Screenshots

Imgur Album: TODO

## Changes

Probably should start with what I didn't change. I tried to stay keep routes the same. Though I made a helper function called `app_route` that emulates `app.route('/').get(controller).post(controller)` from Express 4.x. I didn't touch the models at all. Graveyard, Flagged Users/Scripts and the AdminUserList page are still using the old UI.

All CSS/JS libraries are linked from http://cdnjs.com. Javascript is in the footer. CSS is in the header.

## Templating

**View:** https://github.com/Zren/OpenUserJS.org/blob/css/views/pages/_templatePage.html

**Controller:** https://github.com/Zren/OpenUserJS.org/blob/css/controllers/_template.js

### Template Options (`options.*` )

Eg: `options.authedUser`

* `authedUser` The authed user.
* `isMod` == `authedUser.isMod`
* `isAdmin` == `authedUser.isAdmin`
* `isYou` script.author == authedUser on scriptPage
* `userTools`, `authorTools`, `modTools`, `adminTools` are `{}` or `undefined` depending on if the user can use those panels. Use the style over `isYou` etc so we can have admin's have access to script editing tools in the future.
* `pageMetaDescription` string for ` or null.
* `pageMetaKeywords` Comma seperated list of keywords for `` or null.

### Models: Generated fields from Serialized Data

Use `libs/modelParser` like `authedUser = modelParser,parseUser(authedUser)` to generate urls like `authedUser.userPageUrl`. modelParser will strip all model functions like `.save()` as it does a `obj.toObject()`. I did this as I wasn't 100% sure if modifying fields not specified in the model's schema would get serialized. I also used toObject as the controllers before my edits were not sending the models into the template (like: `options: {username: user.name}`), so I followed that pattern.

### Controllers

Use `libs/modelQuery` to build Model.find() queries. It has a bunch of function to apply on a query (eg: `scriptListQuery = Script.find()` like `modelQuery.parseScriptSearchQuery(scriptListQuery, req.query.q)`, modelQuery.parseModelListSort(scriptListQuery, req.query.orderBy, req.query.orderDir, defaultSortCallback)`. There's also `modelQuery.applyScriptListQueryDefaults(scriptListQuery, options, req)` which deals does the default querystring paramter parsing for you (`q, orderBy, orderDir, p, limit`), and sets up a pagination (`p=1` for page 1) object in `options.pagination`. To complete the pagination, you have to count the total items your query conditions match. When using the `apply___ListQueryDefaults` functions, it's as easy as using `tasks.push(pagination.getCountTask(scriptListQuery));`. Lastly, you have to render the paginationTemplate with `options.paginationRendered = pagination.renderDefault(req);` after the count task has completed (usually right before you do `res.render`).

All my query building function __apply__ onto an existing query. Have the query get defined in the controller.

`var github = require('../libs/githubClient');` will import a pre-setup [github client](https://github.com/mikedeboer/node-github) which you can find the docs for [here](https://mikedeboer.github.io/node-github/).