Skip to content
shimondoodkin edited this page Nov 20, 2010 · 14 revisions

There is server.js it includes basicapp which includes basicmodel. Also server.js includes a 'module' file or files.

A module defines Models and loads Controllers and assigns them to pages(list of routes).

A Model defines a data structure by duplicating a basicmodel and basicfields. The duplication function called cloneextend:

cloneextend (object_to_clone,an_object_to_extend_with_the_cloned_object)

It is like the underline or jquery .clone() function and the underline or jquery .extend() function combined together.

The cloneextend method defined in deps/nodejs-cone-extend/merger.js

In basicapp there is app._=require('deps/nodejs-cone-extend/merger.js');

At the beginning I used underscore so the I named it app._ but underscore's functions ware buggy to do large clone and extend work. I developed my version of clone and extend and then saw that I used them together. I left it named app._ .

The model is defined in the basicmodel_*.js files.

The more important properties of a model are:

model.collection -  A ready to use mongodb collection. To do native operations like map reduce
model.update(val,query,callback) -  Adds {$set:val} around val and does collection.update
model.insert(value,callback)
model.save(value,callback) // Uses the _id inside the object to do update
model.preprocess_document(data , isadd, callback)  // It is used to move uploaded files to storage folder,
// to convert ObjectIds, Dates and Numbers to values of correct data type.
// It is used in update,save and insert before doing the operation.
model.getall(query,callback) // Returns an array
model.getone(query,callback) // Returns the first item as object

In the query for getall and getone there is an additional mongodb-like variable called $options. It goes into the second argument for the collection.find(where,options,callback) function. model.getall({foo:1, $options:{skip:100,limit:10,sort:['item','asc','other','desc']}},callback);

basicfield, The basic filed is used to define the fields in the auto generated editor that is at mywebsite.com/admin/. Also when you use model.getone , It adds the missing fields as empty strings. basicfields structure is defined in basicfields.js

The defaultfield is cloned into app.basicfields as a customized filed to be used in models quickly with minimal modification.

defaultfield It is a structure that defines a column of a table from various perspectives, It says how to show the field is it a select box or a text input or a text area ..., and should it be used in the edit form or list form ...

In a module file you define some models by:

app.model.mymodelname=app._.cloneextend(app.basicmodel,{general:{title:'my shiny mode'},fields:{
 myfield: app.cloneextend(app.basicfields.text,{general:{title:'my field'}}),
 otherfield: app.cloneextend(app.basicfields.text,{general:{title:'my other field'}}),
},
getfunny:function(callback){ // my custom function
 this.getall({that:'funny'},callback);
}
});

The you add some controllers that use those models. You can use some script to automate the process.

   var mypages =  { 
	index:'index',
	pijimi_heb_invite:'invite/design',
   }

  _.each(mypages , function(filename , objectname){
	  app.pages[objectname] = require('templates/website/controllers/' + filename).page.call(app,app);
	  app.watchpage([objectname],'templates/website/controllers/' + filename + '.js');
  });

Structure of a module file. A module file exports setupfirst,setup,setuplast: setupfirst() function // All setupfirst functions are called before all setup functions are called. setup() function // Called before collections are created, after all setup first are called , A place to define models. setuplast() function // After collections are created, A place to add pages that use the data from the database.

An example module file:

function setupfirst(app) {} this.setupfirst=setupfirst;
function setup(app) // exported constructor
{
  var _=app._;
  app.model.mymodelname=app._.cloneextend(app.basicmodel,{general:{title:'my shiny mode'},fields:{
    myfield: app.cloneextend(app.basicfields.text,{general:{title:'my field'}}),
    otherfield: app.cloneextend(app.basicfields.text,{general:{title:'my other field'}}),
   },
  myfunction_fileds_count:function(){
   this.fileds.length()
  },
  myotherfunction_getfunny:function(callback){
    this.getall({that:'funny'},callback);
  }
 });	
} this.setup=setup;  

function setuplast(app)
{
  var _=app._;
   var mypages =  { 
	index:'index',
	common:'common',
   }

  _.each(mypages , function(filename , objectname){
	  app.pages[objectname] = require('templates/website/controllers/' + filename).page.call(app,app);
	  app.watchpage([objectname],'templates/website/controllers/' + filename + '.js');
  });
} this.setuplast=setuplast;

I hope one day it will load models and controllers automatically from a directory and use extension as a convention. Also one missing future of a module is that it lack callbacks.