This commit is contained in:
2026-01-06 13:55:04 +01:00
parent 297de69928
commit f991ea6b9b
393 changed files with 41362 additions and 4811 deletions

View File

@@ -581,8 +581,10 @@ async function exportLogoAndFavicon() {
const assets = {
logo: null,
logoSvg: null,
favicon: null,
appleTouchIcon: null
appleTouchIcon: null,
siteIconId: null
};
try {
@@ -594,16 +596,24 @@ async function exportLogoAndFavicon() {
console.log(`📥 Found custom_logo ID: ${settings.custom_logo}`);
const logoMedia = await fetchMedia(settings.custom_logo);
if (logoMedia && logoMedia.source_url) {
const logoFilename = 'logo.webp';
const ext = path.extname(logoMedia.source_url);
const logoFilename = `logo${ext}`;
await downloadMedia(logoMedia.source_url, logoFilename);
assets.logo = `/media/${logoFilename}`;
console.log(`✅ Logo downloaded: ${logoFilename}`);
// Check if it's SVG
if (logoMedia.mime_type === 'image/svg+xml' || ext === '.svg') {
assets.logoSvg = `/media/${logoFilename}`;
console.log(`✅ SVG logo detected: ${logoFilename}`);
}
}
}
// Try to get site_icon
if (settings.site_icon) {
console.log(`📥 Found site_icon ID: ${settings.site_icon}`);
assets.siteIconId = settings.site_icon;
const iconMedia = await fetchMedia(settings.site_icon);
if (iconMedia && iconMedia.source_url) {
// Download as favicon.ico
@@ -620,26 +630,108 @@ async function exportLogoAndFavicon() {
}
}
// If no logo found in settings, try to find it in media
// WP CLI Equivalent: wp media list --search=logo --format=json
console.log('🔍 WP CLI Equivalent: Searching for logo media...');
if (!assets.logo) {
console.log('⚠️ No logo found in settings, searching media...');
// Try to find logo by filename pattern
const allMedia = await fetchWithPagination('media', { per_page: 100 });
const logoCandidates = allMedia.filter(m =>
m.title?.rendered?.toLowerCase().includes('logo') ||
m.slug?.toLowerCase().includes('logo') ||
m.source_url?.toLowerCase().includes('logo')
);
const logoCandidates = allMedia.filter(m => {
const title = m.title?.rendered?.toLowerCase() || '';
const slug = m.slug?.toLowerCase() || '';
const url = m.source_url?.toLowerCase() || '';
return title.includes('logo') || slug.includes('logo') || url.includes('logo');
});
if (logoCandidates.length > 0) {
const logoMedia = logoCandidates[0];
const logoFilename = 'logo.webp';
const ext = path.extname(logoMedia.source_url);
const logoFilename = `logo${ext}`;
await downloadMedia(logoMedia.source_url, logoFilename);
assets.logo = `/media/${logoFilename}`;
console.log(`✅ Logo found and downloaded: ${logoFilename}`);
if (logoMedia.mime_type === 'image/svg+xml' || ext === '.svg') {
assets.logoSvg = `/media/${logoFilename}`;
console.log(`✅ SVG logo found and downloaded: ${logoFilename}`);
} else {
console.log(`✅ Logo found and downloaded: ${logoFilename}`);
}
}
}
// WP CLI Equivalent: wp media list --mime=image/svg+xml --format=json
console.log('🔍 WP CLI Equivalent: Searching for SVG images...');
const allMedia = await fetchWithPagination('media', { per_page: 200 });
const svgImages = allMedia.filter(m => m.mime_type === 'image/svg+xml');
if (svgImages.length > 0) {
console.log(`📥 Found ${svgImages.length} SVG images`);
for (const svg of svgImages) {
const filename = `svg-${svg.id}-${path.basename(svg.source_url)}`;
await downloadMedia(svg.source_url, filename);
console.log(`✅ SVG downloaded: ${filename}`);
}
}
// WP CLI Equivalent: wp postmeta list --post_type=any --meta_key~=_vc --format=json
console.log('🔍 WP CLI Equivalent: Searching for Salient/VC images...');
const salientImages = new Set();
// Search pages and posts for Visual Composer meta
const searchEndpoints = ['pages', 'posts'];
for (const endpoint of searchEndpoints) {
const items = await fetchWithPagination(endpoint, { per_page: 100 });
items.forEach(item => {
// Look for VC-related meta
if (item.meta) {
Object.keys(item.meta).forEach(key => {
if (key.includes('_vc') || key.includes('vc_') || key.includes('salient')) {
const metaValue = item.meta[key];
if (typeof metaValue === 'string') {
// Extract URLs from meta value
const urlMatches = metaValue.match(/https?:\/\/[^\s"']+/g);
if (urlMatches) {
urlMatches.forEach(url => salientImages.add(url));
}
}
}
});
}
// Also check content for images
const content = item.content?.rendered || '';
const contentUrls = content.match(/https?:\/\/[^\s"']+\.(jpg|jpeg|png|webp|svg)/gi);
if (contentUrls) {
contentUrls.forEach(url => salientImages.add(url));
}
});
}
// Download Salient/VC images
if (salientImages.size > 0) {
console.log(`📥 Found ${salientImages.size} Salient/VC images`);
const salientManifest = [];
for (const url of salientImages) {
try {
const filename = `salient-${Date.now()}-${path.basename(url)}`;
await downloadMedia(url, filename);
salientManifest.push({
originalUrl: url,
localPath: `/media/${filename}`,
filename: filename
});
console.log(`✅ Salient image downloaded: ${filename}`);
} catch (err) {
console.warn(`⚠️ Failed to download Salient image ${url}:`, err.message);
}
}
// Save Salient images manifest
fs.writeFileSync(
path.join(OUTPUT_DIR, 'salient-images.json'),
JSON.stringify(salientManifest, null, 2)
);
}
// If no favicon found, try to download from common locations
if (!assets.favicon) {
console.log('⚠️ No favicon found in settings, trying common locations...');
@@ -744,6 +836,57 @@ async function generateTranslationMapping() {
return mapping;
}
async function exportWPCliPostmeta() {
console.log('\n📊 EXPORTING WP CLI POSTMETA (VC/Salient)');
const vcMeta = [];
try {
// Get all pages and posts
const pages = await fetchWithPagination('pages', { status: 'publish', per_page: 100 });
const posts = await fetchWithPagination('posts', { status: 'publish', per_page: 100 });
const allItems = [...pages, ...posts];
console.log(`🔍 Scanning ${allItems.length} items for VC/Salient meta...`);
allItems.forEach(item => {
if (item.meta) {
const vcKeys = Object.keys(item.meta).filter(key =>
key.includes('_vc') || key.includes('vc_') || key.includes('salient') || key.includes('wpb_')
);
if (vcKeys.length > 0) {
vcKeys.forEach(key => {
const value = item.meta[key];
vcMeta.push({
post_id: item.id,
post_type: item.type || 'page',
post_slug: item.slug,
meta_key: key,
meta_value: typeof value === 'string' ? value.substring(0, 200) : JSON.stringify(value),
full_value: value
});
});
}
}
});
// Save VC postmeta
fs.writeFileSync(
path.join(OUTPUT_DIR, 'vc-postmeta.json'),
JSON.stringify(vcMeta, null, 2)
);
console.log(`✅ VC/Salient postmeta: ${vcMeta.length} entries found`);
} catch (error) {
console.error('❌ Error exporting postmeta:', error.message);
}
return vcMeta;
}
async function generateRedirects() {
console.log('\n📊 GENERATING REDIRECT RULES');
@@ -785,7 +928,7 @@ async function generateRedirects() {
// Main Execution
async function main() {
console.log('🚀 WordPress → Next.js Data Export');
console.log('🚀 WordPress → Next.js Data Export (WP CLI Enhanced)');
console.log('=====================================');
console.log(`Target: ${BASE_URL}`);
console.log(`Output: ${OUTPUT_DIR}`);
@@ -799,10 +942,13 @@ async function main() {
await exportProducts();
await exportProductCategories();
await exportMenus();
// Step 2: WP CLI Enhanced exports
await exportWPCliPostmeta();
await exportMedia();
await exportLogoAndFavicon();
// Step 2: Generate mappings and redirects
// Step 3: Generate mappings and redirects
await generateTranslationMapping();
await generateRedirects();
@@ -812,6 +958,12 @@ async function main() {
console.log(`🖼️ Media directory: public/media/`);
console.log(`🎨 Logo/Favicon: public/`);
console.log('');
console.log('WP CLI Features:');
console.log('✓ SVG logo detection and download');
console.log('✓ All SVG images exported');
console.log('✓ Salient/VC postmeta extracted');
console.log('✓ All media downloaded locally');
console.log('');
console.log('Next steps:');
console.log('1. Review exported data for completeness');
console.log('2. Check for any missing translations');
@@ -838,6 +990,7 @@ module.exports = {
exportMedia,
exportSiteInfo,
exportLogoAndFavicon,
exportWPCliPostmeta,
generateTranslationMapping,
generateRedirects
};