isite 2024.8.5 → 2024.8.6

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