Full series: Building website with Nodejs - A post from my experience
Previous post: Install and Create basic structure for Nodejs website

package.json file

package.json file is used for storing information about your application as well as its dependencies. Usually, when managing your Nodejs application with git, you should ignore the node_modules folder (which contains all the dependencies). Instead, you can specify the library that your app use and then let npm install it automatically for you with npm install. Here is the default package.json file generated by express

{
  "name": "application-name",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "3.4.8",
    "ejs": "*",
    "stylus": "*"
  }
}

You don’t even need to specify the dependencies manually. When you install any new package with npm, just add --save flag so that npm will update the package.json file automatically for you. For example

Read more

Full series: Building website with Nodejs - A post from my experience

Install Nodejs, npm using nvm

There are several ways of installing Nodejs. You can install it using your OS packages manager or compiling it from source. However, the recommended way is to install it using nvm. nvm can help you install, maintain and run multiple versions of Nodejs (without sudo need).

To install nvm, simply do

$ git clone https://github.com/creationix/nvm.git ~/.nvm

Add this to your shell’s rc file

$ source ~/.nvm/nvm.sh

Next, install one version of nodejs that you want using nvm and set it as the default

$ nvm install 0.10
$ nvm alias default 0.10

Installing nodejs with nvm will automatically install npm (packages manager for Node). For more information about nvm, visit it’s homepage at https://github.com/creationix/nvm.

To test whether nodejs works correctly, you can use the example from nodejs page. Create a file named example.js

Read more

1. Introduction

Currently, I’m building a website written entirely in Javascript using NodeJS along with PostgreSQL database server. This series of tutorials is a summary of my experience with NodeJS, PostgreSQL as well as how I solve the problems I encountered. In this first post, I will give an outline of which frameworks, technologies and the list of all following tutorials in this series. The reason why I chose those technologies will be presented in the corresponding post.

2. Frameworks / Technologies

Here is the list of some main frameworks, libraries and technologies that I used for developing the website.

2.1 Database

2.2 Backend

Read more

Setting up ssl connection can be different for different kinds of server. To make the configuration process easier, we can use nginx as a https proxy server. In this design, the client connects to the nginx server using https with encrypted data. After that, nginx decrypts the data and forwards it to the real web server (also running locally in the same server with nginx). This post demonstrates the steps for configuring nginx as an https proxy server.

Installation

First, you need to install nginx with ssl support. On Mac OS, by default, Macports does not install ssl for nginx, you need to use this command

$ port install nginx +ssl

Next, you need to find out the configuration file for nginx. Usually, it is located under /etc/nginx (or /opt/local/etc/nginx for macports version). There are already some sample configuration files with the .default extension there for you. You can use those sample config files by removing the .default extension.

Usually, you don’t put all the settings in nginx.conf file. Instead, you can create another directory for storing your own ones and include them in the main config file. For example, you put all your config files inside site-enabled folder, add this inside the http section of the nginx.conf file.

