@mel000000/weweb-dynamic-metadata 1.0.8 → 1.0.10
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/package.json
CHANGED
|
@@ -172,7 +172,7 @@ export async function processFiles() {
|
|
|
172
172
|
|
|
173
173
|
// Ensure template exists and inject script
|
|
174
174
|
await ensureTemplateExists(templatePath);
|
|
175
|
-
await injectScriptInTemplate(templatePath);
|
|
175
|
+
await injectScriptInTemplate(templatePath, page);
|
|
176
176
|
|
|
177
177
|
// Fetch all metadata
|
|
178
178
|
const metadataMap = new Map();
|
|
@@ -1,53 +1,33 @@
|
|
|
1
1
|
// src/templates/metadata-injector.js
|
|
2
|
-
export
|
|
2
|
+
export async function metadata_injector_script(page) {
|
|
3
|
+
return `
|
|
3
4
|
<!-- METADATA INJECTOR -->
|
|
4
|
-
<script src="/
|
|
5
|
+
<script src="/${page.route}/metadata.js"></script>
|
|
5
6
|
|
|
6
7
|
<script>
|
|
7
8
|
(function() {
|
|
8
9
|
'use strict';
|
|
9
10
|
|
|
10
11
|
// Prevent duplicate execution
|
|
11
|
-
if (window.__METADATA_INJECTOR_LOADED)
|
|
12
|
-
console.log('🔄 Metadata injector already loaded, skipping...');
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
12
|
+
if (window.__METADATA_INJECTOR_LOADED) return;
|
|
15
13
|
window.__METADATA_INJECTOR_LOADED = true;
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// Configuration
|
|
20
|
-
const CONFIG = {
|
|
21
|
-
DEBUG: true,
|
|
22
|
-
META_TIMEOUT: 2000
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
// State
|
|
26
|
-
let currentMetadata = null;
|
|
27
|
-
let appliedId = null;
|
|
28
|
-
|
|
29
|
-
// Debug logging
|
|
30
|
-
function debugLog(...args) {
|
|
31
|
-
if (CONFIG.DEBUG) console.log('[Metadata]', ...args);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Get ID from URL
|
|
35
|
-
function getArticleId() {
|
|
15
|
+
function getId() {
|
|
36
16
|
const path = window.location.pathname;
|
|
37
17
|
const parts = path.split('/').filter(p => p.length);
|
|
38
18
|
|
|
39
|
-
// Case 1: /
|
|
40
|
-
if (parts[0] ===
|
|
19
|
+
// Case 1: /content/2
|
|
20
|
+
if (parts[0] === ${JSON.stringify(page.route)} && parts[1] && parts[1] !== '_param') {
|
|
41
21
|
return parts[1];
|
|
42
22
|
}
|
|
43
23
|
|
|
44
|
-
// Case 2: /
|
|
45
|
-
if (parts[0] ===
|
|
24
|
+
// Case 2: /content/_param/?id=2
|
|
25
|
+
if (parts[0] === ${JSON.stringify(page.route)} && parts[1] === '_param') {
|
|
46
26
|
return new URLSearchParams(window.location.search).get('id');
|
|
47
27
|
}
|
|
48
28
|
|
|
49
29
|
// Case 3: Reference mode (ID stored in global)
|
|
50
|
-
return window.
|
|
30
|
+
return window.__REFERENCE_CONTENT_ID;
|
|
51
31
|
}
|
|
52
32
|
|
|
53
33
|
// Update meta tags
|
|
@@ -62,32 +42,21 @@ export const METADATA_INJECTOR_SCRIPT = `
|
|
|
62
42
|
el.setAttribute('content', String(value).replace(/[<>]/g, ''));
|
|
63
43
|
}
|
|
64
44
|
|
|
65
|
-
// Apply metadata
|
|
66
45
|
function applyMetadata() {
|
|
67
|
-
const id =
|
|
46
|
+
const id = getId();
|
|
68
47
|
if (!id || !window.METADATA) return false;
|
|
69
48
|
|
|
70
49
|
const meta = window.METADATA[id];
|
|
71
|
-
if (!meta)
|
|
72
|
-
console.warn('⚠️ No metadata for ID:', id);
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
50
|
+
if (!meta) return false;
|
|
75
51
|
|
|
76
|
-
//
|
|
77
|
-
if (id === appliedId) return true;
|
|
78
|
-
|
|
79
|
-
debugLog('Applying metadata for ID:', id);
|
|
80
|
-
|
|
81
|
-
// Set title - FIXED: Don't remove the title tag, just update it
|
|
52
|
+
// Set title
|
|
82
53
|
if (meta.title) {
|
|
83
|
-
// Find existing title tag or create new one
|
|
84
54
|
let titleTag = document.querySelector('title');
|
|
85
55
|
if (!titleTag) {
|
|
86
56
|
titleTag = document.createElement('title');
|
|
87
57
|
document.head.appendChild(titleTag);
|
|
88
58
|
}
|
|
89
59
|
titleTag.textContent = meta.title;
|
|
90
|
-
// Also set document.title for good measure
|
|
91
60
|
document.title = meta.title;
|
|
92
61
|
}
|
|
93
62
|
|
|
@@ -123,9 +92,8 @@ export const METADATA_INJECTOR_SCRIPT = `
|
|
|
123
92
|
}
|
|
124
93
|
canonical.setAttribute('href', window.location.href.split('?')[0]);
|
|
125
94
|
|
|
126
|
-
// Structured data
|
|
95
|
+
// Structured data
|
|
127
96
|
if (meta.title || desc || img) {
|
|
128
|
-
// Remove existing JSON-LD
|
|
129
97
|
document.querySelectorAll('script[type="application/ld+json"]').forEach(el => el.remove());
|
|
130
98
|
|
|
131
99
|
const ldJson = {
|
|
@@ -142,10 +110,6 @@ export const METADATA_INJECTOR_SCRIPT = `
|
|
|
142
110
|
document.head.appendChild(script);
|
|
143
111
|
}
|
|
144
112
|
|
|
145
|
-
currentMetadata = meta;
|
|
146
|
-
appliedId = id;
|
|
147
|
-
|
|
148
|
-
console.log('✅ Metadata applied for', id);
|
|
149
113
|
return true;
|
|
150
114
|
}
|
|
151
115
|
|
|
@@ -155,15 +119,9 @@ export const METADATA_INJECTOR_SCRIPT = `
|
|
|
155
119
|
|
|
156
120
|
// Wait for metadata if not loaded
|
|
157
121
|
if (!window.METADATA) {
|
|
158
|
-
const timeout = setTimeout(() => {
|
|
159
|
-
console.log('⏰ Metadata timeout');
|
|
160
|
-
clearInterval(checkInterval);
|
|
161
|
-
}, CONFIG.META_TIMEOUT);
|
|
162
|
-
|
|
163
122
|
const checkInterval = setInterval(() => {
|
|
164
123
|
if (window.METADATA && applyMetadata()) {
|
|
165
124
|
clearInterval(checkInterval);
|
|
166
|
-
clearTimeout(timeout);
|
|
167
125
|
}
|
|
168
126
|
}, 50);
|
|
169
127
|
}
|
|
@@ -176,16 +134,7 @@ export const METADATA_INJECTOR_SCRIPT = `
|
|
|
176
134
|
init();
|
|
177
135
|
}
|
|
178
136
|
|
|
179
|
-
// Handle SPA navigation
|
|
180
|
-
let lastUrl = location.href;
|
|
181
|
-
setInterval(() => {
|
|
182
|
-
if (location.href !== lastUrl) {
|
|
183
|
-
lastUrl = location.href;
|
|
184
|
-
appliedId = null;
|
|
185
|
-
init();
|
|
186
|
-
}
|
|
187
|
-
}, 500);
|
|
188
|
-
|
|
189
137
|
})();
|
|
190
138
|
</script>
|
|
191
|
-
`;
|
|
139
|
+
`;
|
|
140
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// src/utils/template-injector.js
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import {
|
|
4
|
+
import { metadata_injector_script } from '../templates/metadata-injector.js';
|
|
5
5
|
|
|
6
|
-
export async function injectScriptInTemplate(templatePath) {
|
|
6
|
+
export async function injectScriptInTemplate(templatePath, page) {
|
|
7
7
|
try {
|
|
8
8
|
// Check if file exists
|
|
9
9
|
if (!await fs.pathExists(templatePath)) {
|
|
@@ -34,7 +34,7 @@ export async function injectScriptInTemplate(templatePath) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
// Insert script before </head>
|
|
37
|
-
template = template.replace('</head>',
|
|
37
|
+
template = template.replace('</head>', await metadata_injector_script(page) + '\n</head>');
|
|
38
38
|
|
|
39
39
|
// Write back
|
|
40
40
|
await fs.writeFile(templatePath, template, 'utf-8');
|