isite 2024.6.9 → 2024.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +1387 -1387
  3. package/apps/charts/site_files/html/PieChart.html +35 -35
  4. package/apps/charts/site_files/html/PieChart2.html +35 -35
  5. package/apps/charts/site_files/html/XYChart.html +42 -42
  6. package/apps/charts/site_files/html/column.html +60 -60
  7. package/apps/charts/site_files/html/gauge.html +44 -44
  8. package/apps/charts/site_files/html/index.html +92 -92
  9. package/apps/charts/site_files/html/line-graph.html +42 -42
  10. package/apps/charts/site_files/html/pie-chart-rounded-corners.html +38 -38
  11. package/apps/charts/site_files/html/simple-3D-pie-chart.html +43 -43
  12. package/apps/charts/site_files/js/chart-animated.js +2 -2
  13. package/apps/charts/site_files/json/PieChart.json +41 -41
  14. package/apps/charts/site_files/json/PieChart2.json +23 -23
  15. package/apps/charts/site_files/json/XYChart.json +74 -74
  16. package/apps/charts/site_files/json/bar-chart.json +99 -99
  17. package/apps/charts/site_files/json/column-chart.json +80 -80
  18. package/apps/charts/site_files/json/gauge.json +36 -36
  19. package/apps/charts/site_files/json/line-graph.json +1867 -1867
  20. package/apps/charts/site_files/json/pie-chart-rounded-corners.json +42 -42
  21. package/apps/charts/site_files/json/simple-3D-pie-chart.json +50 -50
  22. package/apps/client-side/package-lock.json +5 -5
  23. package/apps/client-side/package.json +21 -21
  24. package/apps/client-side/site_files/css/bootstrap3.css +5 -5
  25. package/apps/client-side/site_files/css/bootstrap4.css +6 -6
  26. package/apps/client-side/site_files/css/bootstrap5-addon.css +2 -2
  27. package/apps/client-side/site_files/css/bootstrap5.css +6 -6
  28. package/apps/client-side/site_files/css/checkbox.css +125 -125
  29. package/apps/client-side/site_files/css/font-awesome.css +4616 -4616
  30. package/apps/client-side/site_files/css/font-awesome.min.css +4 -4
  31. package/apps/client-side/site_files/css/fonts.css +85 -85
  32. package/apps/client-side/site_files/css/help.css +51 -51
  33. package/apps/client-side/site_files/css/images.css +4 -3
  34. package/apps/client-side/site_files/css/main-menu.css +66 -66
  35. package/apps/client-side/site_files/css/print.css +144 -144
  36. package/apps/client-side/site_files/css/prism.css +139 -139
  37. package/apps/client-side/site_files/css/progress.css +7 -7
  38. package/apps/client-side/site_files/css/radio.css +103 -103
  39. package/apps/client-side/site_files/css/scrollbar.css +13 -13
  40. package/apps/client-side/site_files/css/semantic.css +363 -363
  41. package/apps/client-side/site_files/css/table.css +87 -87
  42. package/apps/client-side/site_files/css/treeview.css +84 -84
  43. package/apps/client-side/site_files/css/ui.css +28 -28
  44. package/apps/client-side/site_files/fonts/fontawesome-webfont.svg +2671 -2671
  45. package/apps/client-side/site_files/fonts/glyphicons-halflings-regular.svg +287 -287
  46. package/apps/client-side/site_files/fonts/icons.svg +684 -684
  47. package/apps/client-side/site_files/js/angular-animate.js +4179 -4179
  48. package/apps/client-side/site_files/js/angular.js +36599 -36599
  49. package/apps/client-side/site_files/js/angular.min.js +351 -351
  50. package/apps/client-side/site_files/js/angular.min.js.map +8 -8
  51. package/apps/client-side/site_files/js/barcode.js +1 -1
  52. package/apps/client-side/site_files/js/base64.js +319 -319
  53. package/apps/client-side/site_files/js/bootstrap-5-directive.js +1456 -1456
  54. package/apps/client-side/site_files/js/bootstrap3.js +6 -6
  55. package/apps/client-side/site_files/js/bootstrap4.js +6 -6
  56. package/apps/client-side/site_files/js/bootstrap5.js +6 -6
  57. package/apps/client-side/site_files/js/custom.js +149 -149
  58. package/apps/client-side/site_files/js/directive.min.js +1 -1
  59. package/apps/client-side/site_files/js/hijri.js +965 -965
  60. package/apps/client-side/site_files/js/jquery.js +2 -2
  61. package/apps/client-side/site_files/js/moment.js +4511 -4511
  62. package/apps/client-side/site_files/js/prism.js +6 -6
  63. package/apps/client-side/site_files/js/qrcode.js +1398 -1398
  64. package/apps/client-side/site_files/js/semantic.js +10 -10
  65. package/apps/client-side/site_files/js/xlsx.js +23 -23
  66. package/apps/client-side/site_files/semantic-themes/default/assets/fonts/brand-icons.svg +1008 -1008
  67. package/apps/client-side/site_files/semantic-themes/default/assets/fonts/icons.svg +1518 -1518
  68. package/apps/client-side/site_files/semantic-themes/default/assets/fonts/outline-icons.svg +366 -366
  69. package/apps/client-side/site_files/webfonts/fa-brands-400.svg +3717 -3717
  70. package/apps/client-side/site_files/webfonts/fa-regular-400.svg +801 -801
  71. package/apps/client-side/site_files/webfonts/fa-solid-900.svg +5034 -5034
  72. package/apps/security/README.md +12 -12
  73. package/apps/security/app.js +288 -288
  74. package/apps/security/libs/notifications.js +89 -89
  75. package/apps/security/site_files/html/add_modal.html +36 -36
  76. package/apps/security/site_files/html/content.html +36 -36
  77. package/apps/security/site_files/html/delete_modal.html +31 -31
  78. package/apps/security/site_files/html/head.html +7 -7
  79. package/apps/security/site_files/html/index.html +80 -80
  80. package/apps/security/site_files/html/login_modal.html +24 -24
  81. package/apps/security/site_files/html/logout_modal.html +21 -21
  82. package/apps/security/site_files/html/navbar.html +8 -8
  83. package/apps/security/site_files/html/register_modal.html +32 -32
  84. package/apps/security/site_files/html/update_modal.html +28 -28
  85. package/apps/security/site_files/html/view.html +74 -74
  86. package/apps/security/site_files/html/view_modal.html +32 -32
  87. package/apps/security/site_files/js/app.js +1 -1
  88. package/apps/security/site_files/js/index.js +278 -278
  89. package/apps/security/site_files/js/login.js +35 -35
  90. package/apps/security/site_files/js/logout.js +22 -22
  91. package/apps/security/site_files/js/navbar.js +26 -26
  92. package/apps/security/site_files/js/register.js +30 -30
  93. package/apps/security/site_files/json/permissions.json +7 -7
  94. package/apps/security/site_files/json/roles.json +33 -33
  95. package/apps/security/site_files/json/words.json +28 -28
  96. package/gulpfile.js +17 -17
  97. package/index.js +1 -0
  98. package/isite.postman_collection.json +7 -7
  99. package/isite_files/css/bootstrap.css +5 -5
  100. package/isite_files/css/font-awesome.css +4 -4
  101. package/isite_files/css/prism.css +139 -139
  102. package/isite_files/fonts/fontawesome-webfont.svg +2671 -2671
  103. package/isite_files/fonts/glyphicons-halflings-regular.svg +287 -287
  104. package/isite_files/html/files.html +9 -9
  105. package/isite_files/html/head.html +12 -12
  106. package/isite_files/html/index.html +30 -30
  107. package/isite_files/html/installing.html +27 -27
  108. package/isite_files/html/navbar.html +51 -51
  109. package/isite_files/html/routes.html +13 -13
  110. package/isite_files/html/sessions.html +13 -13
  111. package/isite_files/html/vars.html +9 -9
  112. package/isite_files/js/angular.js +334 -334
  113. package/isite_files/js/bootstrap.js +6 -6
  114. package/isite_files/js/custom.js +149 -149
  115. package/isite_files/js/jquery.js +4 -4
  116. package/isite_files/js/prism.js +6 -6
  117. package/lib/README.md +1 -1
  118. package/lib/cookie.js +81 -81
  119. package/lib/dashboard.js +189 -189
  120. package/lib/mongodb.js +686 -686
  121. package/lib/parser.js +910 -910
  122. package/lib/session.js +158 -158
  123. package/lib/storage.js +6 -0
  124. package/lib/ws.js +4 -26
  125. package/object-options/lib/isite.code-workspace +10 -10
  126. package/object-options/lib/safty.js +13 -16
  127. package/package.json +55 -54
  128. package/ssl/create_ssl.sh +3 -3
