Skip to content

Commit

Permalink
feat: support add locals and add case (#2289)
Browse files Browse the repository at this point in the history
  • Loading branch information
czy88840616 committed Sep 5, 2022
1 parent 159184c commit fc373d9
Show file tree
Hide file tree
Showing 20 changed files with 314 additions and 10 deletions.
1 change: 1 addition & 0 deletions packages/i18n/src/config/config.default.ts
Expand Up @@ -19,4 +19,5 @@ export const i18n: I18nOptions = {
cookieMaxAge: FORMAT.MS.ONE_YEAR,
},
},
localsField: 'i18n',
};
1 change: 1 addition & 0 deletions packages/i18n/src/interface.ts
Expand Up @@ -19,6 +19,7 @@ export interface I18nOptions {
fallbacks: Record<string, any>;
writeCookie: boolean;
resolver: RequestResolver | false,
localsField: string;
}

export const I18N_ATTR_KEY = 'i18n:locale';
18 changes: 18 additions & 0 deletions packages/i18n/src/middleware.ts
Expand Up @@ -98,6 +98,15 @@ export class I18nMiddleware implements IMiddleware<any, any> {
i18nService.saveRequestLocale();
}

res.locals[this.i18nConfig.localsField] = (
message: string,
data: any
) => {
return i18nService.translate(message, {
args: data,
});
};

return next();
};
} else {
Expand Down Expand Up @@ -142,6 +151,15 @@ export class I18nMiddleware implements IMiddleware<any, any> {
} else {
i18nService.saveRequestLocale();
}

ctx.locals[this.i18nConfig.localsField] = (
message: string,
data: any
) => {
return i18nService.translate(message, {
args: data,
});
};
}

// run next middleware and controller
Expand Down
@@ -0,0 +1,3 @@
{
"name": "ali-demo"
}
@@ -0,0 +1,34 @@
import { Configuration, Inject } from '@midwayjs/decorator';
import * as express from '@midwayjs/express';

@Configuration({
imports: [
express,
require('../../../../src')
],
importConfigs: [
{
default: {
keys: '12345',
i18n: {
defaultLocale: 'en_US',
localeTable: {
en_US: {
"HELLO_MESSAGE": "Hello {username}",
},
zh_CN: {
"HELLO_MESSAGE": "浣犲ソ {username}",
}
}
},
}
}
]
})
export class AutoConfiguration {
@Inject()
framework: express.Framework;

async onReady() {
}
}
@@ -0,0 +1,21 @@
import { Controller, Get, Inject, Query } from '@midwayjs/decorator';
import { MidwayI18nService } from '../../../../src';

@Controller('/')
export class UserController {

@Inject()
i18nService: MidwayI18nService;

@Inject()
res;

@Get('/')
async index(@Query('username') username: string) {
const i18n = this.res.locals['i18n'];

return i18n('HELLO_MESSAGE', {
username
});
}
}
@@ -0,0 +1,3 @@
{
"name": "ali-demo"
}
@@ -0,0 +1,34 @@
import { Configuration, Inject } from '@midwayjs/decorator';
import * as koa from '@midwayjs/koa';

@Configuration({
imports: [
koa,
require('../../../../src')
],
importConfigs: [
{
default: {
keys: '12345',
i18n: {
defaultLocale: 'en_US',
localeTable: {
en_US: {
"HELLO_MESSAGE": "Hello {username}",
},
zh_CN: {
"HELLO_MESSAGE": "浣犲ソ {username}",
}
}
},
}
}
]
})
export class AutoConfiguration {
@Inject()
framework: koa.Framework;

async onReady() {
}
}
17 changes: 17 additions & 0 deletions packages/i18n/test/fixtures/base-app-koa-ctx-locals/src/user.ts
@@ -0,0 +1,17 @@
import { Controller, Get, Inject, Query } from '@midwayjs/decorator';

@Controller('/')
export class UserController {

@Inject()
ctx;

@Get('/')
async index(@Query('username') username: string) {
const i18n = this.ctx.locals['i18n'];

return i18n('HELLO_MESSAGE', {
username
});
}
}
32 changes: 32 additions & 0 deletions packages/i18n/test/index.test.ts
Expand Up @@ -297,6 +297,22 @@ describe('test/index.test.ts', () => {
expect(result.headers['set-cookie']).toBeUndefined();
await close(app);
});

it('should test with request ctx.locals', async () => {
const app = await createApp(join(
__dirname,
'./fixtures/base-app-koa-ctx-locals'
));

const result = await createHttpRequest(app).get('/').query({
locale: 'zh_CN',
username: '涓栫晫',
});

expect(result.text).toEqual('浣犲ソ 涓栫晫');

await close(app);
});
});

