|
3 | 3 | var mongoose = require('mongoose'); |
4 | 4 |
|
5 | 5 | var locales=['en','ru']; |
6 | | -var locale='en'; |
| 6 | +var locale=locales[0]; |
| 7 | + |
| 8 | +function currentLocale(){ |
| 9 | + return locale?locale:((locales.length>0)?locales[0]:undefined); |
| 10 | +} |
7 | 11 |
|
8 | 12 | var prototype_mongoose=function(){ |
9 | | - var ma = mongoose.Schema.prototype.add; |
10 | | - var addI18n=function(schema,obj){ |
11 | | - var keys = Object.keys(obj); |
12 | | - |
13 | | - if (keys.length==1 && keys=='_id') return obj; |
14 | | - |
15 | | - var ret={}; |
16 | | - |
17 | | - for (var i = 0; i < keys.length; ++i) { |
18 | | - var key = keys[i]; |
19 | | - var val = obj[key]; |
20 | | - |
21 | | - if (key==='type'){ |
22 | | - ret[key]=val; |
23 | | - continue; |
24 | | - } |
25 | | - |
26 | | - if (typeof val != "object") { |
27 | | - ret[key]=val; |
28 | | - continue; |
29 | | - }; |
30 | | - |
31 | | - if (val instanceof Array) { |
32 | | - ret[key]=val; |
33 | | - continue; |
34 | | - }; |
35 | | - |
36 | | - var kkeys=Object.keys(val); |
37 | | - var localize=false; |
38 | | - for (var ii=0; ii<kkeys.length;++ii){ |
39 | | - var kkey=kkeys[ii]; |
40 | | - var vval=val[kkey]; |
41 | | - if (typeof vval==="object"){ |
42 | | - val[kkey]=addI18n(schema,vval) |
43 | | - }else{ |
44 | | - if (vval && kkey=="localize"){ |
45 | | - localize=true; |
46 | | - } |
47 | | - } |
48 | | - } |
49 | | - if (localize){ |
50 | | - delete(val.localize); |
51 | | - var nval={}; |
52 | | - for (var j=0;j<locales.length;j++){ |
53 | | - nval[locales[j]]=val;// Note: must live without copy JSON.parse(JSON.stringify(va)) because of [Function]; |
54 | | - //nval[locales[j]]=JSON.parse(JSON.stringify(val)); |
55 | | - } |
56 | | - //ret['_localized_'+key]=nval; |
57 | | - ret[key]=nval; |
58 | | - schema.virtual('localized.'+key) |
59 | | - .get(function(value,virtual){ |
60 | | - var n=virtual.path.substring(10); |
61 | | - return this[n][locale]; |
62 | | - })/* |
63 | | - .set(function(value,virtual){ |
64 | | - var n=virtual.path.substring(10); |
65 | | - this[n]=value; |
66 | | - });*/ |
67 | | - }else{ |
68 | | - ret[key]=val; |
69 | | - } |
70 | | - }; |
71 | | - return ret; |
72 | | - } |
73 | | - |
74 | | - mongoose.Schema.prototype.add = function add (obj, prefix) { |
75 | | - var oobj=addI18n(this,obj); |
76 | | - ma.call(this,oobj,prefix); |
77 | | - }; |
| 13 | + var ma = mongoose.Schema.prototype.add; |
| 14 | + if (mongoose.Schema.protection.localized) return; |
| 15 | + mongoose.Schema.protection.localized=()=>true; |
| 16 | + |
| 17 | + //traverse over all fields and modify the objects having "localize" attribute |
| 18 | + var addI18n=function(schema,obj,prefix){ |
| 19 | + var keys = Object.keys(obj); |
| 20 | + |
| 21 | + if (keys.length==1 && keys=='_id') return obj; |
| 22 | + |
| 23 | + var ret={}; |
| 24 | + |
| 25 | + for (var i = 0; i < keys.length; i++) { |
| 26 | + //keys of fields |
| 27 | + var key = keys[i]; |
| 28 | + var field = obj[key]; |
| 29 | + |
| 30 | + if (key==='type'){ |
| 31 | + ret[key]=field; |
| 32 | + continue; |
| 33 | + } |
| 34 | + |
| 35 | + if (typeof field != "object") { |
| 36 | + ret[key]=field; |
| 37 | + continue; |
| 38 | + }; |
| 39 | + |
| 40 | + if (field instanceof Array) { |
| 41 | + //TODO: Should traverse? Than a problem with virtual name path |
| 42 | + ret[key]=field.slice(); |
| 43 | + continue; |
| 44 | + }; |
| 45 | + |
| 46 | + //now we are sure "field" is an object |
| 47 | + //field=addI18n(schema,field,path+(path==''?'':'.')+key); |
| 48 | + |
| 49 | + if (field.localize){ |
| 50 | + if ((locales instanceof Array) && locales.length>0){ |
| 51 | + var nfield={}; |
| 52 | + for (var li=0;li<locales.length;li++){ |
| 53 | + //TODO: remove ES6 |
| 54 | + nfield[locales[li]]=Object.assign({},field); |
| 55 | + delete(nfield[locales[li]].localize); |
| 56 | + } |
| 57 | + ret[key]=nfield; |
| 58 | + var vpath=(prefix?prefix:'')+key; |
| 59 | + schema.virtual(vpath+'._') |
| 60 | + .get(function(){ |
| 61 | + var l=currentLocale(); |
| 62 | + if (l) return this.get(vpath+'.'+l); |
| 63 | + return undefined; |
| 64 | + }).set(function(value,virtual){ |
| 65 | + if (currentLocale(value)) |
| 66 | + this.set((prefix?prefix:'')+key+'.'+l,value); |
| 67 | + }); |
| 68 | + }else{ |
| 69 | + ret[key]=Object.assign({},field); |
| 70 | + delete(ret[key].localize); |
| 71 | + } |
| 72 | + }else{ |
| 73 | + ret[key]=field; |
| 74 | + } |
| 75 | + }; |
| 76 | + return ret; |
| 77 | + } |
| 78 | + |
| 79 | + mongoose.Schema.prototype.add = function add (obj, prefix) { |
| 80 | + console.log({in:obj}); |
| 81 | + var oobj=addI18n(this,obj,prefix); |
| 82 | + console.log({out:oobj}); |
| 83 | + ma.call(this,oobj,prefix); |
| 84 | + }; |
78 | 85 | }; |
79 | 86 |
|
80 | 87 | prototype_mongoose(); |
81 | 88 |
|
| 89 | + |
82 | 90 | module.exports = { |
83 | | -locale:function(){ |
84 | | - return locale; |
85 | | -}, |
86 | | -setLocale:function(sLocale){ |
87 | | - locale=sLocale; |
88 | | -}, |
89 | | -locales:function(){ |
90 | | - return locales; |
91 | | -}, |
92 | | -setLocales:function(sLocales){ |
93 | | - locales=sLocales; |
94 | | -} |
| 91 | + currentLocale:currentLocale, |
| 92 | + setCurrentLocale:function(sLocale){ |
| 93 | + locale=sLocale; |
| 94 | + }, |
| 95 | + locales:function(){ |
| 96 | + return locales; |
| 97 | + }, |
| 98 | + setLocales:function(sLocales){ |
| 99 | + locales=sLocales; |
| 100 | + }, |
| 101 | + activate:prototype_mongoose; |
| 102 | + active:()=>!!mongoose.Schema.protection.localized |
95 | 103 | } |
| 104 | + |
| 105 | + |
0 commit comments