不要怂,就是干,撸起袖子干!

Commit 6e7596de by Sascha Depold

bla

2 parents f3127b14 396dcaed
Showing with 7 additions and 881 deletions
[submodule "doc"]
path = doc
url = git@github.com:sdepold/sequelize-doc.git
Copyright (c) 2011 Sascha Depold
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
var express = require('express')
var app = module.exports = express.createServer()
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views')
app.set('view engine', 'ejs')
app.helpers(require("express-view-helpers"))
app.helpers({
koala: require("koala").render
})
app.use(express.bodyParser())
app.use(express.methodOverride())
app.use(require('connect').compiler({ src: __dirname + '/public', enable: ['less'] }))
app.use(app.router)
app.use(express.static(__dirname + '/public'))
})
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }))
})
app.configure('production', function(){
app.use(express.errorHandler())
})
// Routes
app.get("/background", function(req, res) {
var bgFolder = __dirname + "/public/images/backgrounds/"
require("fs").readdir(bgFolder, function(err, files) {
if(err) sys.log(err)
else {
if(files[0] == ".DS_Store") files.shift()
var i = Math.round(Math.random() * (files.length - 1))
res.sendfile(bgFolder + files[i])
}
})
})
app.get('/', function(req, res){
var navigation = {
"installation": 'Installation',
"usage": 'Usage',
"sync-with-db": 'Synchronize with database',
"instances": "Creating and working with instances",
"expanding-models": "Expanding models",
"chain-queries": "Chain queries",
"associations": "Associations",
"find-objects": "Finding objects",
"projects": "Sequelize-based projects"
}
res.render('index', {
navigation: navigation,
active: req.param('active') || 'installation'
})
})
if (!module.parent) {
app.listen(3000)
console.log("Express server listening on port %d", app.address().port)
}
\ No newline at end of file
{
"name": "sequelizejs.com",
"description": "The official sequelize webite.",
"version": "0.4.3",
"homepage": "http://sequelizejs.com",
"repository": {
"type": "git",
"url": "git://github.com/sdepold/sequelize.git"
},
"author": "Sascha Depold <sascha@depold.com> (http://depold.com)",
"directories": {
"lib": "lib"
},
"engines": {
"node": "*"
},
"dependencies": {
"koala": ">=0.1.2",
"markdown": ">=0.2.1",
"ejs": ">=0.3.1",
"less": ">=1.0.41",
"express-view-helpers": ">=0.0.2"
}
}
\ No newline at end of file
No preview for this file type
body {
padding: 50px;
font-size: 14px;
font-family: "Helvetica Neue", Verdana;
line-height: 1.5;
background: url(/background) repeat top left fixed;
}
h2 {
margin: 0px;
}
.active {
text-decoration: underline !important;
}
.bordered {
-moz-border-radius: 15px;
border-radius: 15px;
padding: 20px;
border: 1px solid #888;
color: white;
background-color: rgba(0, 0, 0, 0.7);
box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
-o-box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
-webkit-box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
-moz-box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
}
#wrapper {
text-align: center;
padding: 0 200px;
}
#navigation, #content, #footer {
width: 800px;
text-align: justify;
margin: 0px auto;
}
#footer {
margin-top: 15px;
color: white;
text-align: center;
}
#footer a {
color: white;
}
#navigation {
margin-bottom: 15px;
padding: 10px 20px;
}
#navigation a {
color: white;
display: block;
text-decoration: none;
font-size: 16px;
font-weight: bold;
}
#navigation a:hover {
text-decoration: underline;
}
#sidebar {
float: left;
position: fixed;
width: 140px;
}
#sidebar a {
color: white;
padding: 5px 0px;
display: block;
text-decoration: none;
}
#sidebar a:hover {
text-decoration: underline;
}
pre, .pre_like {
border: 1px solid #888;
-moz-border-radius: 5px;
border-radius: 5px;
padding: 5px;
background-color: rgba(43, 32, 28, 0.7);
}
.comment {
color: grey;
}
.string {
color: #04d80d;
}
.regexp {
color: #2fe420;
}
.number {
color: #44aa43;
}
.class, .this {
color: #8ac9f2;
}
.inst.variable, .class.variable, .global.variable {
color: #2f5fe0;
}
.keyword {
font-weight: bold;
color: #43a8ed;
}
.seperator {
border-top: 1px solid white;
height: 1px;
overflow: hidden;
margin-bottom: 10px;
}
#forkBadge {
position: fixed;
top: 0px;
right: 0px;
}
#forkBadge img {
border: none;
}
#changelog p {
margin: 0px;
}
#changelog h3 {
margin: 5px 0px;
}
#changelog .pre_like {
margin: 10px 0px;
}
#changelog ul {
margin: 5px 0px;
padding-left: 30px;
padding-bottom: 0px;
}
body {
padding: 50px;
font-size: 14px;
font-family: "Helvetica Neue", Verdana;
line-height: 1.5;
background: url(/background) repeat top left fixed;
}
h2 {
margin: 0px
}
.active {
text-decoration: underline !important;
}
.bordered {
-moz-border-radius: 15px;
border-radius: 15px;
padding: 20px;
border: 1px solid #888;
color: white;
background-color: rgba(0, 0, 0, 0.7);
box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
-o-box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
-webkit-box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
-moz-box-shadow: 0 2px 16px #000, 0 0 1px #000, 0 0 1px #000;
}
#wrapper{ text-align:center; padding:0 200px; }
#navigation, #content, #footer {
width: 800px;
text-align: justify;
margin:0px auto;
}
#footer {
margin-top: 15px;
color: white;
text-align: center;
a { color: white; }
}
#navigation {
margin-bottom: 15px;
padding: 10px 20px;
a {
color: white;
display: block;
text-decoration: none;
font-size: 16px;
font-weight: bold;
&:hover {
text-decoration: underline;
}
}
}
#sidebar {
float: left;
position: fixed;
width: 140px;
a {
color: white;
padding: 5px 0px;
display: block;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
pre, .pre_like {
border: 1px solid #888;
-moz-border-radius: 5px;
border-radius: 5px;
padding: 5px;
background-color: rgba(43, 32, 28, 0.7);
}
.comment { color: grey }
.string { color: #04D80D }
.regexp { color: #2FE420 }
.number { color: #44AA43 }
.class, .this { color: #8AC9F2 }
.inst.variable, .class.variable, .global.variable { color: #2F5FE0 }
.keyword { font-weight: bold; color: #43A8ED }
.seperator {
border-top: 1px solid white;
height: 1px;
overflow: hidden;
margin-bottom: 10px
}
#forkBadge {
position: fixed;
top: 0px;
right: 0px;
img {
border: none
}
}
#changelog {
p { margin: 0px }
h3 { margin: 5px 0px }
.pre_like { margin: 10px 0px }
ul {
margin: 5px 0px;
padding-left: 30px;
padding-bottom: 0px;
}
}
\ No newline at end of file
<%- partial('index/intro') %>
<% for(var key in navigation) { %>
<div class="seperator"></div>
<div>
<a name="<%= key %>"></a>
<h2><%= navigation[key] %></h2>
<p><%- partial('index/'+key) %></p>
</div>
<% } %>
\ No newline at end of file
With Sequelize you can also specify associations between multiple classes. Doing so will help you to easily
access and set those associated objects. The library therefore provides for each defined class the following methods:<br/><br/>
NOTE: Associations with models that use custom primaryKeys (so not the field 'id') are currently unsupported.
<pre><%- koala(".js", partial("code/associations/has-one.ejs")) %></pre>
<pre><%- koala(".js", partial("code/associations/belongs-to.ejs")) %></pre>
<pre><%- koala(".js", partial("code/associations/has-many.ejs")) %></pre>
Because Sequelize is doing a lot of magic, you have to call Sequelize#sync after setting the associations!
Doing so will allow you the following:
<pre><%- koala(".js", partial("code/associations/setter-and-getter.ejs")) %></pre>
To remove created associations you can just call the set method without a specific id:
<pre><%- koala(".js", partial("code/associations/single-add-remove.ejs")) %></pre>
You can of course also do it vice versa:
<pre><%- koala(".js", partial("code/associations/vice-versa.ejs")) %></pre>
For hasOne its basically the same:
<pre><%- koala(".js", partial("code/associations/has-one-example.ejs")) %></pre>
\ No newline at end of file
Because you will want to save several items at once and just go on after all of them are saved, Sequelize provides a handy helper for that:
<pre><%- koala(".js", partial("code/chain-queries/chain-queries-1.ejs")) %></pre>
And a real example:
<pre><%- koala(".js", partial("code/chain-queries/chain-queries-2.ejs")) %></pre>
\ No newline at end of file
var User = sequelize.define('User', {/* ... */})
var Project = sequelize.define('Project', {/* ... */})
// One-way back associations
Project.belongsTo(User)
/*
In this example belongsTo will add an attribute UserId to the Project model!
That's the only difference to hasMany.
*/
\ No newline at end of file
var User = sequelize.define('User', {/* ... */})
var Project = sequelize.define('Project', {/* ... */})
// OK. Now things get more complicated (not really visible to the user :)).
// First let's define a hasMany association
Project.hasMany(User, {as: 'Workers'})
/*
This will add the attribute ProjectId or project_id to User.
Instances of Project will get the accessors getWorkers and setWorkers.
We could just leave it the way it is and let it be a one-way association.
But we want more! Let's define the other way around:
*/
User.hasMany(Project)
/*
This will remove the attribute ProjectId (or project_id) from User and create
a new model called ProjectsUsers with the equivalent foreign keys ProjectId
(or project_id) and UserId (or user_id). If the attributes are camelcase or
not depends on the Model it represents.
Now you can use Project#getWorkers, Project#setWorkers, User#getTasks and
User#setTasks.
*/
\ No newline at end of file
Task.hasOne(User, {as: "Author"})
Task#setAuthor(anAuthor)
\ No newline at end of file
var User = sequelize.define('User', {/* ... */})
var Project = sequelize.define('Project', {/* ... */})
// One-way associations
Project.hasOne(User)
/*
In this example hasOne will add an attribute ProjectId to the User model!
Furthermore, Project.prototype will gain the methods getUser and setUser according
to the first parameter passed to define. If you have underscore style
enabled, the added attribute will be project_id instead of ProjectId.
You can also define the foreign key, e.g. if you already have an existing
database and want to work on it:
*/
Project.hasOne(User, { foreignKey: 'initiator_id' })
/*
Because Sequelize will use the model's name (first parameter of define) for
the accessor methods, it is also possible to pass a special option to hasOne:
*/
Project.hasOne(User, { as: 'Initiator' })
// Now you will get Project#getInitiator and Project#setInitiator
\ No newline at end of file
Project.hasMany(Task)
Task.hasMany(Project)
Project.create()...
Task.create()...
Task.create()...
// save them... and then:
project.setTasks([task1, task2]).on('success', function() {
// saved!
})
// ok now they are save... how do I get them later on?
project.getTasks().on('success', function(associatedTasks) {
// associatedTasks is an array of tasks
})
\ No newline at end of file
// remove the association with task1
project.setTasks([task2]).on('success', function(associatedTasks) {
// you will get task2 only
})
// remove 'em all
projects.setTasks([]).on('success', function(associatedTasks) {
// you will get an empty array
})
// or remove 'em more directly
projects.removeTask(task1).on('success', function() {
// it's gone
})
// and add 'em again
projects.addTask(task1).on('success', function() {
// it's back again
})
\ No newline at end of file
// project is associated with task1 and task2
task2.setProject(null).on('success', function() {
// and it's gone
})
\ No newline at end of file
var chainer = new Sequelize.Utils.QueryChainer
chainer.add(/* Query | EventEmitter */)
chainer.run().on('success', function(){}).on('failure', function(errors){})
\ No newline at end of file
var chainer = new Sequelize.Utils.QueryChainer
var Task = sequelize.define('Task', /* ... */)
chainer
.add(Task.drop())
.add(Task.sync())
for(var i = 0; i < 20; i++)
chainer.add(Task.create({}))
chainer
.run()
.on('success', function(){})
.on('failure', function(errors){})
\ No newline at end of file
var Foo = sequelize.define('Foo', { /* attributes */}, {
classMethods: {
method1: function(){ return 'smth' }
},
instanceMethods: {
method2: function() { return 'foo' }
}
})
// ==>
Foo.method1()
Foo.build().method2()
\ No newline at end of file
// search for known ids
Project.find(123).on('success', function(project) {
// project will be an instance of Project and stores the content of the table entry
// with id 123. if such an entry is not defined you will get null
})
// search for attributes
Project.find({ where: {title: 'aProject'} }).on('succes', function(project) {
// project will be the first entry of the Projects table with the title 'aProject' || null
})
// find multiple entries
Project.findAll().on('success', function(projects) {
// projects will be an array of all Project instances
})
// also possible:
Project.all.on('success', function(projects) {
// projects will be an array of all Project instances
})
// search for specific attributes - hash usage
Project.findAll({where: {name: 'A Project'}}).on('success', function(projects) {
// projects will be an array of Project instances with the specified name
})
// search with string replacements
Project.findAll({where: ["id > ?", 25]}).on('success', function(projects) {
// projects will be an array of Projects having a greater id than 25
})
// or
Project.findAll({where: "name = 'A Project'"}).on('success', function(projects) {
// the difference between this and the usage of hashes (objects) is, that string usage
// is not sql injection safe. so make sure you know what you are doing!
})
\ No newline at end of file
// define the order of the queried data
Project.findAll({order: 'title DESC'})
// limit the results of the query
Project.findAll({limit: 10})
// step over some elements
// this only works with a specified limit
Project.findAll({offset: 10, limit: 2})
\ No newline at end of file
# npm:
npm install sequelize
var Sequelize = require("sequelize")
# checkout:
cd path/to/lib
git clone git://github.com/sdepold/sequelize.git
var Sequelize = require(__dirname + "/lib/sequelize/index")
\ No newline at end of file
var project = Project.build({
title: 'my awesome project',
description: 'woot woot. this will make me a rich man'
})
var task = Task.build({
title: 'specify the project idea',
description: 'bla',
deadline: new Date()
})
\ No newline at end of file
// first define the model
var Task = sequelize.define('Project', {
title: Sequelize.STRING,
rating: {type: Sequelize.STRING, defaultValue: 3}
})
// now instantiate an object
var task = Task.build({title: 'very important task'})
task.title
// ==> 'very important task'
task.rating
// ==> 3
\ No newline at end of file
project.save().on('success', function() {
// my nice callback stuff
})
task.save().on('failure', function(error) {
// mhhh, wth!
})
// you can also build, save and access the object with chaining:
Task.build({ title: 'foo', description: 'bar', deadline: new Date()})
.save().on('success', function(anotherTask) {
// you can now access the currently saved task with the variable <i>anotherTask</i>... nice!
})
\ No newline at end of file
// way 1
task.title = 'a very different title now'
task.save().on('success', function() {})
// way 2
task.updateAttributes({
title: 'a very different title now'
}).on('success', function() {})
// create my nice tables:
Project.sync() // will emit success or failure event
Task.sync() // will emit success or failure event
// force the creation!
Project.sync({force: true}) // this will drop the table first and re-create it afterwards
// drop the tables:
Project.drop() // will emit success or failure event
Task.drop() // will emit success or failure event
// event handling:
Project.[sync|drop]().on('success', function() {
// ok ... everything is nice!
}).on('failure', function(error) {
// oooh, did you entered wrong database credentials?
})
\ No newline at end of file
// create all tables... now!
sequelize.sync() // will emit success or failure
// force it!
sequelize.sync({force: true}) // emit ... nomnomnom
// want to drop 'em all?
sequelize.drop() // I guess you've got it (emit)
// emit handling:
sequelize.[sync|drop]().on('success', function() {
// woot woot
}).on('failure', function(error) {
// whooops
})
\ No newline at end of file
var Project = sequelize.define('Project', {
title: Sequelize.STRING,
description: Sequelize.TEXT
})
var Task = sequelize.define('Task', {
title: Sequelize.STRING,
description: Sequelize.TEXT,
deadline: Sequelize.DATE
})
/*
Sequelize will automatically add the attributes createdAt and updatedAt to the
Model. So you will be able to know when the database entry went into the db and
when it was updated the last time.
*/
// You can also set some options:
var Foo = sequelize.define('Foo', {
// instantiating will automatically set the flag to true if not set
flag: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true},
// setting no title will throw an error when trying to save
title: { type: Sequelize.STRING, allowNull: false},
// creating 2 objects with the same value will throw an error
someUnique: {type: Sequelize.STRING, unique: false},
// go on reading for further information about primary keys
identifier: { type: Sequelize.String, primaryKey: true},
// autoIncrement can be used to create auto_incrementing integer columns
incrementMe: { type: Sequelize.INTEGER, autoIncrement: true }
})
// And you can take influence of the way, Sequelize handles your column names:
var Bar = sequelize.define('Bar', { /* bla */ }, {
// don't add the timestamp attributes (updatedAt, createdAt)
timestamps: false,
// don't delete database entries but set the newly added attribute deletedAt
// to the current date (when deletion was done). paranoid will only work if
// timestamps are not disabled
paranoid: true,
// don't use camelcase for automatically added attributes but underscore style
// so updatedAt will be updated_at
underscore: true,
// disable the modification of tablenames; By default, sequelize will automatically
// transform all passed model names (first parameter of define) into plural.
// if you don't want that, set the following
freezeTableName: true
})
\ No newline at end of file
Sequelize.STRING ===> VARCHAR(255)
Sequelize.TEXT ===> TEXT
Sequelize.INTEGER ===> INT
Sequelize.DATE ===> DATETIME
Sequelize.BOOLEAN ===> TINYINT(1)
\ No newline at end of file
// in your server file - e.g. app.js
var Project = sequelize.import(__dirname + "/path/to/models/project")
// /path/to/models/project.js
// as you might notice, the DataTypes are the very same as explained above
module.exports = function(sequelize, DataTypes) {
return sequelize.define("Project", {
name: DataTypes.STRING,
description: DataTypes.TEXT
})
}
\ No newline at end of file
var sequelize = new Sequelize('database', 'username', 'password', {
host: "my.server.tld",
port: 12345
})
// No need for password?
var sequelize = new Sequelize('database', 'username'[, null])
// Want no logging? Use that:
var sequelize = new Sequelize('database', 'username', 'password', {
logging: false
})
\ No newline at end of file
Sequelize allows you to pass custom class and instance methods. Just do the following:
<pre><%- koala(".js", partial("code/expanding-models.ejs")) %></pre>
\ No newline at end of file
- where -> A hash with conditions (e.g. {name: 'foo'})
OR an ID as integer
OR a string with conditions (e.g. 'name="foo"').
If you use a string, you have to escape it on your own.
- order -> e.g. 'id DESC'
- group
- limit -> The maximum count you want to get.
- offset -> An offset value to start from. Only useable with limit!
OK... you can define classes and associations. You can save them. You would probably like to get them from
the database again ;-) Easy:
<pre><%- koala(".js", partial("code/find-objects/basics.ejs")) %></pre>
Of course you can pass a some options to the finder methods, to get more relevant data:
<pre><%- koala(".js", partial("code/find-objects/options.ejs")) %></pre>
\ No newline at end of file
You can install Sequelize via NPM or just download the code from the git repository and require it's entry file <i>index.js</i>:
<pre><%= partial("code/installation.ejs") %></pre>
This will make the class Sequelize available.
\ No newline at end of file
In order to create instances of defined classes just do as follows. You might recognize the syntax if you coded Ruby in the past.
Using the <i>build</i>-method will return an unsaved object, which you explicitly have to save.
<pre><%- koala(".js", partial("code/instances/build.ejs")) %></pre>
Builded instances will automatically get default values when they were defined:
<pre><%- koala('.js', partial("code/instances/defaults.ejs")) %></pre>
To get it stored in the database, use the save method and catch the events, ..., if needed:
<pre><%- koala(".js", partial("code/instances/save.ejs")) %></pre>
Now lets change some values and save changes to the database... There are two ways to do that:
<pre><%- koala(".js", partial("code/instances/update.ejs")) %></pre>
<div>
<a name="sequelize"></a>
<h1>Sequelize</h1>
<p>
The Sequelize library provides easy access to a MySQL database by mapping database
entries to objects and vice versa. To put it in a nutshell... it's an ORM (Object-Relational-Mapper).
The library is written entirely in JavaScript and can be used in the Node.JS environment.
</p>
</div>
\ No newline at end of file
You are using Sequelize? Let me know and get listed here! Just send me a private message on GitHub :-)
\ No newline at end of file
When starting a new project you won't have a database structure and using Sequelize you won't need to. Just specify
your model structures and let the library do the rest.<br><br>
Currently supported is the creation and deletion of tables:
<pre><%- koala(".js", partial("code/sync-with-db/model-sync.ejs")) %></pre>
Because synchronizing and dropping all of your tables might be a lot of lines to write, you can also let
Sequelize do the work for you:
<pre><%- koala(".js", partial("code/sync-with-db/sequelize-sync.ejs")) %></pre>
To get the ball rollin' you first have to create an instance of Sequelize. Use it the following way:
<pre><%- koala(".js", "var sequelize = new Sequelize('database', 'username'[, 'password'])") %></pre>
This will save the passed database credentials and provide all further methods. Furthermore you can specify
a non-default host or port and some options:
<pre><%- koala(".js", partial("code/usage/options.ejs")) %></pre>
To define mappings between a class and a table, use the define method (Stop telling me that JavaScript don't know classes. Name it however you want to!):
<pre><%- koala(".js", partial("code/usage/basic-mapping.ejs")) %></pre>
Sequelize currently supports the following datatypes:
<pre><%= partial("code/usage/data-types.ejs") %></pre>
You can also store your model definitions in a single file using the import method:
<pre><%- koala(".js", partial("code/usage/import.ejs")) %></pre>
The returned object is exactly the same as defined in the imported file's function.
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Sequelize &raquo; A MySQL Object-Relational-Mapper for NodeJS</title>
<link rel="stylesheet" href="/stylesheets/style.css">
<script type="text/javascript" charset="utf-8">
setTimeout(function() {
if(window.location.href.indexOf('#') == -1)
window.location.href = window.location.href + "#<%= active %>"
}, 50)
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-9039631-4']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div id="sidebar" class="bordered">
<h2>Navigation</h2><br/>
<% for(var key in navigation) { %>
<%- linkTo(navigation[key], "?active=" + key, {class: (active==key) ? "active" : ""}) %>
<% } %>
</div>
<div id="wrapper">
<div id="navigation" class="bordered">
<table width="100%">
<tr>
<td align="center" width="33%"><a href="/">Documentation</a></td>
<td align="center" width="33%"><a href="/examples">Examples</a></td>
<td align="center" width="33%"><a href="/changelog">Changelog</a></td>
</tr>
</table>
</div>
<div id="content" class="bordered"><%- body %></div>
<div id="footer" class="bordered">
&copy; 2010 Layout | Code by <a href="http://depold.com" target="_blank">Sascha Depold</a>;
Website based on <a href="http://nodejs.org" target="_blank" rel="nofollow">NodeJS</a> and
<a href="http://expressjs.com" target="_blank" rel="nofollow">ExpressJS</a>.
</div>
</div>
<a href="http://github.com/sdepold/sequelize" id="forkBadge">
<img src="/images/forkme_right_white_ffffff.png" id="ribbon" alt="Fork me on GitHub">
</a>
</body>
</html>
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!