Bài 2: Cài đặt nhanh KeystoneJS: Yeoman Generator

keystonejs

Để sử dụng generator, bạn cần cài đặt Yeoman (yo)

npm install -g yo

Sau khi có yo, bạn sẽ cần cài đặt trình tạo Keystone:

npm install -g generator-keystone

yo keystone

Chạy yo keystone để tạo một dự án mới. Trình tạo sẽ hỏi bạn các câu hỏi về các thiết lập dự án và sau đó tạo các tệp cơ sở cho bạn trước khi thực hiện npm install

Nếu gặp lỗi:
Error: EACCES: permission denied, open \'/root/.config/insight-nodejs/insight-yo.json
Thì chạy command sau:

chmod g+rwx /root /root/.config /root/.config/insight-nodejs/

Chạy yo keystone sẽ tạo ra hầu hết các phần được mô tả dưới đây, tùy thuộc vào những gì bạn đã chọn. Bạn cũng có thể tạo dự án khởi động bằng tất cả các tùy chọn mặc định (không có lời nhắc) bằng cách sử dụng yo keystone auto

Xem Keystone Yeoman Generator Để biết thêm thông tin.

Các hướng dẫn trong series này sử dụng các tùy chọn mặc định của Pug cho các view templatesLESS cho các CSS templates. Trong dự án của riêng bạn, bạn có thể sử dụng bất kỳ template languages nào bạn thích; xem sử dụng các template languages khác (bên dưới) để biết thêm thông tin.

Cấu hình chi tiết

keystone.js

Nơi đầu tiên để tìm là tệp keystone.js. Đây là tập lệnh sẽ chạy trang web Keystone của bạn và là tệp được sử dụng để đặt hầu hết các tùy chọn cấu hình Keystone.

var keystone = require('keystone');
keystone.init({
  'name': 'My Project',
  'less': 'public',
  'static': 'public',
  'views': 'templates/views',
  'view engine': 'pug',
  'auto update': true,
  'mongo': 'mongodb://localhost/my-project',
  'session': true,
  'auth': true,
  'user model': 'User',
  'cookie secret': '(chuổi bí mật của bạn ở đây)'
});

keystone.import('models');
keystone.set('routes', require('./routes'));
keystone.start();

Để biết thêm thông tin về các tùy chọn mà Keystone hỗ trợ, hãy xem hướng dẫn cấu hình.

Cấu trúc của Project

Keystone Generator tạo ra một cấu trúc dự án được đề xuất để giúp dễ dàng cho việc phát triển website. Dưới đây là cấu trúc thư mục:

|--lib
| Thư viện tạo thêm hoặc các code khác
|--models
| Các files models dữ liệu
|--public
| Các files tĩnh (css, js, images, etc.) công khai
|--routes
| |--api
| | Các api controllers
| |--views
| | Các view controllers
| |--index.js
| | Khởi tạo routes and views
| |--middleware.js
| | Tùy chỉnh trung gian cho routes
|--templates
| |--includes
| | Các file include chung .pug ở đây
| |--layouts
| | Các file .pug cơ bản của layouts ở đây
| |--mixins
| | Các file .pug hỗn hợp ở đây
| |--views
| | Các file của View templates ở đây
|--updates
| Các script cập nhật, mở rộng, di chuyển,... ở đây
|--package.json
| File cấu hình cho npm
|--keystone.js
| File kịch bản chính để chạy ứng dụng Keystone

Ứng dụng của bạn sẽ đơn giản để xây dựng và duy trì hơn nếu bạn làm tương đồng cấu trúc bên trong của các thư mục routes/viewstemplates/views càng nhiều càng tốt.

LƯU Ý: Hướng dẫn khuyên bạn nên làm theo khuyến nghị trên. Tuy nhiên, Keystone không thực sự bắt buộc bạn phải theo bất kỳ cấu trúc nào mà bạn hoàn toàn có thể tự do thay đổi để phù hợp hơn với ứng dụng hoặc sở thích của bạn.

