hapi-meal

A simple MVC framework for HAPI

Hapi-Meal

A simple MVC framework for HAPI

npm install hapi-meal
|_ config // Your settings here
|
|_ controllers
|  |_ index.js // Index controller
|  |_ lolcat.js // Some other
|
|_ nodes_modules
|
|_public // Your static stuff
|  |_ css
|  |_ js
|
|_views // Your templates
|  |_ index
|  |  |_ index.html // Action subtemplates
|  |
|  |_ controller
|  |  |_ action.html
|  |
|  |_ layout.html // The main layout template
|
|_server.js
var HapiMeal = require('hapi-meal');
var path = require('path');
var settings =  {
 app: {
   name: 'MyApp',
   host: 'localhost',
   port: 33000,
   path: __dirname + '/'
 }
};
 
var myApp = HapiMeal.createApplication(
  settings,
 function () {
   myApp.start();
   console.log(
     'Meal cooked and served at ' +
       settings.app.host + ':' + settings.app.port
   );
 }
);
// myApp server is now listening at http://localhost:33000/ 

The settings object given to HapiMeal.createApplication is the same as the one you would use with Hapi.createServer (see https://github.com/spumko/hapi/blob/master/docs/Reference.md#server-options). HapiMeal custom settings are available in the app section of this object :

var path = require('path');
 
module.exports = {
 // START of Hapi-Meal specific settings 
 
 // Application specific settings 
  app: {
 
    // Application name 
    name: 'MyApp',
 
    // Server host 
    host: 'localhost',
 
    // Server port 
    port: 3001,
 
    // Application base directory 
    // Here we assume to be in a config file under a "settings" app subfolder 
    path: __dirname + '/../',
 
    // OPTIONAL : start method : onServerInit callback (this refers to the HapiMeal app) 
    startfunction (requestdatacontrolleraction) { ... },
 
    // OPTIONAL : init method : onServerBeforeStart callback (this refers to the HapiMeal app) 
    initfunction (requestdatacontrolleraction) { ... },
 
    // OPTIONAL : Menu section : See below 
    menu: { ... },
 
    // OPTIONAL :Assets cooking settings : See below 
    assets: { ... },
 
    // NOTE : 
 
    // You may want to separate your section in different files 
    // Your files must use module.exports = {} 
    // Just write : 
    routes: require('./routes')
  },
 
  // END of HapiMeal specific settings 
  // START of Hapi classical settings 
 
  // Authentication settings section 
  // https://github.com/spumko/hapi/blob/master/docs/Reference.md#serverauthname-options 
  auth: {
    default: {
      scheme: 'cookie',
      cookie: 'sid',
      password: 'secret',
      isSecure: false,
      redirectTo: '/login'
    }
  },
 
  // Template settings section 
  views: {
   engines: {
     html: 'handlebars',
     jade: 'jade'
   },
   path: __dirname + '/../views',
   layoutKeyword: 'body'
 },
};

Here is an example of settings.app.assets :

app {
  assets: {
    less: {
      path: [ 'main.less' ], // Just one main file, importing others 
      dir: __dirname + '/../less' // LESS files directory 
    }
  }
}

To import the compiled main.less in your templates, just write :

<link rel='stylesheet' href='<%= app.resources.css.get('main.less') %>' type='text/css'>

Check the example views/layout.html template to see it in action.

This section will generate a "menu" template key, with your object rendered to an HTML menu

    . This is useful when you want to have <li class='active'> on current page links.

Here is an example of settings.app.menu :

app {
  menu: {
    main: {
      ul: 'menuCssClass',
        li: {
          active: 'activeCssClass',
          separator: 'separatorCssClass',
          separatorEl: false, // If the separator is a separate <li> element 
          hasChildren: 'parentCssClass'
      },
      a: { hasChildren: 'parentLinkCssClass' }
    },
    // OPTIONAL : Submenu/Children settings 
    // Overrides main menu settings on sub-elements 
    // (for menu links with sublinks) 
    children: {
      ul: 'submenuListCssClass',
        li: {
          active: 'activeSubClass',
          separator: 'separatorSubClass',
          separatorEl: false,
          hasChildren: 'parentSubCssClass'
      },
      a: { hasChildren: 'parentSublinkCssClass' }
    },
    links: [
      { href: '/', text: "<i>Home</i>", title: 'Back to home' },
      { href: '/foo', text: 'Foo', title: 'Visit this insane section' },
      { href: '/bar', text: 'Bar', title: 'Free beer!' },
      {
        href: '/blog',
        auth: true,
        class: ['pull-right'],
        text: 'Blog',
        title: 'Read our blog',
        // Sublinks of blog (will create a submenu) 
        links: [
          { href: '/archive', text: 'See the archive', title: '', separator: true },
          { href: '/category/pony', text: 'Pony section', title: '' },
          { href: '/category/unicorn', text: 'Unicorn section', title: '' }
        ]
      }
    ]
  }
}

To import the rendered menu in your templates, just write <%= menu %>, or {{menu}} depending on your template engine.