hapi-meal

A simple MVC framework for HAPI

npm install hapi-meal
17 downloads in the last week
29 downloads in the last month

Hapi-Meal

A simple MVC framework for HAPI

Installation

npm install hapi-meal

Use

Tree structure

|_ 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

The server.js file

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

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)
    start: function (request, data, controller, action) { ... },

    // OPTIONAL : init method : onServerBeforeStart callback (this refers to the HapiMeal app)
    init: function (request, data, controller, action) { ... },

    // 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'
 },
};

Assets section : LESS files cooking

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.

npm loves you