describe('i18n in express', function () {
Expand Down Expand Up @@ -393,5 +409,21 @@ describe('test/index.test.ts', () => {
expect(result.headers['set-cookie']).toBeUndefined();
await close(app);
});

it('should test with request req.locals', async () => {
const app = await createApp(join(
__dirname,
'./fixtures/base-app-express-req-locals'
));

const result = await createHttpRequest(app).get('/').query({
locale: 'zh_CN',
username: '涓栫晫',
});

expect(result.text).toEqual('浣犲ソ 涓栫晫');

await close(app);
});
});
});
3 changes: 2 additions & 1 deletion packages/view/src/contextView.ts
Expand Up @@ -38,7 +38,7 @@ export class ContextView implements IViewEngine {
let viewEngineName = options.viewEngine;
if (!viewEngineName) {
const ext = extname(filename);
viewEngineName = this.viewManager.extMap.get(ext);
viewEngineName = this.viewManager.findEngine(ext);
}
// use the default view engine that is configured if no matching above
if (!viewEngineName) {
Expand Down Expand Up @@ -85,6 +85,7 @@ export class ContextView implements IViewEngine {

private setLocals(locals) {
return Object.assign(
this.viewManager.getLocals(),
{
ctx: this.ctx,
request: this.ctx.request,
Expand Down
37 changes: 29 additions & 8 deletions packages/view/src/viewManager.ts
Expand Up @@ -15,18 +15,19 @@ import { IViewEngine } from './interface';
@Scope(ScopeEnum.Singleton)
export class ViewManager extends Map {
@App()
app;
protected app;

@Config('view')
viewConfig;
protected viewConfig;

config;
protected config;

extMap = new Map();
fileMap = new Map();
protected extMap = new Map();
protected fileMap = new Map();
protected localsMap = {};

@Init()
init() {
protected init() {
this.config = this.viewConfig;
const rootSet: Set<string> = new Set(Object.values(this.config.rootDir));
if (this.config.root) {
Expand Down Expand Up @@ -59,7 +60,7 @@ export class ViewManager extends Map {
* @param {String} name - the name of view engine
* @param {Object} viewEngine - the class of view engine
*/
use(name: string, viewEngine: new (...args) => IViewEngine): void {
public use(name: string, viewEngine: new (...args) => IViewEngine): void {
assert(name, 'name is required');
assert(!this.has(name), `${name} has been registered`);

Expand All @@ -83,7 +84,7 @@ export class ViewManager extends Map {
* @param {String} name - the given path name, it's relative to config.root
* @return {String} filename - the full path
*/
async resolve(name: string): Promise<string> {
public async resolve(name: string): Promise<string> {
const config = this.config;

// check cache
Expand All @@ -101,6 +102,26 @@ export class ViewManager extends Map {
this.fileMap.set(name, filename);
return filename;
}

/**
* add a global data for all views
* @param key
* @param localValue
*/
public addLocals(key, localValue) {
this.localsMap[key] = localValue;
}

/**
* get global locals data
*/
public getLocals() {
return this.localsMap;
}

public findEngine(ext: string): string {
return this.extMap.get(ext);
}
}

async function resolvePath(names, root) {
Expand Down
40 changes: 39 additions & 1 deletion packages/view/test/index.test.ts
@@ -1,6 +1,7 @@
import { createApp, close, createHttpRequest } from '@midwayjs/mock';
import { Framework } from '@midwayjs/koa'
import { Framework } from '@midwayjs/koa';
import { join } from 'path';
import { ContextView, ViewManager } from '../src';

describe('/test/index.test.ts', () => {

Expand All @@ -25,4 +26,41 @@ describe('/test/index.test.ts', () => {
expect(result.text).toEqual(join(__dirname, 'fixtures', 'base-app-default/view/a.html'));
await close(app);
});

it('should test context view', async () => {
class CustomView {
async render(name: string,
locals?: Record<string, any>,
options?: any) {
return name;
}
async renderString(tpl: string,
locals?: Record<string, any>,
options?: any) {
const text = locals.b();
return tpl.replace('{{b}}', text);
}
}
const manager = new ViewManager();
manager.use('custom', CustomView);
manager.addLocals('b', () => {
return 'harry';
});

const view = new ContextView();
view.viewManager = manager;
view.ctx = {
requestContext: {
async getAsync() {
return new CustomView();
}
}
};

const result = await view.renderString('hello {{b}}', {}, {
viewEngine: 'custom'
});

expect(result).toEqual('hello harry');
});
});
9 changes: 9 additions & 0 deletions packages/web-koa/src/framework.ts
Expand Up @@ -88,6 +88,15 @@ export class MidwayKoaFramework extends BaseFramework<
enumerable: true,
});

Object.defineProperty(this.app.context, 'locals', {
get() {
return this.state;
},
set(value) {
this.state = value;
},
});

const onerrorConfig = this.configService.getConfiguration('onerror');
setupOnError(this.app, onerrorConfig, this.logger);

Expand Down
@@ -0,0 +1,3 @@
{
"name": "ali-demo"
}
@@ -0,0 +1,9 @@
'use strict';

export const keys = 'key';

export const hello = {
a: 1,
b: 2,
d: [1, 2, 3],
};
@@ -0,0 +1,5 @@

exports.hello = {
b: 4,
c: 3,
};

0 comments on commit fc373d9

Please sign in to comment.