Tutorial for <a href="https://github.com/Enome/jungles">Jungles</a>. You'll need to know Express.js for this tutorial.
Tutorial for Jungles. You'll need to know Express.js for this tutorial.
We are building a portfolio website cause blogs are boring!
~Language|-home|~portfolio| |-project| |-project| `-project`-contact
For this website we'll need 4 different types.
git clone git@githubcom:Enome/jungles-tutorialgit && cd jungles-tutorial && npm install && node appjs
If you have 'npm install forever -g' then you can use:
git clone git@githubcom:Enome/jungles-tutorialgit && cd jungles-tutorial && npm install && make server
Create the app.js file and the package.json.
touch app.jsnpm init
The package.json file is mainly so we can freeze our dependencies.
npm install express --save
In the app.js file create an Express app and attach it to a http server.
var http = require'http';var express = require'express';var app = express;httpcreateServerapplisten3000;
Start your server to see if everything is working correctly.
As of now Jungles was only tested with Jade but normally (touch wood) it should work with other engines too.
appset'view engine' 'jade';appset'views' __dirname + '/views';
Don't forget to create the directory and install Jade.
npm install jade --save
To make this app as portable as possible we use the jungles-data-memory module as our data access layer. You'll use your data on restarts.
var data = require'jungles-data-memory';
The array is your database so you can also specify initial data.
You can put your types into app.js if you want but I like to put them in a separate file.
If you look at the structure of our portfolio site you see that the language node will be the first node we need.
var language =root: truename: 'language';
The other types we need is page, projects and project.
var page =name: 'page';var projects =name: 'projects';var project =name: 'projects';moduleexports = site page projects project ;
Use the 'children' attribute to prevent the users from adding a type to the wrong parent.
var language =root: truename: 'language'children: 'page' 'projects' // can have page and projects;var page =name: 'page';var projects =name: 'projects'children: 'project' // can have project;var project =name: 'project';
A type has two fields by default which you can't change: name and arrange. If you want more fields you have to define a form. The forms get rendered with app.render so we can use our views directory for storing the jade files.
var language =root: truename: 'language'children: 'page' 'projects';var page =name: 'page'form: 'forms/page';var projects =name: 'projects'children: 'project';var project =name: 'project'form: 'forms/project';
The projects type doesn't need any extra fields so we don't have to specify a form. Jungles uses app.render from the base app so you can use the views directory.
Both page and project will use the same fields.
fieldsetlegend Datadivlabel(for='id_body') Bodytextarea#id_body(name='body')= instance.body
We will add a title field to language so we can set a title for each language.
fieldsetlegend Datadivlabel(for='id_title') Titleinput#id_title(type='text', name='title', value=instance.title)
Now that our types are finished lets require them into app.js and register everything with Jungles.
var data = require'jungles-data-memory';var types = require'./types';var jungles = require'jungles'initdata: datatypes: types;
Once you did this and the server restarted you can visit /jungles. There you will have to log in or register with Mozilla Persona.
You may also notice that only arrange and name are being saved. This is because there is no validation or sanitizing yet.
The body of page and project are required so lets add validation for that.
var page =name: 'page'form: 'forms/page'schema:body: validatorsrequired;var project =name: 'project'form: 'forms/project'schema:body: validatorsrequired;
Now if you try to add a page or a project without a body you'll get an validation warning. You might notice that the body still doesn't get saved. That's because you need to whitelist your input. Lets add a sanitizer to body so that it gets stored.
body: validatorsrequired validatorsstring
Validators can validate, sanitize or do both. Try to save a page or project it should store the body now.
Lets add fancy pictures to our projects.
We'll be using jungles-files-disk so we need a directory to store our files.
Store that location in a variable.
var media = __dirname + '/media';
To serve the files we use the static middleware.
appuse'/media' expressstatic__dirname + '/media';
Install and setup jungles-files-disk.
npm install jungles-files-disk --save
var files = require'jungles-files-disk'media;
Also need to pass it to jungles.init.
var jungles = require'jungles'init//...files: files;
Add extra fields to the project.jade file.
fieldsetlegend Filedivlabel(for='id_image') Imageif instance.imageimg(src='/media/' + instance.image, width='50', height='50')input(type='hidden', name='image', value=instance.image)label Removeinput(type='checkbox', name='remove_image')input#id_image(type='file', name='image')
You have to name the hidden field and the file field the same so you don't reset your data when you update a project. Since the image field is optional you need a way to delete it on update. You can delete this by adding a checkbox with the same name but prepened with remove_.
As with all input fields you have to sanitize it.
schema:body: validatorsrequired validatorsstringimage: validatorsstring
Now that you have the back-end running we can start making the front-end of the website. You could create your own routes and just use Jungles as the data access layer. We also provide you with some middleware in the form of a module called jungles-middleware.
npm install jungles-middleware --save
Add it to your app.js file.
The language type doesn't actually render something it should redirect to the first child.
var language =root: truename: 'language'children: 'page' 'projects'return resredirectreslocalscurrentchildren0path;;
You might notice that Express throws 'Failed to lookup view "page"' error. By default jungles-middleware will execute type.middleware. If it doesn't find it then it will try to render a view with the name of the type. So to render home we create a page.jade file.
The 'projects' type will show all the projects so we need to create a view for that as well.
Once you have your views you can start building your website like any other Express site. Each view and middleware has the following locals available.
Since you most likely want to restart your server each time you make a change use forever to auto restart.
npm install forever -g
Add a .foreverignore file so the server doesn't restart when those files change.
Make a Makefile so we don't have to remember the forever command.
I like to call the command 'server'.
server:@forever -w -c node app.js
Start the server.