הפיתוח עובד על הקליינט ומדמה את פעולותיו.
המערכת תעבור על דפים נוספים ותקים קובץ אקסל עם כל המידע לאחר מכן תלך לדפים בלשונית של דפים ותעבור על כל השאר.
בקובץ הדפים שמגיעים מהסרגל העליון יראו בתצורה הבאה:
ראשי > חוות דעת זאפ

יש להיכנס לממשק הניהול לפתוח את האינספקט ( F12) ולהריץ בקונסול את הקוד הבא:
(async function exportKonimboPagesToExcel() {
console.log("? מתחיל באיסוף הדפים וייצוא לקובץ Excel...");
// טעינת ספריית SheetJS במידה ואינה קיימת בדף
if (typeof XLSX === 'undefined') {
console.log("⏳ טוען ספריית XLSX...");
await new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = "https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js";
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
}
// פונקציית עזר לניקוי ונרמול כתובות URL
const normalizeUrl = (rawUrl) => {
try {
const fullUrl = new URL(rawUrl, window.location.origin);
return fullUrl.origin + fullUrl.pathname + fullUrl.search;
} catch (e) {
return null;
}
};
const pagesData = [];
const processedUrls = new Set();
const processedTitles = new Set();
// 1. איסוף קישורים ממסך "דפים נוספים" (/admin/pages)
console.log("? סורק ראשית את מסך 'דפים נוספים'...");
let adminPagesUrls = [];
try {
const res = await fetch('/admin/pages');
if (res.ok) {
const htmlText = await res.text();
const parser = new DOMParser();
const doc = parser.parseFromString(htmlText, 'text/html');
const adminPageLinks = doc.querySelectorAll('a[href*="/admin/pages/"]');
adminPageLinks.forEach(a => {
let pageHref = a.getAttribute('href');
if (pageHref && !pageHref.includes('/new')) {
const cleanUrl = normalizeUrl(pageHref);
if (cleanUrl && cleanUrl.match(/\/admin\/pages\/\d+/)) {
if (!adminPagesUrls.includes(cleanUrl)) {
adminPagesUrls.push(cleanUrl);
}
}
}
});
}
} catch (e) {
console.error("שגיאה בטעינת מסך 'דפים נוספים':", e);
}
console.log(`? נמצאו ${adminPagesUrls.length} דפים במסך 'דפים נוספים'. מתחיל בעיבודם...`);
// 2. מעבר על 'דפים נוספים' ושליפת הנתונים
for (let i = 0; i < adminPagesUrls.length; i++) {
const url = adminPagesUrls[i];
try {
const res = await fetch(url);
const htmlText = await res.text();
const parser = new DOMParser();
const doc = parser.parseFromString(htmlText, 'text/html');
const getValue = (selector) => {
const el = doc.querySelector(selector);
return el ? el.value.trim() : '';
};
const pageTitle = getValue('#page_title, input[name="page[title]"]');
if (!pageTitle || processedTitles.has(pageTitle)) {
continue;
}
processedUrls.add(url);
processedTitles.add(pageTitle);
// בדיקת השדה "הצג תוכן של דף זה ב URL הזה" למניעת כפילות מול הסרגל
const customUrl = getValue('#page_current_search_url, input[name="page[current_search_url]"]');
if (customUrl) {
const cleanCustom = customUrl.replace(/^\//, '').replace(/\/$/, '');
if (cleanCustom) {
processedUrls.add(normalizeUrl(`/admin/edit_${cleanCustom}`));
processedUrls.add(normalizeUrl(`/admin/${cleanCustom}`));
}
}
const getSelectedText = (selector) => {
const el = doc.querySelector(selector);
if (el && el.selectedIndex !== -1 && el.options[el.selectedIndex]) {
return el.options[el.selectedIndex].text.trim();
}
return '';
};
let pageHtmlContent = '';
const textarea = doc.querySelector('textarea#page_content, textarea[name="page[content]"]');
if (textarea) {
pageHtmlContent = textarea.value.trim();
}
let createdAt = '';
let updatedAt = '';
const rows = doc.querySelectorAll('table.medium tbody tr');
rows.forEach(row => {
const text = row.innerText;
if (text.includes('תאריך יצירה')) {
createdAt = row.cells[1] ? row.cells[1].innerText.trim() : '';
}
if (text.includes('תאריך עדכון')) {
updatedAt = row.cells[1] ? row.cells[1].innerText.trim() : '';
}
});
const checkedElements = [];
const checkboxes = doc.querySelectorAll('input[name="page[current_element_ids][]"]:checked');
checkboxes.forEach(cb => {
const label = doc.querySelector(`label[for="${cb.id}"]`) || cb.nextElementSibling;
if (label && label.innerText) {
checkedElements.push(label.innerText.trim());
} else if (cb.id) {
checkedElements.push(cb.id);
}
});
pagesData.push({
"כותרת הדף": pageTitle,
"דף אבא": getSelectedText('#page_parent_id, select[name="page[parent_id]"]'),
"תצוגה בחנות": doc.querySelector('#page_store_visable:checked') ? "כן" : "לא",
"מיקום כללי": getValue('#page_position, input[name="page[position]"]'),
"CSS Class": getValue('#page_css_class, input[name="page[css_class]"]'),
"הצג תוכן ב-URL הזה": customUrl,
"קטגוריה": getSelectedText('#page_store_category_id, select[name="page[store_category_id]"]'),
"תוכן הדף (HTML)": pageHtmlContent,
"גוגל - Title": getValue('#page_seo_title, input[name="page[seo_title]"]'),
"גוגל - Description": getValue('#page_seo_description, input[name="page[seo_description]"]'),
"גוגל - Keywords": getValue('#page_seo_keywords, input[name="page[seo_keywords]"]'),
"גוגל - Slug": getValue('#page_slug, input[name="page[slug]"]'),
"תאריך יצירה": createdAt,
"תאריך עדכון": updatedAt,
"אלמנטים מחוברים": checkedElements.join(', ')
});
console.log(`✅ עובד דף מדפים נוספים (${pagesData.length}): "${pageTitle}"`);
} catch (err) {
console.error(`❌ שגיאה בקריאת הדף ${url}:`, err);
}
}
// 3. כעת עוברים על הסרגל העליון (כולל דף 404 ומעקב הזמנות)
console.log("? בודק דפים בסרגל העליון שלא הופיעו ב'דפים נוספים'...");
const menuLinks = Array.from(document.querySelectorAll('li.store_pages ul li a'));
for (let link of menuLinks) {
let href = link.getAttribute('href');
let titleText = link.innerText.trim();
if (!href) continue;
// להתעלם ממועדון לקוחות וקישורים חיצוניים לחנות
if (href.includes('customer_club') || titleText.includes('מועדון לקוחות')) {
console.log(`⏩ התעלמות מהרשמה למועדון לקוחות: "${titleText}"`);
continue;
}
if (href.startsWith('http://') || href.startsWith('https://')) {
try {
const linkUrl = new URL(href);
if (linkUrl.hostname !== window.location.hostname) {
continue;
}
} catch (e) {
continue;
}
}
// סינון לוגו וקישורי javascript
if (href.includes('edit_logo') || href.startsWith('javascript:')) {
continue;
}
// התעלמות מדף יצירה כללי אך הכללת דפים מיוחדים בעלי page_type (כמו דף 404 ומעקב הזמנות)
if (href.includes('/new') && !href.includes('page_type=')) {
continue;
}
// התעלמות מעמוד הריכוז עצמו
if (href === '/admin/pages' || href.endsWith('/admin/pages')) {
continue;
}
const cleanUrl = normalizeUrl(href);
if (processedUrls.has(cleanUrl)) {
console.log(`⏩ דילוג על דף סרגל שכבר מקושר ב'דפים נוספים': "${titleText}" (${cleanUrl})`);
continue;
}
// סריקת דף מהסרגל שלא היה קיים ב'דפים נוספים'
try {
const res = await fetch(cleanUrl);
if (!res.ok) continue;
const htmlText = await res.text();
const parser = new DOMParser();
const doc = parser.parseFromString(htmlText, 'text/html');
const getValue = (selector) => {
const el = doc.querySelector(selector);
return el ? el.value.trim() : '';
};
let pageTitle = getValue('#page_title, input[name="page[title]"]');
if (!pageTitle) {
// חילוץ כותרת מתוך ה-URL אם היא הועברה כפרמטר (למשל page_title=...)
const urlParams = new URLSearchParams(href.split('?')[1] || '');
if (urlParams.has('page_title')) {
pageTitle = urlParams.get('page_title');
} else {
pageTitle = titleText || "דף סרגל";
}
}
if (processedTitles.has(pageTitle)) {
console.log(`⏩ דילוג על דף סרגל כפול לפי כותרת: "${pageTitle}"`);
continue;
}
processedUrls.add(cleanUrl);
processedTitles.add(pageTitle);
const getSelectedText = (selector) => {
const el = doc.querySelector(selector);
if (el && el.selectedIndex !== -1 && el.options[el.selectedIndex]) {
return el.options[el.selectedIndex].text.trim();
}
return '';
};
let pageHtmlContent = '';
const textarea = doc.querySelector('textarea#page_content, textarea[name="page[content]"]');
if (textarea) {
pageHtmlContent = textarea.value.trim();
} else {
const formArea = doc.querySelector('.form, form');
if (formArea) pageHtmlContent = formArea.innerHTML.trim();
}
let createdAt = '';
let updatedAt = '';
const rows = doc.querySelectorAll('table.medium tbody tr');
rows.forEach(row => {
const text = row.innerText;
if (text.includes('תאריך יצירה')) {
createdAt = row.cells[1] ? row.cells[1].innerText.trim() : '';
}
if (text.includes('תאריך עדכון')) {
updatedAt = row.cells[1] ? row.cells[1].innerText.trim() : '';
}
});
const checkedElements = [];
const checkboxes = doc.querySelectorAll('input[name="page[current_element_ids][]"]:checked');
checkboxes.forEach(cb => {
const label = doc.querySelector(`label[for="${cb.id}"]`) || cb.nextElementSibling;
if (label && label.innerText) {
checkedElements.push(label.innerText.trim());
} else if (cb.id) {
checkedElements.push(cb.id);
}
});
pagesData.push({
"כותרת הדף": pageTitle,
"דף אבא": getSelectedText('#page_parent_id, select[name="page[parent_id]"]'),
"תצוגה בחנות": doc.querySelector('#page_store_visable:checked') ? "כן" : "לא",
"מיקום כללי": getValue('#page_position, input[name="page[position]"]'),
"CSS Class": getValue('#page_css_class, input[name="page[css_class]"]'),
"הצג תוכן ב-URL הזה": getValue('#page_current_search_url, input[name="page[current_search_url]"]'),
"קטגוריה": getSelectedText('#page_store_category_id, select[name="page[store_category_id]"]'),
"תוכן הדף (HTML)": pageHtmlContent,
"גוגל - Title": getValue('#page_seo_title, input[name="page[seo_title]"]'),
"גוגל - Description": getValue('#page_seo_description, input[name="page[seo_description]"]'),
"גוגל - Keywords": getValue('#page_seo_keywords, input[name="page[seo_keywords]"]'),
"גוגל - Slug": getValue('#page_slug, input[name="page[slug]"]'),
"תאריך יצירה": createdAt,
"תאריך עדכון": updatedAt,
"אלמנטים מחוברים": checkedElements.join(', ')
});
console.log(`✅ עובד דף מיוחד מהסרגל (${pagesData.length}): "${pageTitle}"`);
} catch (err) {
console.error(`❌ שגיאה בקריאת דף סרגל ${cleanUrl}:`, err);
}
}
// 4. יצירת קובץ ה-Excel
const worksheet = XLSX.utils.json_to_sheet(pagesData);
worksheet['!dir'] = "rtl";
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "דפי החנות");
XLSX.writeFile(workbook, "konimbo_pages_export.xlsx");
console.log(`? הטיפול הסתיים בהצלחה! נאספו ${pagesData.length} דפים בסך הכל (כולל דף 404 ומעקב הזמנות). הקובץ ירד כעת למחשבך.`);
})();בסיום הפעולה הקובץ יורד אוטומטית למחשב- ויש חיווי בקונסול:
