metaowl 0.2.13 → 0.2.16
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.
- package/README.md +64 -0
- package/modules/templates-manager.js +13 -46
- package/package.json +1 -1
- package/vite/plugin.js +13 -30
package/README.md
CHANGED
|
@@ -63,6 +63,7 @@ All powered by a batteries-included Vite plugin that handles the build pipeline,
|
|
|
63
63
|
- [ESLint Config](#eslint-config)
|
|
64
64
|
- [PostCSS Config](#postcss-config)
|
|
65
65
|
- [TypeScript / jsconfig](#typescript--jsconfig)
|
|
66
|
+
- [Deployment](#deployment)
|
|
66
67
|
- [Contributing](#contributing)
|
|
67
68
|
- [License](#license)
|
|
68
69
|
|
|
@@ -1370,6 +1371,69 @@ Extend from the included base configs to get sensible defaults:
|
|
|
1370
1371
|
|
|
1371
1372
|
---
|
|
1372
1373
|
|
|
1374
|
+
## Deployment
|
|
1375
|
+
|
|
1376
|
+
MetaOWL provides two ways to build your application for production:
|
|
1377
|
+
|
|
1378
|
+
### Option 1: `npm run generate` (Recommended)
|
|
1379
|
+
|
|
1380
|
+
```bash
|
|
1381
|
+
npm run generate
|
|
1382
|
+
```
|
|
1383
|
+
|
|
1384
|
+
This command generates static HTML files for all routes. The result works **without any server configuration** on all web hosts:
|
|
1385
|
+
|
|
1386
|
+
- GitHub Pages
|
|
1387
|
+
- Vercel
|
|
1388
|
+
- Netlify
|
|
1389
|
+
- Cloudflare Pages
|
|
1390
|
+
- Any traditional web host
|
|
1391
|
+
|
|
1392
|
+
All pages are generated as separate HTML files at build time, so every route can be accessed directly.
|
|
1393
|
+
|
|
1394
|
+
### Option 2: `npm run build`
|
|
1395
|
+
|
|
1396
|
+
```bash
|
|
1397
|
+
npm run build
|
|
1398
|
+
```
|
|
1399
|
+
|
|
1400
|
+
This command creates a Single Page Application (SPA). Since all routes are handled client-side, the web server must **forward all requests to `index.html`** (SPA fallback).
|
|
1401
|
+
|
|
1402
|
+
#### Web Server Configuration by Host:
|
|
1403
|
+
|
|
1404
|
+
**Vercel, Netlify, Cloudflare Pages:**
|
|
1405
|
+
Create a `public/serve.json` file before building:
|
|
1406
|
+
|
|
1407
|
+
```json
|
|
1408
|
+
{
|
|
1409
|
+
"rewrites": [
|
|
1410
|
+
{ "source": "**", "destination": "/index.html" }
|
|
1411
|
+
]
|
|
1412
|
+
}
|
|
1413
|
+
```
|
|
1414
|
+
|
|
1415
|
+
**Apache (.htaccess):**
|
|
1416
|
+
```apache
|
|
1417
|
+
RewriteEngine On
|
|
1418
|
+
RewriteCond %{REQUEST_FILENAME} !-f
|
|
1419
|
+
RewriteCond %{REQUEST_FILENAME} !-d
|
|
1420
|
+
RewriteRule ^ /index.html [L]
|
|
1421
|
+
```
|
|
1422
|
+
|
|
1423
|
+
**nginx:**
|
|
1424
|
+
```nginx
|
|
1425
|
+
location / {
|
|
1426
|
+
try_files $uri $uri/ /index.html;
|
|
1427
|
+
}
|
|
1428
|
+
```
|
|
1429
|
+
|
|
1430
|
+
**Node.js (with serve):**
|
|
1431
|
+
```bash
|
|
1432
|
+
npx serve -s dist
|
|
1433
|
+
```
|
|
1434
|
+
|
|
1435
|
+
---
|
|
1436
|
+
|
|
1373
1437
|
## Contributing
|
|
1374
1438
|
|
|
1375
1439
|
Contributions are welcome! Please open an issue before submitting a pull request so we can discuss the change.
|
|
@@ -2,59 +2,26 @@
|
|
|
2
2
|
* @module TemplatesManager
|
|
3
3
|
*
|
|
4
4
|
* Template loading and merging utilities for OWL applications.
|
|
5
|
-
* Supports both runtime loading (legacy) and build-time inlined templates.
|
|
6
5
|
*/
|
|
7
6
|
import { loadFile } from '@odoo/owl'
|
|
8
7
|
|
|
9
|
-
/**
|
|
10
|
-
* Try to import inlined templates from build time.
|
|
11
|
-
* Returns null if not available (dev mode without inline plugin or legacy setup).
|
|
12
|
-
*/
|
|
13
|
-
async function getInlinedTemplates() {
|
|
14
|
-
try {
|
|
15
|
-
// In production (build), templates are inlined via Vite plugin
|
|
16
|
-
const { TEMPLATES } = await import('/src/templates.js')
|
|
17
|
-
return TEMPLATES
|
|
18
|
-
} catch (e) {
|
|
19
|
-
// In development or legacy setup, templates are loaded at runtime
|
|
20
|
-
return null
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
8
|
/**
|
|
25
9
|
* Loads and concatenates a list of OWL XML template files into a single
|
|
26
10
|
* `<templates>` string ready to be passed to OWL's mount() options.
|
|
27
11
|
*
|
|
28
|
-
*
|
|
29
|
-
* Otherwise, falls back to runtime loading of individual XML files.
|
|
30
|
-
*
|
|
31
|
-
* @param {string[]} [files] - Array of URL-style XML paths (ignored if inlined templates exist)
|
|
12
|
+
* @param {string[]} files - Array of URL-style XML paths, e.g. ['/owl/components/Header/Header.xml']
|
|
32
13
|
* @returns {Promise<string>}
|
|
33
14
|
*/
|
|
34
|
-
export async function mergeTemplates(files
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
} catch (e) {
|
|
47
|
-
console.error(`[metaowl] Failed to load template: ${file}`, e)
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return templates + '</templates>'
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Check if inlined templates are available.
|
|
55
|
-
* @returns {Promise<boolean>}
|
|
56
|
-
*/
|
|
57
|
-
export async function hasInlinedTemplates() {
|
|
58
|
-
const templates = await getInlinedTemplates()
|
|
59
|
-
return templates !== null
|
|
15
|
+
export async function mergeTemplates(files) {
|
|
16
|
+
const results = await Promise.all(
|
|
17
|
+
files.map(async (file) => {
|
|
18
|
+
try {
|
|
19
|
+
return await loadFile(file)
|
|
20
|
+
} catch (e) {
|
|
21
|
+
console.error(`[metaowl] Failed to load template: ${file}`, e)
|
|
22
|
+
return ''
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
)
|
|
26
|
+
return '<templates>' + results.join('') + '</templates>'
|
|
60
27
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metaowl",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.16",
|
|
4
4
|
"description": "Lightweight meta-framework for Odoo OWL — file-based routing, app mounting, Fetch helper, Cache, Meta tags, SSG generator, and a Vite plugin.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
package/vite/plugin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fileURLToPath } from 'node:url'
|
|
2
2
|
import { resolve, dirname } from 'node:path'
|
|
3
|
-
import { mkdirSync, copyFileSync, cpSync, existsSync
|
|
3
|
+
import { mkdirSync, copyFileSync, cpSync, existsSync } from 'node:fs'
|
|
4
4
|
import { createRequire } from 'node:module'
|
|
5
5
|
import { globSync } from 'glob'
|
|
6
6
|
import { config as dotenvConfig } from 'dotenv'
|
|
@@ -219,37 +219,20 @@ export async function metaowlPlugin(options = {}) {
|
|
|
219
219
|
closeBundle() {
|
|
220
220
|
const projectRoot = process.cwd()
|
|
221
221
|
|
|
222
|
-
//
|
|
223
|
-
const xmlFiles = [
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
let templates = '<templates>'
|
|
230
|
-
for (const file of xmlFiles) {
|
|
231
|
-
try {
|
|
232
|
-
templates += readFileSync(file, 'utf-8')
|
|
233
|
-
} catch (e) {
|
|
234
|
-
console.warn(`[metaowl] Failed to read template: ${file}`)
|
|
235
|
-
}
|
|
222
|
+
// Copy OWL XML templates (loaded at runtime via fetch — not processed by Vite)
|
|
223
|
+
const xmlFiles = globSync([`${componentsDir}/**/*.xml`, `${pagesDir}/**/*.xml`, `${layoutsDir}/**/*.xml`])
|
|
224
|
+
for (const xmlFile of xmlFiles) {
|
|
225
|
+
const relPath = xmlFile.replace(new RegExp(`^${root}[\\/]`), '')
|
|
226
|
+
const dest = resolve(_outDirResolved, relPath)
|
|
227
|
+
mkdirSync(dirname(dest), { recursive: true })
|
|
228
|
+
copyFileSync(resolve(projectRoot, xmlFile), dest)
|
|
236
229
|
}
|
|
237
|
-
templates += '</templates>'
|
|
238
|
-
|
|
239
|
-
// Escape for JavaScript string
|
|
240
|
-
const escaped = templates
|
|
241
|
-
.replace(/\\/g, '\\\\')
|
|
242
|
-
.replace(/'/g, "\\'")
|
|
243
|
-
.replace(/\n/g, '\\n')
|
|
244
|
-
.replace(/\r/g, '')
|
|
245
230
|
|
|
246
|
-
//
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
console.log(`[metaowl] Inlined ${xmlFiles.length} XML templates into templates.js`)
|
|
231
|
+
// Copy assets/images (referenced via absolute URLs in XML — not processed by Vite)
|
|
232
|
+
const srcImages = resolve(projectRoot, root, 'assets', 'images')
|
|
233
|
+
if (existsSync(srcImages)) {
|
|
234
|
+
cpSync(srcImages, resolve(_outDirResolved, 'assets', 'images'), { recursive: true })
|
|
235
|
+
}
|
|
253
236
|
}
|
|
254
237
|
}
|
|
255
238
|
]
|