### Manually Start ThinkJS Project Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/1.2/start.md Provides instructions to manually start a ThinkJS project by navigating to the 'www' directory and running the index.js file with Node.js. This is an alternative to the auto-starting process during project creation. ```shell cd www; node index.js; ``` -------------------------------- ### ThinkJS Controller Example Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/1.2/start.md A basic controller file for ThinkJS. This example defines an 'indexAction' which renders the 'View/Home/index_index.html' template. It also shows how to directly output a string instead of rendering a view. ```javascript /** * controller * @return */ module.exports = Controller({ indexAction: function(){ //render View/Home/index_index.html file this.display(); }; }); ``` -------------------------------- ### General Configuration Example Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/config.md Demonstrates the basic structure for defining general application configurations in `src/config.js`. This configuration can include port numbers, database connection details, and other application-wide settings. ```javascript // src/config.js module.exports = { port: 1234, redis: { host: '192.168.1.2', port: 2456, password: '' } } ``` -------------------------------- ### ThinkJS Configuration File Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/1.2/start.md An example of a configuration file for a ThinkJS project. It includes settings for the server port, database type, host, port, name, user, password, and table prefix. Default values can be overridden here. ```javascript module.exports = { // Configuration items: Configuration values port: 8360, // Port to listen on db_type: 'mysql', // Database type db_host: 'localhost', // Server address db_port: '', // Port db_name: '', // Database name db_user: 'root', // Username db_pwd: '', // Password db_prefix: 'think_', // Database table prefix }; ``` -------------------------------- ### ThinkJS Project Entry File Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/1.2/start.md Defines global variables for application path, resource path, root path, and debug mode. It then requires the ThinkJS module to start the application. Debug mode automatically reloads files on modification. ```javascript // Define the root directory of the APP global.APP_PATH = __dirname + "/../App"; // Static resource root directory global.RESOURCE_PATH = __dirname; global.ROOT_PATH = __dirname; global.APP_DEBUG = true; // Enable DEBUG mode require('thinkjs'); ``` -------------------------------- ### ThinkJS Common Functions File Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/1.2/start.md Defines commonly used functions globally for the application. These functions are automatically loaded when the system starts and can be accessed directly from anywhere in the application without needing to be required. ```javascript global.getDate = function(){return 'xxx';}; global.getSliceUrl = function(url, length){return ''} ``` -------------------------------- ### Install ThinkJS CLI Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/1.2/start.md Installs the ThinkJS command-line interface globally using npm. It also provides an alternative command using a Chinese npm registry (cnpm) if the default installation fails due to network issues. ```shell npm install -g thinkjs-cmd ``` ```shell npm install -g thinkjs-cmd --registry=http://r.cnpmjs.org ``` -------------------------------- ### Custom Babel Transpilation Setup with Babel 7 Presets/Plugins Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/babel.md This advanced configuration extends the default ThinkJS Babel setup by adding custom Babel 7 presets like '@babel/env' and plugins such as '@babel/plugin-proposal-decorators' and '@babel/plugin-proposal-class-properties'. This allows for more fine-grained control over the transpilation process. Ensure Babel 7 is installed if using these options. ```javascript const Application = require('thinkjs'); const babel = require('think-babel'); const watcher = require('think-watcher'); const notifier = require('node-notifier'); const instance = new Application({ ROOT_PATH: __dirname, watcher: watcher, transpiler: [babel, { presets: ['think-node',"@babel/env"], // 增加了babel 7的预设,需要升级到babel 7,6同理 plugins: [ ["@babel/plugin-proposal-decorators", { "legacy": true }], ["@babel/plugin-proposal-class-properties", { "loose": true }] ]//增加了babel 7的插件,6同理 }], notifier: notifier.notify.bind(notifier), env: 'development' }); instance.run(); ``` -------------------------------- ### Check ThinkJS Version Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/1.2/start.md Displays the currently installed version of the ThinkJS command-line tool. This command is used to verify the installation. ```shell thinkjs -v ``` -------------------------------- ### ThinkJS Model Chained Query Example Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.2/model_intro.md Demonstrates the use of chained methods in ThinkJS models for building database queries. Includes examples of `field`, `where`, `order`, and `select` for fetching data. ```javascript export default class extends think.model.base { /** * 获取列表数据 */ async getList(){ let data = await this.field('title, content').where({ id: ['>', 100] }).order('id DESC').select(); ... } } ``` -------------------------------- ### Controller Action Example Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.2/controller.md An example of an 'Action' method within an ES6 controller. The `detailAction` method is designed to handle requests for detailed information, demonstrating a typical action implementation. ```javascript 'use strict'; import Base from './base.js'; export default class extends Base { /** * 获取详细信息 * @return {Promise} [] */ detailAction(self){ ... } } ``` -------------------------------- ### Create a New ThinkJS Project Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/1.2/start.md Creates a new ThinkJS project by first creating a directory, navigating into it, and then using the thinkjs command to initialize the project structure. ```shell # Create a new directory for your project and name it new_dir_name mkdir new_dir_name; # Navigate into the newly created directory cd new_dir_name; # Use the thinkjs command to create the project thinkjs .; ``` -------------------------------- ### Define Language Variables for English (en) Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/i18n.md Example configuration file for the English language (`en`). It provides the English translations for the same keys defined in the `zh-cn` configuration, allowing the application to display content in English. ```javascript // src/common/config/locale/en.js export default { 'title-home': 'ThinkJS - A Node.js MVC Framework Support All Of ES6/7 Features', 'title-changelog': 'Changelog - ThinkJS' } ``` -------------------------------- ### Dynamic Module Loading with think.npm Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.1/api_think.md Loads npm modules dynamically. If a module is not found, it will be automatically installed via npm. This enables on-the-fly installation of required packages. ```javascript //如果mysql模块,则通过npm安装 let mysql = think.npm('mysql'); ``` ```javascript //指定版本加载一个模块 let mysql = think.npm('mysql@2.0.0') ``` -------------------------------- ### Dynamically Setting Configuration Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/config.md Demonstrates how to dynamically set configuration values at runtime using `think.config(key, value)`. This is useful for loading configurations from external sources like databases during the application's bootstrap process. ```javascript // src/bootstrap/worker.js //HTTP 服务启动前执行 think.beforeStartServer(async () => { const config = await think.model('config').select(); think.config('userConfig', config); //从数据库中将配置读取出来,然后设置 }) ``` -------------------------------- ### Advanced Log4js Configuration in ThinkJS Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/logger.md Provides an example of using advanced configuration options directly from log4js, allowing for more complex logging setups like multiple appenders and log level filtering. Requires `think-logger3 >= 1.1.1`. This configuration is added to `src/config/adapter.js`. ```javascript const path = require('path'); const {Basic} = require('think-logger3'); exports.logger = { type: 'advanced', advanced: { handle: Basic, appenders: { everything: { type: 'file', filename: path.join(think.ROOT_PATH, 'logs/all-the-logs.log') }, emergencies: { type: 'file', filename: path.join(think.ROOT_PATH, 'logs/oh-no-not-again.log') }, 'just-errors': { type: 'logLevelFilter', appender: 'emergencies', level: 'error' } }, categories: { default: { appenders: ['just-errors', 'everything'], level: 'debug' } } } }; ``` -------------------------------- ### Instantiate ThinkJS Model Standalone Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.2/model_intro.md Example of instantiating a ThinkJS model outside of a controller, using `think.model()`. This requires explicitly providing the database configuration and module name. ```javascript let getModelInstance = function(){ let model = think.model('user', think.config('db'), 'home'); } ``` -------------------------------- ### Update ThinkJS within a Project Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/1.2/start.md Updates the ThinkJS dependency for a specific project. Navigate to your project's root directory and then run this npm command. ```shell cd project_directory; npm update thinkjs; ``` -------------------------------- ### Default System Configuration Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/config.md Presents the default configuration object provided by ThinkJS for general settings. This object includes defaults for server port, workers, timeouts, signal handling, and error management. ```javascript { port: 8360, // server port // host: '127.0.0.1', // server host, the default config removed from 3.1.0 workers: 0, // server workers num, if value is 0 then get cpus num createServer: undefined, // create server function startServerTimeout: 3000, // before start server time reloadSignal: 'SIGUSR2', // reload process signal stickyCluster: false, // sticky cluster, add from 3.1.0 onUnhandledRejection: err => think.logger.error(err), // unhandledRejection handle onUncaughtException: err => think.logger.error(err), // uncaughtException handle processKillTimeout: 10 * 1000, // process kill timeout, default is 10s jsonpCallbackField: 'callback', // jsonp callback field jsonContentType: 'application/json', // json content type errnoField: 'errno', // errno field errmsgField: 'errmsg', // errmsg field defaultErrno: 1000, // default errno validateDefaultErrno: 1001 // validate default errno }; ``` -------------------------------- ### Instantiate Models Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/relation_model.md Demonstrates how to get model instances using `think.model()`. You can specify the model name, database type, additional parameters, or module for multi-module projects. ```javascript think.model('user'); // Get the model instance (using default database config) think.model('user', 'sqlite'); // Get the model instance, switching database type to 'sqlite' think.model('user', { type: 'sqlite', aaa: 'bbb' }); // Get the model instance, modifying type and adding other parameters think.model('user', {}, 'admin'); // Get the model instance, specifying the 'admin' module (valid for multi-module projects) ``` -------------------------------- ### Install Mongoose for MongoDB Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/1.2/model_mongo.md Installs the mongoose module, which is required for MongoDB integration in ThinkJS versions 1.1.0 and above. This is a prerequisite for using MongoDB. ```bash npm install mongoose ``` -------------------------------- ### Update ThinkJS CLI Globally Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/1.2/start.md Updates the globally installed ThinkJS command-line tool to the latest version. On Unix-like systems, this command may require administrator privileges (sudo). ```shell npm update -g thinkjs-cmd; // On *nix, you might need to use sudo ``` -------------------------------- ### Accessing Configuration in Context (ctx) Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/config.md Shows how to retrieve configuration values within the request context using `ctx.config(key)`. This is a convenient way to access settings specific to the current request or application-wide configurations. ```javascript const redis = ctx.config('redis'); //获取 redis 配置 ``` -------------------------------- ### Instantiate ThinkJS Model in Controller Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.1/model_intro.md Demonstrates how to get an instance of a ThinkJS model within a controller. If the controller has a `model` method, it can be used directly. Otherwise, `think.model` is used with configuration. ```javascript export default class extends think.controller.base { indexAction(){ let model = this.model('user'); } } ``` ```javascript let getModelInstance = function(){ let model = think.model('user', think.config('db'), 'home'); } ``` -------------------------------- ### Instantiate ThinkJS Model in Controller Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.2/model_intro.md Example of instantiating a ThinkJS model within a controller using the `this.model()` method. This is the preferred way when within a controller context. ```javascript export default class extends think.controller.base { indexAction(){ let model = this.model('user'); } } ``` -------------------------------- ### Controller: Handle HTTP Requests with Actions Source: https://context7.com/thinkjs/cn.thinkjs.org/llms.txt Defines how to create and use controllers in ThinkJS to manage incoming HTTP requests. Controllers extend `think.Controller` and contain action methods that process requests and generate responses. It includes examples of basic actions, pre-action hooks (`__before`), and post-action hooks (`__after`). ```javascript // src/controller/user.js const Base = require('./base.js'); module.exports = class extends Base { // Basic action returning text indexAction() { this.body = 'hello world!'; } // Pre-action hook for authentication async __before() { const userInfo = await this.session('userInfo'); // If no session, return false to stop execution if (think.isEmpty(userInfo)) { return false; } } // Action with session data async profileAction() { const user = await this.session('userInfo'); return this.success(user); } // Post-action hook for cleanup __after() { // Cleanup logic after action execution } } // Creating controller via CLI // Command: thinkjs controller user // Command: thinkjs controller auth api (in api module) // Access URLs: // GET http://127.0.0.1:8360/user/index // GET http://127.0.0.1:8360/user/profile ``` -------------------------------- ### Configure REST method retrieval in Think.js controller Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/api_controller_rest.md This example shows how to configure the `_method` property within the `init` method of a `think.controller.rest` subclass. It prioritizes fetching the method from a GET parameter (e.g., `_method`) before falling back to the HTTP request method, aiding clients that don't support DELETE or PUT requests. ```javascript export default class extends think.controller.rest { init(http){ super.init(http); //设置 _method,表示从 GET 参数获取 _method 字段的值 //如果没有取到,则从 http method 中获取 this._method = '_method'; } } ``` -------------------------------- ### Get GET Parameters in ThinkJS Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/controller.md Demonstrates how to retrieve GET parameters in ThinkJS controllers using the `this.get()` method. It shows how to get a specific parameter by name or retrieve all GET parameters if no name is provided. ```javascript export default class extends think.controller.base { indexAction(){ let name = this.get('name'); let allParams = this.get(); // Get all GET parameters } } ``` -------------------------------- ### Managing Headers Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/api_controller.md Methods for getting and setting HTTP headers. ```APIDOC ## Managing Headers ### `controller.header(name, value)` * **Parameters**: * `name` {String} - The name of the header. * `value` {String} - Optional. The value to set for the header. * **Description**: Gets or sets an HTTP header. If `value` is provided, it sets the header; otherwise, it retrieves the header's value. ```javascript export default class extends think.controller.base { indexAction(){ let accept = this.header('accept'); // Get a header this.header('X-NAME', 'thinks'); // Set a header } } ``` ``` -------------------------------- ### Configure View Adapter (Nunjucks Example) Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/view.md This configuration sets up the 'nunjucks' template engine as the default view adapter. It specifies the template file path, separator, and extension, and configures the nunjucks handler with options for pre-rendering and engine parameters. ```javascript const nunjucks = require('think-view-nunjucks'); const path = require('path'); // 视图的 adapter 名称为 view exports.view = { type: 'nunjucks', // 这里指定默认的模板引擎是 nunjucks common: { viewPath: path.join(think.ROOT_PATH, 'view'), //模板文件的根目录 sep: '_', //Controller 与 Action 之间的连接符 extname: '.html' //模板文件扩展名 }, nunjucks: { handle: nunjucks, beforeRender: () => {}, // 模板渲染预处理 options: { // 模板引擎额外的配置参数 } } } ``` -------------------------------- ### Configure Middleware Pipeline (JavaScript) Source: https://context7.com/thinkjs/cn.thinkjs.org/llms.txt Configures the middleware pipeline for a ThinkJS application by defining an array of middleware objects. Each object specifies the 'handle' (middleware name or function), 'enable' status, and 'options'. This example includes 'meta', 'resource', custom 'timing', and 'router' middleware. ```javascript // Middleware configuration: src/config/middleware.js const path = require('path'); const isDev = think.env === 'development'; module.exports = [ { handle: 'meta', options: { logRequest: isDev, sendResponseTime: isDev } }, { handle: 'resource', enable: isDev, // Only in development options: { root: path.join(think.ROOT_PATH, 'www'), publicPath: /^\/(static|favicon\.ico)/ // Using regex for publicPath } }, { handle: 'timing', // Custom middleware options: { enabled: true } }, { handle: 'router', options: {} } ]; ``` -------------------------------- ### Create Authentication Middleware (JavaScript) Source: https://context7.com/thinkjs/cn.thinkjs.org/llms.txt An example of an authentication middleware that checks for an 'authorization' header, verifies a token (assuming a `verifyToken` function exists), and attaches user information to `ctx.state.user`. It handles unauthorized and forbidden responses. ```javascript // Authentication middleware example module.exports = (options = {}) => { return async (ctx, next) => { const token = ctx.header('authorization'); if (!token) { ctx.status = 401; ctx.body = {error: 'No authorization token'}; return; } try { // Assuming verifyToken is a globally available function or imported ctx.state.user = await verifyToken(token); await next(); } catch (e) { ctx.status = 403; ctx.body = {error: 'Invalid token'}; } }; }; ``` -------------------------------- ### think.http.base Class Documentation Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/api_think_http_base.md Provides an overview of the think.http.base class, its inheritance, and usage examples for ES6 and common JS inheritance. ```APIDOC ## think.http.base `think.http.base` inherits from `think.base` and is the base class for classes that handle HTTP objects. It is extended by `middleware`, `controller`, and `view` classes. ### Inheritance #### Using ES6 Syntax ```javascript export default class extends think.http.base { init() { // Initialization method, automatically called on instantiation. Do not write a constructor. } } ``` #### Using CommonJS Syntax ```javascript module.exports = think.Class(think.http.base, { init: function() { // Initialization method } }); ``` ### Properties #### http Encapsulates the HTTP object. Refer to [API -> http](./api_http.html) for its properties and methods. ### Methods #### config(name, value) * `name` {String} - Configuration name * `value` {Mixed} - Configuration value Reads or sets configuration values. If `value` is `undefined`, it reads the configuration; otherwise, it sets the configuration. This method can read system preset configurations as well as project-defined configurations. **Note**: Do not set the current request's user information as configuration, as it may be overwritten by other users. **Example**: ```javascript export default class extends think.controller.base { indexAction() { // Get configuration value let value = this.config('name'); } } ``` ``` -------------------------------- ### Instantiate ThinkJS Service in Multi-level Directory Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/service.md Demonstrates instantiating a Service located in a subdirectory within the `src/service` folder. The `think.service` method supports path notation (e.g., 'aaa/sms') to access services organized in nested directories. The example assumes the service is defined at `src/service/aaa/sms.js`. ```javascript // src/service/aaa/sms.js module.exports = class extends think.Service { xxx() { } } const sms = think.servie('aaa/sms'); ``` -------------------------------- ### Instantiate Service in Multi-Module ThinkJS Project Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/service.md Illustrates how to instantiate a Service in a multi-module ThinkJS project. The `think.service` method allows specifying the module name (e.g., 'home') as the second argument to locate the service file within that module's `service` directory. The example shows a service defined in `src/home/service/sms.js`. ```javascript // src/home/service/sms.js module.exports = class extends think.Service { constructor(key, secret) { super(); this.key = key; this.secret = secret; } xxx() { } } // 指定从 home 下查找 service 类 const sms = think.service('sms', 'home', key, secret); ``` -------------------------------- ### ThinkJS Controller Usage for Views Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/view.md Example of a ThinkJS controller action demonstrating how to assign data to templates and render them using the `display` method. The `assign` method is used to pass variables, and `display` handles the template rendering process. ```javascript module.exports = class extends think.Controller { indexAction(){ this.assign('title', 'thinkjs'); //给模板赋值 return this.display(); //渲染模板 } } ``` -------------------------------- ### Accessing Configuration in Controller Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/config.md Illustrates how to access configuration settings from within a ThinkJS controller using `this.config(key)`. This method is specific to controller instances and provides direct access to configurations. ```javascript module.exports = class extends think.Controller { indexAction() { const redis = this.config('redis'); // 在 controller 中通过 this.config 获取配置 } } ``` -------------------------------- ### Extend ThinkJS for View Support Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/view.md This configuration adds the 'think-view' module as an extension to the ThinkJS project, enabling template rendering capabilities. It requires the 'think-view' package to be installed. ```javascript const view = require('think-view'); module.exports = [ view ] ``` -------------------------------- ### Get controller instance Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.1/api_think_http_base.md Illustrates how to obtain an instance of a controller using the `controller` method. You can fetch controllers from the current module or other modules by specifying a module path (e.g., 'admin/user'). If a controller is not found, an error will be thrown. ```javascript export default class extends think.controller.base { indexAction(){ //获取当前模块下 user controller 的实例 let controller = this.controller('user'); //获取admin模块下 user controller 的实例 let controller1 = this.controller('admin/user'); } } ``` -------------------------------- ### Accessing Request Parameters Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/api_controller.md Methods for retrieving GET, POST, and general parameters. ```APIDOC ## Accessing Request Parameters ### `controller.get(name)` * **Parameters**: * `name` {String} - The name of the GET parameter. * **Description**: Retrieves the value of a GET parameter. If no name is provided, it returns all GET parameters. ```javascript export default class extends think.controller.base { indexAction(){ // Get a specific GET parameter let value = this.get('xxx'); // Get all GET parameters let values = this.get(); } } ``` ### `controller.post(name)` * **Parameters**: * `name` {String} - The name of the POST parameter. * **Description**: Retrieves the value of a POST parameter. If no name is provided, it returns all POST parameters. ```javascript export default class extends think.controller.base { indexAction(){ // Get a specific POST parameter let value = this.post('xxx'); // Get all POST parameters let values = this.post(); } } ``` ### `controller.param(name)` * **Parameters**: * `name` {String} - The name of the parameter. * **Description**: Retrieves a parameter value. It prioritizes POST parameters over GET parameters. ``` -------------------------------- ### Create or Get Service with think.service Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.1/api_think.md Allows for the creation and retrieval of service components. Services can be defined as classes inheriting from `think.service.base` or using ES6 class syntax. Services can be fetched with parameters and module context, and will be automatically instantiated if they are classes. ```javascript //创建一个 service 类 let service = think.service({ }) ``` ```javascript //ES6 里直接继承 think.service.base 类 let service = class extends think.service.base { } ``` ```javascript //获取 home 模块下 post service,并传递参数 {} //如果获取到的 service 是个类,则自动实例化 think.service('post', {}, 'home'); ``` -------------------------------- ### Create or Get Model with think.model Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.1/api_think.md Handles the creation and retrieval of model instances. Models can be defined directly or by extending `think.model.base` or other model types like `think.model.mongo`. Model instances can be fetched with specific configurations and module context. ```javascript //创建一个 model let model = think.model({ getList: function(){ } }); ``` ```javascript //ES6 里直接继承 think.model.base 类 let model = class extends think.model.base { getList(){ } } ``` ```javascript //创建一个 model 继承自 mongo model let model = think.model('mongo', { getList: function(){ } }); ``` ```javascript //ES6 里直接继承 think.model.mongo 类 let model = class extends think.model.mongo { getList(){ } } ``` ```javascript let configs = { host: '127.0.0.1', name: 'user' } //获取 home 模块下 user model let instance = think.model('user', configs, 'home'); ``` -------------------------------- ### ThinkJS Controller: Rendering and Outputting Content Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/view.md Details the asynchronous `display` method in a ThinkJS controller, which renders a template and directly assigns the output to `ctx.body`. Examples cover rendering based on convention, specifying template names, changing template types, and passing additional parameters, similar to the `render` method. ```javascript //根据当前请求解析的 controller 和 action 自动匹配模板文件 await this.display(); //指定文件名 await this.display('doc'); await this.display('doc/detail'); await this.display('doc_detail'); //不指定文件名切换模板类型 await this.display(undefined, 'ejs'); //指定文件名且切换模板类型 await this.display('doc', 'ejs'); //切换模板类型,并配置额外的参数 await this.display('doc', { type: 'ejs', xxx: 'yyy' }); ``` -------------------------------- ### Get Service - ThinkJS Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.2/api_think.md Retrieves a service instance, automatically instantiating it if it's a class. This function allows fetching services by name, passing arguments, and specifying the module. ```javascript //获取 home 模块下 post service,并传递参数 {} //如果获取到的 service 是个类,则自动实例化 think.service('post', {}, 'home'); ``` -------------------------------- ### Get User Language with http.lang() Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/i18n.md Retrieves the current user's language from cookies or headers. Configuration for the cookie name used to store language preferences is available in `src/common/config/locale.js`. This is a foundational step for i18n. ```javascript let lang = http.lang(); ``` -------------------------------- ### Nunjucks Template Pre-processing with beforeRender Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/view.md Shows how to use the `beforeRender` function within the view adapter configuration to add custom filters or perform pre-processing on templates. This example adds a 'utc' filter to the Nunjucks environment. ```javascript const nunjucks = require('think-view-nunjucks'); const path = require('path'); exports.view = { type: 'nunjucks', common: { viewPath: path.join(think.ROOT_PATH, 'view'), //模板文件的根目录 sep: '_', //Controller 与 Action 之间的连接符 extname: '.html' //文件扩展名 }, nunjucks: { handle: nunjucks, beforeRender(env, nunjucks, config) { env.addFilter('utc', time => (new Date(time)).toUTCString()); } } } ``` -------------------------------- ### Configure Environment-Specific Settings Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.1/question.md Demonstrates how to use environment-specific configuration files (e.g., `production.js`) to set different configurations, such as database credentials, for various deployment environments. ```javascript export default { db: { //这里要有一级 db type: 'mysql', adapter: { mysql: { host: '', port: '' } } } } ``` -------------------------------- ### Get Locale Variable in Controller Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/i18n.md Demonstrates how to retrieve a localized string (e.g., a page title) within a ThinkJS controller using the `this.locale()` method. This method accesses the translations defined in the language configuration files. ```javascript export default class extends think.controller.base { indexAction(){ let homeTitle = this.locale('title-home'); } } ``` -------------------------------- ### Define Language Variables for Chinese (zh-cn) Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/i18n.md Example configuration file for the Chinese language (`zh-cn`). It defines translations for various strings, such as page titles, using key-value pairs. These are loaded based on the detected user language. ```javascript // src/common/config/locale/zh-cn.js export default { 'title-home': 'ThinkJS官网 - A Node.js MVC Framework Support All Of ES6/7 Features', 'title-changelog': '更新日志 - ThinkJS官网', } ``` -------------------------------- ### Set advanced cache options Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/api_model.md Provides an example of setting more detailed cache configurations, including the cache key, timeout, and cache type (e.g., 'file'). This offers flexibility in cache implementation. ```javascript export default class extends think.model.base { getList(){ return this.cache({ key: 'getList', timeout: 1000, type: 'file' //使用文件方式缓存 }).where({id: {'>': 100}}).select(); } } ``` -------------------------------- ### Create a Model File Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/relation_model.md Define a custom model by creating a JavaScript file that extends `think.Model`. This example shows a `user.js` model with a `getList` method to fetch user names. ```javascript // src/model/user.js module.exports = class extends think.Model { getList() { return this.field('name').select(); } } ``` -------------------------------- ### Default Babel Transpilation Setup in ThinkJS Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/babel.md This configuration sets up ThinkJS with the default 'think-node' Babel preset for transpilation. It includes Babel, a file watcher, and a notifier for error feedback during development. The transpiler converts the 'src/' directory to 'app/'. ```javascript const Application = require('thinkjs'); const babel = require('think-babel'); const watcher = require('think-think-watcher'); const notifier = require('node-notifier'); const instance = new Application({ ROOT_PATH: __dirname, watcher: watcher, transpiler: [babel, { presets: ['think-node'] // 默认使用 babel-preset-think-node }], notifier: notifier.notify.bind(notifier), env: 'development' }); instance.run(); ``` -------------------------------- ### Implement Add Method for MongoDB Model Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/1.2/model_mongo.md Example implementation of an 'add' method for a MongoDB model. It retrieves the model instance, creates a new instance with provided data, and saves it to the database. ```javascript add: function(data){ return this.model().then(function(model){ var instance = new model(data); var deferred = getDefer(); instance.save(function(err){ if (err) { deferred.reject(err); }else{ deferred.resolve(); } }) return deferred.promise; }) } ``` -------------------------------- ### Accessing Context in ThinkJS Middleware Source: https://context7.com/thinkjs/cn.thinkjs.org/llms.txt Illustrates how middleware functions can access and utilize the Koa context object (ctx). This example shows how to log the HTTP method, URL, and client IP address of incoming requests, and how to set a custom 'X-Response-Time' header on the response. ```javascript // Middleware access to context module.exports = () => { return async (ctx, next) => { const start = Date.now(); // Same context properties available console.log(`${ctx.method} ${ctx.url} from ${ctx.ip}`); await next(); const ms = Date.now() - start; ctx.set('X-Response-Time', `${ms}ms`); }; }; ``` -------------------------------- ### Getting GET Parameters Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/api_controller.md Retrieves GET parameters from the request URL. It can fetch a specific parameter by name or all parameters if no name is provided. ```javascript export default class extends think.controller.base { indexAction(){ //获取一个参数值 let value = this.get('xxx'); //获取所有的参数值 let values = this.get(); } } ``` -------------------------------- ### Configure and Implement WebSocket Server with Socket.IO in ThinkJS Source: https://context7.com/thinkjs/cn.thinkjs.org/llms.txt This snippet demonstrates how to configure ThinkJS to use the socket.io adapter for WebSocket communication. It includes setting up the adapter in the configuration file and defining WebSocket controller actions for handling connection opening, user addition, message broadcasting, and connection closing. Dependencies include 'think-websocket-socket.io'. ```javascript // Configuration: src/config/adapter.js const socketio = require('think-websocket-socket.io'); exports.websocket = { type: 'socketio', socketio: { handle: socketio, path: '/socket.io', allowOrigin: '*', adapter: null, // For clustering with Redis messages: [ {open: '/websocket/open'}, {addUser: '/websocket/addUser'} ] } }; // WebSocket controller: src/controller/websocket.js module.exports = class extends think.Controller { async openAction() { // Connection opened const socketId = this.wsCtx.id; console.log(`WebSocket connected: ${socketId}`); // Send welcome message this.emit('connected', { message: 'Welcome!', time: Date.now() }); } async addUserAction() { const username = this.wsData.username; const socketId = this.wsCtx.id; // Store user mapping await this.cache(`ws_user_${socketId}`, username); // Broadcast to all clients this.broadcast('userJoined', { username, time: Date.now() }); } async messageAction() { const message = this.wsData.message; const socketId = this.wsCtx.id; const username = await this.cache(`ws_user_${socketId}`); // Broadcast message to all except sender this.broadcast('newMessage', { username, message, time: Date.now() }, true); // true = exclude sender } async closeAction() { const socketId = this.wsCtx.id; const username = await this.cache(`ws_user_${socketId}`); await this.cache(`ws_user_${socketId}`, null); this.broadcast('userLeft', {username}); } } ``` -------------------------------- ### ThinkJS 生产环境配置 - 关闭静态资源处理 (JavaScript) Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.1/deploy.md 在 ThinkJS 的生产环境配置文件 `src/common/config/env/production.js` 中,通过设置 `resource_on: false` 来关闭 ThinkJS 内置的静态资源处理功能。这会将静态资源的处理交给 Nginx,从而提高性能。 ```javascript export default { resource_on: false } ``` -------------------------------- ### Accessing GET Parameters Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.2/controller.md Retrieves GET parameters from the request URL. ```APIDOC ## Accessing GET Parameters ### Description Retrieves GET parameters from the request URL. If a parameter does not exist, an empty string is returned. ### Method Implicitly used within controller actions. ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```javascript export default class extends think.controller.base { indexAction(){ let name = this.get('name'); let allParams = this.get(); // Get all GET parameters } } ``` ### Response #### Success Response (200) - **param** (string) - The value of the requested GET parameter, or an empty string if not found. - **allParams** (object) - An object containing all GET parameters. #### Response Example N/A ``` -------------------------------- ### Modifying Nunjucks Template Engine Options Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/view.md Demonstrates how to customize Nunjucks template engine parameters, such as changing delimiters, through the `options` object in the view adapter configuration. This example modifies the block and variable delimiters. ```javascript const nunjucks = require('think-view-nunjucks'); const path = require('path'); exports.view = { type: 'nunjucks', common: { viewPath: path.join(think.ROOT_PATH, 'view'), //模板文件的根目录 sep: '_', //Controller 与 Action 之间的连接符 extname: '.html' //文件扩展名 }, nunjucks: { handle: nunjucks, options: { tags: { // 修改定界符相关的参数 blockStart: '<%', blockEnd: '%>', variableStart: '<$', variableEnd: '$>', commentStart: '<#', commentEnd: '#>' } } } } ``` -------------------------------- ### Create a ThinkJS Service File Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/service.md Defines the basic structure for a Service file in ThinkJS. Service files inherit from `think.Service` and are typically placed in the `src/service/` directory. The base class itself doesn't provide methods, but functionality can be added via extensions. ```javascript module.exports = class extends think.Service { constructor() { } xxx() { } } ``` -------------------------------- ### Limit data start position and length Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/api_model.md Shows how to specify both the starting offset and the length for query results. This is fundamental for implementing pagination logic. ```javascript export default class extends think.model.base { getList(){ //从起始位置100开始查询20调数据 return this.limit(100, 20).where({id: {'>': 100}}).select(); } } ``` -------------------------------- ### Getting Request Method Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/api_controller.md Fetches the HTTP request method (e.g., 'get', 'post') in lowercase. This is useful for conditional logic based on the request type. ```javascript export default class extends think.controller.base { indexAction(){ let method = this.method(); //get or post ... } } ``` -------------------------------- ### ThinkJS Environment-Based Configuration Source: https://context7.com/thinkjs/cn.thinkjs.org/llms.txt Manages application configuration by defining base settings and environment-specific overrides. Supports adapter configurations for different services and module-specific settings in multi-module projects. Access configuration values using `think.config()`. ```javascript // Base config: src/config/config.js module.exports = { port: 8360, workers: 0, // 0 = CPU count host: '0.0.0.0', encoding: 'utf-8', pathname_prefix: '', pathname_suffix: '.html', proxy: false, timeout: 120, jsonContentType: 'application/json', outputErrorStack: false }; // Development override: src/config/config.development.js module.exports = { workers: 1, outputErrorStack: true }; // Production override: src/config/config.production.js module.exports = { workers: 4, outputErrorStack: false }; // Adapter config: src/config/adapter.js const mysql = require('think-model-mysql'); const redis = require('think-cache-redis'); const fileSession = require('think-session-file'); exports.model = { type: 'mysql', common: { logConnect: true, logSql: true, logger: msg => think.logger.info(msg) }, mysql: { handle: mysql, database: process.env.DB_NAME || 'myapp', user: process.env.DB_USER || 'root', password: process.env.DB_PASS || '', host: process.env.DB_HOST || '127.0.0.1', port: process.env.DB_PORT || 3306, connectionLimit: 5, prefix: 'app_' } }; exports.cache = { type: 'redis', redis: { handle: redis, host: '127.0.0.1', port: 6379, password: '' } }; exports.session = { type: 'file', file: { handle: fileSession, sessionPath: path.join(think.ROOT_PATH, 'runtime/session') } }; // Accessing config in application module.exports = class extends think.Controller { async indexAction() { const port = think.config('port'); // Get single value const dbConfig = think.config('model.mysql'); // Nested value const allConfig = think.config(); // All config // Module-specific config (multi-module projects) const adminConfig = think.config('key', undefined, 'admin'); } } // Environment variable usage: // NODE_ENV=production node development.js (loads config.production.js) // NODE_ENV=development node development.js (loads config.development.js) // Multi-module config structure: // src/common/config/config.js (shared config) // src/admin/config/config.js (admin module config) // src/api/config/config.js (api module config) ``` -------------------------------- ### Implement getAction for resource retrieval in Think.js Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/api_controller_rest.md This example implements the `getAction` method for a `think.controller.rest` subclass. It fetches a single resource by ID if `this.id` is present, otherwise, it retrieves a list of all resources. It utilizes `this.modelInstance` for database operations. ```javascript //方法实现,可以根据需要修改 export default class extends think.controller.rest { async getAction(){ let data; if (this.id) { let pk = await this.modelInstance.getPk(); data = await this.modelInstance.where({[pk]: this.id}).find(); return this.success(data); } data = await this.modelInstance.select(); return this.success(data); } } ``` -------------------------------- ### Correct `display` Method Usage (Async Handling) Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/view.md Addresses a common issue where calling `display` without proper asynchronous handling leads to a 'NotFoundError'. It provides correct usage examples using `return this.display()` and `await this.display()` to ensure the asynchronous operation completes before the response is sent. ```javascript module.exports = class extends think.Controller { indexAction() { return this.display(); // 通过 return 将 display 的异步返回 } } ``` ```javascript module.exports = class extends think.Controller { async indexAction() { await this.display(); // 通过 await 等待 display 方法的返回 } } ``` -------------------------------- ### Instantiate Controller - ThinkJS Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.2/api_think.md Instantiates a controller for a specific module and HTTP context. It requires the controller name, the HTTP object, and the module name. ```javascript //实例化 home 模块下 user controller let instance = think.controller('user', http, 'home'); ``` -------------------------------- ### ThinkJS Controller: Rendering Template Content Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/view.md Illustrates the use of the asynchronous `render` method in a ThinkJS controller to get the rendered content of a template. It shows how to render based on the current controller/action, specify a template file name, change the template engine type, and pass additional parameters. ```javascript //根据当前请求解析的 controller 和 action 自动匹配模板文件 const content1 = await this.render(); //指定文件名 const content2 = await this.render('doc'); const content3 = await this.render('doc/detail'); const content4 = await this.render('doc_detail'); //不指定文件名但切换模板类型 const content5 = await this.render(undefined, 'ejs'); //指定文件名且切换模板类型 const content6 = await this.render('doc', 'ejs'); //切换模板类型,并配置额外的参数 //切换模板类型时,需要在 adapter 配置里配置对应的类型 const content7 = await this.render('doc', { type: 'ejs', xxx: 'yyy' }); ``` -------------------------------- ### Get list of users and select data by IDs Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/2.0/api_model.md Illustrates how to get a list of user models, extract their IDs, and then select data from the same table based on those IDs. This is useful for complex querying scenarios. ```javascript export default class extends think.model.base { async getList(){ //获取 user 模型实例 let instance = this.model('user'); let list = await instance.select(); let ids = list.map(item => { return item.id; }); let data = await this.where({id: ['IN', ids]}).select(); return data; } } ``` -------------------------------- ### Extend ThinkJS Service Class Methods Source: https://github.com/thinkjs/cn.thinkjs.org/blob/master/3.0/service.md Shows how to extend the base `think.Service` class with custom methods. By defining methods in `src/extend/service.js`, these methods become available directly within Service files. The example adds a `getDataFromApi` method, which is then called within a Service's `xxx` method. ```javascript // src/extend/service.js module.exports = { getDataFromApi() { } } // src/service/sms.js module.exports = class extends think.Service { async xxx() { const data = await this.getDataFromApi(); // 这个访问为 extend/service.js 里扩展的方法 } } ```