Models

Trước khi bạn có thể bắt đầu ứng dụng Keystone, chúng ta sẽ cần một số Models. Chúng tôi sẽ bắt đầu với model
User, model bắt buộc đối với xác thực và quản lý Session của Keystone.

models/users.js

Script này khởi tạo model User. Không cần phải export ra dữ liệu nào cả, nhưng model cần được register với Keystone, như sau:

var keystone = require('keystone');
var Types = keystone.Field.Types;
var User = new keystone.List('User');

User.add({
  name: { type: Types.Name, required: true, index: true },
  email: { type: Types.Email, initial: true, required: true, index: true },
  password: { type: Types.Password, initial: true },
  canAccessKeystone: { type: Boolean, initial: true }
});

User.register();

Để biết thêm thông tin về cách thiết lập các mô hình ứng dụng của bạn và tài liệu đầy đủ cho danh sách và các trường, hãy xem Database Configuration .

Xác thực và quản lý Session

Để Keystone cung cấp xác thực và quản lý Session cho ứng dụng của bạn, nó cần biết một số thông tin:

  • Tên model user: Phải là tên của Model mà Keystone tìm người dùng của bạn. Nếu bạn sử dụng tên khác, hãy đảm bảo cấu hình tùy chọn này chính xác.
  • Session: Nếu bạn muốn ứng dụng của mình hỗ trợ quản lý Session, hãy cấu hình tùy chọn session thành true. Việc load Session sẽ tốn một ít tài nguyên, vì vậy nếu ứng dụng của bạn không cần Session, bạn có thể tắt Session.
  • Xác thực: Keystone có các views được tích hợp sẵn cho việc đăng nhập và đăng xuất. Để kích hoạt chúng, hãy đặt tùy chọn auth thành true. Bạn cũng có thể điều chỉnh giao diện đăng nhập và đăng xuất trong views.
  • Các Session được duy trì bằng cách sử dụng cookie được mã hóa lưu trữ ID người dùng. Hãy chắc chắn rằng bạn đặt cookie secret thành một chuỗi dài, ngẫu nhiên.
  • User model phải có thuộc tính canAccessKeystone cho biết người dùng có thể truy cập Admin UI của Keystone hay không. Thuộc tính này có thể là một phương thức ảo hoặc boolean. Lưu ý: Nếu bạn chọn sử dụng phương thức ảo, đặt trực tiếp giá trị trong MongoDB sẽ không xác thực chính xác. Phương thức ảo rất hữu ích khi các tiêu chí truy cập phức tạp hơn. Xem thêm Mongoose virtuals.

Routes & Views

Cách dễ nhất và rõ ràng nhất để định cấu hình logic cho các Routes (hoặc Views) khác nhau trong ứng dụng của bạn thường là thiết lập tất cả các ràng buộc trong một file, sau đó đặt bất kỳ logic chung (hoặc phần mềm trung gian) vào tệp khác.

Sau đó, controller cho mỗi route bạn liên kết sẽ đi vào file riêng của nó và có thể được tổ chức tương tự như template render ra view.

Keystone\'s importer và middleware của Express hổ trợ làm cho việc cài đặt trở nên dễ dàng.

Routes and Middleware

routes/index.js

Đoạn script này import các route controllers và binds chúng vào URLs:

var keystone = require('keystone');
var middleware = require('./middleware');
var importRoutes = keystone.importer(__dirname);

// Common Middleware
keystone.pre('routes', middleware.initErrorHandlers);
keystone.pre('routes', middleware.initLocals);
keystone.pre('render', middleware.flashMessages);

// Handle 404 errors
keystone.set('404', function(req, res, next) {
  res.notfound();
});

// Handle other errors
keystone.set('500', function(err, req, res, next) {
  var title, message;
  if (err instanceof Error) {
    message = err.message;
    err = err.stack;
  }
  res.err(err, title, message);
});