http {

    # ...
    # other config
    # ...

    include sites-enabled/*;
}
Read more

Gulp Task runner

Gulp is a task runner written in Javascript and run on Nodejs (similar to Grunt). It helps you to automate your daily boring, repetitive and time consuming development tasks when working with Javascript. Some examples of those tasks are compiling LESS file to CSS, browserify modules, compiling and uglify JS files. Simply defining those tasks in a task file and Gulp will take care of the rest for you. This post shows how to install and config Gulp as well as the basic usage.

Installation

You can install Gulp using Nodejs packages managing system

$ npm install -g gulp

Also, you will need to install Gulp locally inside your project to in order to load the module

$ npm install --save-dev gulp

Next, install some required Gulp plugins, I will explain about these plugins later

$ npm install --save-dev gulp-uglify gulp-rename gulp-jshint
Read more

Zoom behavior in d3js

Zooming functionality is a very useful feature for working with large and complicated svg diagram. Often for those types of graph, zoom ability allows users to have a detail view of one specific part on that graph. Fortunately, creating zoom behavior in d3js is an uncomplicated task since the library already takes care of it all for you. Everything you need to do is to apply the zoom function function on the svg element that you want. For example

// create the zoom listener
var zoomListener = d3.behavior.zoom()
  .scaleExtent([0.1, 3])
  .on("zoom", zoomHandler);

// function for handling zoom event
function zoomHandler() {
  vis.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}

// create the svg
rootSvg = d3.select("#tree-body").append("svg:svg");
/*
  creating your svg image here
*/

// apply the zoom behavior to the svg image
zoomListener(rootSvg);
Read more

In my previous post, I have demonstrated how to use aria2 as the main downloader on Unix/Linux (Aria2 as Default Download Manager on Unix/Linux). However, there is still one thing missing. That is browser integration. Luckily, Conkeror allow me to customize it very easily through the init file. To achieve, you need to modify the content_handler_prompt function in content-handler.js file. Add this to your .conkerorrc file for it to overwrite the conkeror’s built in one (sadly, I haven’t found any better solution).

function content_handler_prompt (ctx) {
  var action_chosen = false;
  var can_view_internally = ctx.frame != null &&
    can_override_mime_type_for_uri(ctx.launcher.source);
  var panel;
  try {
    panel = create_info_panel(ctx.window, "download-panel",
                              [["downloading", "Downloading:", ctx.launcher.source.spec],
                               ["mime-type", "Mime type:", ctx.launcher.MIMEInfo.MIMEType]]);
    // add my own option (a for aria2)
    var action = yield ctx.window.minibuffer.read_single_character_option(
      $prompt = "Action to perform: (s: save; o: open; O: open URL; c: copy URL; a: aria2; "+
        (can_view_internally ? "i: view internally; t: view as text)" : ")"),
      $options = (can_view_internally ? ["s", "o", "O", "c", "a", "i", "t"] : ["s", "o", "O", "c", "a"]));
    switch (action) {
    case "s":
      yield content_handler_save(ctx);
      action_chosen = true;
      break;
    case "o":
      yield content_handler_open(ctx);
      action_chosen = true;
      break;
    case "O":
      yield content_handler_open_url(ctx);
      action_chosen = true;
      break;
    case "c":
      yield content_handler_copy_url(ctx);
      action_chosen = true;
      break;
    case "i":
      yield content_handler_view_internally(ctx);
      action_chosen = true;
      break;
    case "t":
      yield content_handler_view_as_text(ctx);
      action_chosen = true;
      break;
    case "a":
      yield content_handler_add_to_aria2(ctx);
      action_chosen = true;
      break;
    }
  } catch (e) {
    handle_interactive_error(ctx.window, e);
  } finally {
    if (! action_chosen)
      ctx.abort();
    if (panel)
      panel.destroy();
  }
}
Read more

Update Jun 21 2014: add another better solution that uses web-mode

1. Syntax highlighting

If you are working with Javascript, especially ReactJS, you definitely have known about JSX, the XML syntax inside of Javascript. This section will demonstrate how to setup Emacs for working with JSX files using web-mode, an autonomous emacs major-mode for editing web templates. For web-mode to work properly with JSX files, add this to your .emacs

(add-to-list 'auto-mode-alist '("\\.jsx$" . web-mode))
(defadvice web-mode-highlight-part (around tweak-jsx activate)
  (if (equal web-mode-content-type "jsx")
      (let ((web-mode-enable-part-face nil))
        ad-do-it)
    ad-do-it))

This is how web-mode indents and highlights my jsx files (taken from my Emacs).

2. JSX Syntax Checking

Alt Text

Next, we need a tool for syntax checking. For Javascript, we have jslint (or jshint), which I have previously written another post about how to set it up in Emacs here Emacs - Setup JSHint for on-the-fly (potential) errors checking. For JSX, there is a similar tool called jsxhint. Of course, you need to install it before you can use

Read more

By default, Sequelize (an ORM system for NodeJS) only allows you to specify custom table name. Currently, there is no such feature in Sequelize to help you define custom column names and then map them to properties in model objects. To achieve this, you may need a workaround that is to use getter and setter methods provided by Sequelize. When you creating the model, set the property names to the same with the corresponding column name in database first. After that, define the setter and getter functions to map those column to the desired properties name that you want. This example transforms model properties name from snake_case (SQL style) to camelCase (JS style).

var model =
	sequelize.define('People', { 
    name: Sequelize.INTEGER,
    birth_date: Sequelize.DATE, // should be the same with
    death_date: Sequelize.DATE  // column name in database
  }, {
    // getters and setters
    getterMethods: {
      birthDate: function(){return this.getDataValue("birth_date");},
      deathDate: function(){return this.getDataValue("death_date");}
    },
    setterMethods: {
      birthDate: function(v){this.setDataValue("birth_date", v);},
      deathDate: function(v){this.setDataValue("death_date", v);}
    },
    timestamps: false,
    tableName: "people"
	});

Later, when you want to create a new instance, you can use the birthDate instead of birth_date.

Read more
This post is the seventh part of the series Dired as Default File Manager

Wdired is a special mode that allows you to perform file operations by editing the Dired buffer directly (the “W” in “Wdired” stands for “writable”.). Imagine that you want to rename multiple files, you will have to call the rename command several times. Wdired help you to transform the current dired buffer to an editable one, then you can change multiple file names and apply the changes. To activate it, simply run the command dired-toggle-read-only (bound to C-x C-q by default). When you finish, just call wdired-finish-edit (C-c C-c) to commit the changes or wdired-abort-changes (C-c C-k) to cancel.

This is much faster comparing to the other GUI file managers. However, it's still not very convenience since you still have to mark the text that you want to change. Also, in normal file manager, when you rename one file, it will auto select the file name exclude the extension for you to edit. This can be achieved easily using a little emacs lisp.

Read more