0.0.0 • Published 2 years ago

fmk v0.0.0

Weekly downloads
-
License
ISC
Repository
-
Last release
2 years ago

A modular web framework

https://www.npmjs.com/package/fmk

Disclaimer:

This module is not production ready.

It is part of a personal project aiming to improve my coding skills.

cli-tool is coming is this week


Fmk aims to be a modular framework. It's promise is to enhance your project by a single drag and drop.

Fmk can manage a large variety of templates. (see templating section).

  1. Installation
  2. Project structure
  3. Module structure
  4. Controller structure
  5. Templates
  6. Router structure
  7. Model structure
  8. Crud Model structure
  9. Server config
  10. Sequelize config
  11. Template engines
  12. Routes in views
  13. Modules in views

Installation:

Fmk runs on nodejs.

Use npm to install it.

$ npm install --save fmk

Running the server is easy.

const { Fmk } = require("fmk");

Fmk.start();

Fmk is based on the MVC design pattern.

Project structure`:

Fmk structure must be respected as follow:

  • /config
    • index.js
  • /models
    • model1.js
    • model2.js
    • ...
    • inxdx.js
    • each model must be in a seperate file and imported by index.js
  • /modules
    • /module1
    • /module2
    • ...
    • index.js
    • each module must be in a seperate folder. Index should not be touched as it imports and rexports the modules
  • /templates
    • template1.ejs|pug|hbs|html...
    • template2.ejs|pug|hbs|html...
    • ...
  • /public
    • /css
    • /js
    • /img
    • ...
  • app.js

Module structure Fmk

Fmk is module based

A module must contain a controller, routes, an optionnal model and optionnal views

A module should be seen as an independant brick that you can add and remove without causing a breakdown of the app.

This is the structure of a module

  • /modules
    • /module1
      • controller.js
      • model.js
      • routes.js
      • index.js
      • /views
        • view1.ejs|pug|hbs|html...
        • view2.ejs|pug|hbs|html...
    • /module2
      • controller.js
      • model.js
      • routes.js
      • index.js
      • /views
        • view1.ejs|pug|hbs|html...
        • view2.ejs|pug|hbs|html...
        • ...

Fmk requires every module when running the start method and the Controller base class receives all those modules.

Controller example:

const { Controller } = require('fmk');

module.exports = class Foo extends Controller {
    static getIndex(req, res) {
        res.end(Foo.render('index.ejs', 'template.ejs', { title: "coucou twé" }));
    }
};

The controller methods are used as callbacks by express, they should receive req and res in order to manipulate users inputs and render data or views.

The render method receives the name of one of the views in his module. It is important that the name of the view keeps it's etension since it will determinate wich template engine to use. Second parameter is an optional template placed in the templates folder of the project. Third argument will be the data to pass in the views.

the view and the template can be written in different template languages only if both template engines are defined in the config.

Templating:

Fmk aims to manage many template engines. Controller.render calls the renderor compile method of those template engines.

  1. ejs,
  2. pug,
  3. handlebars,
  4. doT,
  5. mustache,
  6. twig,
  7. underscore,
  8. hogan,
  9. nunjucks,
  10. markdown-it

(I didn't test all the template engines for now but implemented their rendering/compiling method)

<!--view.html-->

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Am a html template</title>
  </head>
  <body>
    <app /><!-- `render` calls str.replace on this tag in order to nest the view in the template -->
  </body>
</html>

The template and the view will be compiled from their template language to html separately then merged

Routing:

module.exports = [
    ['/', []], //[prefix,mainMiddlewares]
    [
        ['index : GET / getIndex', "i'm the index title", []]
        //['routeName : method path controllerAction', title for link generation, routeMiddlewares]
    ]
]

The routes.js file exports an Array of 2 Arrays. First is for the main route, second is an array of all the sub routes.

Models:

Models definition follows Sequelize schema.

const { Model, DataTypes } = require('sequelize');
const { Fmk } = require('fmk');

class BlankModel extends Model { }

BlankModel.init({
    name: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true,
        validate: {
            is: /^[a-z]{3,18}$/
        }
    }
}, {
    sequelize: Fmk.sequelize,
    tableName: "blank"
});

module.exports = BlankModel;

CRUD models:

Fmk aims to generate Modules from Models (generation cli-tool coming soons)

CRUD models must have a path and prefix parameters to generate personalized routing

class BlankModel extends Model{ }

...
...

BlankModel.prefix = "prefix";
BlankModel.path = "path";

module.exports = BlankModel;

Server configuration:

// config/index.js
...
server = {
  port: 80,
  host: "localhost",
},
...

Configuration de la base de données:

Fmk uses Sequelize as its ORM.

// config/index.js

const {Sequelize} = require('sequelize');

...

sequelize = new Sequelize({
    storage: 'db.sqlite',
    dialect: 'sqlite',
    //database : '',
    //host: '',
    //username:'',
    //passwrod: '',
    //port: '',
    //...
})

...

template engines:

Template engines must be installed first:

$ npm install --save ejs, handlebars, dot, mustache ....

Engines are defined in the config file at engines.

The template engine must be called the same name as it's require name.

template:{
  engines : [
    //"ejs", // : .ejs
    //"dot", // : .dot
    //"handlebars", // : .hbs
    //"hogan.js", // : .hog
    //"mustache", // : .must
    //"nunjucks", // : .nunj
    //"pug", // : .pug
    //"twig", // : .twig
    //"markdown-it", // : .md
    "underscore.template" : require("underscore.template")//: .und
  ]
};

Routes in templates:

Every route of the module is an instance of the Route class and are passed to every view in the datas as the routes parameter.

//view.ejs

...

<%= routes.name  %>

...

routes only calls the routes of the module

Route.link() return an hypertext link and has label and title optional parameters since the label is by default the route name and the title is defined in the routes.js file.

//view.ejs

<%- routes['some-route'].link(label,title) %>

The Route.resolve method resolves a route with params

let resolved = routes.someRoute.resolve({ id: 4, name: "hello" });

Other routes in views:

Other modules are passed in the views as the modules parameter. Since every module has a controller and every controller gets the routes, youi can call modules['moduleName'].controller.routes['routeName'].link/resolve().

Official docs:

1.0.0

2 years ago

0.0.0

2 years ago

0.7.3

4 years ago

0.7.2

4 years ago

0.7.1

4 years ago

0.6.0

4 years ago

0.5.14

4 years ago

0.5.13

4 years ago

0.5.12

4 years ago

0.5.11

4 years ago

0.5.10

4 years ago

0.5.9

4 years ago

0.5.8

4 years ago

0.5.7

4 years ago

0.5.6

4 years ago

0.5.5

4 years ago

0.5.4

4 years ago

0.5.3

4 years ago

0.5.0

4 years ago

0.5.2

4 years ago

0.5.1

4 years ago

0.4.1

4 years ago

0.4.0

4 years ago

0.3.1

4 years ago

0.3.0

4 years ago

0.2.2

4 years ago

0.2.1

4 years ago

0.2.0

4 years ago