package/README.md CHANGED
@@ -1,1387 +1,1387 @@
1
- isite now integrated with Social Browser https://social-browser.com
2
- so your site work on Social Browser by default
3
-
4
- ## Create [ Node Js Web Site ] Supporting Many Development features
5
-
6
- - More Secure
7
- - Multi Language
8
- - Custom Apps [Modules]
9
- - Best Performance
10
- - Less Time
11
- - Less Cost
12
- - Fast Development
13
-
14
- # Features
15
-
16
- - Auto Routes [Simple & Advanced & Custom]
17
- - Auto Handle File Types Encoding [Fonts - Images - ...]
18
- - Merge Multi Files Contents in One Route
19
- - Auto Handle Request & Response Headers [Cookies - Parameters - params]
20
- - Auto Detect & Configer User Session
21
- - Built-in Security System [Users , Roles, Permissions]
22
- - Easy Creating Master Pages
23
- - Auto Caching All Routes & Management Site Files in Memory
24
- - Fast Read Files Content [Site Folder Structure]
25
- - [ Upload / Download ] Files
26
- - Custom Html Attributes [Server side Tags]
27
- - MongoDB Full Integration
28
- - Client libraries [jquery - bootstrap - font-awesome - angular]
29
- - Local Multi Charts Apps
30
- - Development Helper Functions
31
- - Site Dynamic Events Callback
32
- - Auto WebSocket Handle
33
-
34
- ## Fast Startup
35
-
36
- - Download Startup Template
37
-
38
- ```sh
39
- git clone https://github.com/absunstar/isite-template
40
- cd isite-template
41
- npm i
42
- npm start
43
- ```
44
-
45
- ## Installation
46
-
47
- `npm install isite`
48
-
49
- - Works Stand-Alone or With Other Libs
50
- - updated every 1 month at least ( npm i isite ) for production apps
51
-
52
- ## Using
53
-
54
- - Fast Startup Web Server.
55
-
56
- ```js
57
- var isite = require('isite');
58
- var site = isite({ port: 8080 });
59
-
60
- site.loadLocalApp('client-side');
61
- site.loadLocalApp('security');
62
-
63
- site.run();
64
- ```
65
-
66
- - Multi port opens
67
-
68
- ```js
69
- var isite = require('isite');
70
- var site = isite();
71
-
72
- site.loadLocalApp('client-side');
73
- site.loadLocalApp('security');
74
-
75
- site.run([8080, 5555, 9090, 12345]);
76
- ```
77
-
78
- - Default Options.
79
-
80
- ```js
81
- var isite = require('isite');
82
- site = isite({
83
- port: process.env.port || 80,
84
- cwd: process.cwd(),
85
- dir: process.cwd() + '/site_files',
86
- upload_dir: process.cwd() + '/../uploads',
87
- download_dir: process.cwd() + '/../downloads',
88
- backup_dir: process.cwd() + '/../backup',
89
- apps: !0,
90
- apps_dir: process.cwd() + '/apps',
91
- name: 'Your Site',
92
- dynamic: false, // (auto set )dynamic db & prot based on folder name [ smart-Your Site-3000 ]
93
- savingTime: 60 // 60 minutes then save sessions and site data,
94
- log: !0,
95
- lang: 'ar',
96
- theme: 'default',
97
- help: !0,
98
- stdin: !0,
99
- https: {
100
- enabled: false,
101
- port: null,
102
- ports: [],
103
- key: null // path or will use default,
104
- cert: null // path or will use default,
105
- },
106
- mongodb: {
107
- enabled: !0,
108
- host: 'localhost',
109
- port: '27017',
110
- userName: null,
111
- password: null,
112
- db: 'default_db',
113
- collection: 'default_collection',
114
- limit: 10,
115
- prefix: {
116
- db: '',
117
- collection: '',
118
- },
119
- identity: {
120
- enabled: !0,
121
- start: 1,
122
- step: 1,
123
- },
124
- },
125
- session: {
126
- timeout: 60 * 24 * 30,
127
- enabled: !0,
128
- storage: 'file' || 'mongodb',
129
- db: null,
130
- collection: 'users_sessions',
131
- },
132
- security: {
133
- enabled: !0,
134
- db: null,
135
- users_collection: 'users_info',
136
- roles_collection: 'users_roles',
137
- admin: {
138
- email: 'admin@isite',
139
- password: 'P@$$w0rd',
140
- },
141
- users: [],
142
- },
143
- cache: {
144
- enabled: !0,
145
- html: 0,
146
- txt: 60 * 24 * 30,
147
- js: 60 * 24 * 30,
148
- css: 60 * 24 * 30,
149
- fonts: 60 * 24 * 30,
150
- images: 60 * 24 * 30,
151
- json: 60 * 24 * 30,
152
- xml: 60 * 24 * 30,
153
- },
154
- proto: {
155
- object: !0,
156
- },
157
- });
158
-
159
- site.run();
160
- ```
161
-
162
- ## Site Folder Structure
163
-
164
- - site stucture help you to manage you site easy and fast
165
-
166
- ```html
167
- - server.js - package.json - README.md -- apps -- site_files --- css - bootstrap.css - custom.css --- js - jquery.js - bootstrap.js - custom.js --- html - index.html --- fonts --- images - logo.png
168
- --- json - items.json - words.json - roles.json - permissions.json --- xml - rss.xml
169
- ```
170
-
171
- - Create Folder Name "site_files"
172
- - inside it create these Sub folders [
173
- html , css , js , json , fonts , images , xml , ...
174
- ]
175
-
176
- ## Routes
177
-
178
- - Auto Convert All Routes URL & Parameters to Lower Case
179
- - Auto Manage Reponse Headers and Files Types
180
- - Support Multi Files in One Route
181
- - Save Route Response in Memory to Reuse for Fast Response
182
- - Auto Handle URL parametes
183
- - Auto Handle Body Parameters in not get header [post , put , delete , ...]
184
- - Auto Handle URL params [custom parameters from url structure]
185
- - Auto cache Files Content in memory
186
- - support compress to remove unwanted spaces and tabs and empty lines ...etc
187
- - support parser to handle custom html server side tags
188
- - Call Route From Other Route [ Server Side ]
189
-
190
- Easy and Auto Site Routing
191
-
192
- ```js
193
- /* site.dir = process.cwd() + "/site_files"
194
- You Can Change This Default Value when define isite
195
- or set site.dir = new path
196
- */
197
-
198
- site.onGET({ name: ['/', '/home', '/index'], path: site.dir + '/html/index.html' });
199
- site.onGET({ name: '/css/bootstrap.css', path: site.dir + '/css/bootstrap.min.css' });
200
- site.onGET({ name: '/js/jquery.js', path: site.dir + '/js/jquery.js' });
201
- site.onGET({ name: '/js/bootstrap.js', path: site.dir + '/js/bootstrap.js' });
202
- site.onGET({ name: '/favicon.png', path: site.dir + '/images/logo.png' });
203
- site.onPOST({ name: '/api', path: site.dir + '/json/employees.json' });
204
- ```
205
-
206
- Merge Multi Files in one route
207
-
208
- ```js
209
- site.onGET({
210
- name: '/css/style.css',
211
- path: [site.dir + '/css/bootstrap.css', site.dir + '/css/custom.css'],
212
- });
213
- site.onGET({
214
- name: '/js/script.js',
215
- path: [site.dir + '/js/jquery.js', site.dir + '/js/bootstrap.js', site.dir + '/js/custom.js'],
216
- });
217
- ```
218
-
219
- Advanced Site Routing
220
-
221
- ```js
222
- site.onREQUEST('get', '/', (req, res) => {});
223
-
224
- site.onREQUEST('get', { name: '/' }, (req, res) => {});
225
-
226
- site.onGET('/home2', (req, res) => {
227
- site.callRoute('/home', req, res);
228
- });
229
-
230
- site.onGET({
231
- name: 'api/user/add',
232
- content: {
233
- done: true,
234
- id: 1,
235
- },
236
- });
237
-
238
- site.onGET('/', (req, res) => {
239
- site.readFile(site.dir + '/html/index.html', function (err, content, file) {
240
- res.set('Content-type', 'text/html');
241
- res.set('Content-size', file.stat.size);
242
- res.status(200).end(content);
243
- });
244
- });
245
-
246
- site.onGET('/', (req, res) => {
247
- site.html('index', function (err, content) {
248
- res.set('Content-type', 'text/html');
249
- res.status(200).end(content);
250
- });
251
- });
252
-
253
- site.onGET({
254
- // can use [get , post , put , delete , all]
255
- name: '/',
256
- path: site.dir + '/html/index.html', //Required
257
- parser: 'html', // default static [not paresed]
258
- compress: !0, // default false
259
- cache: false, // default !0
260
- });
261
-
262
- site.onGET({
263
- name: '/',
264
- callback: function (req, res) {
265
- res.set('Content-type', 'text/html');
266
- site.html('index', function (err, content) {
267
- res.status(200).end(content);
268
- });
269
- },
270
- });
271
- ```
272
-
273
- Auto Route All Files in Folder
274
-
275
- ```js
276
- site.onGET({ name: '/js', path: site.dir + '/js' });
277
- site.onGET({ name: '/css', path: site.dir + '/css' });
278
- ```
279
-
280
- Custom Route - Using \* [any letters]
281
-
282
- ```js
283
- site.onGET('/post/*', function (req, res) {
284
- res.end('Any Route like /post/11212154545 ');
285
- });
286
- site.onGET('*', function (req, res) {
287
- res.end('Any Route Requested Not Handled Before This Code');
288
- });
289
- ```
290
-
291
- Request Parameters [GET , POST | PUT | Delete] Restful API
292
-
293
- ```js
294
- // read query parameter lower case
295
- site.onGET('/api', function (req, res) {
296
- res.end('GET | name : ' + req.query.name);
297
- });
298
- // read query parameter default case as requested
299
- site.onGET('/api', function (req, res) {
300
- res.end('GET | name : ' + req.queryRaw.name);
301
- });
302
-
303
- site.onPOST('/api', function (req, res) {
304
- res.end('POST | id : ' + req.body.id + ' , Name : ' + req.body.name);
305
- });
306
- site.onPUT('/api', function (req, res) {
307
- res.end('PUT | id : ' + req.body.id + ' , Name : ' + req.body.name);
308
- });
309
- site.onDELETE('/api', function (req, res) {
310
- res.end('Delete | id : ' + req.body.id);
311
- });
312
- site.onALL('/api', function (req, res) {
313
- res.end('Any Request Routing Type Not Handled Yet : ' + req.method);
314
- });
315
- ```
316
-
317
- Dynamic Parameters
318
-
319
- ```js
320
- // read params lower case
321
- site.onGET('/post/:id/category/:cat_id', function (req, res) {
322
- res.end('GET | Id : ' + req.params.id + ', catId : ' + req.params.cat_id);
323
- });
324
- // read params default case as requested
325
- site.onGET('/post/:id/category/:cat_id', function (req, res) {
326
- res.end('GET | Id : ' + req.paramsRaw.id + ', catId : ' + req.paramsRaw.cat_id);
327
- });
328
- //example : /post/AbCdEf/category/DDDDD
329
- ```
330
-
331
- MVC Custom Route
332
-
333
- ```js
334
- site.onGET('/:controller/:Action/:Arg1', function (req, res) {
335
- res.end(
336
- 'GET | Controller : ' +
337
- req.params.controller +
338
- ', Action : ' +
339
- req.params.Action /* Normal case*/ +
340
- ', action : ' +
341
- req.params.action /* lower case*/ +
342
- ', Arg 1 : ' +
343
- req.params.Arg1 /* Normal case*/ +
344
- ', arg 1 : ' +
345
- req.params.arg1 /* lower case*/,
346
- );
347
- });
348
- //example : /facebook/post/xxxxxxxxxx
349
- ```
350
-
351
- - To Easy Read File Contents From "site_files" Folder
352
-
353
- ```js
354
- site.html('index', function (err, content) {
355
- site.log(content);
356
- });
357
- site.css('bootstrap', function (err, content) {
358
- site.log(content);
359
- });
360
- site.js('jquery', function (err, content) {
361
- site.log(content);
362
- });
363
- site.json('items', function (err, content) {
364
- site.log(content);
365
- });
366
- site.xml('rss', function (err, content) {
367
- site.log(content);
368
- });
369
- ```
370
-
371
- - Custom Read Files
372
-
373
- - Read From Local File in First Time and save in memory
374
- - next time Read Will be From Memory
375
-
376
- ```js
377
- //read file with custom header
378
- site.onGET("/rss", function(req, res) {
379
- site.readFile(__dirname + "/site_files/xml/rss.xml", function(err, content , file) {
380
- res.set("content-type" , "text/xml")
381
- res.set("content-size" , file.stat.size)
382
- res.status(200).end(content) // or res.end(content)
383
- })
384
- })
385
- // or [ if file in site_files/xml folder]
386
- site.onGET("/rss", function(req, res) {
387
- site.xml("rss", function(err, content , file) {
388
- res.set("content-type" , "text/xml")
389
- res.set("content-size" , file.stat.size)
390
- res.status(200).end(content)
391
- })
392
- })
393
-
394
- // Read and Merge multi files with custom header
395
- site.onGET("/", function(req, res) {
396
- site.readFiles(
397
- [
398
- __dirname + "/site_files/html/head.html",
399
- __dirname + "/site_files/html/content.html",
400
- __dirname + "/site_files/html/footer.html"
401
- ],
402
- function(err, content) {
403
- res.writeHead(200, { "content-type": "text/html" });
404
- res.end(content);
405
- })
406
- })
407
-
408
- // Check if File Exits
409
- site.isFileExists(path , (yes)=>{
410
- if(yes){
411
- // ...
412
- }
413
- })
414
- // or
415
- let yes = site.isFileExistsSync(path)
416
- if(yes){
417
- // ...
418
- }
419
-
420
- // Get File Info
421
- site.fileStat(path , (err , stats)=>{
422
- console.log(stats)
423
- })
424
- // or
425
- let stats = site.fileStatSync(path)
426
-
427
- // Write Data to File
428
- site.writeFile(path , data , err =>{
429
-
430
- }
431
- // Delete File
432
- site.removeFile(path , err =>{
433
-
434
- }) // or site.deleteFile
435
-
436
-
437
- // Create New Dir
438
- site.createDir(path , (err , path)=>{
439
- if(!err){
440
- // ...
441
- }
442
- }) // or site.makeDir
443
-
444
- ```
445
-
446
- ## WebSocket
447
-
448
- - Server Side
449
-
450
- ```js
451
- site.onWS('/chat', (client) => {
452
- client.onMessage = function (message) {
453
- console.log(message);
454
- if (message.type === 'connected') {
455
- client.send({ type: 'ready' });
456
- }
457
- };
458
- console.log('New Client ...' + client.ip);
459
- });
460
- ```
461
-
462
- - Client Side
463
-
464
- ```html
465
- <script src="/x-js/all.js"></script>
466
- ```
467
-
468
- ```js
469
- site.ws('ws://localhost/chat', (server) => {
470
- window.server = server;
471
- server.onOpen = () => {
472
- server.send({ type: 'accessToken', content: '##session.accessToken##' });
473
- };
474
- server.onMessage = (msg) => {
475
- console.log(msg);
476
- };
477
- });
478
-
479
- // or
480
-
481
- var ws = new WebSocket('ws://localhost/chat');
482
-
483
- ws.onerror = function (error) {};
484
- ws.onclose = function () {};
485
-
486
- ws.onopen = function () {
487
- ws.send(JSON.stringify({ type: 'connect' }));
488
- };
489
-
490
- ws.onmessage = function (msg) {
491
- msg = JSON.parse(msg.data);
492
- if (msg.type === 'ready') {
493
- ws.send(JSON.stringify({ type: 'ready' }));
494
- }
495
- };
496
- ```
497
-
498
- ## Cookies
499
-
500
- - Cookie is Client Side Data Per User
501
- - Cookie is Enabled by Default
502
- - Support Multi Keys
503
-
504
- ```js
505
- site.onGET('/testSetCookie', function (req, res) {
506
- res.cookie('name', req.query.name);
507
- res.cookie('ip', req.ip);
508
- res.cookie('more', 'any data');
509
- res.end('cookie set');
510
- }); //example : /testSetCookie?name=amr
511
-
512
- site.onGET('/testGetCookie', function (req, res) {
513
- res.end('name from cookie : ' + req.cookie('name'));
514
- }); //example : /testGetCookie
515
- ```
516
-
517
- ## Sessions
518
-
519
- - Session is Server Side Data Per User
520
- - Every User has Unique Access Token
521
- - Session Management Automatic
522
- - Session Store in Database by Default
523
-
524
- ```js
525
- site.onGET('/testSetSession', function (req, res) {
526
- req.session.user_name = req.query.user_name;
527
- res.session.ip = req.ip;
528
- res.session.more = 'any data';
529
- site.saveSession(res.session);
530
- res.end('Session Set ok !! ');
531
- }); //example : /testSetSession?user_name=absunstar
532
-
533
- site.onGET('/testGetSession', function (req, res) {
534
- res.end('User Name from session : ' + req.session.user_name);
535
- }); //example : /testGetSession
536
- ```
537
-
538
- ## Custom App
539
-
540
- - Custom App Help you to Easy Management Site Life-Cycle
541
- - Easy Register & Integrated
542
- - Best Solution when work with Team
543
-
544
- ### How to make it
545
-
546
- - Create your app folder in global apps folder
547
- - Add app.js file with this code
548
-
549
- ```js
550
- module.exports = function (site) {
551
- // write here your custom code
552
- };
553
- ```
554
-
555
- - App Will Be Auto Register And Integerated With Your Site
556
-
557
- ### add App From github
558
-
559
- - Add Apps from github to Your Site
560
-
561
- ```sh
562
- cd apps
563
- git clone https://github.com/absunstar/isite-client
564
- git clone https://github.com/absunstar/isite-security
565
- ```
566
-
567
- ### add App From Local Path
568
-
569
- ```js
570
- site.importApp(FOLDER_PATH);
571
- ```
572
-
573
- ## Master Pages
574
-
575
- - Master Page put content between header and footer
576
- - Master Page help you to not repate you code
577
- - Master Page make site layout look good with less code
578
- - Master Page has tow parts header and footer
579
-
580
- ```js
581
- site.addMasterPage({
582
- name: 'masterPage1',
583
- header: site.dir + '/html/header.html',
584
- footer: site.dir + '/html/footer.html',
585
- });
586
-
587
- site.addMasterPage({
588
- name: 'masterPage2',
589
- header: site.dir + '/html/header2.html',
590
- footer: site.dir + '/html/footer2.html',
591
- });
592
-
593
- site.onGET({
594
- name: '/ContactUs',
595
- masterPage: 'masterPage1',
596
- path: site.dir + '/html/contact.html',
597
- parser: 'html',
598
- });
599
- ```
600
-
601
- ## HTML Server Tags & Attributes
602
-
603
- - html server tags is html tags run in server side
604
- - html server tags make html structure easy management
605
- - html server tags is the next generation of html
606
-
607
- Add Custom Html Content
608
-
609
- ```js
610
- site.onGET({ name: '/', path: site.dir + '/html/index.html', parser: 'html' });
611
- ```
612
-
613
- ```html
614
- <style x-import="page2.css"></style>
615
- <div x-import="navbar.html"></div>
616
- <div class="container">
617
- <h2>Page Heading 2</h2>
618
- <p x-import="info.html"></p>
619
- </div>
620
- <script x-import="custom.js"></script>
621
- ```
622
-
623
- - Pages "navbar.html" & "info.html" Must Be In HTML Site Folder ['/site_files/html/']
624
- - Style "page2.css" Must Be In HTML Site Folder ['/site_files/css/']
625
- - Script "custom.js" Must Be In HTML Site Folder ['/site_files/js/']
626
-
627
- Dynamic Varibles Sets
628
-
629
- ```js
630
- site.var('siteName', 'First Site With Isite Library ');
631
- site.var('siteBrand', 'XSite');
632
- ```
633
-
634
- ```html
635
- <title>##var.siteName##</title>
636
- <h2>##var.siteBrand##</h2>
637
- <h2>Lang : ##session.lang## , Theme : ##session.theme##</h2>
638
- <h2>query name : ##query.name## , query age : ##query.age##</h2>
639
- <h2>data name : ##data.name## , data age : ##data.age##</h2>
640
- <h2>param category : ##params.category## , param post : ##params.post##</h2>
641
-
642
- <div x-lang="ar">Show if Site Language is Arabic</div>
643
- <div x-lang="en">Show if Site Language is English</div>
644
- // auto detect user session language
645
-
646
- <div x-permission="admin">Only Admi Users Can Show This Content</div>
647
- <div x-permission="accounting">Only Accounting Users Can Show This Content</div>
648
-
649
- <div x-feature="login">Only Login Users Can Show This Content</div>
650
- <div x-feature="!login">Only Not Login Users Can Show This Content</div>
651
- // auto detect user login status
652
-
653
- <div x-features="os.mobile || os.android">Only Users From Mobile or Android Can Show This Content</div>
654
- <div x-features="os.mobile && os.android">Only Users From Mobile and Android Can Show This Content</div>
655
- // Using || , && to Multi Features
656
-
657
- <div x-feature="os.mobile">Only Users From Mobile Can Show This Content</div>
658
- <div x-feature="os.desktop">Only Users From Mobile Can Show This Content</div>
659
-
660
- <div x-feature="os.windows">Only Users From Windows Can Show This Content</div>
661
- <div x-feature="!os.windows">Only Users From Not Windows Can Show This Content</div>
662
- <div x-feature="os.windowsxp">Only Users From Windows XP Can Show This Content</div>
663
- <div x-feature="os.windows7">Only Users From Windows 7 Can Show This Content</div>
664
- <div x-feature="os.windows8">Only Users From Windows 8 Can Show This Content</div>
665
- <div x-feature="os.windows10">Only Users From Windows 10 Can Show This Content</div>
666
-
667
- <div x-feature="os.linux">Only Users From Linux Systems Can Show This Content</div>
668
- <div x-feature="os.mac">Only Users From Mac Systems Can Show This Content</div>
669
- <div x-feature="os.android">Only Users From Android Systems Can Show This Content</div>
670
- <div x-feature="os.unknown">Only Users From unknown Systems Can Show This Content</div>
671
-
672
- <div x-feature="browser.edge">Only Users From Edge Browser Can Show This Content</div>
673
- <div x-feature="browser.firefox">Only Users From FireFox Browser Can Show This Content</div>
674
- <div x-feature="browser.chrome">Only Users From Chrome Browser Can Show This Content</div>
675
- <div x-feature="browser.opera">Only Users From Opera Browser Can Show This Content</div>
676
- <div x-feature="browser.unknown">Only Users From unknown Browser Can Show This Content</div>
677
-
678
- <div x-feature="ip.xxx.xxx.xxx.xxx">Only Users From IP xxx.xxx.xxx.xxx Can Show This Content</div>
679
-
680
- //auto detect user browser
681
- ```
682
-
683
- ## MongoDB Integration
684
-
685
- - Auto Add [ id ] as auto increment number [Like SQL]
686
- - Handle [ _id ] Data Type
687
- - Manage Closed Connections and Timeout
688
- - Manage Multi Connections
689
- - Manage Bulk [ Inserts & Updates & Deletes ]
690
- - Global Database Events
691
- - User Friendly Coding
692
-
693
- ```js
694
-
695
- // use connect collection [ Best Way For Security ]
696
-
697
- $employees = site.connectCollection("employees")
698
-
699
- // with database
700
- $employees = site.connectCollection("employees" , "company")
701
- //or
702
- $employees = site.connectCollection({collection : "employees" , db : "company")
703
-
704
-
705
- // insert one doc [ can use also [add , addOne , insert , insertOne]]
706
- $employees.insertOne({name : 'amr' , salary : 50000} , (err , doc)=>{
707
- site.log(doc) // doc after inserted
708
- })
709
-
710
- // insert Many Docs [ can use also [ addMany , addAll , insertMany , insertAll]]
711
- $employee.insertMany([{name : 'a'} , {name : 'b'}] , (err , docs)=>{
712
- site.log(docs , 'docs')
713
- })
714
-
715
- // select one doc [ can use also [ get , getOne , find , findOne , select , selectOne ]]
716
- $employees.findOne({where:{id : 5} , select:{salary:1}} , (err , doc)=>{
717
- site.log(doc)
718
- })
719
- //or
720
- $employees.findOne({ id : 5 } , (err , doc)=>{
721
- site.log(doc)
722
- })
723
-
724
-
725
- // select Multi docs [ can use also [getAll , getMany , findAll , findMany , selectAll , selectMany ]]
726
- $employees.findMany({
727
- where:{name : /a/i} ,
728
- select:{name: 1 , salary:1} ,
729
- limit : 50 ,
730
- skip : 10 ,
731
- sort:{salary : -1}
732
- } , (err , docs , count)=>{
733
- site.log(docs)
734
- }
735
- )
736
-
737
- // Update One Doc [ can use [ updateOne , update , editOne , edit]]
738
- $employees.updateOne({
739
- where:{_id : 'df54fdt8h3n48ykd136vg'} ,
740
- set:{salary: 30000}} , (err , result)=>{
741
- site.log(result)
742
- })
743
- // or [ auto update by _id ]
744
- $employees.updateOne({_id : 'df54fdt8h3n48ykd136vg' , salary : 5000} , (err , result)=>{
745
- site.log(result)
746
- })
747
-
748
- // Update Many Docs [ can use [ updateAll , updateMany , editAll , editMany]]
749
- $employees.updateMany({
750
- where:{name : /a/i} ,
751
- set:{salary: 30000}} , (err , result)=>{
752
- site.log(result)
753
- })
754
-
755
- // Delete One Doc [ can use [ deleteOne , delete , removeOne , remove]]
756
- $employees.deleteOne({where:{ _id : 'df54fdt8h3n48ykd136vg'}} , (err , result)=>{
757
- site.log(result)
758
- })
759
- // or [ auto delete by _id]
760
- $employees.deleteOne('df54fdt8h3n48ykd136vg', (err , result)=>{
761
- site.log(result)
762
- })
763
- // or
764
- $employees.deleteOne({name : /a/i} , (err , result)=>{
765
- site.log(result)
766
- })
767
-
768
- // Delete Many Docs [ can use [ deleteAll , deleteManye , removeAll , removeMany ]]
769
- $employees.deleteMany({where:{name : /a/i}} , (err , result)=>{
770
- site.log(result)
771
- })
772
- // or
773
- $employees.deleteMany({name : /a/i} , (err , result)=>{
774
- site.log(result)
775
- })
776
-
777
- // Import Object Data From Json File
778
- $employees.import(FILE_PATH , (result)=>{
779
-
780
- })
781
-
782
- // Import Array Data From Json File
783
- $employees.import(FILE_PATH , (result)=>{
784
-
785
- })
786
-
787
- // Export Object Data From Json File
788
- $employees.export( OPTONS , FILE_PATH , (err , docs)=>{
789
-
790
- })
791
- // Export 10 employees that salary more than 1000
792
- $employees.export({limit : 10 , where : {salary : {$gt : 1000}}} , FILE_PATH , (err , docs)=>{
793
-
794
- })
795
-
796
- // Remove duplicate data [ can use [deleteDuplicate , removeDuplicate]]
797
- $employees.deleteDuplicate('name' , (err , result)=>{
798
-
799
- })
800
- // Remove Duplicate [ name and mobile ] Employee
801
- $employees.deleteDuplicate({name : 1 , mobile : 1} , (err , result)=>{
802
-
803
- })
804
- // Remove Duplicate [ profile.name ] Employee
805
- $employees.deleteDuplicate({'profile.name' : 1 } , (err , result)=>{
806
-
807
- })
808
-
809
- // Create Index Field
810
- $employees.createIndex({name : 1} , (err , result)=>{
811
-
812
- }
813
-
814
- // Create Unique Field
815
- $employees.createUnique({name : 1} , (err , result)=>{
816
-
817
- }
818
- // Create Unique Fields
819
- $employees.createUnique({user_name : 1 , user_password : 1} , (err , result)=>{
820
-
821
- }
822
-
823
- // backup database
824
- site.backupDB() // backup current database to current backup folder
825
- site.backupDB({db:'' , path : ''})
826
-
827
- // restore database
828
- site.restoreDB() // restore current database from current backup folder
829
- site.restoreDB({db:'' , path : ''})
830
-
831
- // API to download backup db
832
- site.onGET('db', (req, res) => {
833
- site.backupDB(null, (err, options) => {
834
- if (!err) {
835
- res.download(options.path);
836
- } else {
837
- res.json(err);
838
- }
839
- });
840
- });
841
-
842
- //==================================================================
843
- // Global Database Events
844
- // from here you can catch all transactions
845
-
846
- site.on('mongodb after insert' , (result)=>{
847
-
848
- })
849
- site.on('mongodb after insert many' , (result)=>{
850
-
851
- })
852
- site.on('mongodb after find' , (result)=>{
853
-
854
- })
855
- site.on('mongodb after find many' , (result)=>{
856
-
857
- })
858
- site.on('mongodb after update' , (result)=>{
859
-
860
- })
861
- site.on('mongodb after update many' , (result)=>{
862
-
863
- })
864
- site.on('mongodb after delete' , (result)=>{
865
-
866
- })
867
- site.on('mongodb after delete many' , (result)=>{
868
-
869
- })
870
-
871
-
872
- // ==================================================================
873
- // Low Level Access Database Functions [ For Advanced Work ]
874
-
875
- // Insert One Doc
876
- site.mongodb.insertOne({
877
- dbName: 'company',
878
- collectionName: 'employess',
879
- doc:{name:'amr',salary:35000}
880
- }, function (err, docInserted) {
881
- if (err) {
882
- site.log(err.message)
883
- } else {
884
- site.log(docInserted)
885
- }
886
- } , /* default waiting Sync or !0 for Async*/)
887
-
888
- // Insert Many Docs
889
- site.mongodb.insertMany({
890
- dbName: 'company',
891
- collectionName: 'employess',
892
- docs:[
893
- {name:'amr',salary:35000} ,
894
- {name:'Gomana',salary:9000} ,
895
- {name:'Maryem',salary:7000}
896
- ]
897
- }, function (err, result) {
898
- if (err) {
899
- site.log(err.message)
900
- } else {
901
- site.log(result)
902
- }
903
- }/* default waiting Sync or !0 for Async*/)
904
-
905
- // Find One Doc
906
- site.mongodb.findOne({
907
- dbName: 'company',
908
- collectionName: 'employees',
909
- where:{},
910
- select : {}
911
- }, function (err, doc) {
912
- if (err) {
913
- site.log(err.message)
914
- } else {
915
- site.log(doc)
916
- }
917
- }/* default waiting Sync or !0 for Async*/)
918
-
919
- // Find Many Docs
920
- site.mongodb.findMany({
921
- dbName: 'company',
922
- collectionName: 'employees',
923
- where:{},
924
- select : {}
925
- }, function (err, docs , count) {
926
- if (err) {
927
- site.log(err.message)
928
- } else {
929
- site.log(docs)
930
- }
931
- }/* default waiting Sync or !0 for Async*/)
932
-
933
- //Update One Doc
934
- site.mongodb.updateOne({
935
- dbName: 'company',
936
- collectionName: 'employees',
937
- where:{salary:7000},
938
- set : {name:'New MARYEM'}
939
- }, function (err, result) {
940
- if (err) {
941
- site.log(err.message)
942
- } else {
943
- site.log(result)
944
- }
945
- }/* default waiting Sync or !0 for Async*/)
946
-
947
- // Update Many Docs
948
- site.mongodb.updateMany({
949
- dbName: 'company',
950
- collectionName: 'employees',
951
- where:{salary:9000},
952
- set : {salary:9000 * .10}
953
- }, function (err, result) {
954
- if (err) {
955
- site.log(err.message)
956
- } else {
957
- site.log(result)
958
- }
959
- }/* default waiting Sync or !0 for Async*/)
960
-
961
- // Delete One Doc
962
- site.mongodb.deleteOne({
963
- dbName: 'company',
964
- collectionName: 'employess',
965
- where:{_id: new site.mongodb.ObjectID('df54fdt8h3n48ykd136vg')}
966
- }, function (err, result) {
967
- if (err) {
968
- site.log(err.message)
969
- } else {
970
- site.log(result)
971
- }
972
- }/* default waiting Sync or !0 for Async*/)
973
- // Delete Many Docs
974
- site.mongodb.deleteMany({
975
- dbName: 'company',
976
- collectionName: 'employess',
977
- where:{name : /a/}
978
- }, function (err, result) {
979
- if (err) {
980
- site.log(err.message)
981
- } else {
982
- site.log(result)
983
- }
984
- }/* default waiting Sync or !0 for Async*/)
985
-
986
- // ==================================================================
987
- // Mongodb Native Client Provider
988
-
989
- site.mongodb.client // = require("mongodb").MongoClient
990
-
991
- // Create a database called "mydb":
992
-
993
- var url = "mongodb://localhost:27017/mydb";
994
-
995
- site.mongodb.client.connect(url, function(err, db) {
996
- if (err) throw err;
997
- console.log("Database created!");
998
- db.close();
999
- });
1000
-
1001
- // all code can be found in offical mongodb site or w3schools
1002
-
1003
- ```
1004
-
1005
- ## Upload File
1006
-
1007
- - upload File using HTML
1008
-
1009
- ```html
1010
- <form action="uploadFile" method="post" enctype="multipart/form-data">
1011
- <input type="file" name="fileToUpload" /><br />
1012
- <input type="submit" />
1013
- </form>
1014
- ```
1015
-
1016
- - Upload File Using Angular js
1017
-
1018
- ```html
1019
- <form class="form">
1020
- <label>Select File To Upload</label>
1021
- <input type="file" name="fileToUpload" onchange="angular.element(this).scope().uploadFile(this.files)" />
1022
- <p>{{uploadStatus}}</p>
1023
- </form>
1024
- ```
1025
-
1026
- ```js
1027
- $scope.uploadFile = function (files) {
1028
- var fd = new FormData();
1029
- fd.append('fileToUpload', files[0]);
1030
- $http
1031
- .post('/uploadFile', fd, {
1032
- withCredentials: !0,
1033
- headers: {
1034
- 'Content-Type': undefined,
1035
- },
1036
- uploadEventHandlers: {
1037
- progress: function (e) {
1038
- $scope.uploadStatus = 'Uploading : ' + Math.round((e.loaded * 100) / e.total) + ' %';
1039
- if (e.loaded == e.total) {
1040
- $scope.uploadStatus = '100%';
1041
- }
1042
- },
1043
- },
1044
- transformRequest: angular.identity,
1045
- })
1046
- .then(
1047
- function (res) {
1048
- if (res.data && res.data.done) {
1049
- $scope.uploadStatus = 'File Uploaded';
1050
- }
1051
- },
1052
- function (error) {
1053
- $scope.uploadStatus = error;
1054
- },
1055
- );
1056
- };
1057
- ```
1058
-
1059
- - Recive Uploading File from [html , angular , jquery , ...]
1060
-
1061
- ```js
1062
- site.onPOST('uploadFile', (req, res) => {
1063
- var response = { done: !0 };
1064
- var file = req.files.fileToUpload;
1065
- var newpath = site.dir + '/../../uploads/' + file.originalFilename;
1066
- site.mv(file.filepath, newpath, function (err) {
1067
- if (err) {
1068
- response.error = err;
1069
- response.done = false;
1070
- }
1071
- res.end(JSON.stringify(response));
1072
- });
1073
- });
1074
- ```
1075
-
1076
- ## Download File
1077
-
1078
- - download any file from server
1079
- - auto handle file content and size
1080
- - force client browser to download file
1081
-
1082
- ```js
1083
- // download any file
1084
- site.onGET('/files/file1.zip', (req, res) => {
1085
- res.download(site.dir + '/downloads/file1.zip');
1086
- });
1087
- //download and change file name
1088
- site.onGET('/files/file1.zip', (req, res) => {
1089
- res.download(site.dir + '/downloads/file1.zip', 'info.zip');
1090
- });
1091
- ```
1092
-
1093
- ## Multi Languages
1094
-
1095
- - Can Add Any Custom Language You Want
1096
- - Can Change Default Language on Site Options
1097
- - Stores Words in Diffrent Language in words json file
1098
- - Auto Detect Words.json
1099
- - Folder Structure Like This
1100
-
1101
- ```html
1102
- - apps - server.js - package.json - README.md -- site_files --- json - words.json
1103
- ```
1104
-
1105
- - Words Json File Structure Like This
1106
-
1107
- ```json
1108
- [
1109
- { "name": "user_name", "en": "User Name", "ar": "أسم المستخدم" },
1110
- { "name": "user_email", "en": "Email", "ar": "البريد الالكترونى" },
1111
- { "name": "user_password", "en": "Password", "ar": "كلمة المرور" }
1112
- ]
1113
- ```
1114
-
1115
- - Use in html Like This
1116
-
1117
- ```html
1118
- <form>
1119
- <label> ##word.user_name## </label>
1120
- <input />
1121
- <br />
1122
-
1123
- <label> ##word.user_email## </label>
1124
- <input />
1125
- <br />
1126
-
1127
- <label> ##word.user_password## </label>
1128
- <input />
1129
- <br />
1130
- </form>
1131
- ```
1132
-
1133
- - Cahnge Site Language
1134
-
1135
- ```js
1136
- $scope.changeLang = function (lang= 'EN' , langDir = 'ltr') {
1137
- $http({
1138
- method: 'POST',
1139
- url: '/x-language/change',
1140
- data: { name: lang , dir : langDir },
1141
- }).then(function (response) {
1142
- if (response.data.done) {
1143
- window.location.reload(!0);
1144
- }
1145
- });
1146
- };
1147
- ```
1148
-
1149
- ```html
1150
- <a ng-click="changeLang('ar')"> Change To Arabic </a> <a ng-click="changeLang('en')"> Change To English </a>
1151
- ```
1152
-
1153
- - Show Content Depended on Language
1154
-
1155
- ```html
1156
- <div x-lang="ar">This Content Will Display When Site Language is Arabic</div>
1157
- <div x-lang="en">This Content Will Display When Site Language is English</div>
1158
- ```
1159
-
1160
- ## Client libraries
1161
-
1162
- - install Custom App From https://github.com/absunstar/isite-client
1163
-
1164
- ```sh
1165
- cd apps
1166
- git clone https://github.com/absunstar/isite-client
1167
- ```
1168
-
1169
- - no need to install any client library
1170
- - no need to install any fonts
1171
- - no need to manage library routes
1172
- - just use it
1173
-
1174
- ```html
1175
- <link rel="stylesheet" href="/x-css/bootstrap3.css" />
1176
- <link rel="stylesheet" href="/x-css/font-awesome.css" />
1177
-
1178
- <script src="/x-js/jquery.js"></script>
1179
- <script src="/x-js/bootstrap3.js"></script>
1180
- <script src="/x-js/angular.js"></script>
1181
- ```
1182
-
1183
- ## Charts
1184
-
1185
- - Server Side
1186
-
1187
- ```js
1188
- site.loadLocalApp('charts');
1189
- ```
1190
-
1191
- - Client Site
1192
-
1193
- ```html
1194
- <div id="chart1"></div>
1195
- <script src="/js/charts.js"></script>
1196
- ```
1197
-
1198
- ```js
1199
- var data = [
1200
- {
1201
- item: 'item 1',
1202
- count: 500,
1203
- },
1204
- {
1205
- item: 'item 2',
1206
- count: 200,
1207
- },
1208
- {
1209
- item: 'item 3',
1210
- count: 700,
1211
- },
1212
- {
1213
- item: 'item 4',
1214
- count: 300,
1215
- },
1216
- {
1217
- item: 'item 5',
1218
- count: 800,
1219
- },
1220
- {
1221
- item: 'item 6',
1222
- count: 60,
1223
- },
1224
- ];
1225
-
1226
- site.create_chart({
1227
- type: 'xy',
1228
- x: 'item',
1229
- y: 'count',
1230
- data: data,
1231
- selector: '#chart1',
1232
- });
1233
- ```
1234
-
1235
- ## Security
1236
-
1237
- - Bulit-in Users Management System
1238
- - Auto Detect Users Sessions & Permissions
1239
- - install Custom Security App From https://github.com/absunstar/isite-security
1240
-
1241
- ```sh
1242
- cd apps
1243
- git clone https://github.com/absunstar/isite-security
1244
- ```
1245
-
1246
- - Manage users From This Route [ /security ]
1247
-
1248
- ## Helper Functions
1249
-
1250
- ```js
1251
- site.onGET('/', (req, res) => {
1252
- res.render('index.html', { name: 'amr', age: '36' }, { compress: !0, cache: false, parser: 'html css js' });
1253
- res.render('custom.css', { 'font-size': '18px' }, { parser: 'css' });
1254
- res.render('custom.js', { 'allow-ads': !0 }, { parser: 'js' });
1255
- res.code = 301; // set response code to 301
1256
- res.status(301); // set response code if not set to 301 and return response object
1257
- res.set('Content-Type', 'text/plain'); // add response header
1258
- res.remove('Content-Type'); // remove response header
1259
- res.delete('Content-Type'); // remove response header
1260
- res.redirect('/URL' , 302); // Any URL
1261
- res.send('HTML CONTENT'); // Any HTML Content or object
1262
- res.send(obj); // Any HTML Content or object
1263
- res.htmlContent('HTML CONTENT'); // Any HTML Content
1264
- res.html('index'); // like res.render
1265
- res.css('bootstrap'); // css file name
1266
- res.js('jquery'); // js file name
1267
- res.json('items'); // json file name or object
1268
- res.json(obj); // json file name or object
1269
-
1270
- if (req.hasFeature('browser.chrome')) {
1271
- }
1272
- if (req.hasFeature('browser.firefox')) {
1273
- }
1274
- if (req.hasFeature('browser.edge')) {
1275
- }
1276
- if (req.hasFeature('browser.opera')) {
1277
- }
1278
- if (req.hasFeature('browser.ucbrowser')) {
1279
- }
1280
- if (req.hasFeature('browser.baidu')) {
1281
- }
1282
- if (req.hasFeature('browser.chromium')) {
1283
- }
1284
- if (req.hasFeature('browser.unknown')) {
1285
- }
1286
-
1287
- if (req.hasFeature('os.windows')) {
1288
- }
1289
- if (req.hasFeature('os.linux')) {
1290
- }
1291
- if (req.hasFeature('os.mac')) {
1292
- }
1293
- if (req.hasFeature('os.android')) {
1294
- }
1295
- if (req.hasFeature('os.unknown')) {
1296
- }
1297
-
1298
- req.ip; // user ip
1299
- req.port; // user port
1300
- req.ip2; // server ip
1301
- req.port2; // server port
1302
- req.features; // array of user info [os , browser]
1303
- });
1304
-
1305
- var person = { name: 'amr', email: 'absunstar' };
1306
- var person2 = site.copy(person);
1307
- person2.name = 'Abd Allah';
1308
- site.log(person);
1309
- site.log(person2);
1310
-
1311
- var hash = site.md5('this content will be hashed as md5');
1312
- var base64 = site.toBase64('this content will be encript as base64 string');
1313
- var normal = site.fromBase64(base64);
1314
- var jsonString = site.toJson(person);
1315
- var jsonObj = site.fromJson(jsonString);
1316
- site.log(hash);
1317
- site.log(base64);
1318
- site.log(normal);
1319
- site.log(jsonString);
1320
- site.log(jsonObj);
1321
-
1322
- var name = 'absunstar';
1323
- if (name.like('*sun*')) {
1324
- site.log('yes');
1325
- }
1326
- ```
1327
-
1328
- ## Events
1329
-
1330
- - Events Are Global Actions Across Site
1331
-
1332
- ```js
1333
- site.on('event name', function (obj) {
1334
- console.log('name : ' + obj.name);
1335
- });
1336
-
1337
- site.on('event name 2', function (list) {
1338
- console.log('name : ' + list[0].name);
1339
- console.log('name : ' + list[1].name);
1340
- });
1341
-
1342
- site.on('event name 3', function (obj, callback) {
1343
- console.log('try long code : ' + obj.name);
1344
- setTimeout(function () {
1345
- callback();
1346
- }, 3000);
1347
- });
1348
-
1349
- site.on('sync event name 1', function (obj, callback, next) {
1350
- console.log('name : ' + obj.name);
1351
- next(); // to run next event
1352
- });
1353
- site.on('sync event name 2', function (obj, callback, next) {
1354
- console.log('name : ' + obj.name);
1355
- next(); // to run next event
1356
- });
1357
- site.call('event name', { name: 'x1' });
1358
- site.call('event name 2', [{ name: 'n1' }, { name: 'n2' }]);
1359
- site.call('event name 3', { name: 'some long code' }, () => {
1360
- console.log('after excute some long code');
1361
- });
1362
-
1363
- site.quee('sync event name 1', { name: 'x1' });
1364
- site.quee('sync event name 2', { name: 'x2' });
1365
- ```
1366
-
1367
- ## Must Update
1368
-
1369
- - You Must Update This Lib Every Month ( npm i isite )
1370
-
1371
- ## Hints
1372
-
1373
- - This Framework Make Security and Safty in the First Place
1374
- - This Framework From Developer to Developers
1375
- - This Framework Free for Education and Supported For Ever
1376
- - This Framework Upgraded Arround the Clock
1377
- - This Framework Development by One Developer
1378
- - For Producation Contract what's up (+966568118373)
1379
-
1380
- # Contact Me
1381
-
1382
- - Patreon : https://www.patreon.com/next_corporation
1383
- - Email : Absunstar@gmail.com
1384
- - Linkedin : https://www.linkedin.com/in/absunstar
1385
- - Github : https://github.com/absunstar
1386
- - Paypal : https://paypal.me/absunstar
1387
- - What's up: +966568118373
1
+ isite now integrated with Social Browser https://social-browser.com
2
+ so your site work on Social Browser by default
3
+
4
+ ## Create [ Node Js Web Site ] Supporting Many Development features
5
+
6
+ - More Secure
7
+ - Multi Language
8
+ - Custom Apps [Modules]
9
+ - Best Performance
10
+ - Less Time
11
+ - Less Cost
12
+ - Fast Development
13
+
14
+ # Features
15
+
16
+ - Auto Routes [Simple & Advanced & Custom]
17
+ - Auto Handle File Types Encoding [Fonts - Images - ...]
18
+ - Merge Multi Files Contents in One Route
19
+ - Auto Handle Request & Response Headers [Cookies - Parameters - params]
20
+ - Auto Detect & Configer User Session
21
+ - Built-in Security System [Users , Roles, Permissions]
22
+ - Easy Creating Master Pages
23
+ - Auto Caching All Routes & Management Site Files in Memory
24
+ - Fast Read Files Content [Site Folder Structure]
25
+ - [ Upload / Download ] Files
26
+ - Custom Html Attributes [Server side Tags]
27
+ - MongoDB Full Integration
28
+ - Client libraries [jquery - bootstrap - font-awesome - angular]
29
+ - Local Multi Charts Apps
30
+ - Development Helper Functions
31
+ - Site Dynamic Events Callback
32
+ - Auto WebSocket Handle
33
+
34
+ ## Fast Startup
35
+
36
+ - Download Startup Template
37
+
38
+ ```sh
39
+ git clone https://github.com/absunstar/isite-template
40
+ cd isite-template
41
+ npm i
42
+ npm start
43
+ ```
44
+
45
+ ## Installation
46
+
47
+ `npm install isite`
48
+
49
+ - Works Stand-Alone or With Other Libs
50
+ - updated every 1 month at least ( npm i isite ) for production apps
51
+
52
+ ## Using
53
+
54
+ - Fast Startup Web Server.
55
+
56
+ ```js
57
+ var isite = require('isite');
58
+ var site = isite({ port: 8080 });
59
+
60
+ site.loadLocalApp('client-side');
61
+ site.loadLocalApp('security');
62
+
63
+ site.run();
64
+ ```
65
+
66
+ - Multi port opens
67
+
68
+ ```js
69
+ var isite = require('isite');
70
+ var site = isite();
71
+
72
+ site.loadLocalApp('client-side');
73
+ site.loadLocalApp('security');
74
+
75
+ site.run([8080, 5555, 9090, 12345]);
76
+ ```
77
+
78
+ - Default Options.
79
+
80
+ ```js
81
+ var isite = require('isite');
82
+ site = isite({
83
+ port: process.env.port || 80,
84
+ cwd: process.cwd(),
85
+ dir: process.cwd() + '/site_files',
86
+ upload_dir: process.cwd() + '/../uploads',
87
+ download_dir: process.cwd() + '/../downloads',
88
+ backup_dir: process.cwd() + '/../backup',
89
+ apps: !0,
90
+ apps_dir: process.cwd() + '/apps',
91
+ name: 'Your Site',
92
+ dynamic: false, // (auto set )dynamic db & prot based on folder name [ smart-Your Site-3000 ]
93
+ savingTime: 60 // 60 minutes then save sessions and site data,
94
+ log: !0,
95
+ lang: 'ar',
96
+ theme: 'default',
97
+ help: !0,
98
+ stdin: !0,
99
+ https: {
100
+ enabled: false,
101
+ port: null,
102
+ ports: [],
103
+ key: null // path or will use default,
104
+ cert: null // path or will use default,
105
+ },
106
+ mongodb: {
107
+ enabled: !0,
108
+ host: 'localhost',
109
+ port: '27017',
110
+ userName: null,
111
+ password: null,
112
+ db: 'default_db',
113
+ collection: 'default_collection',
114
+ limit: 10,
115
+ prefix: {
116
+ db: '',
117
+ collection: '',
118
+ },
119
+ identity: {
120
+ enabled: !0,
121
+ start: 1,
122
+ step: 1,
123
+ },
124
+ },
125
+ session: {
126
+ timeout: 60 * 24 * 30,
127
+ enabled: !0,
128
+ storage: 'file' || 'mongodb',
129
+ db: null,
130
+ collection: 'users_sessions',
131
+ },
132
+ security: {
133
+ enabled: !0,
134
+ db: null,
135
+ users_collection: 'users_info',
136
+ roles_collection: 'users_roles',
137
+ admin: {
138
+ email: 'admin@isite',
139
+ password: 'P@$$w0rd',
140
+ },
141
+ users: [],
142
+ },
143
+ cache: {
144
+ enabled: !0,
145
+ html: 0,
146
+ txt: 60 * 24 * 30,
147
+ js: 60 * 24 * 30,
148
+ css: 60 * 24 * 30,
149
+ fonts: 60 * 24 * 30,
150
+ images: 60 * 24 * 30,
151
+ json: 60 * 24 * 30,
152
+ xml: 60 * 24 * 30,
153
+ },
154
+ proto: {
155
+ object: !0,
156
+ },
157
+ });
158
+
159
+ site.run();
160
+ ```
161
+
162
+ ## Site Folder Structure
163
+
164
+ - site stucture help you to manage you site easy and fast
165
+
166
+ ```html
167
+ - server.js - package.json - README.md -- apps -- site_files --- css - bootstrap.css - custom.css --- js - jquery.js - bootstrap.js - custom.js --- html - index.html --- fonts --- images - logo.png
168
+ --- json - items.json - words.json - roles.json - permissions.json --- xml - rss.xml
169
+ ```
170
+
171
+ - Create Folder Name "site_files"
172
+ - inside it create these Sub folders [
173
+ html , css , js , json , fonts , images , xml , ...
174
+ ]
175
+
176
+ ## Routes
177
+
178
+ - Auto Convert All Routes URL & Parameters to Lower Case
179
+ - Auto Manage Reponse Headers and Files Types
180
+ - Support Multi Files in One Route
181
+ - Save Route Response in Memory to Reuse for Fast Response
182
+ - Auto Handle URL parametes
183
+ - Auto Handle Body Parameters in not get header [post , put , delete , ...]
184
+ - Auto Handle URL params [custom parameters from url structure]
185
+ - Auto cache Files Content in memory
186
+ - support compress to remove unwanted spaces and tabs and empty lines ...etc
187
+ - support parser to handle custom html server side tags
188
+ - Call Route From Other Route [ Server Side ]
189
+
190
+ Easy and Auto Site Routing
191
+
192
+ ```js
193
+ /* site.dir = process.cwd() + "/site_files"
194
+ You Can Change This Default Value when define isite
195
+ or set site.dir = new path
196
+ */
197
+
198
+ site.onGET({ name: ['/', '/home', '/index'], path: site.dir + '/html/index.html' });
199
+ site.onGET({ name: '/css/bootstrap.css', path: site.dir + '/css/bootstrap.min.css' });
200
+ site.onGET({ name: '/js/jquery.js', path: site.dir + '/js/jquery.js' });
201
+ site.onGET({ name: '/js/bootstrap.js', path: site.dir + '/js/bootstrap.js' });
202
+ site.onGET({ name: '/favicon.png', path: site.dir + '/images/logo.png' });
203
+ site.onPOST({ name: '/api', path: site.dir + '/json/employees.json' });
204
+ ```
205
+
206
+ Merge Multi Files in one route
207
+
208
+ ```js
209
+ site.onGET({
210
+ name: '/css/style.css',
211
+ path: [site.dir + '/css/bootstrap.css', site.dir + '/css/custom.css'],
212
+ });
213
+ site.onGET({
214
+ name: '/js/script.js',
215
+ path: [site.dir + '/js/jquery.js', site.dir + '/js/bootstrap.js', site.dir + '/js/custom.js'],
216
+ });
217
+ ```
218
+
219
+ Advanced Site Routing
220
+
221
+ ```js
222
+ site.onREQUEST('get', '/', (req, res) => {});
223
+
224
+ site.onREQUEST('get', { name: '/' }, (req, res) => {});
225
+
226
+ site.onGET('/home2', (req, res) => {
227
+ site.callRoute('/home', req, res);
228
+ });
229
+
230
+ site.onGET({
231
+ name: 'api/user/add',
232
+ content: {
233
+ done: true,
234
+ id: 1,
235
+ },
236
+ });
237
+
238
+ site.onGET('/', (req, res) => {
239
+ site.readFile(site.dir + '/html/index.html', function (err, content, file) {
240
+ res.set('Content-type', 'text/html');
241
+ res.set('Content-size', file.stat.size);
242
+ res.status(200).end(content);
243
+ });
244
+ });
245
+
246
+ site.onGET('/', (req, res) => {
247
+ site.html('index', function (err, content) {
248
+ res.set('Content-type', 'text/html');
249
+ res.status(200).end(content);
250
+ });
251
+ });
252
+
253
+ site.onGET({
254
+ // can use [get , post , put , delete , all]
255
+ name: '/',
256
+ path: site.dir + '/html/index.html', //Required
257
+ parser: 'html', // default static [not paresed]
258
+ compress: !0, // default false
259
+ cache: false, // default !0
260
+ });
261
+
262
+ site.onGET({
263
+ name: '/',
264
+ callback: function (req, res) {
265
+ res.set('Content-type', 'text/html');
266
+ site.html('index', function (err, content) {
267
+ res.status(200).end(content);
268
+ });
269
+ },
270
+ });
271
+ ```
272
+
273
+ Auto Route All Files in Folder
274
+
275
+ ```js
276
+ site.onGET({ name: '/js', path: site.dir + '/js' });
277
+ site.onGET({ name: '/css', path: site.dir + '/css' });
278
+ ```
279
+
280
+ Custom Route - Using \* [any letters]
281
+
282
+ ```js
283
+ site.onGET('/post/*', function (req, res) {
284
+ res.end('Any Route like /post/11212154545 ');
285
+ });
286
+ site.onGET('*', function (req, res) {
287
+ res.end('Any Route Requested Not Handled Before This Code');
288
+ });
289
+ ```
290
+
291
+ Request Parameters [GET , POST | PUT | Delete] Restful API
292
+
293
+ ```js
294
+ // read query parameter lower case
295
+ site.onGET('/api', function (req, res) {
296
+ res.end('GET | name : ' + req.query.name);
297
+ });
298
+ // read query parameter default case as requested
299
+ site.onGET('/api', function (req, res) {
300
+ res.end('GET | name : ' + req.queryRaw.name);
301
+ });
302
+
303
+ site.onPOST('/api', function (req, res) {
304
+ res.end('POST | id : ' + req.body.id + ' , Name : ' + req.body.name);
305
+ });
306
+ site.onPUT('/api', function (req, res) {
307
+ res.end('PUT | id : ' + req.body.id + ' , Name : ' + req.body.name);
308
+ });
309
+ site.onDELETE('/api', function (req, res) {
310
+ res.end('Delete | id : ' + req.body.id);
311
+ });
312
+ site.onALL('/api', function (req, res) {
313
+ res.end('Any Request Routing Type Not Handled Yet : ' + req.method);
314
+ });
315
+ ```
316
+
317
+ Dynamic Parameters
318
+
319
+ ```js
320
+ // read params lower case
321
+ site.onGET('/post/:id/category/:cat_id', function (req, res) {
322
+ res.end('GET | Id : ' + req.params.id + ', catId : ' + req.params.cat_id);
323
+ });
324
+ // read params default case as requested
325
+ site.onGET('/post/:id/category/:cat_id', function (req, res) {
326
+ res.end('GET | Id : ' + req.paramsRaw.id + ', catId : ' + req.paramsRaw.cat_id);
327
+ });
328
+ //example : /post/AbCdEf/category/DDDDD
329
+ ```
330
+
331
+ MVC Custom Route
332
+
333
+ ```js
334
+ site.onGET('/:controller/:Action/:Arg1', function (req, res) {
335
+ res.end(
336
+ 'GET | Controller : ' +
337
+ req.params.controller +
338
+ ', Action : ' +
339
+ req.params.Action /* Normal case*/ +
340
+ ', action : ' +
341
+ req.params.action /* lower case*/ +
342
+ ', Arg 1 : ' +
343
+ req.params.Arg1 /* Normal case*/ +
344
+ ', arg 1 : ' +
345
+ req.params.arg1 /* lower case*/,
346
+ );
347
+ });
348
+ //example : /facebook/post/xxxxxxxxxx
349
+ ```
350
+
351
+ - To Easy Read File Contents From "site_files" Folder
352
+
353
+ ```js
354
+ site.html('index', function (err, content) {
355
+ site.log(content);
356
+ });
357
+ site.css('bootstrap', function (err, content) {
358
+ site.log(content);
359
+ });
360
+ site.js('jquery', function (err, content) {
361
+ site.log(content);
362
+ });
363
+ site.json('items', function (err, content) {
364
+ site.log(content);
365
+ });
366
+ site.xml('rss', function (err, content) {
367
+ site.log(content);
368
+ });
369
+ ```
370
+
371
+ - Custom Read Files
372
+
373
+ - Read From Local File in First Time and save in memory
374
+ - next time Read Will be From Memory
375
+
376
+ ```js
377
+ //read file with custom header
378
+ site.onGET("/rss", function(req, res) {
379
+ site.readFile(__dirname + "/site_files/xml/rss.xml", function(err, content , file) {
380
+ res.set("content-type" , "text/xml")
381
+ res.set("content-size" , file.stat.size)
382
+ res.status(200).end(content) // or res.end(content)
383
+ })
384
+ })
385
+ // or [ if file in site_files/xml folder]
386
+ site.onGET("/rss", function(req, res) {
387
+ site.xml("rss", function(err, content , file) {
388
+ res.set("content-type" , "text/xml")
389
+ res.set("content-size" , file.stat.size)
390
+ res.status(200).end(content)
391
+ })
392
+ })
393
+
394
+ // Read and Merge multi files with custom header
395
+ site.onGET("/", function(req, res) {
396
+ site.readFiles(
397
+ [
398
+ __dirname + "/site_files/html/head.html",
399
+ __dirname + "/site_files/html/content.html",
400
+ __dirname + "/site_files/html/footer.html"
401
+ ],
402
+ function(err, content) {
403
+ res.writeHead(200, { "content-type": "text/html" });
404
+ res.end(content);
405
+ })
406
+ })
407
+
408
+ // Check if File Exits
409
+ site.isFileExists(path , (yes)=>{
410
+ if(yes){
411
+ // ...
412
+ }
413
+ })
414
+ // or
415
+ let yes = site.isFileExistsSync(path)
416
+ if(yes){
417
+ // ...
418
+ }
419
+
420
+ // Get File Info
421
+ site.fileStat(path , (err , stats)=>{
422
+ console.log(stats)
423
+ })
424
+ // or
425
+ let stats = site.fileStatSync(path)
426
+
427
+ // Write Data to File
428
+ site.writeFile(path , data , err =>{
429
+
430
+ }
431
+ // Delete File
432
+ site.removeFile(path , err =>{
433
+
434
+ }) // or site.deleteFile
435
+
436
+
437
+ // Create New Dir
438
+ site.createDir(path , (err , path)=>{
439
+ if(!err){
440
+ // ...
441
+ }
442
+ }) // or site.makeDir
443
+
444
+ ```
445
+
446
+ ## WebSocket
447
+
448
+ - Server Side
449
+
450
+ ```js
451
+ site.onWS('/chat', (client) => {
452
+ client.onMessage = function (message) {
453
+ console.log(message);
454
+ if (message.type === 'connected') {
455
+ client.send({ type: 'ready' });
456
+ }
457
+ };
458
+ console.log('New Client ...' + client.ip);
459
+ });
460
+ ```
461
+
462
+ - Client Side
463
+
464
+ ```html
465
+ <script src="/x-js/all.js"></script>
466
+ ```
467
+
468
+ ```js
469
+ site.ws('ws://localhost/chat', (server) => {
470
+ window.server = server;
471
+ server.onOpen = () => {
472
+ server.send({ type: 'accessToken', content: '##session.accessToken##' });
473
+ };
474
+ server.onMessage = (msg) => {
475
+ console.log(msg);
476
+ };
477
+ });
478
+
479
+ // or
480
+
481
+ var ws = new WebSocket('ws://localhost/chat');
482
+
483
+ ws.onerror = function (error) {};
484
+ ws.onclose = function () {};
485
+
486
+ ws.onopen = function () {
487
+ ws.send(JSON.stringify({ type: 'connect' }));
488
+ };
489
+
490
+ ws.onmessage = function (msg) {
491
+ msg = JSON.parse(msg.data);
492
+ if (msg.type === 'ready') {
493
+ ws.send(JSON.stringify({ type: 'ready' }));
494
+ }
495
+ };
496
+ ```
497
+
498
+ ## Cookies
499
+
500
+ - Cookie is Client Side Data Per User
501
+ - Cookie is Enabled by Default
502
+ - Support Multi Keys
503
+
504
+ ```js
505
+ site.onGET('/testSetCookie', function (req, res) {
506
+ res.cookie('name', req.query.name);
507
+ res.cookie('ip', req.ip);
508
+ res.cookie('more', 'any data');
509
+ res.end('cookie set');
510
+ }); //example : /testSetCookie?name=amr
511
+
512
+ site.onGET('/testGetCookie', function (req, res) {
513
+ res.end('name from cookie : ' + req.cookie('name'));
514
+ }); //example : /testGetCookie
515
+ ```
516
+
517
+ ## Sessions
518
+
519
+ - Session is Server Side Data Per User
520
+ - Every User has Unique Access Token
521
+ - Session Management Automatic
522
+ - Session Store in Database by Default
523
+
524
+ ```js
525
+ site.onGET('/testSetSession', function (req, res) {
526
+ req.session.user_name = req.query.user_name;
527
+ res.session.ip = req.ip;
528
+ res.session.more = 'any data';
529
+ site.saveSession(res.session);
530
+ res.end('Session Set ok !! ');
531
+ }); //example : /testSetSession?user_name=absunstar
532
+
533
+ site.onGET('/testGetSession', function (req, res) {
534
+ res.end('User Name from session : ' + req.session.user_name);
535
+ }); //example : /testGetSession
536
+ ```
537
+
538
+ ## Custom App
539
+
540
+ - Custom App Help you to Easy Management Site Life-Cycle
541
+ - Easy Register & Integrated
542
+ - Best Solution when work with Team
543
+
544
+ ### How to make it
545
+
546
+ - Create your app folder in global apps folder
547
+ - Add app.js file with this code
548
+
549
+ ```js
550
+ module.exports = function (site) {
551
+ // write here your custom code
552
+ };
553
+ ```
554
+
555
+ - App Will Be Auto Register And Integerated With Your Site
556
+
557
+ ### add App From github
558
+
559
+ - Add Apps from github to Your Site
560
+
561
+ ```sh
562
+ cd apps
563
+ git clone https://github.com/absunstar/isite-client
564
+ git clone https://github.com/absunstar/isite-security
565
+ ```
566
+
567
+ ### add App From Local Path
568
+
569
+ ```js
570
+ site.importApp(FOLDER_PATH);
571
+ ```
572
+
573
+ ## Master Pages
574
+
575
+ - Master Page put content between header and footer
576
+ - Master Page help you to not repate you code
577
+ - Master Page make site layout look good with less code
578
+ - Master Page has tow parts header and footer
579
+
580
+ ```js
581
+ site.addMasterPage({
582
+ name: 'masterPage1',
583
+ header: site.dir + '/html/header.html',
584
+ footer: site.dir + '/html/footer.html',
585
+ });
586
+
587
+ site.addMasterPage({
588
+ name: 'masterPage2',
589
+ header: site.dir + '/html/header2.html',
590
+ footer: site.dir + '/html/footer2.html',
591
+ });
592
+
593
+ site.onGET({
594
+ name: '/ContactUs',
595
+ masterPage: 'masterPage1',
596
+ path: site.dir + '/html/contact.html',
597
+ parser: 'html',
598
+ });
599
+ ```
600
+
601
+ ## HTML Server Tags & Attributes
602
+
603
+ - html server tags is html tags run in server side
604
+ - html server tags make html structure easy management
605
+ - html server tags is the next generation of html
606
+
607
+ Add Custom Html Content
608
+
609
+ ```js
610
+ site.onGET({ name: '/', path: site.dir + '/html/index.html', parser: 'html' });
611
+ ```
612
+
613
+ ```html
614
+ <style x-import="page2.css"></style>
615
+ <div x-import="navbar.html"></div>
616
+ <div class="container">
617
+ <h2>Page Heading 2</h2>
618
+ <p x-import="info.html"></p>
619
+ </div>
620
+ <script x-import="custom.js"></script>
621
+ ```
622
+
623
+ - Pages "navbar.html" & "info.html" Must Be In HTML Site Folder ['/site_files/html/']
624
+ - Style "page2.css" Must Be In HTML Site Folder ['/site_files/css/']
625
+ - Script "custom.js" Must Be In HTML Site Folder ['/site_files/js/']
626
+
627
+ Dynamic Varibles Sets
628
+
629
+ ```js
630
+ site.var('siteName', 'First Site With Isite Library ');
631
+ site.var('siteBrand', 'XSite');
632
+ ```
633
+
634
+ ```html
635
+ <title>##var.siteName##</title>
636
+ <h2>##var.siteBrand##</h2>
637
+ <h2>Lang : ##session.lang## , Theme : ##session.theme##</h2>
638
+ <h2>query name : ##query.name## , query age : ##query.age##</h2>
639
+ <h2>data name : ##data.name## , data age : ##data.age##</h2>
640
+ <h2>param category : ##params.category## , param post : ##params.post##</h2>
641
+
642
+ <div x-lang="ar">Show if Site Language is Arabic</div>
643
+ <div x-lang="en">Show if Site Language is English</div>
644
+ // auto detect user session language
645
+
646
+ <div x-permission="admin">Only Admi Users Can Show This Content</div>
647
+ <div x-permission="accounting">Only Accounting Users Can Show This Content</div>
648
+
649
+ <div x-feature="login">Only Login Users Can Show This Content</div>
650
+ <div x-feature="!login">Only Not Login Users Can Show This Content</div>
651
+ // auto detect user login status
652
+
653
+ <div x-features="os.mobile || os.android">Only Users From Mobile or Android Can Show This Content</div>
654
+ <div x-features="os.mobile && os.android">Only Users From Mobile and Android Can Show This Content</div>
655
+ // Using || , && to Multi Features
656
+
657
+ <div x-feature="os.mobile">Only Users From Mobile Can Show This Content</div>
658
+ <div x-feature="os.desktop">Only Users From Mobile Can Show This Content</div>
659
+
660
+ <div x-feature="os.windows">Only Users From Windows Can Show This Content</div>
661
+ <div x-feature="!os.windows">Only Users From Not Windows Can Show This Content</div>
662
+ <div x-feature="os.windowsxp">Only Users From Windows XP Can Show This Content</div>
663
+ <div x-feature="os.windows7">Only Users From Windows 7 Can Show This Content</div>
664
+ <div x-feature="os.windows8">Only Users From Windows 8 Can Show This Content</div>
665
+ <div x-feature="os.windows10">Only Users From Windows 10 Can Show This Content</div>
666
+
667
+ <div x-feature="os.linux">Only Users From Linux Systems Can Show This Content</div>
668
+ <div x-feature="os.mac">Only Users From Mac Systems Can Show This Content</div>
669
+ <div x-feature="os.android">Only Users From Android Systems Can Show This Content</div>
670
+ <div x-feature="os.unknown">Only Users From unknown Systems Can Show This Content</div>
671
+
672
+ <div x-feature="browser.edge">Only Users From Edge Browser Can Show This Content</div>
673
+ <div x-feature="browser.firefox">Only Users From FireFox Browser Can Show This Content</div>
674
+ <div x-feature="browser.chrome">Only Users From Chrome Browser Can Show This Content</div>
675
+ <div x-feature="browser.opera">Only Users From Opera Browser Can Show This Content</div>
676
+ <div x-feature="browser.unknown">Only Users From unknown Browser Can Show This Content</div>
677
+
678
+ <div x-feature="ip.xxx.xxx.xxx.xxx">Only Users From IP xxx.xxx.xxx.xxx Can Show This Content</div>
679
+
680
+ //auto detect user browser
681
+ ```
682
+
683
+ ## MongoDB Integration
684
+
685
+ - Auto Add [ id ] as auto increment number [Like SQL]
686
+ - Handle [ _id ] Data Type
687
+ - Manage Closed Connections and Timeout
688
+ - Manage Multi Connections
689
+ - Manage Bulk [ Inserts & Updates & Deletes ]
690
+ - Global Database Events
691
+ - User Friendly Coding
692
+
693
+ ```js
694
+
695
+ // use connect collection [ Best Way For Security ]
696
+
697
+ $employees = site.connectCollection("employees")
698
+
699
+ // with database
700
+ $employees = site.connectCollection("employees" , "company")
701
+ //or
702
+ $employees = site.connectCollection({collection : "employees" , db : "company")
703
+
704
+
705
+ // insert one doc [ can use also [add , addOne , insert , insertOne]]
706
+ $employees.insertOne({name : 'amr' , salary : 50000} , (err , doc)=>{
707
+ site.log(doc) // doc after inserted
708
+ })
709
+
710
+ // insert Many Docs [ can use also [ addMany , addAll , insertMany , insertAll]]
711
+ $employee.insertMany([{name : 'a'} , {name : 'b'}] , (err , docs)=>{
712
+ site.log(docs , 'docs')
713
+ })
714
+
715
+ // select one doc [ can use also [ get , getOne , find , findOne , select , selectOne ]]
716
+ $employees.findOne({where:{id : 5} , select:{salary:1}} , (err , doc)=>{
717
+ site.log(doc)
718
+ })
719
+ //or
720
+ $employees.findOne({ id : 5 } , (err , doc)=>{
721
+ site.log(doc)
722
+ })
723
+
724
+
725
+ // select Multi docs [ can use also [getAll , getMany , findAll , findMany , selectAll , selectMany ]]
726
+ $employees.findMany({
727
+ where:{name : /a/i} ,
728
+ select:{name: 1 , salary:1} ,
729
+ limit : 50 ,
730
+ skip : 10 ,
731
+ sort:{salary : -1}
732
+ } , (err , docs , count)=>{
733
+ site.log(docs)
734
+ }
735
+ )
736
+
737
+ // Update One Doc [ can use [ updateOne , update , editOne , edit]]
738
+ $employees.updateOne({
739
+ where:{_id : 'df54fdt8h3n48ykd136vg'} ,
740
+ set:{salary: 30000}} , (err , result)=>{
741
+ site.log(result)
742
+ })
743
+ // or [ auto update by _id ]
744
+ $employees.updateOne({_id : 'df54fdt8h3n48ykd136vg' , salary : 5000} , (err , result)=>{
745
+ site.log(result)
746
+ })
747
+
748
+ // Update Many Docs [ can use [ updateAll , updateMany , editAll , editMany]]
749
+ $employees.updateMany({
750
+ where:{name : /a/i} ,
751
+ set:{salary: 30000}} , (err , result)=>{
752
+ site.log(result)
753
+ })
754
+
755
+ // Delete One Doc [ can use [ deleteOne , delete , removeOne , remove]]
756
+ $employees.deleteOne({where:{ _id : 'df54fdt8h3n48ykd136vg'}} , (err , result)=>{
757
+ site.log(result)
758
+ })
759
+ // or [ auto delete by _id]
760
+ $employees.deleteOne('df54fdt8h3n48ykd136vg', (err , result)=>{
761
+ site.log(result)
762
+ })
763
+ // or
764
+ $employees.deleteOne({name : /a/i} , (err , result)=>{
765
+ site.log(result)
766
+ })
767
+
768
+ // Delete Many Docs [ can use [ deleteAll , deleteManye , removeAll , removeMany ]]
769
+ $employees.deleteMany({where:{name : /a/i}} , (err , result)=>{
770
+ site.log(result)
771
+ })
772
+ // or
773
+ $employees.deleteMany({name : /a/i} , (err , result)=>{
774
+ site.log(result)
775
+ })
776
+
777
+ // Import Object Data From Json File
778
+ $employees.import(FILE_PATH , (result)=>{
779
+
780
+ })
781
+
782
+ // Import Array Data From Json File
783
+ $employees.import(FILE_PATH , (result)=>{
784
+
785
+ })
786
+
787
+ // Export Object Data From Json File
788
+ $employees.export( OPTONS , FILE_PATH , (err , docs)=>{
789
+
790
+ })
791
+ // Export 10 employees that salary more than 1000
792
+ $employees.export({limit : 10 , where : {salary : {$gt : 1000}}} , FILE_PATH , (err , docs)=>{
793
+
794
+ })
795
+
796
+ // Remove duplicate data [ can use [deleteDuplicate , removeDuplicate]]
797
+ $employees.deleteDuplicate('name' , (err , result)=>{
798
+
799
+ })
800
+ // Remove Duplicate [ name and mobile ] Employee
801
+ $employees.deleteDuplicate({name : 1 , mobile : 1} , (err , result)=>{
802
+
803
+ })
804
+ // Remove Duplicate [ profile.name ] Employee
805
+ $employees.deleteDuplicate({'profile.name' : 1 } , (err , result)=>{
806
+
807
+ })
808
+
809
+ // Create Index Field
810
+ $employees.createIndex({name : 1} , (err , result)=>{
811
+
812
+ }
813
+
814
+ // Create Unique Field
815
+ $employees.createUnique({name : 1} , (err , result)=>{
816
+
817
+ }
818
+ // Create Unique Fields
819
+ $employees.createUnique({user_name : 1 , user_password : 1} , (err , result)=>{
820
+
821
+ }
822
+
823
+ // backup database
824
+ site.backupDB() // backup current database to current backup folder
825
+ site.backupDB({db:'' , path : ''})
826
+
827
+ // restore database
828
+ site.restoreDB() // restore current database from current backup folder
829
+ site.restoreDB({db:'' , path : ''})
830
+
831
+ // API to download backup db
832
+ site.onGET('db', (req, res) => {
833
+ site.backupDB(null, (err, options) => {
834
+ if (!err) {
835
+ res.download(options.path);
836
+ } else {
837
+ res.json(err);
838
+ }
839
+ });
840
+ });
841
+
842
+ //==================================================================
843
+ // Global Database Events
844
+ // from here you can catch all transactions
845
+
846
+ site.on('mongodb after insert' , (result)=>{
847
+
848
+ })
849
+ site.on('mongodb after insert many' , (result)=>{
850
+
851
+ })
852
+ site.on('mongodb after find' , (result)=>{
853
+
854
+ })
855
+ site.on('mongodb after find many' , (result)=>{
856
+
857
+ })
858
+ site.on('mongodb after update' , (result)=>{
859
+
860
+ })
861
+ site.on('mongodb after update many' , (result)=>{
862
+
863
+ })
864
+ site.on('mongodb after delete' , (result)=>{
865
+
866
+ })
867
+ site.on('mongodb after delete many' , (result)=>{
868
+
869
+ })
870
+
871
+
872
+ // ==================================================================
873
+ // Low Level Access Database Functions [ For Advanced Work ]
874
+
875
+ // Insert One Doc
876
+ site.mongodb.insertOne({
877
+ dbName: 'company',
878
+ collectionName: 'employess',
879
+ doc:{name:'amr',salary:35000}
880
+ }, function (err, docInserted) {
881
+ if (err) {
882
+ site.log(err.message)
883
+ } else {
884
+ site.log(docInserted)
885
+ }
886
+ } , /* default waiting Sync or !0 for Async*/)
887
+
888
+ // Insert Many Docs
889
+ site.mongodb.insertMany({
890
+ dbName: 'company',
891
+ collectionName: 'employess',
892
+ docs:[
893
+ {name:'amr',salary:35000} ,
894
+ {name:'Gomana',salary:9000} ,
895
+ {name:'Maryem',salary:7000}
896
+ ]
897
+ }, function (err, result) {
898
+ if (err) {
899
+ site.log(err.message)
900
+ } else {
901
+ site.log(result)
902
+ }
903
+ }/* default waiting Sync or !0 for Async*/)
904
+
905
+ // Find One Doc
906
+ site.mongodb.findOne({
907
+ dbName: 'company',
908
+ collectionName: 'employees',
909
+ where:{},
910
+ select : {}
911
+ }, function (err, doc) {
912
+ if (err) {
913
+ site.log(err.message)
914
+ } else {
915
+ site.log(doc)
916
+ }
917
+ }/* default waiting Sync or !0 for Async*/)
918
+
919
+ // Find Many Docs
920
+ site.mongodb.findMany({
921
+ dbName: 'company',
922
+ collectionName: 'employees',
923
+ where:{},
924
+ select : {}
925
+ }, function (err, docs , count) {
926
+ if (err) {
927
+ site.log(err.message)
928
+ } else {
929
+ site.log(docs)
930
+ }
931
+ }/* default waiting Sync or !0 for Async*/)
932
+
933
+ //Update One Doc
934
+ site.mongodb.updateOne({
935
+ dbName: 'company',
936
+ collectionName: 'employees',
937
+ where:{salary:7000},
938
+ set : {name:'New MARYEM'}
939
+ }, function (err, result) {
940
+ if (err) {
941
+ site.log(err.message)
942
+ } else {
943
+ site.log(result)
944
+ }
945
+ }/* default waiting Sync or !0 for Async*/)
946
+
947
+ // Update Many Docs
948
+ site.mongodb.updateMany({
949
+ dbName: 'company',
950
+ collectionName: 'employees',
951
+ where:{salary:9000},
952
+ set : {salary:9000 * .10}
953
+ }, function (err, result) {
954
+ if (err) {
955
+ site.log(err.message)
956
+ } else {
957
+ site.log(result)
958
+ }
959
+ }/* default waiting Sync or !0 for Async*/)
960
+
961
+ // Delete One Doc
962
+ site.mongodb.deleteOne({
963
+ dbName: 'company',
964
+ collectionName: 'employess',
965
+ where:{_id: new site.mongodb.ObjectID('df54fdt8h3n48ykd136vg')}
966
+ }, function (err, result) {
967
+ if (err) {
968
+ site.log(err.message)
969
+ } else {
970
+ site.log(result)
971
+ }
972
+ }/* default waiting Sync or !0 for Async*/)
973
+ // Delete Many Docs
974
+ site.mongodb.deleteMany({
975
+ dbName: 'company',
976
+ collectionName: 'employess',
977
+ where:{name : /a/}
978
+ }, function (err, result) {
979
+ if (err) {
980
+ site.log(err.message)
981
+ } else {
982
+ site.log(result)
983
+ }
984
+ }/* default waiting Sync or !0 for Async*/)
985
+
986
+ // ==================================================================
987
+ // Mongodb Native Client Provider
988
+
989
+ site.mongodb.client // = require("mongodb").MongoClient
990
+
991
+ // Create a database called "mydb":
992
+
993
+ var url = "mongodb://localhost:27017/mydb";
994
+
995
+ site.mongodb.client.connect(url, function(err, db) {
996
+ if (err) throw err;
997
+ console.log("Database created!");
998
+ db.close();
999
+ });
1000
+
1001
+ // all code can be found in offical mongodb site or w3schools
1002
+
1003
+ ```
1004
+
1005
+ ## Upload File
1006
+
1007
+ - upload File using HTML
1008
+
1009
+ ```html
1010
+ <form action="uploadFile" method="post" enctype="multipart/form-data">
1011
+ <input type="file" name="fileToUpload" /><br />
1012
+ <input type="submit" />
1013
+ </form>
1014
+ ```
1015
+
1016
+ - Upload File Using Angular js
1017
+
1018
+ ```html
1019
+ <form class="form">
1020
+ <label>Select File To Upload</label>
1021
+ <input type="file" name="fileToUpload" onchange="angular.element(this).scope().uploadFile(this.files)" />
1022
+ <p>{{uploadStatus}}</p>
1023
+ </form>
1024
+ ```
1025
+
1026
+ ```js
1027
+ $scope.uploadFile = function (files) {
1028
+ var fd = new FormData();
1029
+ fd.append('fileToUpload', files[0]);
1030
+ $http
1031
+ .post('/uploadFile', fd, {
1032
+ withCredentials: !0,
1033
+ headers: {
1034
+ 'Content-Type': undefined,
1035
+ },
1036
+ uploadEventHandlers: {
1037
+ progress: function (e) {
1038
+ $scope.uploadStatus = 'Uploading : ' + Math.round((e.loaded * 100) / e.total) + ' %';
1039
+ if (e.loaded == e.total) {
1040
+ $scope.uploadStatus = '100%';
1041
+ }
1042
+ },
1043
+ },
1044
+ transformRequest: angular.identity,
1045
+ })
1046
+ .then(
1047
+ function (res) {
1048
+ if (res.data && res.data.done) {
1049
+ $scope.uploadStatus = 'File Uploaded';
1050
+ }
1051
+ },
1052
+ function (error) {
1053
+ $scope.uploadStatus = error;
1054
+ },
1055
+ );
1056
+ };
1057
+ ```
1058
+
1059
+ - Recive Uploading File from [html , angular , jquery , ...]
1060
+
1061
+ ```js
1062
+ site.onPOST('uploadFile', (req, res) => {
1063
+ var response = { done: !0 };
1064
+ var file = req.files.fileToUpload;
1065
+ var newpath = site.dir + '/../../uploads/' + file.originalFilename;
1066
+ site.mv(file.filepath, newpath, function (err) {
1067
+ if (err) {
1068
+ response.error = err;
1069
+ response.done = false;
1070
+ }
1071
+ res.end(JSON.stringify(response));
1072
+ });
1073
+ });
1074
+ ```
1075
+
1076
+ ## Download File
1077
+
1078
+ - download any file from server
1079
+ - auto handle file content and size
1080
+ - force client browser to download file
1081
+
1082
+ ```js
1083
+ // download any file
1084
+ site.onGET('/files/file1.zip', (req, res) => {
1085
+ res.download(site.dir + '/downloads/file1.zip');
1086
+ });
1087
+ //download and change file name
1088
+ site.onGET('/files/file1.zip', (req, res) => {
1089
+ res.download(site.dir + '/downloads/file1.zip', 'info.zip');
1090
+ });
1091
+ ```
1092
+
1093
+ ## Multi Languages
1094
+
1095
+ - Can Add Any Custom Language You Want
1096
+ - Can Change Default Language on Site Options
1097
+ - Stores Words in Diffrent Language in words json file
1098
+ - Auto Detect Words.json
1099
+ - Folder Structure Like This
1100
+
1101
+ ```html
1102
+ - apps - server.js - package.json - README.md -- site_files --- json - words.json
1103
+ ```
1104
+
1105
+ - Words Json File Structure Like This
1106
+
1107
+ ```json
1108
+ [
1109
+ { "name": "user_name", "en": "User Name", "ar": "أسم المستخدم" },
1110
+ { "name": "user_email", "en": "Email", "ar": "البريد الالكترونى" },
1111
+ { "name": "user_password", "en": "Password", "ar": "كلمة المرور" }
1112
+ ]
1113
+ ```
1114
+
1115
+ - Use in html Like This
1116
+
1117
+ ```html
1118
+ <form>
1119
+ <label> ##word.user_name## </label>
1120
+ <input />
1121
+ <br />
1122
+
1123
+ <label> ##word.user_email## </label>
1124
+ <input />
1125
+ <br />
1126
+
1127
+ <label> ##word.user_password## </label>
1128
+ <input />
1129
+ <br />
1130
+ </form>
1131
+ ```
1132
+
1133
+ - Cahnge Site Language
1134
+
1135
+ ```js
1136
+ $scope.changeLang = function (lang= 'EN' , langDir = 'ltr') {
1137
+ $http({
1138
+ method: 'POST',
1139
+ url: '/x-language/change',
1140
+ data: { name: lang , dir : langDir },
1141
+ }).then(function (response) {
1142
+ if (response.data.done) {
1143
+ window.location.reload(!0);
1144
+ }
1145
+ });
1146
+ };
1147
+ ```
1148
+
1149
+ ```html
1150
+ <a ng-click="changeLang('ar')"> Change To Arabic </a> <a ng-click="changeLang('en')"> Change To English </a>
1151
+ ```
1152
+
1153
+ - Show Content Depended on Language
1154
+
1155
+ ```html
1156
+ <div x-lang="ar">This Content Will Display When Site Language is Arabic</div>
1157
+ <div x-lang="en">This Content Will Display When Site Language is English</div>
1158
+ ```
1159
+
1160
+ ## Client libraries
1161
+
1162
+ - install Custom App From https://github.com/absunstar/isite-client
1163
+
1164
+ ```sh
1165
+ cd apps
1166
+ git clone https://github.com/absunstar/isite-client
1167
+ ```
1168
+
1169
+ - no need to install any client library
1170
+ - no need to install any fonts
1171
+ - no need to manage library routes
1172
+ - just use it
1173
+
1174
+ ```html
1175
+ <link rel="stylesheet" href="/x-css/bootstrap3.css" />
1176
+ <link rel="stylesheet" href="/x-css/font-awesome.css" />
1177
+
1178
+ <script src="/x-js/jquery.js"></script>
1179
+ <script src="/x-js/bootstrap3.js"></script>
1180
+ <script src="/x-js/angular.js"></script>
1181
+ ```
1182
+
1183
+ ## Charts
1184
+
1185
+ - Server Side
1186
+
1187
+ ```js
1188
+ site.loadLocalApp('charts');
1189
+ ```
1190
+
1191
+ - Client Site
1192
+
1193
+ ```html
1194
+ <div id="chart1"></div>
1195
+ <script src="/js/charts.js"></script>
1196
+ ```
1197
+
1198
+ ```js
1199
+ var data = [
1200
+ {
1201
+ item: 'item 1',
1202
+ count: 500,
1203
+ },
1204
+ {
1205
+ item: 'item 2',
1206
+ count: 200,
1207
+ },
1208
+ {
1209
+ item: 'item 3',
1210
+ count: 700,
1211
+ },
1212
+ {
1213
+ item: 'item 4',
1214
+ count: 300,
1215
+ },
1216
+ {
1217
+ item: 'item 5',
1218
+ count: 800,
1219
+ },
1220
+ {
1221
+ item: 'item 6',
1222
+ count: 60,
1223
+ },
1224
+ ];
1225
+
1226
+ site.create_chart({
1227
+ type: 'xy',
1228
+ x: 'item',
1229
+ y: 'count',
1230
+ data: data,
1231
+ selector: '#chart1',
1232
+ });
1233
+ ```
1234
+
1235
+ ## Security
1236
+
1237
+ - Bulit-in Users Management System
1238
+ - Auto Detect Users Sessions & Permissions
1239
+ - install Custom Security App From https://github.com/absunstar/isite-security
1240
+
1241
+ ```sh
1242
+ cd apps
1243
+ git clone https://github.com/absunstar/isite-security
1244
+ ```
1245
+
1246
+ - Manage users From This Route [ /security ]
1247
+
1248
+ ## Helper Functions
1249
+
1250
+ ```js
1251
+ site.onGET('/', (req, res) => {
1252
+ res.render('index.html', { name: 'amr', age: '36' }, { compress: !0, cache: false, parser: 'html css js' });
1253
+ res.render('custom.css', { 'font-size': '18px' }, { parser: 'css' });
1254
+ res.render('custom.js', { 'allow-ads': !0 }, { parser: 'js' });
1255
+ res.code = 301; // set response code to 301
1256
+ res.status(301); // set response code if not set to 301 and return response object
1257
+ res.set('Content-Type', 'text/plain'); // add response header
1258
+ res.remove('Content-Type'); // remove response header
1259
+ res.delete('Content-Type'); // remove response header
1260
+ res.redirect('/URL' , 302); // Any URL
1261
+ res.send('HTML CONTENT'); // Any HTML Content or object
1262
+ res.send(obj); // Any HTML Content or object
1263
+ res.htmlContent('HTML CONTENT'); // Any HTML Content
1264
+ res.html('index'); // like res.render
1265
+ res.css('bootstrap'); // css file name
1266
+ res.js('jquery'); // js file name
1267
+ res.json('items'); // json file name or object
1268
+ res.json(obj); // json file name or object
1269
+
1270
+ if (req.hasFeature('browser.chrome')) {
1271
+ }
1272
+ if (req.hasFeature('browser.firefox')) {
1273
+ }
1274
+ if (req.hasFeature('browser.edge')) {
1275
+ }
1276
+ if (req.hasFeature('browser.opera')) {
1277
+ }
1278
+ if (req.hasFeature('browser.ucbrowser')) {
1279
+ }
1280
+ if (req.hasFeature('browser.baidu')) {
1281
+ }
1282
+ if (req.hasFeature('browser.chromium')) {
1283
+ }
1284
+ if (req.hasFeature('browser.unknown')) {
1285
+ }
1286
+
1287
+ if (req.hasFeature('os.windows')) {
1288
+ }
1289
+ if (req.hasFeature('os.linux')) {
1290
+ }
1291
+ if (req.hasFeature('os.mac')) {
1292
+ }
1293
+ if (req.hasFeature('os.android')) {
1294
+ }
1295
+ if (req.hasFeature('os.unknown')) {
1296
+ }
1297
+
1298
+ req.ip; // user ip
1299
+ req.port; // user port
1300
+ req.ip2; // server ip
1301
+ req.port2; // server port
1302
+ req.features; // array of user info [os , browser]
1303
+ });
1304
+
1305
+ var person = { name: 'amr', email: 'absunstar' };
1306
+ var person2 = site.copy(person);
1307
+ person2.name = 'Abd Allah';
1308
+ site.log(person);
1309
+ site.log(person2);
1310
+
1311
+ var hash = site.md5('this content will be hashed as md5');
1312
+ var base64 = site.toBase64('this content will be encript as base64 string');
1313
+ var normal = site.fromBase64(base64);
1314
+ var jsonString = site.toJson(person);
1315
+ var jsonObj = site.fromJson(jsonString);
1316
+ site.log(hash);
1317
+ site.log(base64);
1318
+ site.log(normal);
1319
+ site.log(jsonString);
1320
+ site.log(jsonObj);
1321
+
1322
+ var name = 'absunstar';
1323
+ if (name.like('*sun*')) {
1324
+ site.log('yes');
1325
+ }
1326
+ ```
1327
+
1328
+ ## Events
1329
+
1330
+ - Events Are Global Actions Across Site
1331
+
1332
+ ```js
1333
+ site.on('event name', function (obj) {
1334
+ console.log('name : ' + obj.name);
1335
+ });
1336
+
1337
+ site.on('event name 2', function (list) {
1338
+ console.log('name : ' + list[0].name);
1339
+ console.log('name : ' + list[1].name);
1340
+ });
1341
+
1342
+ site.on('event name 3', function (obj, callback) {
1343
+ console.log('try long code : ' + obj.name);
1344
+ setTimeout(function () {
1345
+ callback();
1346
+ }, 3000);
1347
+ });
1348
+
1349
+ site.on('sync event name 1', function (obj, callback, next) {
1350
+ console.log('name : ' + obj.name);
1351
+ next(); // to run next event
1352
+ });
1353
+ site.on('sync event name 2', function (obj, callback, next) {
1354
+ console.log('name : ' + obj.name);
1355
+ next(); // to run next event
1356
+ });
1357
+ site.call('event name', { name: 'x1' });
1358
+ site.call('event name 2', [{ name: 'n1' }, { name: 'n2' }]);
1359
+ site.call('event name 3', { name: 'some long code' }, () => {
1360
+ console.log('after excute some long code');
1361
+ });
1362
+
1363
+ site.quee('sync event name 1', { name: 'x1' });
1364
+ site.quee('sync event name 2', { name: 'x2' });
1365
+ ```
1366
+
1367
+ ## Must Update
1368
+
1369
+ - You Must Update This Lib Every Month ( npm i isite )
1370
+
1371
+ ## Hints
1372
+
1373
+ - This Framework Make Security and Safty in the First Place
1374
+ - This Framework From Developer to Developers
1375
+ - This Framework Free for Education and Supported For Ever
1376
+ - This Framework Upgraded Arround the Clock
1377
+ - This Framework Development by One Developer
1378
+ - For Producation Contract what's up (+966568118373)
1379
+
1380
+ # Contact Me
1381
+
1382
+ - Patreon : https://www.patreon.com/next_corporation
1383
+ - Email : Absunstar@gmail.com
1384
+ - Linkedin : https://www.linkedin.com/in/absunstar
1385
+ - Github : https://github.com/absunstar
1386
+ - Paypal : https://paypal.me/absunstar
1387
+ - What's up: +966568118373