// Load Routes
var routes = {
  views: importRoutes('./views')
};

// Bind Routes
exports = module.exports = function(app) {
  app.get('/', routes.views.index);
}

Từng bước xuyên suốt route controller index

  • Load keystone, middleware.js file (bên dưới), và tạo một importer cho thư mục hiện tại
  • Bind middleware (bên dưới)
    • Khởi tạo xử lý lỗi cơ bản
    • Khởi tạo biến cục bộ dùng chung cho view templates
    • Lấy flash messages từ session trước khi view template được render ra.
  • Nói với Keystone cách xử lý lỗi 404500
  • Sử dụng importer để load tất cả route controllers trong thư mục /routes/views
  • Export một phương thức binds index route controller tới GET requests trên root url /
    • Các app argument vào phương thức này đến từ Express app, vì thế vài thứ có thể thực hiện binding routes trong Express, tại đây.
  • Bộ điều khiển Route bổ sung mà bạn thêm vào ứng dụng của mình nên được thêm bằng cách sử dụngg app.get, app.post hoặc app.allbên dưới root controller.

Common Route Middleware

Đặt các định tuyến trung gian trong file routes/middleware.js giữ cho route của bạn gọn gàng và sạch. Nếu file này có dung lượng quá lớn, ý tưởng tốt hơn là bạn nên tái cấu trúc xử lý và cho vào thư mục /lib.

routes/middleware.js

Đoạn code này bao gồm các routes chung trung gian:

var _ = require('lodash');

/**
  Khởi tạo view chuẩn.
  Include những thứ cần thiết trước khi thực thi route controller.
*/
exports.initLocals = function(req, res, next) {
  var locals = res.locals;
  locals.user = req.user;
  // Thêm các variables của bạn ở đây
  next();
};

/**
    Khởi tạo chức năng xử lý lỗi vào `res`
*/
exports.initErrorHandlers = function(req, res, next) {
  res.err = function(err, title, message) {
    res.status(500).render('errors/500', {
      err: err,
      errorTitle: title,
      errorMsg: message
    });
  }

  res.notfound = function(title, message) {
    res.status(404).render('errors/404', {
      errorTitle: title,
      errorMsg: message
    });
  }
  next();
};

/**
  Tìm nạp và xóa flashMessages trước khi chế độ xem được hiển thị
*/
exports.flashMessages = function(req, res, next) {
  var flashMessages = {
    info: req.flash('info'),
    success: req.flash('success'),
    warning: req.flash('warning'),
    error: req.flash('error')
  };
  res.locals.messages = _.some(flashMessages, function(msgs) { return msgs.length }) ? flashMessages : false;
  next();
};

Middleware functions

Keystone yêu cầu các hàm phần mềm trung gian chấp nhận các đối số sau:

  • req - một đối tượng request của Express
  • res - một đối tượng response của Express
  • next - phương thức được gọi khi middleware đã chạy xong (bao gồm mọi internal callbacks)

Flash message support (no, not that flash)

Keystone hổ trợ \'flashing\' messages đến người truy cập thống qua session. Cài đặt mật định ở trên hổ trợ 4 danh mục mà có thể được định style khác nhau:

  • info
  • success
  • warning
  • error

Bạn có thể dễ dàng hỗ trợ kiểu message khác bằng cách update middleware và .pug template renders ra chúng.

Để dùng flash messages trong route controller, như sau:

req.flash('info', 'Some information!');

Messages sử dụng sessions vì thế chúng tồn tại các redirect và chỉ hiển thị đến người dùng một lần, làm cho chúng trở nên hoàn hảo cho status messages (vd: Your changes have been saved) hoặc form validation (vd: Please enter a valid email address).

Một vài tính năng của Keystone (ví dụ như Update Handler) có thể tự động tạo ra flash messages.

Templates

(... còn nữa ...)

Mr.Phan

KTS, KSXD, Developer

You may also like...

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *